[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:
|
||||
def __init__(self):
|
||||
self.name = "";
|
||||
self.brief = "";
|
||||
self.return_type = "";
|
||||
self.return_brief = "";
|
||||
self.name = ""
|
||||
self.brief = ""
|
||||
self.return_type = ""
|
||||
self.return_brief = ""
|
||||
self.parameters = []
|
||||
self.is_action = False
|
||||
|
||||
def set_action(self):
|
||||
self.is_action = True
|
||||
|
||||
def set_function_name(self, name):
|
||||
self.name = remove_start_stop_spacer(name);
|
||||
@ -249,13 +253,14 @@ class FunctionDefinition:
|
||||
out += elem["name"] + " "
|
||||
if 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 != "":
|
||||
out += space + " * @return " + self.return_brief + "\n"
|
||||
out += space + " */\n"
|
||||
return out
|
||||
|
||||
def generate_cpp(self, space, class_name="", virtual=True):
|
||||
def generate_cpp(self, space, class_name="", virtual=True, action=False):
|
||||
out = "";
|
||||
out += self.generate_doxy(space)
|
||||
out += space
|
||||
@ -268,6 +273,9 @@ class FunctionDefinition:
|
||||
out += self.name + "("
|
||||
param_data = ""
|
||||
id_parameter = 0
|
||||
if self.is_action == True:
|
||||
param_data += "zeus::ActionNotification& _notifs"
|
||||
id_parameter += 1
|
||||
for elem in self.parameters:
|
||||
id_parameter += 1
|
||||
if len(param_data) != 0:
|
||||
@ -320,7 +328,10 @@ class FunctionDefinition:
|
||||
out += param_data
|
||||
out += ") {\n"
|
||||
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
|
||||
for elem in self.parameters:
|
||||
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.error(" support only: '#brief:' '#param:' '#return:' '#elem-brief:' '#elem-version:' '#elem-type:' '#elem-author:'")
|
||||
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 + "'")
|
||||
if line[:7] == "import ":
|
||||
debug.debug("find import : " + line)
|
||||
# TODO : Add check ...
|
||||
service_def.add_import(line.split(" ")[1])
|
||||
elif line[-1] == ")":
|
||||
# Find a fundtion ==> parse it
|
||||
elif line[-1] == ")":
|
||||
# Find a function ==> parse it
|
||||
#debug.error("line " + str(id_line) + " Can not parse function the line dos not ended by a ')'")
|
||||
#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:
|
||||
debug.error("line " + str(id_line) + " function parsing error missing the '(' element")
|
||||
fist_part = list_elems[0].replace(" ", " ").replace(" ", " ").replace(" ", " ")
|
||||
@ -919,44 +953,50 @@ def tool_generate_idl(target, module, data_option):
|
||||
# separate the
|
||||
list_elems = fist_part.split(" ")
|
||||
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]
|
||||
function_name = list_elems[1]
|
||||
# check types:
|
||||
debug.extreme_verbose(" Parse of function done :")
|
||||
current_def.set_function_name(function_name)
|
||||
type_function = "normal"
|
||||
if return_value[:13] == "[tool-remote]":
|
||||
type_function = "tool"
|
||||
current_def.set_return_type(return_value[13:])
|
||||
debug.extreme_verbose(" return:" + return_value[13:])
|
||||
if validate_type(return_value[13:]) == False:
|
||||
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 type_function == "tool":
|
||||
current_def.set_return_type(return_value)
|
||||
debug.extreme_verbose(" return:" + return_value)
|
||||
if validate_type(return_value) == False:
|
||||
debug.error("line " + str(id_line) + " function return type unknow : '" + return_value + "' not in " + str(get_list_type()))
|
||||
elif type_function == "factory":
|
||||
if function_name != "create":
|
||||
debug.error("line " + str(id_line) + " factory function name must be 'create' not '" + function_name + "'")
|
||||
debug.extreme_verbose(" return: --- ")
|
||||
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:
|
||||
current_def.set_return_type(return_value)
|
||||
debug.extreme_verbose(" return:" + return_value)
|
||||
|
||||
for elem in argument_list:
|
||||
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(" arguments:" + str(argument_list))
|
||||
for elem in argument_list:
|
||||
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)
|
||||
elif type_function == "factory":
|
||||
service_def.add_factory(current_def)
|
||||
else:
|
||||
elif type_function == "tool-remote":
|
||||
service_def.add_tool(current_def)
|
||||
else:
|
||||
debug.error("line " + str(id_line) + " Unknow type : " + str(type_function))
|
||||
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 len(line.split("(")) != 1:
|
||||
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/Event.cpp',
|
||||
'zeus/message/Flow.cpp',
|
||||
'zeus/message/Progress.cpp',
|
||||
'zeus/message/Parameter_addParameter.cpp',
|
||||
'zeus/message/Parameter_getParameter.cpp',
|
||||
'zeus/message/ParamType.cpp',
|
||||
@ -73,6 +74,7 @@ def configure(target, my_module):
|
||||
'zeus/message/Data.hpp',
|
||||
'zeus/message/Event.hpp',
|
||||
'zeus/message/Flow.hpp',
|
||||
'zeus/message/Progress.hpp',
|
||||
'zeus/message/ParamType.hpp',
|
||||
'zeus/message/type.hpp',
|
||||
])
|
||||
|
@ -171,7 +171,10 @@ namespace appl {
|
||||
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;
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(g_mutex);
|
||||
@ -249,6 +252,7 @@ namespace appl {
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
g_needToStore = true;
|
||||
}
|
||||
if (find == false) {
|
||||
throw std::invalid_argument("Wrong file name ...");
|
||||
|
@ -32,11 +32,12 @@ obj:zeus-Media get(uint32)
|
||||
#brief:Add a new media in the service
|
||||
#param:data:A file reference on the media (transmission is async)
|
||||
#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)
|
||||
#param:mediaId:Id of the media
|
||||
void remove(uint32)
|
||||
[function] void remove(uint32)
|
||||
|
||||
|
||||
/*
|
||||
|
@ -12,6 +12,45 @@
|
||||
|
||||
|
||||
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
|
||||
* @param[in] _interfaceClient Web interface to send data
|
||||
@ -54,6 +93,40 @@ namespace zeus {
|
||||
* @param[in] _func pointer on the function to call
|
||||
*/
|
||||
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,
|
||||
ememory::SharedPtr<zeus::message::Parameter> _obj,
|
||||
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
|
||||
*/
|
||||
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 {
|
||||
protected:
|
||||
static const zeus::message::ParamType m_returnType;
|
||||
@ -215,6 +422,12 @@ namespace zeus {
|
||||
};
|
||||
// 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_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>();
|
||||
// specialization
|
||||
template <class ZEUS_RETURN, class ZEUS_CLASS_TYPE, class... ZEUS_TYPES>
|
||||
@ -226,6 +439,16 @@ namespace zeus {
|
||||
* @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::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...)) {
|
||||
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;
|
||||
}
|
||||
|
||||
void zeus::FutureBase::setAction() {
|
||||
if (m_promise == nullptr) {
|
||||
return;
|
||||
}
|
||||
m_promise->setAction();
|
||||
}
|
||||
|
||||
ememory::SharedPtr<zeus::Message> zeus::FutureBase::getRaw() {
|
||||
if (m_promise == nullptr) {
|
||||
return nullptr;
|
||||
|
@ -43,6 +43,11 @@ namespace zeus {
|
||||
* @param[in] _source Source that is waiting for answer
|
||||
*/
|
||||
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
|
||||
* @param[in] _callback Handle on the function to call in all case
|
||||
|
@ -110,9 +110,46 @@ namespace zeus {
|
||||
}
|
||||
public:
|
||||
/**
|
||||
* @brief
|
||||
* @param[in]
|
||||
* @return
|
||||
* @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 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,
|
||||
class ZEUS_CLASS_TYPE,
|
||||
|
@ -107,9 +107,10 @@ namespace zeus {
|
||||
bool exist() const;
|
||||
public:
|
||||
/**
|
||||
* @brief
|
||||
* @param[in]
|
||||
* @return
|
||||
* @brief Call a remote function of the current object
|
||||
* @param[in] _functionName Name of the function
|
||||
* @param[in] _args All argument function needed by the remote to process the function
|
||||
* @return A generic future with all datas
|
||||
*/
|
||||
template<class... _ARGS>
|
||||
zeus::FutureBase call(const std::string& _functionName, _ARGS&&... _args) {
|
||||
@ -126,6 +127,17 @@ namespace zeus {
|
||||
_functionName,
|
||||
_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/FutureBase.hpp>
|
||||
#include <zeus/message/Answer.hpp>
|
||||
#include <zeus/message/Progress.hpp>
|
||||
#include <zeus/debug.hpp>
|
||||
#include <zeus/WebServer.hpp>
|
||||
|
||||
@ -43,6 +44,10 @@ void zeus::Promise::remoteObjectDestroyed() {
|
||||
setMessage(answer);
|
||||
}
|
||||
|
||||
void zeus::Promise::setAction() {
|
||||
m_isAction = true;
|
||||
}
|
||||
|
||||
void zeus::Promise::andAll(zeus::Promise::Observer _callback) {
|
||||
{
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -123,8 +131,8 @@ bool zeus::Promise::setMessage(ememory::SharedPtr<zeus::Message> _value) {
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
// notification of a progresion ...
|
||||
if (m_callbackProgress != nullptr) {
|
||||
// TODO: return m_callbackProgress(_value.);
|
||||
#warning progress callback to do ..
|
||||
m_callbackProgress(static_cast<const zeus::message::Progress*>(m_message.get())->getData());
|
||||
return false; // no error
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -33,6 +33,8 @@ namespace zeus {
|
||||
//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_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:
|
||||
/**
|
||||
* @brief Contructor of the FutureBase with an ofserver
|
||||
@ -48,6 +50,11 @@ namespace zeus {
|
||||
* @param[in] _source Source that is waiting for answer
|
||||
*/
|
||||
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
|
||||
* @param[in] _callback Handle on the function to call in all case
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <zeus/message/Call.hpp>
|
||||
#include <zeus/message/Data.hpp>
|
||||
#include <zeus/message/Flow.hpp>
|
||||
#include <zeus/message/Progress.hpp>
|
||||
#include <zeus/message/Event.hpp>
|
||||
#include <zeus/WebServer.hpp>
|
||||
|
||||
@ -99,6 +100,9 @@ void zeus::Message::generateDisplay(std::ostream& _os) const {
|
||||
case zeus::message::type::data:
|
||||
_os << " -DATA-";
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user