From da1afb377131cc753bf0a8dd3c9dec393a6173fa Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Wed, 18 May 2016 22:10:21 +0200 Subject: [PATCH] [DEV] Create function signature in c++11 and call with a json object (simple function not class function) --- jus/Client.h | 2 +- jus/Service.cpp | 93 ++++++++++++++++ jus/Service.h | 214 ++++++++++++++++++++++++++++++++++++ test/service1/appl/main.cpp | 3 +- 4 files changed, 310 insertions(+), 2 deletions(-) diff --git a/jus/Client.h b/jus/Client.h index ce48484..733add6 100644 --- a/jus/Client.h +++ b/jus/Client.h @@ -87,7 +87,7 @@ namespace jus { void createParam(ejson::Object& _obj, const std::vector& _param, _ARGS&&... _args) { ejson::Array array = _obj["param"].toArray(); ejson::Array array2; - for (auto& it : _param) { + for (const auto& it : _param) { array2.add(ejson::Boolean(it)); } array.add(array2); diff --git a/jus/Service.cpp b/jus/Service.cpp index 34bb094..68f4ed9 100644 --- a/jus/Service.cpp +++ b/jus/Service.cpp @@ -9,6 +9,99 @@ #include +generate_basic_type(void, "void"); +generate_basic_type(bool, "bool"); +generate_basic_type(float, "float"); +generate_basic_type(double, "double"); +generate_basic_type(int64_t, "int64"); +generate_basic_type(int32_t, "int32"); +generate_basic_type(int16_t, "int16"); +generate_basic_type(int8_t, "int8"); +generate_basic_type(uint64_t, "uint64"); +generate_basic_type(uint32_t, "uint32"); +generate_basic_type(uint16_t, "uint16"); +generate_basic_type(uint8_t, "uint8"); +generate_basic_type(std::string, "string"); + +template<> bool convertJsonTo(const ejson::Value& _value) { + return _value.toBoolean().get(); +} +template<> float convertJsonTo(const ejson::Value& _value) { + return _value.toNumber().get(); +} +template<> double convertJsonTo(const ejson::Value& _value) { + return _value.toNumber().get(); +} +template<> int64_t convertJsonTo(const ejson::Value& _value) { + return int64_t(_value.toNumber().get()); +} +template<> int32_t convertJsonTo(const ejson::Value& _value) { + return int32_t(_value.toNumber().get()); +} +template<> int16_t convertJsonTo(const ejson::Value& _value) { + return int16_t(_value.toNumber().get()); +} +template<> int8_t convertJsonTo(const ejson::Value& _value) { + return int8_t(_value.toNumber().get()); +} +template<> uint64_t convertJsonTo(const ejson::Value& _value) { + return uint64_t(_value.toNumber().get()); +} +template<> uint32_t convertJsonTo(const ejson::Value& _value) { + return uint32_t(_value.toNumber().get()); +} +template<> uint16_t convertJsonTo(const ejson::Value& _value) { + return uint16_t(_value.toNumber().get()); +} +template<> uint8_t convertJsonTo(const ejson::Value& _value) { + return uint8_t(_value.toNumber().get()); +} +template<> std::string convertJsonTo(const ejson::Value& _value) { + _value.display(); + return _value.toString().get(); +} + +template<> ejson::Value convertToJson(const bool& _value) { + return ejson::Boolean(_value); +} +template<> ejson::Value convertToJson(const float& _value) { + return ejson::Number(_value); +} +template<> ejson::Value convertToJson(const double& _value) { + return ejson::Number(_value); +} +template<> ejson::Value convertToJson(const int64_t& _value) { + return ejson::Number(_value); +} +template<> ejson::Value convertToJson(const int32_t& _value) { + return ejson::Number(_value); +} +template<> ejson::Value convertToJson(const int16_t& _value) { + return ejson::Number(_value); +} +template<> ejson::Value convertToJson(const int8_t& _value) { + return ejson::Number(_value); +} +template<> ejson::Value convertToJson(const uint64_t& _value) { + return ejson::Number(_value); +} +template<> ejson::Value convertToJson(const uint32_t& _value) { + return ejson::Number(_value); +} +template<> ejson::Value convertToJson(const uint16_t& _value) { + return ejson::Number(_value); +} +template<> ejson::Value convertToJson(const uint8_t& _value) { + return ejson::Number(_value); +} +template<> ejson::Value convertToJson(const std::string& _value) { + return ejson::String(_value); +} + + + + + jus::Service::Service() : propertyIp(this, "ip", "127.0.0.1", "Ip to connect server", &jus::Service::onPropertyChangeIp), propertyPort(this, "port", 1984, "Port to connect server", &jus::Service::onPropertyChangePort), diff --git a/jus/Service.h b/jus/Service.h index 9e20900..82d260d 100644 --- a/jus/Service.h +++ b/jus/Service.h @@ -10,6 +10,193 @@ #include #include +class ParamType { + protected: + const char* m_typeName; + public: + ParamType(const char* _name = ""): + m_typeName(_name) { + + } + const char* getName() const { + return m_typeName; + } +}; + +template +ParamType createType(); + +#define generate_basic_type(_type, _name) \ +template<> ParamType createType<_type>() {\ + return ParamType(_name); \ +} + +class CmdBase { + public: + template + class Type2String { + public: + //std::string operator()(); + static std::string name(); + }; + protected: + const std::string m_name; + public: + const std::string& getName() const { + return m_name; + } + protected: + const std::string m_description; + public: + const std::string& getDescription() const { + return m_description; + } + protected: + ParamType m_returnType; + std::vector m_listParamType; + protected: + CmdBase(const std::string& _name, + const std::string& _desc, + const ParamType& _retType, + const std::vector& _params): + m_name(_name), + m_description(_desc), + m_returnType(_retType), + m_listParamType(_params) { + + } + public: + virtual ~CmdBase() {}; + //virtual bool checkArguments(const std::vector& _params) = 0; + public: + std::string getPrototype() const { + std::string ret; + ret += m_returnType.getName(); + ret += " "; + ret += m_name; + ret += "("; + for (size_t iii=0; iii +JUS_TYPE convertJsonTo(const ejson::Value& _value); + +template +ejson::Value convertToJson(const JUS_TYPE& _value); + +template +class TypeList: public CmdBase { + protected: + //int32_t m_sizeParam; + public: + using functionType = JUS_RETURN (*)(JUS_TYPES...); + functionType m_function; + TypeList(const std::string& _name, const std::string& _desc, functionType _fptr): + CmdBase(_name, _desc, createType(), {createType()...}), + //m_sizeParam(sizeof...(JUS_TYPES)), + m_function(_fptr) { + + } + //template ::value>::type > + ejson::Value execute2(const ejson::Array& _params) { + ejson::Object out; + if (_params.size() != m_listParamType.size()) { + JUS_ERROR("Wrong number of Parameters ..."); + out.add("error", ejson::String("WRONG-PARAMETER-NUMBER")); + std::string help = "request "; + help += etk::to_string(_params.size()); + help += " parameters and need "; + help += etk::to_string(m_listParamType.size()); + help += " parameters. prototype function:"; + help += getPrototype(); + out.add("error-help", ejson::String(help)); + return out; + } + // TODO : Check params ... + int32_t idParam = 0; + ejson::Value retVal = convertToJson(m_function(convertJsonTo(_params[idParam++])...)); + out.add("return", retVal); + return out; + } + + ejson::Value execute(const ejson::Array& _params) override { + return execute2(_params); + } +}; +// Void special case : +template +class TypeListVoid: public CmdBase { + protected: + //int32_t m_sizeParam; + public: + using functionType = void (*)(JUS_TYPES...); + functionType m_function; + TypeListVoid(const std::string& _name, const std::string& _desc, functionType _fptr): + CmdBase(_name, _desc, createType(), {createType()...}), + //m_sizeParam(sizeof...(JUS_TYPES)), + m_function(_fptr) { + + } + ejson::Value execute(const ejson::Array& _params) override { + ejson::Object out; + if (_params.size() != m_listParamType.size()) { + JUS_ERROR("Wrong number of Parameters ..."); + out.add("error", ejson::String("WRONG-PARAMETER-NUMBER")); + std::string help = "request "; + help += etk::to_string(_params.size()); + help += " parameters and need "; + help += etk::to_string(m_listParamType.size()); + help += " parameters. prototype function:"; + help += getPrototype(); + out.add("error-help", ejson::String(help)); + return out; + } + // TODO : Check params ... + int32_t idParam = m_listParamType.size()-1; + m_function(convertJsonTo(_params[idParam--])...); + out.add("return", ejson::Null()); + return out; + } +}; + +template +CmdBase* createCmd(const std::string& _name, const std::string& _desc, JUS_RETURN (*_fffp)(JUS_TYPES...)) { + return new TypeList(_name, _desc, _fffp); +} +template +CmdBase* createCmd(const std::string& _name, const std::string& _desc, void (*_fffp)(JUS_TYPES...)) { + return new TypeListVoid(_name, _desc, _fffp); +} + + +static double mulllll(double _val1) { + double _val2 = 2.0f; + JUS_ERROR("Call with parameter : " << _val1); + return _val1*_val2; +} + +static void mulllll2(std::string _value, int32_t _val1) { + JUS_ERROR("Call with parameter : " << _value); + JUS_ERROR(" parameter : " << _val1); +} + +static std::string mulllll3(float _value, bool _val1) { + double _val2 = 1.0f; + return ""; +} + +static bool mulllll4() { + return false; +} namespace jus { class Service : public eproperty::Interface { public: @@ -71,6 +258,33 @@ namespace jus { void advertise(const std::string& _name, JUS_RETURN_VALUE (JUS_CLASS_TYPE::*_func)(const JUS_FUNC_ARGS_TYPE&... _args), const std::string& _desc) { + + //CmdBase* tmp = createCmd(_name, &mulllll); + CmdBase* tmp = createCmd(_name, "desc", &mulllll); + JUS_ERROR("Signature : " << tmp->getPrototype()); + { + ejson::Array param; + param.add(ejson::Number(58.5)); + ejson::Value out = tmp->execute(param); + JUS_ERROR(" return: "); + out.display(); + } + + + tmp = createCmd(_name, "desc", &mulllll2); + JUS_ERROR("Signature2 : " << tmp->getPrototype()); + { + ejson::Array param; + param.add(ejson::String("coucou")); + param.add(ejson::Number(1563)); + ejson::Value out = tmp->execute(param); + JUS_ERROR(" return: "); + out.display(); + } + tmp = createCmd(_name, "desc", &mulllll3); + JUS_ERROR("Signature3 : " << tmp->getPrototype()); + tmp = createCmd(_name, "desc", &mulllll4); + JUS_ERROR("Signature4 : " << tmp->getPrototype()); /* std::vector plop = createSignature(_args): JUS_ERROR("signature:"); diff --git a/test/service1/appl/main.cpp b/test/service1/appl/main.cpp index 10cf04a..63638d3 100644 --- a/test/service1/appl/main.cpp +++ b/test/service1/appl/main.cpp @@ -13,7 +13,8 @@ namespace appl { class Service1 : public jus::Service { private: - double mul(const double& _val1, const double& _val2) { + double mul(const double& _val1) {//, const double& _val2) { + double _val2 = 1.0f; return _val1*_val2; } public: