/** @file * @author Edouard DUPIN * @copyright 2016, Edouard DUPIN, all right reserved * @license APACHE v2.0 (see license file) */ #pragma once #include #include #include #include #include namespace jus { template void executeCall(const ememory::SharedPtr& _interfaceClient, uint64_t _transactionId, uint64_t _clientId, JUS_RETURN (*_func)(JUS_TYPES...), jus::Buffer& _obj) { #if defined(__clang__) // clang generate a basic warning: // warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced] int32_t idParam = 0; JUS_RETURN ret = jus::convertToJson(_func(_obj.getParameter(idParam++)...)); #elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER) int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1; JUS_RETURN ret = jus::convertToJson(_func(_obj.getParameter(idParam--)...)); #else #error Must be implemented ... JUS_RETURN ret = ejson::Null(); #endif _interfaceClient->addAsync([=](TcpString* _interface) { _interface->answerValue(_transactionId, ret, _clientId); return true; }); } template void executeCall(const ememory::SharedPtr& _interfaceClient, uint64_t _transactionId, uint64_t _clientId, void (*_func)(JUS_TYPES...), jus::Buffer& _obj) { ejson::Object out; #if defined(__clang__) // clang generate a basic warning: // warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced] int32_t idParam = 0; _func(_obj.getParameter(idParam++)...); #elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER) int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1; _func(_obj.getParameter(idParam--)...); #else #error Must be implemented ... #endif _interfaceClient->addAsync([=](TcpString* _interface) { _interface->answerVoid(_transactionId, _clientId); return true; }); } template class AbstractFunctionTypeDirect: public jus::AbstractFunction { protected: static const ParamType m_returnType; static const ParamType m_paramType[sizeof...(JUS_TYPES)]; public: using functionType = JUS_RETURN (*)(JUS_TYPES...); functionType m_function; AbstractFunctionTypeDirect(const std::string& _name, const std::string& _desc, functionType _fptr): AbstractFunction(_name, _desc), m_function(_fptr) { } std::string getPrototype() const override { std::string ret; ret += m_returnType.getName(); ret += " "; ret += m_name; ret += "("; for (size_t iii=0; iii getPrototypeParam() const override { std::vector out; for (size_t iii=0; iii& _interfaceClient, uint64_t _transactionId, uint64_t _clientId, jus::Buffer& _obj, void* _class) override { // check parameter number if (_obj.getNumberParameter() != sizeof...(JUS_TYPES)) { std::string help = "request "; help += etk::to_string(_obj.getNumberParameter()); help += " parameters and need "; help += etk::to_string(sizeof...(JUS_TYPES)); help += " parameters. prototype function:"; help += getPrototype(); _interfaceClient->answerError(_transactionId, "WRONG-PARAMETER-NUMBER", help, _clientId); return; } // check parameter compatibility for (size_t iii=0; iiianswerError(_transactionId, "WRONG-PARAMETER-TYPE", std::string("Parameter id ") + etk::to_string(iii) + " not compatible with type: '" + m_paramType[iii].getName() + "'", _clientId); return; } } // execute cmd: jus::executeCall(_interfaceClient, _transactionId, _clientId, m_function, _obj); } }; template const ParamType AbstractFunctionTypeDirect::m_returnType = createType(); template const ParamType AbstractFunctionTypeDirect::m_paramType[sizeof...(JUS_TYPES)] = {createType()...}; template AbstractFunction* createAbstractFunctionDirect(const std::string& _name, const std::string& _desc, JUS_RETURN (*_fffp)(JUS_TYPES...)) { return new AbstractFunctionTypeDirect(_name, _desc, _fffp); } }