[DEV] add service and object action notification bases
This commit is contained in:
parent
e4ddecc0eb
commit
6ee0c7047e
@ -181,11 +181,15 @@ class AttributeDefinition:
|
|||||||
|
|
||||||
class FunctionDefinition:
|
class FunctionDefinition:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.name = "";
|
self.name = ""
|
||||||
self.brief = "";
|
self.brief = ""
|
||||||
self.return_type = "";
|
self.return_type = ""
|
||||||
self.return_brief = "";
|
self.return_brief = ""
|
||||||
self.parameters = []
|
self.parameters = []
|
||||||
|
self.is_action = False
|
||||||
|
|
||||||
|
def set_action(self):
|
||||||
|
self.is_action = True
|
||||||
|
|
||||||
def set_function_name(self, name):
|
def set_function_name(self, name):
|
||||||
self.name = remove_start_stop_spacer(name);
|
self.name = remove_start_stop_spacer(name);
|
||||||
@ -249,13 +253,14 @@ class FunctionDefinition:
|
|||||||
out += elem["name"] + " "
|
out += elem["name"] + " "
|
||||||
if elem["brief"] != "":
|
if elem["brief"] != "":
|
||||||
out += elem["brief"] + " "
|
out += elem["brief"] + " "
|
||||||
out += "\n"
|
if self.is_action == True:
|
||||||
|
out += space + " * @note: This is an action ==> it can notify of the progression of the call\n"
|
||||||
if self.return_brief != "":
|
if self.return_brief != "":
|
||||||
out += space + " * @return " + self.return_brief + "\n"
|
out += space + " * @return " + self.return_brief + "\n"
|
||||||
out += space + " */\n"
|
out += space + " */\n"
|
||||||
return out
|
return out
|
||||||
|
|
||||||
def generate_cpp(self, space, class_name="", virtual=True):
|
def generate_cpp(self, space, class_name="", virtual=True, action=False):
|
||||||
out = "";
|
out = "";
|
||||||
out += self.generate_doxy(space)
|
out += self.generate_doxy(space)
|
||||||
out += space
|
out += space
|
||||||
@ -268,6 +273,9 @@ class FunctionDefinition:
|
|||||||
out += self.name + "("
|
out += self.name + "("
|
||||||
param_data = ""
|
param_data = ""
|
||||||
id_parameter = 0
|
id_parameter = 0
|
||||||
|
if self.is_action == True:
|
||||||
|
param_data += "zeus::ActionNotification& _notifs"
|
||||||
|
id_parameter += 1
|
||||||
for elem in self.parameters:
|
for elem in self.parameters:
|
||||||
id_parameter += 1
|
id_parameter += 1
|
||||||
if len(param_data) != 0:
|
if len(param_data) != 0:
|
||||||
@ -320,7 +328,10 @@ class FunctionDefinition:
|
|||||||
out += param_data
|
out += param_data
|
||||||
out += ") {\n"
|
out += ") {\n"
|
||||||
space += " "
|
space += " "
|
||||||
out += space + 'return m_obj.call("' + self.name + '"'
|
if self.is_action == True:
|
||||||
|
out += space + 'return m_obj.callAction("' + self.name + '"'
|
||||||
|
else:
|
||||||
|
out += space + 'return m_obj.call("' + self.name + '"'
|
||||||
id_parameter = 0
|
id_parameter = 0
|
||||||
for elem in self.parameters:
|
for elem in self.parameters:
|
||||||
id_parameter += 1
|
id_parameter += 1
|
||||||
@ -897,17 +908,40 @@ def tool_generate_idl(target, module, data_option):
|
|||||||
debug.warning("line " + str(id_line) + " ==> Unknow: keyword: '" + doc_keyword + "'")
|
debug.warning("line " + str(id_line) + " ==> Unknow: keyword: '" + doc_keyword + "'")
|
||||||
debug.error(" support only: '#brief:' '#param:' '#return:' '#elem-brief:' '#elem-version:' '#elem-type:' '#elem-author:'")
|
debug.error(" support only: '#brief:' '#param:' '#return:' '#elem-brief:' '#elem-version:' '#elem-type:' '#elem-author:'")
|
||||||
continue
|
continue
|
||||||
debug.extreme_verbose("Need to parse the fucntion/attribute line:")
|
debug.extreme_verbose("Need to parse the function/attribute line:")
|
||||||
debug.extreme_verbose(" '" + line + "'")
|
debug.extreme_verbose(" '" + line + "'")
|
||||||
if line[:7] == "import ":
|
if line[:7] == "import ":
|
||||||
debug.debug("find import : " + line)
|
debug.debug("find import : " + line)
|
||||||
# TODO : Add check ...
|
# TODO : Add check ...
|
||||||
service_def.add_import(line.split(" ")[1])
|
service_def.add_import(line.split(" ")[1])
|
||||||
elif line[-1] == ")":
|
elif line[-1] == ")":
|
||||||
# Find a fundtion ==> parse it
|
# Find a function ==> parse it
|
||||||
#debug.error("line " + str(id_line) + " Can not parse function the line dos not ended by a ')'")
|
#debug.error("line " + str(id_line) + " Can not parse function the line dos not ended by a ')'")
|
||||||
#get first part (befor '('):
|
#get first part (befor '('):
|
||||||
list_elems = line.replace("[tool-remote] ", "[tool-remote]").split("(")
|
# get type of the function (factory, tool, action, function(default))
|
||||||
|
type_function = "function"
|
||||||
|
if line[0] == "[":
|
||||||
|
if line[:13] == "[tool-remote]":
|
||||||
|
type_function = "tool-remote"
|
||||||
|
line = line[13:]
|
||||||
|
if line[:9] == "[factory]":
|
||||||
|
type_function = "factory"
|
||||||
|
line = line[9:]
|
||||||
|
if line[:10] == "[function]":
|
||||||
|
type_function = "function"
|
||||||
|
line = line[10:]
|
||||||
|
if line[:8] == "[action]":
|
||||||
|
type_function = "action"
|
||||||
|
line = line[8:]
|
||||||
|
|
||||||
|
# remove wihte space
|
||||||
|
while len(line)>0 \
|
||||||
|
and line[0] == " ":
|
||||||
|
line = line[1:]
|
||||||
|
if type_function == "factory":
|
||||||
|
line = " " + line
|
||||||
|
# parse the fuction
|
||||||
|
list_elems = line.split("(")
|
||||||
if len(list_elems) <= 1:
|
if len(list_elems) <= 1:
|
||||||
debug.error("line " + str(id_line) + " function parsing error missing the '(' element")
|
debug.error("line " + str(id_line) + " function parsing error missing the '(' element")
|
||||||
fist_part = list_elems[0].replace(" ", " ").replace(" ", " ").replace(" ", " ")
|
fist_part = list_elems[0].replace(" ", " ").replace(" ", " ").replace(" ", " ")
|
||||||
@ -919,44 +953,50 @@ def tool_generate_idl(target, module, data_option):
|
|||||||
# separate the
|
# separate the
|
||||||
list_elems = fist_part.split(" ")
|
list_elems = fist_part.split(" ")
|
||||||
if len(list_elems) <= 1:
|
if len(list_elems) <= 1:
|
||||||
debug.error("line " + str(id_line) + " fucntion return and name is nt parsable")
|
debug.error("line " + str(id_line) + " function return and name is not parsable")
|
||||||
return_value = list_elems[0]
|
return_value = list_elems[0]
|
||||||
function_name = list_elems[1]
|
function_name = list_elems[1]
|
||||||
# check types:
|
# check types:
|
||||||
debug.extreme_verbose(" Parse of function done :")
|
debug.extreme_verbose(" Parse of function done :")
|
||||||
current_def.set_function_name(function_name)
|
current_def.set_function_name(function_name)
|
||||||
type_function = "normal"
|
if type_function == "tool":
|
||||||
if return_value[:13] == "[tool-remote]":
|
current_def.set_return_type(return_value)
|
||||||
type_function = "tool"
|
debug.extreme_verbose(" return:" + return_value)
|
||||||
current_def.set_return_type(return_value[13:])
|
if validate_type(return_value) == False:
|
||||||
debug.extreme_verbose(" return:" + return_value[13:])
|
debug.error("line " + str(id_line) + " function return type unknow : '" + return_value + "' not in " + str(get_list_type()))
|
||||||
if validate_type(return_value[13:]) == False:
|
elif type_function == "factory":
|
||||||
debug.error("line " + str(id_line) + " fucntion return type unknow : '" + return_value + "' not in " + str(get_list_type()))
|
|
||||||
elif return_value == "[factory]":
|
|
||||||
type_function = "factory"
|
|
||||||
if function_name != "create":
|
if function_name != "create":
|
||||||
debug.error("line " + str(id_line) + " factory function name must be 'create' not '" + function_name + "'")
|
debug.error("line " + str(id_line) + " factory function name must be 'create' not '" + function_name + "'")
|
||||||
debug.extreme_verbose(" return: --- ")
|
debug.extreme_verbose(" return: --- ")
|
||||||
elif validate_type(return_value) == False:
|
elif validate_type(return_value) == False:
|
||||||
debug.error("line " + str(id_line) + " fucntion return type unknow : '" + return_value + "' not in " + str(get_list_type()))
|
debug.error("line " + str(id_line) + " function return type unknow : '" + return_value + "' not in " + str(get_list_type()))
|
||||||
else:
|
else:
|
||||||
current_def.set_return_type(return_value)
|
current_def.set_return_type(return_value)
|
||||||
debug.extreme_verbose(" return:" + return_value)
|
debug.extreme_verbose(" return:" + return_value)
|
||||||
|
|
||||||
for elem in argument_list:
|
for elem in argument_list:
|
||||||
if validate_type(elem) == False:
|
if validate_type(elem) == False:
|
||||||
debug.error("line " + str(id_line) + " fucntion argument type unknow : '" + elem + "' not in " + str(get_list_type()))
|
debug.error("line " + str(id_line) + " function argument type unknow : '" + elem + "' not in " + str(get_list_type()))
|
||||||
debug.extreme_verbose(" name:" + function_name)
|
debug.extreme_verbose(" name:" + function_name)
|
||||||
debug.extreme_verbose(" arguments:" + str(argument_list))
|
debug.extreme_verbose(" arguments:" + str(argument_list))
|
||||||
for elem in argument_list:
|
for elem in argument_list:
|
||||||
current_def.add_parameter_type(elem)
|
current_def.add_parameter_type(elem)
|
||||||
if type_function == "normal":
|
if type_function == "function":
|
||||||
|
service_def.add_function(current_def)
|
||||||
|
elif type_function == "action":
|
||||||
|
current_def.set_action()
|
||||||
service_def.add_function(current_def)
|
service_def.add_function(current_def)
|
||||||
elif type_function == "factory":
|
elif type_function == "factory":
|
||||||
service_def.add_factory(current_def)
|
service_def.add_factory(current_def)
|
||||||
else:
|
elif type_function == "tool-remote":
|
||||||
service_def.add_tool(current_def)
|
service_def.add_tool(current_def)
|
||||||
|
else:
|
||||||
|
debug.error("line " + str(id_line) + " Unknow type : " + str(type_function))
|
||||||
else:
|
else:
|
||||||
|
# remove optionnal "property " at the start
|
||||||
|
if line[:9] == "property ":
|
||||||
|
line = line[9:]
|
||||||
|
# attribute parsing ==> parameters
|
||||||
# if must be a simple element separate with a space
|
# if must be a simple element separate with a space
|
||||||
if len(line.split("(")) != 1:
|
if len(line.split("(")) != 1:
|
||||||
debug.error("line " + str(id_line) + " Can not parse function the line does not ended by a ')'")
|
debug.error("line " + str(id_line) + " Can not parse function the line does not ended by a ')'")
|
||||||
|
@ -60,6 +60,7 @@ def configure(target, my_module):
|
|||||||
'zeus/message/Data.cpp',
|
'zeus/message/Data.cpp',
|
||||||
'zeus/message/Event.cpp',
|
'zeus/message/Event.cpp',
|
||||||
'zeus/message/Flow.cpp',
|
'zeus/message/Flow.cpp',
|
||||||
|
'zeus/message/Progress.cpp',
|
||||||
'zeus/message/Parameter_addParameter.cpp',
|
'zeus/message/Parameter_addParameter.cpp',
|
||||||
'zeus/message/Parameter_getParameter.cpp',
|
'zeus/message/Parameter_getParameter.cpp',
|
||||||
'zeus/message/ParamType.cpp',
|
'zeus/message/ParamType.cpp',
|
||||||
@ -73,6 +74,7 @@ def configure(target, my_module):
|
|||||||
'zeus/message/Data.hpp',
|
'zeus/message/Data.hpp',
|
||||||
'zeus/message/Event.hpp',
|
'zeus/message/Event.hpp',
|
||||||
'zeus/message/Flow.hpp',
|
'zeus/message/Flow.hpp',
|
||||||
|
'zeus/message/Progress.hpp',
|
||||||
'zeus/message/ParamType.hpp',
|
'zeus/message/ParamType.hpp',
|
||||||
'zeus/message/type.hpp',
|
'zeus/message/type.hpp',
|
||||||
])
|
])
|
||||||
|
@ -171,7 +171,10 @@ namespace appl {
|
|||||||
throw std::invalid_argument("Wrong file ID ...");
|
throw std::invalid_argument("Wrong file ID ...");
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
uint32_t add(zeus::ProxyFile _dataFile) override {
|
uint32_t add(zeus::ActionNotification& _notifs, zeus::ProxyFile _dataFile) override {
|
||||||
|
//_action.setProgress("{\"pourcent\":" + etk::to_string(23.54) + ", \"comment\":\"Start loading file\"");
|
||||||
|
//_action.setProgress("{\"pourcent\":" + etk::to_string(23.54) + ", \"comment\":\"transfering file\"");;
|
||||||
|
//_action.setProgress("{\"pourcent\":" + etk::to_string(23.54) + ", \"comment\":\"synchronize meta-data\"");
|
||||||
uint64_t id = 0;
|
uint64_t id = 0;
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(g_mutex);
|
std::unique_lock<std::mutex> lock(g_mutex);
|
||||||
@ -249,6 +252,7 @@ namespace appl {
|
|||||||
} else {
|
} else {
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
g_needToStore = true;
|
||||||
}
|
}
|
||||||
if (find == false) {
|
if (find == false) {
|
||||||
throw std::invalid_argument("Wrong file name ...");
|
throw std::invalid_argument("Wrong file name ...");
|
||||||
|
@ -32,11 +32,12 @@ obj:zeus-Media get(uint32)
|
|||||||
#brief:Add a new media in the service
|
#brief:Add a new media in the service
|
||||||
#param:data:A file reference on the media (transmission is async)
|
#param:data:A file reference on the media (transmission is async)
|
||||||
#return:Local personal ID of the media
|
#return:Local personal ID of the media
|
||||||
uint32 add(obj:zeus-File)
|
//#notification:Send progression in json
|
||||||
|
[action] uint32 add(obj:zeus-File)
|
||||||
|
|
||||||
#brief:Remove a media in the service (no trash)
|
#brief:Remove a media in the service (no trash)
|
||||||
#param:mediaId:Id of the media
|
#param:mediaId:Id of the media
|
||||||
void remove(uint32)
|
[function] void remove(uint32)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -12,6 +12,45 @@
|
|||||||
|
|
||||||
|
|
||||||
namespace zeus {
|
namespace zeus {
|
||||||
|
class ActionNotification {
|
||||||
|
public:
|
||||||
|
ActionNotification() {}
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* @brief Execute a call on the function with a return value
|
||||||
|
* @param[in] _interfaceClient Web interface to send data
|
||||||
|
* @param[in] _obj Message input call (that have parameter already check)
|
||||||
|
* @param[in] _pointer Pointer on the class to call
|
||||||
|
* @param[in] _func pointer on the function to call
|
||||||
|
*/
|
||||||
|
template <class ZEUS_CLASS_TYPE, class ZEUS_RETURN, class... ZEUS_TYPES>
|
||||||
|
void executeClassCall(ememory::SharedPtr<zeus::WebServer> _interfaceClient,
|
||||||
|
ememory::SharedPtr<zeus::message::Parameter> _obj,
|
||||||
|
ZEUS_CLASS_TYPE* _pointer,
|
||||||
|
ZEUS_RETURN (ZEUS_CLASS_TYPE::*_func)(zeus::ActionNotification& _notifs, ZEUS_TYPES...)) {
|
||||||
|
if (_obj == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ZEUS_RETURN ret;
|
||||||
|
zeus::ActionNotification notifs;
|
||||||
|
if (zeus::checkOrderFunctionParameter() == true) {
|
||||||
|
// clang generate a basic warning:
|
||||||
|
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
|
||||||
|
int32_t idParam = 0;
|
||||||
|
ret = (*_pointer.*_func)(notifs, _obj->getParameter<ZEUS_TYPES>(idParam++)...);
|
||||||
|
} else {
|
||||||
|
int32_t idParam = int32_t(sizeof...(ZEUS_TYPES))-1;
|
||||||
|
ret = (*_pointer.*_func)(notifs, _obj->getParameter<ZEUS_TYPES>(idParam--)...);
|
||||||
|
}
|
||||||
|
if (_interfaceClient == nullptr) {
|
||||||
|
ZEUS_ERROR("Nullptr for _interfaceWeb");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_interfaceClient->addAsync([=](WebServer* _interface) {
|
||||||
|
_interface->answerValue(_obj->getTransactionId(), _obj->getDestination(), _obj->getSource(), ret);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @brief Execute a call on the function with a return value
|
* @brief Execute a call on the function with a return value
|
||||||
* @param[in] _interfaceClient Web interface to send data
|
* @param[in] _interfaceClient Web interface to send data
|
||||||
@ -54,6 +93,40 @@ namespace zeus {
|
|||||||
* @param[in] _func pointer on the function to call
|
* @param[in] _func pointer on the function to call
|
||||||
*/
|
*/
|
||||||
template <class ZEUS_CLASS_TYPE, class... ZEUS_TYPES>
|
template <class ZEUS_CLASS_TYPE, class... ZEUS_TYPES>
|
||||||
|
void executeClassCall(ememory::SharedPtr<zeus::WebServer> _interfaceClient,
|
||||||
|
ememory::SharedPtr<zeus::message::Parameter> _obj,
|
||||||
|
ZEUS_CLASS_TYPE* _pointer,
|
||||||
|
void (ZEUS_CLASS_TYPE::*_func)(zeus::ActionNotification& _notifs, ZEUS_TYPES...)) {
|
||||||
|
if (_obj == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
zeus::ActionNotification notifs;
|
||||||
|
if (zeus::checkOrderFunctionParameter() == true) {
|
||||||
|
// clang generate a basic warning:
|
||||||
|
// warning: multiple unsequenced modifications to 'idParam' [-Wunsequenced]
|
||||||
|
int32_t idParam = 0;
|
||||||
|
(*_pointer.*_func)(notifs, _obj->getParameter<ZEUS_TYPES>(idParam++)...);
|
||||||
|
} else {
|
||||||
|
int32_t idParam = int32_t(sizeof...(ZEUS_TYPES))-1;
|
||||||
|
(*_pointer.*_func)(notifs, _obj->getParameter<ZEUS_TYPES>(idParam--)...);
|
||||||
|
}
|
||||||
|
if (_interfaceClient == nullptr) {
|
||||||
|
ZEUS_ERROR("Nullptr for _interfaceWeb");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_interfaceClient->addAsync([=](WebServer* _interface) {
|
||||||
|
_interface->answerVoid(_obj->getTransactionId(), _obj->getDestination(), _obj->getSource());
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief Execute a call on the function with NO return value
|
||||||
|
* @param[in] _interfaceClient Web interface to send data
|
||||||
|
* @param[in] _obj Message input call (that have parameter already check)
|
||||||
|
* @param[in] _pointer Pointer on the class to call
|
||||||
|
* @param[in] _func pointer on the function to call
|
||||||
|
*/
|
||||||
|
template <class ZEUS_CLASS_TYPE, class... ZEUS_TYPES>
|
||||||
void executeClassCall(ememory::SharedPtr<zeus::WebServer> _interfaceClient,
|
void executeClassCall(ememory::SharedPtr<zeus::WebServer> _interfaceClient,
|
||||||
ememory::SharedPtr<zeus::message::Parameter> _obj,
|
ememory::SharedPtr<zeus::message::Parameter> _obj,
|
||||||
ZEUS_CLASS_TYPE* _pointer,
|
ZEUS_CLASS_TYPE* _pointer,
|
||||||
@ -83,6 +156,140 @@ namespace zeus {
|
|||||||
* @brief Chass that permit to declare a function that call intanced element or a class element
|
* @brief Chass that permit to declare a function that call intanced element or a class element
|
||||||
*/
|
*/
|
||||||
template <class ZEUS_RETURN, class ZEUS_CLASS_TYPE, class... ZEUS_TYPES>
|
template <class ZEUS_RETURN, class ZEUS_CLASS_TYPE, class... ZEUS_TYPES>
|
||||||
|
class AbstractActionTypeClass: public zeus::AbstractFunction {
|
||||||
|
protected:
|
||||||
|
static const zeus::message::ParamType m_returnType;
|
||||||
|
static const zeus::message::ParamType m_paramType[sizeof...(ZEUS_TYPES)];
|
||||||
|
public:
|
||||||
|
using functionType = ZEUS_RETURN (ZEUS_CLASS_TYPE::*)(zeus::ActionNotification& _notifs, ZEUS_TYPES...);
|
||||||
|
functionType m_function;
|
||||||
|
/**
|
||||||
|
* @brief Constructor
|
||||||
|
* @param[in] _name Name of the function
|
||||||
|
* @param[in] _fptr Pointer on the function
|
||||||
|
*/
|
||||||
|
AbstractActionTypeClass(const std::string& _name, functionType _fptr):
|
||||||
|
AbstractFunction(_name),
|
||||||
|
m_function(_fptr) {
|
||||||
|
}
|
||||||
|
std::string getPrototypeReturn() const override {
|
||||||
|
return m_returnType.getName();
|
||||||
|
}
|
||||||
|
std::vector<std::string> getPrototypeParam() const override {
|
||||||
|
std::vector<std::string> out;
|
||||||
|
for (size_t iii=0; iii<sizeof...(ZEUS_TYPES); ++iii) {
|
||||||
|
out.push_back(m_paramType[iii].getName());
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
void execute(ememory::SharedPtr<zeus::WebServer> _interfaceClient,
|
||||||
|
ememory::SharedPtr<zeus::message::Call> _obj,
|
||||||
|
void* _class) override {
|
||||||
|
if (_obj == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ZEUS_CLASS_TYPE* tmpClass = nullptr;
|
||||||
|
if (_class != nullptr) {
|
||||||
|
tmpClass = (ZEUS_CLASS_TYPE*)_class;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_interfaceClient == nullptr) {
|
||||||
|
ZEUS_ERROR("Nullptr for _interfaceWeb");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// check parameter number
|
||||||
|
if (_obj->getNumberParameter() != sizeof...(ZEUS_TYPES)) {
|
||||||
|
ZEUS_ERROR("Wrong number of Parameters ...");
|
||||||
|
std::string help = "request ";
|
||||||
|
help += etk::to_string(_obj->getNumberParameter());
|
||||||
|
help += " parameters and need ";
|
||||||
|
help += etk::to_string(sizeof...(ZEUS_TYPES));
|
||||||
|
help += " parameters. prototype function:";
|
||||||
|
help += getPrototype();
|
||||||
|
_interfaceClient->answerError(_obj->getTransactionId(),
|
||||||
|
_obj->getDestination(),
|
||||||
|
_obj->getSource(),
|
||||||
|
"WRONG-PARAMETER-NUMBER",
|
||||||
|
help);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// check parameter compatibility
|
||||||
|
for (size_t iii=0; iii<sizeof...(ZEUS_TYPES); ++iii) {
|
||||||
|
if (checkCompatibility(m_paramType[iii], _obj->getParameterType(iii)) == false) {
|
||||||
|
_interfaceClient->answerError(_obj->getTransactionId(),
|
||||||
|
_obj->getDestination(),
|
||||||
|
_obj->getSource(),
|
||||||
|
"WRONG-PARAMETER-TYPE",
|
||||||
|
std::string("Parameter id ") + etk::to_string(iii) + " not compatible with type: '" + m_paramType[iii].getName() + "'");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ethread::metadataSet(zeus::g_threadKeyTransactionId, _obj->getTransactionId());
|
||||||
|
ethread::metadataSet(zeus::g_threadKeyTransactionSource, _obj->getSource());
|
||||||
|
ethread::metadataSet(zeus::g_threadKeyTransactionDestination, _obj->getDestination());
|
||||||
|
try {
|
||||||
|
// execute cmd:
|
||||||
|
zeus::executeClassCall(_interfaceClient, _obj, tmpClass, m_function);
|
||||||
|
} catch (const std::invalid_argument& eee) {
|
||||||
|
_interfaceClient->addAsync([=](WebServer* _interface) {
|
||||||
|
_interface->answerError(_obj->getTransactionId(), _obj->getDestination(), _obj->getSource(), "INVALID-ARGUMENT", eee.what());
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
} catch (const std::domain_error& eee) {
|
||||||
|
_interfaceClient->addAsync([=](WebServer* _interface) {
|
||||||
|
_interface->answerError(_obj->getTransactionId(), _obj->getDestination(), _obj->getSource(), "DOMAIN-ERROR", eee.what());
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
} catch (const std::length_error& eee) {
|
||||||
|
_interfaceClient->addAsync([=](WebServer* _interface) {
|
||||||
|
_interface->answerError(_obj->getTransactionId(), _obj->getDestination(), _obj->getSource(), "LENGTH-ERROR", eee.what());
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
} catch (const std::out_of_range& eee) {
|
||||||
|
_interfaceClient->addAsync([=](WebServer* _interface) {
|
||||||
|
_interface->answerError(_obj->getTransactionId(), _obj->getDestination(), _obj->getSource(), "OUT-OF-RANGE", eee.what());
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
} catch (const std::range_error& eee) {
|
||||||
|
_interfaceClient->addAsync([=](WebServer* _interface) {
|
||||||
|
_interface->answerError(_obj->getTransactionId(), _obj->getDestination(), _obj->getSource(), "RANGE-ERROR", eee.what());
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
} catch (const std::overflow_error& eee) {
|
||||||
|
_interfaceClient->addAsync([=](WebServer* _interface) {
|
||||||
|
_interface->answerError(_obj->getTransactionId(), _obj->getDestination(), _obj->getSource(), "OVERFLOW-ERROR", eee.what());
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
} catch (const std::underflow_error& eee) {
|
||||||
|
_interfaceClient->addAsync([=](WebServer* _interface) {
|
||||||
|
_interface->answerError(_obj->getTransactionId(), _obj->getDestination(), _obj->getSource(), "UNDERFLOW-ERROR", eee.what());
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
} catch (const std::logic_error& eee) {
|
||||||
|
_interfaceClient->addAsync([=](WebServer* _interface) {
|
||||||
|
_interface->answerError(_obj->getTransactionId(), _obj->getDestination(), _obj->getSource(), "LOGIC-ERROR", eee.what());
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
} catch (const std::runtime_error& eee) {
|
||||||
|
_interfaceClient->addAsync([=](WebServer* _interface) {
|
||||||
|
_interface->answerError(_obj->getTransactionId(), _obj->getDestination(), _obj->getSource(), "RUNTIME-ERROR", eee.what());
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
} catch ( ... ) {
|
||||||
|
_interfaceClient->addAsync([=](WebServer* _interface) {
|
||||||
|
_interface->answerError(_obj->getTransactionId(), _obj->getDestination(), _obj->getSource(), "?-ERROR", "catch unknow error");
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
ethread::metadataRemove(zeus::g_threadKeyTransactionId);
|
||||||
|
ethread::metadataRemove(zeus::g_threadKeyTransactionSource);
|
||||||
|
ethread::metadataRemove(zeus::g_threadKeyTransactionDestination);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* @brief Chass that permit to declare a function that call intanced element or a class element
|
||||||
|
*/
|
||||||
|
template <class ZEUS_RETURN, class ZEUS_CLASS_TYPE, class... ZEUS_TYPES>
|
||||||
class AbstractFunctionTypeClass: public zeus::AbstractFunction {
|
class AbstractFunctionTypeClass: public zeus::AbstractFunction {
|
||||||
protected:
|
protected:
|
||||||
static const zeus::message::ParamType m_returnType;
|
static const zeus::message::ParamType m_returnType;
|
||||||
@ -215,6 +422,12 @@ namespace zeus {
|
|||||||
};
|
};
|
||||||
// specialization
|
// specialization
|
||||||
template <class ZEUS_RETURN, class ZEUS_CLASS_TYPE, class... ZEUS_TYPES>
|
template <class ZEUS_RETURN, class ZEUS_CLASS_TYPE, class... ZEUS_TYPES>
|
||||||
|
const zeus::message::ParamType AbstractActionTypeClass<ZEUS_RETURN, ZEUS_CLASS_TYPE, ZEUS_TYPES...>::m_returnType = zeus::message::createType<ZEUS_RETURN>();
|
||||||
|
// specialization
|
||||||
|
template <class ZEUS_RETURN, class ZEUS_CLASS_TYPE, class... ZEUS_TYPES>
|
||||||
|
const zeus::message::ParamType AbstractActionTypeClass<ZEUS_RETURN, ZEUS_CLASS_TYPE, ZEUS_TYPES...>::m_paramType[sizeof...(ZEUS_TYPES)] = {zeus::message::createType<ZEUS_TYPES>()...};
|
||||||
|
// specialization
|
||||||
|
template <class ZEUS_RETURN, class ZEUS_CLASS_TYPE, class... ZEUS_TYPES>
|
||||||
const zeus::message::ParamType AbstractFunctionTypeClass<ZEUS_RETURN, ZEUS_CLASS_TYPE, ZEUS_TYPES...>::m_returnType = zeus::message::createType<ZEUS_RETURN>();
|
const zeus::message::ParamType AbstractFunctionTypeClass<ZEUS_RETURN, ZEUS_CLASS_TYPE, ZEUS_TYPES...>::m_returnType = zeus::message::createType<ZEUS_RETURN>();
|
||||||
// specialization
|
// specialization
|
||||||
template <class ZEUS_RETURN, class ZEUS_CLASS_TYPE, class... ZEUS_TYPES>
|
template <class ZEUS_RETURN, class ZEUS_CLASS_TYPE, class... ZEUS_TYPES>
|
||||||
@ -226,6 +439,16 @@ namespace zeus {
|
|||||||
* @return Abstract type of the function
|
* @return Abstract type of the function
|
||||||
*/
|
*/
|
||||||
template <typename ZEUS_RETURN, class ZEUS_CLASS_TYPE, typename... ZEUS_TYPES>
|
template <typename ZEUS_RETURN, class ZEUS_CLASS_TYPE, typename... ZEUS_TYPES>
|
||||||
|
AbstractFunction* createAbstractFunctionClass(const std::string& _name, ZEUS_RETURN (ZEUS_CLASS_TYPE::*_fffp)(zeus::ActionNotification& _notifs, ZEUS_TYPES...)) {
|
||||||
|
return new AbstractActionTypeClass<ZEUS_RETURN, ZEUS_CLASS_TYPE, ZEUS_TYPES...>(_name, _fffp);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief Create a function information with the function type
|
||||||
|
* @param[in] _name Name of the function
|
||||||
|
* @param[in] _fffp Pointer of the function
|
||||||
|
* @return Abstract type of the function
|
||||||
|
*/
|
||||||
|
template <typename ZEUS_RETURN, class ZEUS_CLASS_TYPE, typename... ZEUS_TYPES>
|
||||||
AbstractFunction* createAbstractFunctionClass(const std::string& _name, ZEUS_RETURN (ZEUS_CLASS_TYPE::*_fffp)(ZEUS_TYPES...)) {
|
AbstractFunction* createAbstractFunctionClass(const std::string& _name, ZEUS_RETURN (ZEUS_CLASS_TYPE::*_fffp)(ZEUS_TYPES...)) {
|
||||||
return new AbstractFunctionTypeClass<ZEUS_RETURN, ZEUS_CLASS_TYPE, ZEUS_TYPES...>(_name, _fffp);
|
return new AbstractFunctionTypeClass<ZEUS_RETURN, ZEUS_CLASS_TYPE, ZEUS_TYPES...>(_name, _fffp);
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,13 @@ zeus::FutureBase::FutureBase(ememory::SharedPtr<zeus::Promise> _promise) {
|
|||||||
m_promise = _promise;
|
m_promise = _promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void zeus::FutureBase::setAction() {
|
||||||
|
if (m_promise == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_promise->setAction();
|
||||||
|
}
|
||||||
|
|
||||||
ememory::SharedPtr<zeus::Message> zeus::FutureBase::getRaw() {
|
ememory::SharedPtr<zeus::Message> zeus::FutureBase::getRaw() {
|
||||||
if (m_promise == nullptr) {
|
if (m_promise == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -43,6 +43,11 @@ namespace zeus {
|
|||||||
* @param[in] _source Source that is waiting for answer
|
* @param[in] _source Source that is waiting for answer
|
||||||
*/
|
*/
|
||||||
FutureBase(uint32_t _transactionId, ememory::SharedPtr<zeus::Message> _returnData, uint32_t _source=0);
|
FutureBase(uint32_t _transactionId, ememory::SharedPtr<zeus::Message> _returnData, uint32_t _source=0);
|
||||||
|
/**
|
||||||
|
* @brief set the call is an action an then it can receive remote data ==> the authorize the onProgress Callback ..
|
||||||
|
* @note system use only ==> user have never to call this function...
|
||||||
|
*/
|
||||||
|
void setAction();
|
||||||
/**
|
/**
|
||||||
* @brief Attach callback on all return type of value
|
* @brief Attach callback on all return type of value
|
||||||
* @param[in] _callback Handle on the function to call in all case
|
* @param[in] _callback Handle on the function to call in all case
|
||||||
|
@ -110,9 +110,46 @@ namespace zeus {
|
|||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief Advertise a new signal that use a specific call processing order
|
||||||
* @param[in]
|
* @param[in] _name Name of the function
|
||||||
* @return
|
* @param[in] _func Pointer on the function to call when name call is requested
|
||||||
|
* @return Pointer on the function abstraction call that is done
|
||||||
|
* @note: this is for ACTION function call not normal function call
|
||||||
|
*/
|
||||||
|
template<class ZEUS_RETURN_VALUE,
|
||||||
|
class ZEUS_CLASS_TYPE,
|
||||||
|
class... ZEUS_FUNC_ARGS_TYPE>
|
||||||
|
zeus::AbstractFunction* advertise(const std::string& _name,
|
||||||
|
ZEUS_RETURN_VALUE (ZEUS_CLASS_TYPE::*_func)(zeus::ActionNotification& _notifs, ZEUS_FUNC_ARGS_TYPE... _args)) {
|
||||||
|
if (etk::start_with(_name, "srv.") == true) {
|
||||||
|
ZEUS_ERROR("Advertise function start with 'srv.' is not permited ==> only allow for internal service: '" << _name << "'");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
for (auto &it : m_listFunction) {
|
||||||
|
if (it == nullptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (it->getName() == _name) {
|
||||||
|
ZEUS_ERROR("Advertise function already bind .. ==> can not be done...: '" << _name << "'");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zeus::AbstractFunction* tmp = createAbstractFunctionClass(_name, _func);
|
||||||
|
if (tmp == nullptr) {
|
||||||
|
ZEUS_ERROR("can not create abstract function ... '" << _name << "'");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
tmp->setType(zeus::AbstractFunction::type::object);
|
||||||
|
ZEUS_VERBOSE("Add function '" << _name << "' in object mode");
|
||||||
|
m_listFunction.push_back(tmp);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief Advertise a new signal that use a specific call processing order
|
||||||
|
* @param[in] _name Name of the function
|
||||||
|
* @param[in] _func Pointer on the function to call when name call is requested
|
||||||
|
* @return Pointer on the function abstraction call that is done
|
||||||
|
* @note: this is for normal function call not action call
|
||||||
*/
|
*/
|
||||||
template<class ZEUS_RETURN_VALUE,
|
template<class ZEUS_RETURN_VALUE,
|
||||||
class ZEUS_CLASS_TYPE,
|
class ZEUS_CLASS_TYPE,
|
||||||
|
@ -107,9 +107,10 @@ namespace zeus {
|
|||||||
bool exist() const;
|
bool exist() const;
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief
|
* @brief Call a remote function of the current object
|
||||||
* @param[in]
|
* @param[in] _functionName Name of the function
|
||||||
* @return
|
* @param[in] _args All argument function needed by the remote to process the function
|
||||||
|
* @return A generic future with all datas
|
||||||
*/
|
*/
|
||||||
template<class... _ARGS>
|
template<class... _ARGS>
|
||||||
zeus::FutureBase call(const std::string& _functionName, _ARGS&&... _args) {
|
zeus::FutureBase call(const std::string& _functionName, _ARGS&&... _args) {
|
||||||
@ -126,6 +127,17 @@ namespace zeus {
|
|||||||
_functionName,
|
_functionName,
|
||||||
_args...);
|
_args...);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* @param[in]
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
template<class... _ARGS>
|
||||||
|
zeus::FutureBase callAction(const std::string& _functionName, _ARGS&&... _args) {
|
||||||
|
zeus::FutureBase tmp = call(_functionName, _args...);
|
||||||
|
tmp.setAction();
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <zeus/Promise.hpp>
|
#include <zeus/Promise.hpp>
|
||||||
#include <zeus/FutureBase.hpp>
|
#include <zeus/FutureBase.hpp>
|
||||||
#include <zeus/message/Answer.hpp>
|
#include <zeus/message/Answer.hpp>
|
||||||
|
#include <zeus/message/Progress.hpp>
|
||||||
#include <zeus/debug.hpp>
|
#include <zeus/debug.hpp>
|
||||||
#include <zeus/WebServer.hpp>
|
#include <zeus/WebServer.hpp>
|
||||||
|
|
||||||
@ -43,6 +44,10 @@ void zeus::Promise::remoteObjectDestroyed() {
|
|||||||
setMessage(answer);
|
setMessage(answer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void zeus::Promise::setAction() {
|
||||||
|
m_isAction = true;
|
||||||
|
}
|
||||||
|
|
||||||
void zeus::Promise::andAll(zeus::Promise::Observer _callback) {
|
void zeus::Promise::andAll(zeus::Promise::Observer _callback) {
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::unique_lock<std::mutex> lock(m_mutex);
|
||||||
@ -103,6 +108,9 @@ void zeus::Promise::andElse(zeus::Promise::Observer _callback) {
|
|||||||
|
|
||||||
void zeus::Promise::onProgress(zeus::Promise::ObserverProgress _callback) {
|
void zeus::Promise::onProgress(zeus::Promise::ObserverProgress _callback) {
|
||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::unique_lock<std::mutex> lock(m_mutex);
|
||||||
|
if (m_isAction == false) {
|
||||||
|
ZEUS_ERROR("Request a progress calback on a simple function call");
|
||||||
|
}
|
||||||
m_callbackProgress = _callback;
|
m_callbackProgress = _callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,8 +131,8 @@ bool zeus::Promise::setMessage(ememory::SharedPtr<zeus::Message> _value) {
|
|||||||
std::unique_lock<std::mutex> lock(m_mutex);
|
std::unique_lock<std::mutex> lock(m_mutex);
|
||||||
// notification of a progresion ...
|
// notification of a progresion ...
|
||||||
if (m_callbackProgress != nullptr) {
|
if (m_callbackProgress != nullptr) {
|
||||||
// TODO: return m_callbackProgress(_value.);
|
m_callbackProgress(static_cast<const zeus::message::Progress*>(m_message.get())->getData());
|
||||||
#warning progress callback to do ..
|
return false; // no error
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,8 @@ namespace zeus {
|
|||||||
//Observer m_callbackAbort; //!< observer callback When Action is abort by user
|
//Observer m_callbackAbort; //!< observer callback When Action is abort by user
|
||||||
echrono::Steady m_sendTime; //!< time when the future has been sended request
|
echrono::Steady m_sendTime; //!< time when the future has been sended request
|
||||||
echrono::Steady m_receiveTime; //!< time when the future has receve answer
|
echrono::Steady m_receiveTime; //!< time when the future has receve answer
|
||||||
|
// TODO: Chek if it is not good to set it in DEBUG only ....
|
||||||
|
bool m_isAction; //!< Permit to filter the user setting a callbak that is never called ==> cosmetc usage
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Contructor of the FutureBase with an ofserver
|
* @brief Contructor of the FutureBase with an ofserver
|
||||||
@ -48,6 +50,11 @@ namespace zeus {
|
|||||||
* @param[in] _source Source that is waiting for answer
|
* @param[in] _source Source that is waiting for answer
|
||||||
*/
|
*/
|
||||||
Promise(uint32_t _transactionId, ememory::SharedPtr<zeus::Message> _returnData, uint32_t _source=0);
|
Promise(uint32_t _transactionId, ememory::SharedPtr<zeus::Message> _returnData, uint32_t _source=0);
|
||||||
|
/**
|
||||||
|
* @brief set the call is an action an then it can receive remote data ==> the authorize the onProgress Callback ..
|
||||||
|
* @note system use only ==> user have never to call this function...
|
||||||
|
*/
|
||||||
|
void setAction();
|
||||||
/**
|
/**
|
||||||
* @brief Attach callback on all return type of value
|
* @brief Attach callback on all return type of value
|
||||||
* @param[in] _callback Handle on the function to call in all case
|
* @param[in] _callback Handle on the function to call in all case
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <zeus/message/Call.hpp>
|
#include <zeus/message/Call.hpp>
|
||||||
#include <zeus/message/Data.hpp>
|
#include <zeus/message/Data.hpp>
|
||||||
#include <zeus/message/Flow.hpp>
|
#include <zeus/message/Flow.hpp>
|
||||||
|
#include <zeus/message/Progress.hpp>
|
||||||
#include <zeus/message/Event.hpp>
|
#include <zeus/message/Event.hpp>
|
||||||
#include <zeus/WebServer.hpp>
|
#include <zeus/WebServer.hpp>
|
||||||
|
|
||||||
@ -99,6 +100,9 @@ void zeus::Message::generateDisplay(std::ostream& _os) const {
|
|||||||
case zeus::message::type::data:
|
case zeus::message::type::data:
|
||||||
_os << " -DATA-";
|
_os << " -DATA-";
|
||||||
break;
|
break;
|
||||||
|
case zeus::message::type::progress:
|
||||||
|
_os << " -PROGRESS-";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,6 +270,22 @@ ememory::SharedPtr<zeus::Message> zeus::Message::create(ememory::SharedPtr<zeus:
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case zeus::message::type::progress: {
|
||||||
|
ememory::SharedPtr<zeus::message::Progress> value = zeus::message::Progress::create(_iface);
|
||||||
|
if (value == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
value->setTransactionId(header.transactionId);
|
||||||
|
value->setSourceId(header.sourceId);
|
||||||
|
value->setSourceObjectId(header.sourceObjectId);
|
||||||
|
value->setDestinationId(header.destinationId);
|
||||||
|
value->setDestinationObjectId(header.destinationObjectId);
|
||||||
|
value->setPartFinish((header.flags & ZEUS_BUFFER_FLAG_FINISH) != 0);
|
||||||
|
value->composeWith(&_buffer[sizeof(zeus::message::headerBin)],
|
||||||
|
_buffer.size() - sizeof(zeus::message::headerBin));
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user