[DEV] connect and unconnect better interface

This commit is contained in:
Edouard DUPIN 2016-05-24 22:29:03 +02:00
parent 2978045244
commit 181930f01d
22 changed files with 734 additions and 489 deletions

View File

@ -6,120 +6,146 @@
#include <jus/AbstractFunction.h>
#include <jus/debug.h>
template<> bool convertJsonTo<bool>(const ejson::Value& _value) {
template<> bool jus::convertJsonTo<bool>(const ejson::Value& _value) {
return _value.toBoolean().get();
}
template<> float convertJsonTo<float>(const ejson::Value& _value) {
template<> float jus::convertJsonTo<float>(const ejson::Value& _value) {
return _value.toNumber().get();
}
template<> double convertJsonTo<double>(const ejson::Value& _value) {
template<> double jus::convertJsonTo<double>(const ejson::Value& _value) {
return _value.toNumber().get();
}
template<> int64_t convertJsonTo<int64_t>(const ejson::Value& _value) {
template<> int64_t jus::convertJsonTo<int64_t>(const ejson::Value& _value) {
return int64_t(_value.toNumber().get());
}
template<> int32_t convertJsonTo<int32_t>(const ejson::Value& _value) {
template<> int32_t jus::convertJsonTo<int32_t>(const ejson::Value& _value) {
//_value.display();
return int32_t(_value.toNumber().get());
}
template<> int16_t convertJsonTo<int16_t>(const ejson::Value& _value) {
template<> int16_t jus::convertJsonTo<int16_t>(const ejson::Value& _value) {
return int16_t(_value.toNumber().get());
}
template<> int8_t convertJsonTo<int8_t>(const ejson::Value& _value) {
template<> int8_t jus::convertJsonTo<int8_t>(const ejson::Value& _value) {
return int8_t(_value.toNumber().get());
}
template<> uint64_t convertJsonTo<uint64_t>(const ejson::Value& _value) {
template<> uint64_t jus::convertJsonTo<uint64_t>(const ejson::Value& _value) {
return uint64_t(_value.toNumber().get());
}
template<> uint32_t convertJsonTo<uint32_t>(const ejson::Value& _value) {
template<> uint32_t jus::convertJsonTo<uint32_t>(const ejson::Value& _value) {
return uint32_t(_value.toNumber().get());
}
template<> uint16_t convertJsonTo<uint16_t>(const ejson::Value& _value) {
template<> uint16_t jus::convertJsonTo<uint16_t>(const ejson::Value& _value) {
return uint16_t(_value.toNumber().get());
}
template<> uint8_t convertJsonTo<uint8_t>(const ejson::Value& _value) {
template<> uint8_t jus::convertJsonTo<uint8_t>(const ejson::Value& _value) {
return uint8_t(_value.toNumber().get());
}
template<> std::string convertJsonTo<std::string>(const ejson::Value& _value) {
template<> std::string jus::convertJsonTo<std::string>(const ejson::Value& _value) {
//_value.display();
return _value.toString().get();
}
template<> ejson::Value convertToJson<bool>(const bool& _value) {
template<> ejson::Value jus::convertToJson<bool>(const bool& _value) {
return ejson::Boolean(_value);
}
template<> ejson::Value convertToJson<float>(const float& _value) {
template<> ejson::Value jus::convertToJson<float>(const float& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<double>(const double& _value) {
template<> ejson::Value jus::convertToJson<double>(const double& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<int64_t>(const int64_t& _value) {
template<> ejson::Value jus::convertToJson<int64_t>(const int64_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<int32_t>(const int32_t& _value) {
template<> ejson::Value jus::convertToJson<int32_t>(const int32_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<int16_t>(const int16_t& _value) {
template<> ejson::Value jus::convertToJson<int16_t>(const int16_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<int8_t>(const int8_t& _value) {
template<> ejson::Value jus::convertToJson<int8_t>(const int8_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<uint64_t>(const uint64_t& _value) {
template<> ejson::Value jus::convertToJson<uint64_t>(const uint64_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<uint32_t>(const uint32_t& _value) {
template<> ejson::Value jus::convertToJson<uint32_t>(const uint32_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<uint16_t>(const uint16_t& _value) {
template<> ejson::Value jus::convertToJson<uint16_t>(const uint16_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<uint8_t>(const uint8_t& _value) {
template<> ejson::Value jus::convertToJson<uint8_t>(const uint8_t& _value) {
return ejson::Number(_value);
}
template<> ejson::Value convertToJson<std::string>(const std::string& _value) {
template<> ejson::Value jus::convertToJson<std::string>(const std::string& _value) {
return ejson::String(_value);
}
template<> bool convertStringTo<bool>(const std::string& _value) {
template<> bool jus::convertStringTo<bool>(const std::string& _value) {
return etk::string_to_bool(_value);
}
template<> float convertStringTo<float>(const std::string& _value) {
template<> float jus::convertStringTo<float>(const std::string& _value) {
return etk::string_to_float(_value);
}
template<> double convertStringTo<double>(const std::string& _value) {
template<> double jus::convertStringTo<double>(const std::string& _value) {
return etk::string_to_double(_value);
}
template<> int64_t convertStringTo<int64_t>(const std::string& _value) {
template<> int64_t jus::convertStringTo<int64_t>(const std::string& _value) {
return etk::string_to_int64_t(_value);
}
template<> int32_t convertStringTo<int32_t>(const std::string& _value) {
template<> int32_t jus::convertStringTo<int32_t>(const std::string& _value) {
return etk::string_to_int32_t(_value);
}
template<> int16_t convertStringTo<int16_t>(const std::string& _value) {
template<> int16_t jus::convertStringTo<int16_t>(const std::string& _value) {
return etk::string_to_int16_t(_value);
}
template<> int8_t convertStringTo<int8_t>(const std::string& _value) {
template<> int8_t jus::convertStringTo<int8_t>(const std::string& _value) {
return etk::string_to_int8_t(_value);
}
template<> uint64_t convertStringTo<uint64_t>(const std::string& _value) {
template<> uint64_t jus::convertStringTo<uint64_t>(const std::string& _value) {
return etk::string_to_uint64_t(_value);
}
template<> uint32_t convertStringTo<uint32_t>(const std::string& _value) {
template<> uint32_t jus::convertStringTo<uint32_t>(const std::string& _value) {
return etk::string_to_uint32_t(_value);
}
template<> uint16_t convertStringTo<uint16_t>(const std::string& _value) {
template<> uint16_t jus::convertStringTo<uint16_t>(const std::string& _value) {
return etk::string_to_uint16_t(_value);
}
template<> uint8_t convertStringTo<uint8_t>(const std::string& _value) {
template<> uint8_t jus::convertStringTo<uint8_t>(const std::string& _value) {
return etk::string_to_uint8_t(_value);
}
template<> std::string convertStringTo<std::string>(const std::string& _value) {
template<> std::string jus::convertStringTo<std::string>(const std::string& _value) {
return _value;
}
bool AbstractFunction::checkCompatibility(const ParamType& _type, const ejson::Value& _params) {
const std::string& jus::AbstractFunction::getName() const {
return m_name;
}
const std::string& jus::AbstractFunction::getDescription() const {
return m_description;
}
void jus::AbstractFunction::setDescription(const std::string& _desc) {
m_description = _desc;
}
void jus::AbstractFunction::setParam(int32_t _idParam, const std::string& _name, const std::string& _desc) {
JUS_TODO("not implemented set param ... '" << _name << "'");
}
void jus::AbstractFunction::addParam(const std::string& _name, const std::string& _desc) {
m_paramsDescription.push_back(std::make_pair(_name, _desc));
}
jus::AbstractFunction::AbstractFunction(const std::string& _name,
const std::string& _desc):
m_name(_name),
m_description(_desc) {
}
bool jus::AbstractFunction::checkCompatibility(const ParamType& _type, const ejson::Value& _params) {
if (createType<bool>() == _type) {
return _params.isBoolean();
}
@ -140,6 +166,6 @@ bool AbstractFunction::checkCompatibility(const ParamType& _type, const ejson::V
}
return false;
}
bool AbstractFunction::checkCompatibility(const ParamType& _type, const std::string& _params) {
bool jus::AbstractFunction::checkCompatibility(const ParamType& _type, const std::string& _params) {
return false;
}

View File

@ -10,47 +10,42 @@
#include <ejson/ejson.h>
#include <jus/debug.h>
#include <jus/ParamType.h>
class AbstractFunction {
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:
AbstractFunction(const std::string& _name,
const std::string& _desc):
m_name(_name),
m_description(_desc) {
}
public:
virtual ~AbstractFunction() {};
bool checkCompatibility(const ParamType& _type, const ejson::Value& _params);
bool checkCompatibility(const ParamType& _type, const std::string& _params);
public:
virtual std::string getPrototype() const = 0;
virtual ejson::Value executeJson(const ejson::Array& _params, void* _class=nullptr) = 0;
virtual std::string executeString(const std::vector<std::string>& _params, void* _class=nullptr) = 0;
};
template<class JUS_TYPE>
JUS_TYPE convertStringTo(const std::string& _value);
template<class JUS_TYPE>
JUS_TYPE convertJsonTo(const ejson::Value& _value);
template<class JUS_TYPE>
ejson::Value convertToJson(const JUS_TYPE& _value);
/*
template <class, class...>
class TypeList;
*/
namespace jus {
class AbstractFunction {
protected:
std::string m_name;
public:
const std::string& getName() const;
protected:
std::string m_description;
public:
const std::string& getDescription() const;
void setDescription(const std::string& _desc);
protected:
std::vector<std::pair<std::string, std::string>> m_paramsDescription;
public:
void setParam(int32_t _idParam, const std::string& _name, const std::string& _desc);
void addParam(const std::string& _name, const std::string& _desc);
protected:
AbstractFunction(const std::string& _name, const std::string& _desc="");
public:
virtual ~AbstractFunction() {};
public:
bool checkCompatibility(const ParamType& _type, const ejson::Value& _params);
bool checkCompatibility(const ParamType& _type, const std::string& _params);
public:
virtual std::string getPrototype() const = 0;
virtual ejson::Value executeJson(const ejson::Array& _params, void* _class=nullptr) = 0;
virtual std::string executeString(const std::vector<std::string>& _params, void* _class=nullptr) = 0;
};
template<class JUS_TYPE>
JUS_TYPE convertStringTo(const std::string& _value);
template<class JUS_TYPE>
JUS_TYPE convertJsonTo(const ejson::Value& _value);
template<class JUS_TYPE>
ejson::Value convertToJson(const JUS_TYPE& _value);
}

View File

@ -10,166 +10,167 @@
#include <ejson/ejson.h>
#include <jus/debug.h>
#include <jus/AbstractFunction.h>
template <class JUS_CLASS_TYPE, class JUS_RETURN, class... JUS_TYPES>
ejson::Value executeClassCallJson(JUS_CLASS_TYPE* _pointer, JUS_RETURN (JUS_CLASS_TYPE::*_func)(JUS_TYPES...), const ejson::Array& _params) {
#if defined(__clang__)
// clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0;
return convertToJson((*_pointer.*_func)((convertJsonTo<JUS_TYPES>(_params[idParam++]))...));
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
return convertToJson((*_pointer.*_func)(convertJsonTo<JUS_TYPES>(_params[idParam--])...));
#else
#error Must be implemented ...
#endif
return ejson::Null();
}
template <class JUS_CLASS_TYPE, class... JUS_TYPES>
ejson::Value executeClassCallJson(JUS_CLASS_TYPE* _pointer, void (JUS_CLASS_TYPE::*_func)(JUS_TYPES...), const ejson::Array& _params) {
ejson::Object out;
#if defined(__clang__)
// clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0;
(*_pointer.*_func)((convertJsonTo<JUS_TYPES>(_params[idParam++]))...);
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
(*_pointer.*_func)(convertJsonTo<JUS_TYPES>(_params[idParam--])...);
#else
#error Must be implemented ...
#endif
return ejson::Null();
}
template <class JUS_CLASS_TYPE, class JUS_RETURN, class... JUS_TYPES>
std::string executeClassCallString(JUS_CLASS_TYPE* _pointer, JUS_RETURN (JUS_CLASS_TYPE::*_func)(JUS_TYPES...), const std::vector<std::string>& _params) {
#if defined(__clang__)
// clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0;
return etk::to_string((*_pointer.*_func)((convertStringTo<JUS_TYPES>(_params[idParam++]))...));
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
return etk::to_string((*_pointer.*_func)(convertStringTo<JUS_TYPES>(_params[idParam--])...));
#else
#error Must be implemented ...
#endif
return "";
}
template <class JUS_CLASS_TYPE, class... JUS_TYPES>
std::string executeClassCallString(JUS_CLASS_TYPE* _pointer, void (JUS_CLASS_TYPE::*_func)(JUS_TYPES...), const std::vector<std::string>& _params) {
ejson::Object out;
#if defined(__clang__)
// clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0;
(*_pointer.*_func)((convertStringTo<JUS_TYPES>(_params[idParam++]))...);
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
(*_pointer.*_func)(convertStringTo<JUS_TYPES>(_params[idParam--])...);
#else
#error Must be implemented ...
#endif
return "";
}
template <class JUS_RETURN, class JUS_CLASS_TYPE, class... JUS_TYPES>
class AbstractFunctionTypeClass: public AbstractFunction {
protected:
static const ParamType m_returnType;
static const ParamType m_paramType[sizeof...(JUS_TYPES)];
public:
using functionType = JUS_RETURN (JUS_CLASS_TYPE::*)(JUS_TYPES...);
functionType m_function;
AbstractFunctionTypeClass(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<sizeof...(JUS_TYPES); ++iii) {
if (iii != 0) {
ret += ", ";
namespace jus {
template <class JUS_CLASS_TYPE, class JUS_RETURN, class... JUS_TYPES>
ejson::Value executeClassCallJson(JUS_CLASS_TYPE* _pointer, JUS_RETURN (JUS_CLASS_TYPE::*_func)(JUS_TYPES...), const ejson::Array& _params) {
#if defined(__clang__)
// clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0;
return convertToJson((*_pointer.*_func)((convertJsonTo<JUS_TYPES>(_params[idParam++]))...));
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
return convertToJson((*_pointer.*_func)(convertJsonTo<JUS_TYPES>(_params[idParam--])...));
#else
#error Must be implemented ...
#endif
return ejson::Null();
}
template <class JUS_CLASS_TYPE, class... JUS_TYPES>
ejson::Value executeClassCallJson(JUS_CLASS_TYPE* _pointer, void (JUS_CLASS_TYPE::*_func)(JUS_TYPES...), const ejson::Array& _params) {
ejson::Object out;
#if defined(__clang__)
// clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0;
(*_pointer.*_func)((convertJsonTo<JUS_TYPES>(_params[idParam++]))...);
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
(*_pointer.*_func)(convertJsonTo<JUS_TYPES>(_params[idParam--])...);
#else
#error Must be implemented ...
#endif
return ejson::Null();
}
template <class JUS_CLASS_TYPE, class JUS_RETURN, class... JUS_TYPES>
std::string executeClassCallString(JUS_CLASS_TYPE* _pointer, JUS_RETURN (JUS_CLASS_TYPE::*_func)(JUS_TYPES...), const std::vector<std::string>& _params) {
#if defined(__clang__)
// clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0;
return etk::to_string((*_pointer.*_func)((convertStringTo<JUS_TYPES>(_params[idParam++]))...));
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
return etk::to_string((*_pointer.*_func)(convertStringTo<JUS_TYPES>(_params[idParam--])...));
#else
#error Must be implemented ...
#endif
return "";
}
template <class JUS_CLASS_TYPE, class... JUS_TYPES>
std::string executeClassCallString(JUS_CLASS_TYPE* _pointer, void (JUS_CLASS_TYPE::*_func)(JUS_TYPES...), const std::vector<std::string>& _params) {
ejson::Object out;
#if defined(__clang__)
// clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0;
(*_pointer.*_func)((convertStringTo<JUS_TYPES>(_params[idParam++]))...);
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
(*_pointer.*_func)(convertStringTo<JUS_TYPES>(_params[idParam--])...);
#else
#error Must be implemented ...
#endif
return "";
}
template <class JUS_RETURN, class JUS_CLASS_TYPE, class... JUS_TYPES>
class AbstractFunctionTypeClass: public jus::AbstractFunction {
protected:
static const ParamType m_returnType;
static const ParamType m_paramType[sizeof...(JUS_TYPES)];
public:
using functionType = JUS_RETURN (JUS_CLASS_TYPE::*)(JUS_TYPES...);
functionType m_function;
AbstractFunctionTypeClass(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<sizeof...(JUS_TYPES); ++iii) {
if (iii != 0) {
ret += ", ";
}
ret += m_paramType[iii].getName();
}
ret += m_paramType[iii].getName();
ret += ");";
return ret;
}
ret += ");";
return ret;
}
ejson::Value executeJson(const ejson::Array& _params, void* _class) override {
JUS_CLASS_TYPE* tmpClass = (JUS_CLASS_TYPE*)_class;
ejson::Object out;
// check parameter number
if (_params.size() != sizeof...(JUS_TYPES)) {
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(sizeof...(JUS_TYPES));
help += " parameters. prototype function:";
help += getPrototype();
out.add("error-help", ejson::String(help));
return out;
}
// check parameter compatibility
for (size_t iii=0; iii<sizeof...(JUS_TYPES); ++iii) {
if (checkCompatibility(m_paramType[iii], _params[iii]) == false) {
out.add("error", ejson::String("WRONG-PARAMETER-TYPE"));
out.add("error-help", ejson::String("Parameter id " + etk::to_string(iii) + " not compatible with type: '" + m_paramType[iii].getName() + "'"));
ejson::Value executeJson(const ejson::Array& _params, void* _class) override {
JUS_CLASS_TYPE* tmpClass = (JUS_CLASS_TYPE*)_class;
ejson::Object out;
// check parameter number
if (_params.size() != sizeof...(JUS_TYPES)) {
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(sizeof...(JUS_TYPES));
help += " parameters. prototype function:";
help += getPrototype();
out.add("error-help", ejson::String(help));
return out;
}
}
// execute cmd:
ejson::Value retVal = executeClassCallJson(tmpClass, m_function, _params);
out.add("return", retVal);
return out;
}
std::string executeString(const std::vector<std::string>& _params, void* _class) override {
JUS_CLASS_TYPE* tmpClass = (JUS_CLASS_TYPE*)_class;
std::string out;
// check parameter number
if (_params.size() != sizeof...(JUS_TYPES)) {
JUS_ERROR("Wrong number of Parameters ...");
out += "error:WRONG-PARAMETER-NUMBER;";
out += "error-help:request ";
out += etk::to_string(_params.size());
out += " parameters and need ";
out += etk::to_string(sizeof...(JUS_TYPES));
out += " parameters. prototype function:";
out += getPrototype();
// check parameter compatibility
for (size_t iii=0; iii<sizeof...(JUS_TYPES); ++iii) {
if (checkCompatibility(m_paramType[iii], _params[iii]) == false) {
out.add("error", ejson::String("WRONG-PARAMETER-TYPE"));
out.add("error-help", ejson::String("Parameter id " + etk::to_string(iii) + " not compatible with type: '" + m_paramType[iii].getName() + "'"));
return out;
}
}
// execute cmd:
ejson::Value retVal = jus::executeClassCallJson(tmpClass, m_function, _params);
out.add("return", retVal);
return out;
}
// check parameter compatibility
for (size_t iii=0; iii<sizeof...(JUS_TYPES); ++iii) {
if (checkCompatibility(m_paramType[iii], _params[iii]) == false) {
out += "error:WRONG-PARAMETER-TYPE;";
out += "error-help:Parameter id " + etk::to_string(iii) + " not compatible with type: '" + m_paramType[iii].getName() + "'";
std::string executeString(const std::vector<std::string>& _params, void* _class) override {
JUS_CLASS_TYPE* tmpClass = (JUS_CLASS_TYPE*)_class;
std::string out;
// check parameter number
if (_params.size() != sizeof...(JUS_TYPES)) {
JUS_ERROR("Wrong number of Parameters ...");
out += "error:WRONG-PARAMETER-NUMBER;";
out += "error-help:request ";
out += etk::to_string(_params.size());
out += " parameters and need ";
out += etk::to_string(sizeof...(JUS_TYPES));
out += " parameters. prototype function:";
out += getPrototype();
return out;
}
// check parameter compatibility
for (size_t iii=0; iii<sizeof...(JUS_TYPES); ++iii) {
if (checkCompatibility(m_paramType[iii], _params[iii]) == false) {
out += "error:WRONG-PARAMETER-TYPE;";
out += "error-help:Parameter id " + etk::to_string(iii) + " not compatible with type: '" + m_paramType[iii].getName() + "'";
return out;
}
}
// execute cmd:
out = jus::executeClassCallString(tmpClass, m_function, _params);
return out;
}
// execute cmd:
out = executeClassCallString(tmpClass, m_function, _params);
return out;
}
};
template <class JUS_RETURN, class JUS_CLASS_TYPE, class... JUS_TYPES>
const ParamType AbstractFunctionTypeClass<JUS_RETURN, JUS_CLASS_TYPE, JUS_TYPES...>::m_returnType = createType<JUS_RETURN>();
template <class JUS_RETURN, class JUS_CLASS_TYPE, class... JUS_TYPES>
const ParamType AbstractFunctionTypeClass<JUS_RETURN, JUS_CLASS_TYPE, JUS_TYPES...>::m_paramType[sizeof...(JUS_TYPES)] = {createType<JUS_TYPES>()...};
template <typename JUS_RETURN, class JUS_CLASS_TYPE, typename... JUS_TYPES>
AbstractFunction* createAbstractFunctionClass(const std::string& _name, const std::string& _desc, JUS_RETURN (JUS_CLASS_TYPE::*_fffp)(JUS_TYPES...)) {
return new AbstractFunctionTypeClass<JUS_RETURN, JUS_CLASS_TYPE, JUS_TYPES...>(_name, _desc, _fffp);
};
template <class JUS_RETURN, class JUS_CLASS_TYPE, class... JUS_TYPES>
const ParamType AbstractFunctionTypeClass<JUS_RETURN, JUS_CLASS_TYPE, JUS_TYPES...>::m_returnType = createType<JUS_RETURN>();
template <class JUS_RETURN, class JUS_CLASS_TYPE, class... JUS_TYPES>
const ParamType AbstractFunctionTypeClass<JUS_RETURN, JUS_CLASS_TYPE, JUS_TYPES...>::m_paramType[sizeof...(JUS_TYPES)] = {createType<JUS_TYPES>()...};
template <typename JUS_RETURN, class JUS_CLASS_TYPE, typename... JUS_TYPES>
AbstractFunction* createAbstractFunctionClass(const std::string& _name, const std::string& _desc, JUS_RETURN (JUS_CLASS_TYPE::*_fffp)(JUS_TYPES...)) {
return new AbstractFunctionTypeClass<JUS_RETURN, JUS_CLASS_TYPE, JUS_TYPES...>(_name, _desc, _fffp);
}
}

View File

@ -10,164 +10,164 @@
#include <ejson/ejson.h>
#include <jus/debug.h>
#include <jus/AbstractFunction.h>
template <class JUS_RETURN, class... JUS_TYPES>
ejson::Value executeCallJson(JUS_RETURN (*_func)(JUS_TYPES...), const ejson::Array& _params) {
#if defined(__clang__)
// clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0;
return convertToJson(_func((convertJsonTo<JUS_TYPES>(_params[idParam++]))...));
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
return convertToJson(_func(convertJsonTo<JUS_TYPES>(_params[idParam--])...));
#else
#error Must be implemented ...
#endif
return ejson::Null();
}
template <class... JUS_TYPES>
ejson::Value executeCallJson(void (*_func)(JUS_TYPES...), const ejson::Array& _params) {
ejson::Object out;
#if defined(__clang__)
// clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0;
_func((convertJsonTo<JUS_TYPES>(_params[idParam++]))...);
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
_func(convertJsonTo<JUS_TYPES>(_params[idParam--])...);
#else
#error Must be implemented ...
#endif
return ejson::Null();
}
template <class JUS_RETURN, class... JUS_TYPES>
std::string executeCallString(JUS_RETURN (*_func)(JUS_TYPES...), const std::vector<std::string>& _params) {
#if defined(__clang__)
// clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0;
return etk::to_string(_func((convertStringTo<JUS_TYPES>(_params[idParam++]))...));
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
return etk::to_string(_func(convertStringTo<JUS_TYPES>(_params[idParam--])...));
#else
#error Must be implemented ...
#endif
return "";
}
template <class... JUS_TYPES>
std::string executeCallString(void (*_func)(JUS_TYPES...), const std::vector<std::string>& _params) {
ejson::Object out;
#if defined(__clang__)
// clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0;
_func((convertStringTo<JUS_TYPES>(_params[idParam++]))...);
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
_func(convertStringTo<JUS_TYPES>(_params[idParam--])...);
#else
#error Must be implemented ...
#endif
return "";
}
template <class JUS_RETURN, class... JUS_TYPES>
class AbstractFunctionTypeDirect: public 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<sizeof...(JUS_TYPES); ++iii) {
if (iii != 0) {
ret += ", ";
namespace jus {
template <class JUS_RETURN, class... JUS_TYPES>
ejson::Value executeCallJson(JUS_RETURN (*_func)(JUS_TYPES...), const ejson::Array& _params) {
#if defined(__clang__)
// clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0;
return convertToJson(_func((convertJsonTo<JUS_TYPES>(_params[idParam++]))...));
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
return convertToJson(_func(convertJsonTo<JUS_TYPES>(_params[idParam--])...));
#else
#error Must be implemented ...
#endif
return ejson::Null();
}
template <class... JUS_TYPES>
ejson::Value executeCallJson(void (*_func)(JUS_TYPES...), const ejson::Array& _params) {
ejson::Object out;
#if defined(__clang__)
// clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0;
_func((convertJsonTo<JUS_TYPES>(_params[idParam++]))...);
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
_func(convertJsonTo<JUS_TYPES>(_params[idParam--])...);
#else
#error Must be implemented ...
#endif
return ejson::Null();
}
template <class JUS_RETURN, class... JUS_TYPES>
std::string executeCallString(JUS_RETURN (*_func)(JUS_TYPES...), const std::vector<std::string>& _params) {
#if defined(__clang__)
// clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0;
return etk::to_string(_func((convertStringTo<JUS_TYPES>(_params[idParam++]))...));
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
return etk::to_string(_func(convertStringTo<JUS_TYPES>(_params[idParam--])...));
#else
#error Must be implemented ...
#endif
return "";
}
template <class... JUS_TYPES>
std::string executeCallString(void (*_func)(JUS_TYPES...), const std::vector<std::string>& _params) {
ejson::Object out;
#if defined(__clang__)
// clang generate a basic warning:
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
int32_t idParam = 0;
_func((convertStringTo<JUS_TYPES>(_params[idParam++]))...);
#elif defined(__GNUC__) || defined(__GNUG__) || defined(_MSC_VER)
int32_t idParam = int32_t(sizeof...(JUS_TYPES))-1;
_func(convertStringTo<JUS_TYPES>(_params[idParam--])...);
#else
#error Must be implemented ...
#endif
return "";
}
template <class JUS_RETURN, class... JUS_TYPES>
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<sizeof...(JUS_TYPES); ++iii) {
if (iii != 0) {
ret += ", ";
}
ret += m_paramType[iii].getName();
}
ret += m_paramType[iii].getName();
ret += ");";
return ret;
}
ret += ");";
return ret;
}
ejson::Value executeJson(const ejson::Array& _params, void* _class) override {
ejson::Object out;
// check parameter number
if (_params.size() != sizeof...(JUS_TYPES)) {
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(sizeof...(JUS_TYPES));
help += " parameters. prototype function:";
help += getPrototype();
out.add("error-help", ejson::String(help));
return out;
}
// check parameter compatibility
for (size_t iii=0; iii<sizeof...(JUS_TYPES); ++iii) {
if (checkCompatibility(m_paramType[iii], _params[iii]) == false) {
out.add("error", ejson::String("WRONG-PARAMETER-TYPE"));
out.add("error-help", ejson::String("Parameter id " + etk::to_string(iii) + " not compatible with type: '" + m_paramType[iii].getName() + "'"));
ejson::Value executeJson(const ejson::Array& _params, void* _class) override {
ejson::Object out;
// check parameter number
if (_params.size() != sizeof...(JUS_TYPES)) {
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(sizeof...(JUS_TYPES));
help += " parameters. prototype function:";
help += getPrototype();
out.add("error-help", ejson::String(help));
return out;
}
}
// execute cmd:
ejson::Value retVal = executeCallJson(m_function, _params);
out.add("return", retVal);
return out;
}
std::string executeString(const std::vector<std::string>& _params, void* _class) override {
std::string out;
// check parameter number
if (_params.size() != sizeof...(JUS_TYPES)) {
JUS_ERROR("Wrong number of Parameters ...");
out += "error:WRONG-PARAMETER-NUMBER;";
out += "error-help:request ";
out += etk::to_string(_params.size());
out += " parameters and need ";
out += etk::to_string(sizeof...(JUS_TYPES));
out += " parameters. prototype function:";
out += getPrototype();
// check parameter compatibility
for (size_t iii=0; iii<sizeof...(JUS_TYPES); ++iii) {
if (checkCompatibility(m_paramType[iii], _params[iii]) == false) {
out.add("error", ejson::String("WRONG-PARAMETER-TYPE"));
out.add("error-help", ejson::String("Parameter id " + etk::to_string(iii) + " not compatible with type: '" + m_paramType[iii].getName() + "'"));
return out;
}
}
// execute cmd:
ejson::Value retVal = jus::executeCallJson(m_function, _params);
out.add("return", retVal);
return out;
}
// check parameter compatibility
for (size_t iii=0; iii<sizeof...(JUS_TYPES); ++iii) {
if (checkCompatibility(m_paramType[iii], _params[iii]) == false) {
out += "error:WRONG-PARAMETER-TYPE;";
out += "error-help:Parameter id " + etk::to_string(iii) + " not compatible with type: '" + m_paramType[iii].getName() + "'";
std::string executeString(const std::vector<std::string>& _params, void* _class) override {
std::string out;
// check parameter number
if (_params.size() != sizeof...(JUS_TYPES)) {
JUS_ERROR("Wrong number of Parameters ...");
out += "error:WRONG-PARAMETER-NUMBER;";
out += "error-help:request ";
out += etk::to_string(_params.size());
out += " parameters and need ";
out += etk::to_string(sizeof...(JUS_TYPES));
out += " parameters. prototype function:";
out += getPrototype();
return out;
}
// check parameter compatibility
for (size_t iii=0; iii<sizeof...(JUS_TYPES); ++iii) {
if (checkCompatibility(m_paramType[iii], _params[iii]) == false) {
out += "error:WRONG-PARAMETER-TYPE;";
out += "error-help:Parameter id " + etk::to_string(iii) + " not compatible with type: '" + m_paramType[iii].getName() + "'";
return out;
}
}
// execute cmd:
out = jus::executeCallString(m_function, _params);
return out;
}
// execute cmd:
out = executeCallString(m_function, _params);
return out;
}
};
template <class JUS_RETURN, class... JUS_TYPES>
const ParamType AbstractFunctionTypeDirect<JUS_RETURN, JUS_TYPES...>::m_returnType = createType<JUS_RETURN>();
template <class JUS_RETURN, class... JUS_TYPES>
const ParamType AbstractFunctionTypeDirect<JUS_RETURN, JUS_TYPES...>::m_paramType[sizeof...(JUS_TYPES)] = {createType<JUS_TYPES>()...};
template <typename JUS_RETURN, typename... JUS_TYPES>
AbstractFunction* createAbstractFunctionDirect(const std::string& _name, const std::string& _desc, JUS_RETURN (*_fffp)(JUS_TYPES...)) {
return new AbstractFunctionTypeDirect<JUS_RETURN, JUS_TYPES...>(_name, _desc, _fffp);
};
template <class JUS_RETURN, class... JUS_TYPES>
const ParamType AbstractFunctionTypeDirect<JUS_RETURN, JUS_TYPES...>::m_returnType = createType<JUS_RETURN>();
template <class JUS_RETURN, class... JUS_TYPES>
const ParamType AbstractFunctionTypeDirect<JUS_RETURN, JUS_TYPES...>::m_paramType[sizeof...(JUS_TYPES)] = {createType<JUS_TYPES>()...};
template <typename JUS_RETURN, typename... JUS_TYPES>
AbstractFunction* createAbstractFunctionDirect(const std::string& _name, const std::string& _desc, JUS_RETURN (*_fffp)(JUS_TYPES...)) {
return new AbstractFunctionTypeDirect<JUS_RETURN, JUS_TYPES...>(_name, _desc, _fffp);
}
}

View File

@ -45,6 +45,9 @@ void jus::Client::unlink(const std::string& _serviceName) {
}
std::string jus::Client::asyncRead() {
if (m_interfaceClient.isActive() == false) {
return "";
}
int32_t iii = 5000;
while (iii>0) {
usleep(10000);
@ -102,9 +105,11 @@ ejson::Object jus::Client::createBaseCall(const std::string& _functionName, cons
ejson::Object jus::Client::callJson(const ejson::Object& _obj) {
JUS_VERBOSE("Call JSON [START] ");
std::string tmpVal = _obj.generate();
JUS_DEBUG("Call JSON '" << tmpVal << "'");
m_interfaceClient.write(_obj.generate());
if (m_interfaceClient.isActive() == false) {
return ejson::Object();
}
JUS_DEBUG("Call JSON '" << _obj.generateHumanString() << "'");
m_interfaceClient.write(_obj.generateMachineString());
std::string ret = asyncRead();
JUS_VERBOSE("Call JSON [STOP]");
return ejson::Object(ret);

View File

@ -130,6 +130,37 @@ void jus::GateWay::answer(uint64_t _userSessionId, ejson::Object _data) {
}
}
void jus::GateWay::cleanIO() {
auto it = m_serviceList.begin();
while (it != m_serviceList.end()) {
if (*it != nullptr) {
if ((*it)->isAlive() == false) {
it = m_serviceList.erase(it);
continue;
}
} else {
it = m_serviceList.erase(it);
continue;
}
++it;
}
auto it2 = m_clientList.begin();
while (it2 != m_clientList.end()) {
if (*it2 != nullptr) {
if ((*it2)->isAlive() == false) {
it2 = m_clientList.erase(it2);
continue;
}
} else {
it2 = m_clientList.erase(it2);
continue;
}
++it2;
}
}
void jus::GateWay::onClientConnect(const bool& _value) {
JUS_TODO("Client connection: " << _value);
}

View File

@ -35,6 +35,7 @@ namespace jus {
void answer(uint64_t _userSessionId, ejson::Object _data);
void newService(enet::Tcp _connection);
void newClient(enet::Tcp _connection);
void cleanIO();
private:
void onPropertyChangeClientIp();
void onPropertyChangeClientPort();

View File

@ -12,14 +12,18 @@
jus::GateWayClient::GateWayClient(enet::Tcp _connection, jus::GateWay* _gatewayInterface) :
m_gatewayInterface(_gatewayInterface),
m_interfaceClient(std::move(_connection)),
m_returnValueOk(false) {
m_interfaceClient(std::move(_connection)) {
JUS_INFO("----------------");
JUS_INFO("-- NEW Client --");
JUS_INFO("----------------");
}
jus::GateWayClient::~GateWayClient() {
JUS_TODO("Call All unlink ...");
stop();
JUS_INFO("-------------------");
JUS_INFO("-- DELETE Client --");
JUS_INFO("-------------------");
}
void jus::GateWayClient::start(size_t _uid) {
@ -30,9 +34,20 @@ void jus::GateWayClient::start(size_t _uid) {
}
void jus::GateWayClient::stop() {
for (auto &it : m_listConnectedService) {
if (it == nullptr) {
continue;
}
it->SendData(m_uid, ejson::Object(), "delete");
}
m_listConnectedService.clear();
m_interfaceClient.disconnect();
}
bool jus::GateWayClient::isAlive() {
return m_interfaceClient.isActive();
}
void jus::GateWayClient::onClientData(const std::string& _value) {
JUS_DEBUG("On data: " << _value);
ejson::Object data(_value);
@ -93,18 +108,8 @@ void jus::GateWayClient::onClientData(const std::string& _value) {
ejson::Object linkService;
linkService.add("user", ejson::String(m_userConnectionName));
srv->SendData(m_uid, linkService, "new");
while (m_returnValueOk == false) {
JUS_DEBUG("wait Return Value (LINK)");
usleep(20000);
}
JUS_DEBUG("new answer: " << m_returnMessage.generate());
if (m_returnMessage["return"].toString().get() == "OK") {
m_listConnectedService.push_back(srv);
answer.add("return", ejson::Boolean(true));
} else {
answer.add("return", ejson::Boolean(false));
}
m_returnValueOk = false;
m_listConnectedService.push_back(srv);
answer.add("return", ejson::Boolean(true));
} else {
answer.add("return", ejson::Boolean(false));
}
@ -129,30 +134,18 @@ void jus::GateWayClient::onClientData(const std::string& _value) {
break;
}
if (it == m_listConnectedService.end()) {
// TODO : Service already unlink;
answer.add("return", ejson::Boolean(false));
} else {
(*it)->SendData(m_uid, ejson::Object(), "delete");
while (m_returnValueOk == false) {
JUS_DEBUG("wait Return Value (UNLINK)");
usleep(20000);
}
JUS_DEBUG("new answer: " << m_returnMessage.generate());
if (m_returnMessage["return"].toString().get() == "OK") {
m_listConnectedService.erase(it);
answer.add("return", ejson::Boolean(true));
} else {
answer.add("return", ejson::Boolean(false));
}
m_returnValueOk = false;
m_listConnectedService.erase(it);
answer.add("return", ejson::Boolean(true));
}
} else {
JUS_ERROR("Function does not exist ... '" << call << "'");
answer.add("error", ejson::String("CALL-UNEXISTING"));
}
std::string valueReturn = answer.generate();
JUS_DEBUG("answer: " << valueReturn);
m_interfaceClient.write(valueReturn);
JUS_DEBUG("answer: " << answer.generateHumanString());
m_interfaceClient.write(answer.generateMachineString());
} else if (service == "Authentification") {
std::string call = data["call"].toString().get();
@ -176,26 +169,17 @@ void jus::GateWayClient::onClientData(const std::string& _value) {
answer.add("id", data["id"]);
JUS_ERROR("Service not linked ... " << service);
answer.add("error", ejson::String("SERVICE-NOT-LINK"));
std::string valueReturn = answer.generate();
JUS_DEBUG("answer: " << valueReturn);
m_interfaceClient.write(valueReturn);
JUS_DEBUG("answer: " << answer.generateHumanString());
m_interfaceClient.write(answer.generateMachineString());
} else {
JUS_ERROR("Add in link the name of the user in parameter ...");
data.remove("service");
(*it)->SendData(m_uid, data);
while (m_returnValueOk == false) {
JUS_DEBUG("wait Return Value");
usleep(20000);
}
std::string valueReturn = m_returnMessage.generate();
JUS_DEBUG("answer: " << valueReturn);
m_interfaceClient.write(valueReturn);
m_returnValueOk = false;
}
}
}
void jus::GateWayClient::returnMessage(ejson::Object _data) {
m_returnMessage = _data;
m_returnValueOk = true;
JUS_DEBUG("answer: " << _data.generateHumanString());
m_interfaceClient.write(_data.generateMachineString());
}

View File

@ -19,8 +19,6 @@ namespace jus {
public:
esignal::Signal<bool> signalIsConnected;
esignal::Connection m_dataCallback;
bool m_returnValueOk;
ejson::Object m_returnMessage;
std::vector<ememory::SharedPtr<jus::GateWayService>> m_listConnectedService;
size_t m_uid;
std::string m_userConnectionName;
@ -34,6 +32,7 @@ namespace jus {
size_t getId() const {
return m_uid;
}
bool isAlive();
};
}

View File

@ -12,11 +12,20 @@
jus::GateWayService::GateWayService(enet::Tcp _connection, jus::GateWay* _gatewayInterface) :
m_gatewayInterface(_gatewayInterface),
m_interfaceClient(std::move(_connection)) {
JUS_INFO("-----------------");
JUS_INFO("-- NEW Service --");
JUS_INFO("-----------------");
}
jus::GateWayService::~GateWayService() {
JUS_INFO("--------------------");
JUS_INFO("-- DELETE Service --");
JUS_INFO("--------------------");
}
bool jus::GateWayService::isAlive() {
return m_interfaceClient.isActive();
}
void jus::GateWayService::start() {
@ -32,14 +41,21 @@ void jus::GateWayService::stop() {
void jus::GateWayService::SendData(size_t _userSessionId, ejson::Object _data, const std::string& _action) {
_data.add("client-id", ejson::String(etk::to_string(_userSessionId)));
_data.add("action", ejson::String(_action));
std::string value = _data.generate();
JUS_DEBUG("Send Service: " << value);
m_interfaceClient.write(value);
JUS_DEBUG("Send Service: " << _data.generateHumanString());
m_interfaceClient.write(_data.generateMachineString());
}
void jus::GateWayService::onServiceData(const std::string& _value) {
JUS_DEBUG("On service data: " << _value);
ejson::Object data(_value);
if (data.valueExist("event") == true) {
if (data["event"].toString().get() == "IS-ALIVE") {
JUS_INFO("Service Alive ...");
} else {
JUS_INFO("Unknow service event: '" << data["event"].toString().get() << "'");
}
return;
}
if (data.valueExist("connect-service") == true) {
if (m_name != "") {
JUS_WARNING("Service interface ==> try change the servie name after init: '" << data["connect-service"].toString().get());

View File

@ -31,6 +31,7 @@ namespace jus {
const std::string& getName() {
return m_name;
}
bool isAlive();
};
}

View File

@ -23,8 +23,8 @@ bool jus::ParamType::operator == (const ParamType& _obj) const {
#define generate_basic_type(_type, _name) \
template<> ParamType createType<_type>() {\
return ParamType(_name); \
template<> jus::ParamType jus::createType<_type>() {\
return jus::ParamType(_name); \
}
generate_basic_type(void, "void");

View File

@ -4,18 +4,18 @@
* @license APACHE v2.0 (see license file)
*/
#pragma once
class ParamType {
protected:
const char* m_typeName;
public:
ParamType(const char* _name = "");
const char* getName() const;
bool operator == (const ParamType& _obj) const;
};
template<class JUS_TYPE>
ParamType createType();
namespace jus {
class ParamType {
protected:
const char* m_typeName;
public:
ParamType(const char* _name = "");
const char* getName() const;
bool operator == (const ParamType& _obj) const;
};
template<class JUS_TYPE>
ParamType createType();
}

86
jus/RemoteProcessCall.cpp Normal file
View File

@ -0,0 +1,86 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#include <jus/RemoteProcessCall.h>
std::vector<jus::AbstractFunction*> m_listFunction;
void jus::RemoteProcessCall::setDescription(const std::string& _desc) {
m_description = _desc;
}
const std::string& jus::RemoteProcessCall::getDescription() const {
return m_description;
}
void jus::RemoteProcessCall::setVersion(const std::string& _desc) {
m_version = _desc;
}
const std::string& jus::RemoteProcessCall::getVersion() const {
return m_version;
}
void jus::RemoteProcessCall::addAuthor(const std::string& _name, const std::string& _email) {
m_authors.push_back(std::make_pair(_name, _email));
}
const std::vector<std::pair<std::string,std::string>>& jus::RemoteProcessCall::getAuthors() const {
return m_authors;
}
void jus::RemoteProcessCall::setLastFuncDesc(const std::string& _desc) {
if (m_listFunction.size() == 0) {
JUS_ERROR("Can not set description to a function with no function advertise before ...");
return;
}
if (m_listFunction[m_listFunction.size()-1] == nullptr) {
JUS_ERROR("Last element is nullptr ... ==> what are you doing??");
return;
}
m_listFunction[m_listFunction.size()-1]->setDescription(_desc);
}
void jus::RemoteProcessCall::setFuncDesc(const std::string& _funcName, const std::string& _desc) {
for (auto &it : m_listFunction) {
if (it == nullptr) {
continue;
}
if (it->getName() != _funcName) {
continue;
}
it->setDescription(_desc);
return;
}
JUS_ERROR("function '" << _funcName << "' des not exist");
}
void jus::RemoteProcessCall::addLastFuncParam(const std::string& _name, const std::string& _desc) {
if (m_listFunction.size() == 0) {
JUS_ERROR("Can not set description to a function with no function advertise before ...");
return;
}
if (m_listFunction[m_listFunction.size()-1] == nullptr) {
JUS_ERROR("Last element is nullptr ... ==> what are you doing??");
return;
}
m_listFunction[m_listFunction.size()-1]->addParam(_name, _desc);
}
void jus::RemoteProcessCall::setFuncParam(const std::string& _funcName, int32_t _idParam, const std::string& _name, const std::string& _desc) {
for (auto &it : m_listFunction) {
if (it == nullptr) {
continue;
}
if (it->getName() != _funcName) {
continue;
}
it->setParam(_idParam, _name, _desc);
return;
}
JUS_ERROR("function '" << _funcName << "' des not exist");
}

59
jus/RemoteProcessCall.h Normal file
View File

@ -0,0 +1,59 @@
/** @file
* @author Edouard DUPIN
* @copyright 2016, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#pragma once
#include <jus/TcpString.h>
#include <eproperty/Value.h>
#include <ejson/ejson.h>
#include <jus/AbstractFunctionTypeDirect.h>
#include <jus/AbstractFunctionTypeClass.h>
#include <jus/debug.h>
namespace jus {
class RemoteProcessCall {
protected:
std::vector<jus::AbstractFunction*> m_listFunction;
protected:
std::string m_description;
public:
void setDescription(const std::string& _desc);
const std::string& getDescription() const;
protected:
std::string m_version;
public:
void setVersion(const std::string& _desc);
const std::string& getVersion() const;
protected:
std::vector<std::pair<std::string,std::string>> m_authors;
public:
void addAuthor(const std::string& _name, const std::string& _email);
const std::vector<std::pair<std::string,std::string>>& getAuthors() const;
public:
void setLastFuncDesc(const std::string& _desc);
void setFuncDesc(const std::string& _funcName, const std::string& _desc);
void addLastFuncParam(const std::string& _name, const std::string& _desc);
void setFuncParam(const std::string& _funcName, int32_t _idParam, const std::string& _name, const std::string& _desc);
public:
template<class JUS_RETURN_VALUE,
class... JUS_FUNC_ARGS_TYPE>
void advertise(const std::string& _name,
JUS_RETURN_VALUE (*_func)(JUS_FUNC_ARGS_TYPE... _args),
const std::string& _desc = "") {
for (auto &it : m_listFunction) {
if (it == nullptr) {
continue;
}
if (it->getName() == _name) {
JUS_ERROR("Advertise function already bind .. ==> can not be done...: '" << _name << "'");
return;
}
}
AbstractFunction* tmp = createAbstractFunctionDirect(_name, _desc, _func);
m_listFunction.push_back(tmp);
}
};
}

View File

@ -27,10 +27,12 @@ jus::Service::~Service() {
void jus::Service::onClientData(const std::string& _value) {
ejson::Object request(_value);
JUS_INFO("Request: " << _value);
ejson::Object answer = callJson(request);
std::string answerString = answer.generate();
JUS_INFO("Answer: " << answerString);
m_interfaceClient.write(answerString);
ejson::Value answer = callJson(request);
// check if an answer is needed
if (answer.isNull() == false) {
JUS_INFO("Answer: " << answer.generateHumanString());
m_interfaceClient.write(answer.generateMachineString());
}
}
void jus::Service::onPropertyChangeIp() {
@ -58,33 +60,44 @@ void jus::Service::disconnect(){
JUS_DEBUG("disconnect [STOP]");
}
ejson::Object jus::Service::callJson(const ejson::Object& _obj) {
void jus::Service::pingIsAlive() {
m_interfaceClient.write("{\"event\":\"IS-ALIVE\"}");
}
ejson::Value jus::Service::callJson(const ejson::Object& _obj) {
std::string action = _obj["action"].toString().get();
if (action == "new") {
uint64_t clientId = etk::string_to_uint64_t(_obj["client-id"].toString().get());
std::string userName = _obj["user"].toString().get();
clientConnect(clientId, userName);
/*
ejson::Object tmpp;
tmpp.add("client-id", ejson::String(etk::to_string(clientId)));
tmpp.add("return", ejson::String("OK"));
return tmpp;
} else if (action == "delete") {
return tmpp
*/
return ejson::Null();
}
if (action == "delete") {
uint64_t clientId = etk::string_to_uint64_t(_obj["client-id"].toString().get());
clientDisconnect(clientId);
/*
ejson::Object tmpp;
tmpp.add("client-id", ejson::String(etk::to_string(clientId)));
tmpp.add("return", ejson::String("OK"));
return tmpp;
} else if ( action == "call"
|| action == "") {
*/
return ejson::Null();
}
if ( action == "call"
|| action == "") {
uint64_t clientId = etk::string_to_uint64_t(_obj["client-id"].toString().get());
ejson::Object tmpp = callJson2(clientId, _obj);
tmpp.add("client-id", ejson::String(etk::to_string(clientId)));
return tmpp;
} else {
ejson::Object tmpp;
tmpp.add("error", ejson::String("NOT-IMPLEMENTED-ACTION"));
return tmpp;
}
return ejson::Object();
ejson::Object tmpp;
tmpp.add("error", ejson::String("NOT-IMPLEMENTED-ACTION"));
return tmpp;
}

View File

@ -11,9 +11,10 @@
#include <jus/AbstractFunctionTypeDirect.h>
#include <jus/AbstractFunctionTypeClass.h>
#include <jus/debug.h>
#include <jus/RemoteProcessCall.h>
namespace jus {
class Service : public eproperty::Interface {
class Service : public eproperty::Interface, public jus::RemoteProcessCall {
public:
eproperty::Value<std::string> propertyIp;
eproperty::Value<uint16_t> propertyPort;
@ -25,25 +26,16 @@ namespace jus {
public:
Service();
virtual ~Service();
// Genenric function call:
ejson::Object callJson(const ejson::Object& _obj);
virtual ejson::Object callJson2(size_t _clientId, const ejson::Object& _obj) = 0;
void connect(const std::string& _serviceName);
void disconnect();
private:
void onClientData(const std::string& _value);
std::string asyncRead();
public:
void pingIsAlive();
private:
void onPropertyChangeIp();
void onPropertyChangePort();
public:
template<class JUS_RETURN_VALUE,
class... JUS_FUNC_ARGS_TYPE>
void advertise(const std::string& _name,
JUS_RETURN_VALUE (*_func)(JUS_FUNC_ARGS_TYPE... _args),
const std::string& _desc) {
AbstractFunction* tmp = createAbstractFunctionDirect(_name, _desc, _func);
}
/**
* @brief A extern client connect on specific user
* @param[in] _clientSessionID Source session Id on the client
@ -52,6 +44,9 @@ namespace jus {
*/
virtual void clientConnect(size_t _clientSessionID, const std::string& _userName) = 0;
virtual void clientDisconnect(size_t _clientSessionID) = 0;
// Genenric function call:
ejson::Value callJson(const ejson::Object& _obj);
virtual ejson::Object callJson2(size_t _clientId, const ejson::Object& _obj) = 0;
};
template<class JUS_TYPE_SERVICE, class JUS_USER_ACCESS>
class ServiceType : public jus::Service {
@ -59,15 +54,23 @@ namespace jus {
JUS_USER_ACCESS& m_getUserInterface;
// no need of shared_ptr or unique_ptr (if service die all is lost and is client die, the gateway notify us...)
std::map<size_t, JUS_TYPE_SERVICE*> m_interface;
std::vector<AbstractFunction*> m_listFunction;
public:
template<class JUS_RETURN_VALUE,
class JUS_CLASS_TYPE,
class... JUS_FUNC_ARGS_TYPE>
void advertise(const std::string& _name,
JUS_RETURN_VALUE (JUS_CLASS_TYPE::*_func)(JUS_FUNC_ARGS_TYPE... _args),
const std::string& _desc) {
// TODO: check if fucntion does not exist ...
const std::string& _desc = "") {
for (auto &it : m_listFunction) {
if (it == nullptr) {
continue;
}
if (it->getName() == _name) {
JUS_ERROR("Advertise function already bind .. ==> can not be done...: '" << _name << "'");
return;
}
}
AbstractFunction* tmp = createAbstractFunctionClass(_name, _desc, _func);
m_listFunction.push_back(tmp);
}

View File

@ -48,9 +48,14 @@ void jus::TcpString::threadCallback() {
signalData.emit(data);
}
}
m_threadRunning = false;
JUS_DEBUG("End of thread");
}
bool jus::TcpString::isActive() const {
return m_threadRunning;
}
void jus::TcpString::connect(bool _async){
JUS_DEBUG("connect [START]");
m_threadRunning = true;
@ -75,13 +80,13 @@ void jus::TcpString::connect(bool _async){
void jus::TcpString::disconnect(){
JUS_DEBUG("disconnect [START]");
if (m_thread != nullptr) {
m_threadRunning = false;
}
if (m_connection.getConnectionStatus() == enet::Tcp::status::link) {
uint32_t size = 0xFFFFFFFF;
m_connection.write(&size, 4);
}
if (m_thread != nullptr) {
m_threadRunning = false;
}
if (m_connection.getConnectionStatus() != enet::Tcp::status::unlink) {
m_connection.unlink();
}
@ -94,6 +99,9 @@ void jus::TcpString::disconnect(){
}
int32_t jus::TcpString::write(const std::string& _data) {
if (m_threadRunning == false) {
return -2;
}
if (_data.size() == 0) {
return 0;
}
@ -103,6 +111,11 @@ int32_t jus::TcpString::write(const std::string& _data) {
}
std::string jus::TcpString::read() {
JUS_VERBOSE("Read [START]");
if (m_threadRunning == false) {
JUS_DEBUG("Read [END] Disconected");
return "";
}
// TODO : Do it better with a correct way to check data size ...
JUS_VERBOSE("Read [START]");
std::string out;

View File

@ -26,6 +26,7 @@ namespace jus {
void setInterface(enet::Tcp _connection);
void connect(bool _async = false);
void disconnect();
bool isActive() const;
void setInterfaceName(const std::string& _name);
int32_t write(const std::string& _data);
std::string asyncRead();

View File

@ -40,6 +40,7 @@ def create(target, module_name):
'jus/GateWay.cpp',
'jus/GateWayService.cpp',
'jus/GateWayClient.cpp',
'jus/RemoteProcessCall.cpp',
'jus/Service.cpp',
'jus/ServiceRemote.cpp',
'jus/TcpString.cpp',
@ -54,6 +55,7 @@ def create(target, module_name):
'jus/GateWay.h',
'jus/GateWayService.h',
'jus/GateWayClient.h',
'jus/RemoteProcessCall.h',
'jus/Service.h',
'jus/ServiceRemote.h',
'jus/TcpString.h',

View File

@ -69,7 +69,13 @@ int main(int _argc, const char *_argv[]) {
etk::init(_argc, _argv);
appl::UserManager userMng;
jus::ServiceType<appl::Calculator, appl::UserManager> serviceInterface(userMng);
serviceInterface.advertise("mul", &appl::Calculator::mul, "simple multiplication to test double IO");
serviceInterface.setDescription("Calculator interface");
serviceInterface.setVersion("0.1.1");
serviceInterface.addAuthor("Heero Yui", "yui.heero@gmail.com");
serviceInterface.advertise("mul", &appl::Calculator::mul);
serviceInterface.setLastFuncDesc("simple multiplication to test double IO");
serviceInterface.addLastFuncParam("val1", "First Parameter To multiply");
serviceInterface.addLastFuncParam("val2", "Second Parameter To multiply");
for (int32_t iii=0; iii<_argc ; ++iii) {
std::string data = _argv[iii];
if (etk::start_with(data, "--ip=") == true) {
@ -91,7 +97,8 @@ int main(int _argc, const char *_argv[]) {
serviceInterface.connect("serviceTest1");
int32_t iii=0;
while (true) {
usleep(500000);
usleep(1000000);
serviceInterface.pingIsAlive();
APPL_INFO("service in waiting ... " << iii << "/inf");
iii++;
}

View File

@ -46,8 +46,10 @@ int main(int _argc, const char *_argv[]) {
APPL_INFO("==================================");
basicGateway.start();
while (true) {
usleep(200000);
usleep(100000);
basicGateway.cleanIO();
}
basicGateway.stop();
APPL_INFO("==================================");
APPL_INFO("== JUS gateway stop ==");
APPL_INFO("==================================");