[DEV] add service and object action notification bases

This commit is contained in:
Edouard DUPIN 2017-05-28 16:22:54 +02:00
parent e4ddecc0eb
commit 6ee0c7047e
12 changed files with 402 additions and 36 deletions

View File

@ -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 ')'")

View File

@ -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',
])

View File

@ -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 ...");

View File

@ -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)
/*

View File

@ -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);
}

View File

@ -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;

View File

@ -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

View File

@ -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,

View File

@ -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;
}
};

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}