[DEV] rework Signal implementation callback ==> must update all soft

This commit is contained in:
Edouard DUPIN 2014-08-21 21:22:51 +02:00
parent 153774177e
commit 12c4a88c88
3 changed files with 128 additions and 63 deletions

View File

@ -15,24 +15,15 @@ namespace ewol {
namespace object {
class Message {
private:
std::shared_ptr<ewol::Object> m_callerObject; //!< Caller class.
const char* m_event; //!< Event pointer == > unique Id define by the system ...
std::string m_data; //!< compositing additionnal message Value.
public:
Message(const std::shared_ptr<ewol::Object>& _caller,
const char* _message,
Message(const char* _message,
const std::string& _data) :
m_callerObject(_caller),
m_event(_message),
m_data(_data) {
};
void setCaller(const std::shared_ptr<ewol::Object>& _caller) {
m_callerObject = _caller;
};
inline std::shared_ptr<ewol::Object> getCaller() const {
return m_callerObject;
};
void setMessage(const char* _message) {
m_event = _message;
};

View File

@ -71,7 +71,7 @@ void ewol::object::MultiCast::send(const std::shared_ptr<ewol::Object>& _object,
if (obj != nullptr) {
EWOL_VERBOSE(" id = " << obj->getId() << " type=" << obj->getObjectType());
// generate event ... (create message before ...
ewol::object::Message tmpMsg(_object, it.m_message, _data);
ewol::object::Message tmpMsg(it.m_message, _data);
obj->onReceiveMessage(tmpMsg);
}
}

View File

@ -11,11 +11,11 @@
#ifndef __EWOL_SIGNAL_H__
#define __EWOL_SIGNAL_H__
#include <functional>
#include <ewol/object/ParameterList.h>
#include <ewol/object/SignalBase.h>
#include <ewol/object/Object.h>
namespace ewol {
namespace object {
class SignalCallerIdentifier {
@ -32,7 +32,8 @@ namespace ewol {
};
template<typename T> class Signal : public SignalBase {
private:
//std::vector<std::funtion<void(const T&)>> m_callerList;
std::vector<std::pair<std::weak_ptr<ewol::Object>,
std::function<void(const T&)>>> m_callerList;
std::vector<SignalCallerIdentifier> m_serializedCallerList;
public:
/**
@ -54,9 +55,39 @@ namespace ewol {
* @brief Destructor.
*/
virtual ~Signal() { };
void connect(std::shared_ptr<ewol::Object> _obj, const char* _destId=nullptr, const std::string& _data="" ) {
/**
* @brief Bind a callback function to the current signal (generic methis (simplest))
* @param[in] _obj Shared pointer on the caller object
* @param[in] _func Link on the fuction that might be called (inside a class)
* @example signalXXXX.connect(shared_from_this(), &ClassName::onCallbackXXX);
*/
template<class TYPE> void bind(std::shared_ptr<ewol::Object> _obj, void (TYPE::*_func)(const T&)) {
std::shared_ptr<TYPE> obj2 = std::dynamic_pointer_cast<TYPE>(_obj);
if (obj2 == nullptr) {
EWOL_ERROR("Can not bind signal ...");
return;
}
m_callerList.push_back(std::make_pair(std::weak_ptr<ewol::Object>(_obj), std::bind(_func, obj2.get(), std::placeholders::_1)));
}
/**
* @brief Advanced binding a callback function to the current signal.
* @param[in] _obj Shared pointer on the caller object
* @param[in] _func functor to call (do it yourself)
* @example signalXXXX.connect(shared_from_this(), std::bind(&ClassName::onCallbackXXX, this, std::placeholders::_1));
*/
void connect(std::shared_ptr<ewol::Object> _obj, std::function<void(const T&)> _function ) {
m_callerList.push_back(std::make_pair(std::weak_ptr<ewol::Object>(_obj), _function));
}
/**
* @brief DEPRECATED: old connect signal between Objects
*/
void connect(std::shared_ptr<ewol::Object> _obj, const char* _destId=nullptr, const std::string& _data="" ) __attribute__ ((deprecated)) {
m_serializedCallerList.push_back(SignalCallerIdentifier(_obj, _destId, _data));
}
/**
* @brief remove link on the signal.
* @param[in] _obj shared pointer on the removing object
*/
void release(std::shared_ptr<ewol::Object> _obj) {
for (auto it(m_serializedCallerList.begin()) ; it != m_serializedCallerList.end(); ++it) {
if (it->m_object.lock() == _obj) {
@ -64,68 +95,63 @@ namespace ewol {
it = m_serializedCallerList.begin();
}
}
}
/*
bool emitString(const std::shared_ptr<ewol::Object>& _source, const std::string& _data) {
// note : this can not emit on function ....
for (auto &it : m_serializedCallerList) {
std::shared_ptr<ewol::Object> destObject = std::get<0>(it).lock();
if (destObject == nullptr) {
// TODO : Remove instance ...
EWOL_VERBOSE(" nullptr dest");
continue;
}
const char* eventId = m_name.c_str();
if (std::get<1>(it) != nullptr) {
eventId = std::get<1>(it);
}
if (std::get<2>(it).size() <= 0){
ewol::object::Message tmpMsg(_source, eventId, _data);
EWOL_VERBOSE("send message " << tmpMsg);
destObject->onReceiveMessage(tmpMsg);
} else {
// set the user requested data ...
ewol::object::Message tmpMsg(_source, eventId, std::get<2>(it));
EWOL_VERBOSE("send message " << tmpMsg);
destObject->onReceiveMessage(tmpMsg);
for (auto it(m_callerList.begin()) ; it != m_callerList.end(); ++it) {
if (it->first.lock() == _obj) {
m_callerList.erase(it);
it = m_callerList.begin();
}
}
}
*/
void emit(const std::shared_ptr<ewol::Object>& _source, const T& _data) {
/**
* @brief Generate a signal on all interface listening.
* @param[in] _data data to emit
*/
void emit(const std::shared_ptr<ewol::Object>& _source, const T& _data) __attribute__ ((deprecated)) {
emit(_data);
}
void emit(const T& _data) {
// note : this can not emit on function ....
std::string stringData;
if (m_serializedCallerList.size()>0 ) {
stringData = etk::to_string(_data);
std::string stringData = etk::to_string(_data);
for (auto &it : m_serializedCallerList) {
std::shared_ptr<ewol::Object> destObject = it.m_object.lock();
if (destObject == nullptr) {
// TODO : Remove instance ...
EWOL_VERBOSE(" nullptr dest");
continue;
}
const char* eventId = m_name.c_str();
if (it.m_enevntId != nullptr) {
eventId = it.m_enevntId;
}
if (it.m_data.size() <= 0){
ewol::object::Message tmpMsg(eventId, stringData);
EWOL_VERBOSE("send message " << tmpMsg);
destObject->onReceiveMessage(tmpMsg);
} else {
// set the user requested data ...
ewol::object::Message tmpMsg(eventId, it.m_data);
EWOL_VERBOSE("send message " << tmpMsg);
destObject->onReceiveMessage(tmpMsg);
}
}
}
for (auto &it : m_serializedCallerList) {
std::shared_ptr<ewol::Object> destObject = it.m_object.lock();
for (auto &it : m_callerList) {
std::shared_ptr<ewol::Object> destObject = it.first.lock();
if (destObject == nullptr) {
// TODO : Remove instance ...
EWOL_VERBOSE(" nullptr dest");
continue;
}
const char* eventId = m_name.c_str();
if (it.m_enevntId != nullptr) {
eventId = it.m_enevntId;
}
if (it.m_data.size() <= 0){
ewol::object::Message tmpMsg(_source, eventId, stringData);
EWOL_VERBOSE("send message " << tmpMsg);
destObject->onReceiveMessage(tmpMsg);
} else {
// set the user requested data ...
ewol::object::Message tmpMsg(_source, eventId, it.m_data);
EWOL_VERBOSE("send message " << tmpMsg);
destObject->onReceiveMessage(tmpMsg);
}
it.second(_data);
}
}
};
template<> class Signal<void> : public SignalBase {
private:
//std::vector<std::funtion<void(const T&)>> m_callerList;
std::vector<std::pair<std::weak_ptr<ewol::Object>,
std::function<void()>>> m_callerList;
std::vector<SignalCallerIdentifier> m_serializedCallerList;
public:
/**
@ -148,9 +174,39 @@ namespace ewol {
*/
virtual ~Signal() { };
void connect(std::shared_ptr<ewol::Object> _obj, const char* _destId=nullptr, const std::string& _data="" ) {
/**
* @brief Bind a callback function to the current signal (generic methis (simplest))
* @param[in] _obj Shared pointer on the caller object
* @param[in] _func Link on the fuction that might be called (inside a class)
* @example signalXXXX.connect(shared_from_this(), &ClassName::onCallbackXXX);
*/
template<class TYPE> void bind(std::shared_ptr<ewol::Object> _obj, void (TYPE::*_func)()) {
std::shared_ptr<TYPE> obj2 = std::dynamic_pointer_cast<TYPE>(_obj);
if (obj2 == nullptr) {
EWOL_ERROR("Can not bind signal ...");
return;
}
m_callerList.push_back(std::make_pair(std::weak_ptr<ewol::Object>(_obj), std::bind(_func, obj2.get(), std::placeholders::_1)));
}
/**
* @brief Advanced binding a callback function to the current signal.
* @param[in] _obj Shared pointer on the caller object
* @param[in] _func functor to call (do it yourself)
* @example signalXXXX.connect(shared_from_this(), std::bind(&ClassName::onCallbackXXX, this, std::placeholders::_1));
*/
void connect(std::shared_ptr<ewol::Object> _obj, std::function<void()> _function ) {
m_callerList.push_back(std::make_pair(std::weak_ptr<ewol::Object>(_obj), _function));
}
/**
* @brief DEPRECATED: old connect signal between Objects
*/
void connect(std::shared_ptr<ewol::Object> _obj, const char* _destId=nullptr, const std::string& _data="" ) __attribute__ ((deprecated)) {
m_serializedCallerList.push_back(SignalCallerIdentifier(_obj, _destId, _data));
}
/**
* @brief remove link on the signal.
* @param[in] _obj shared pointer on the removing object
*/
void release(std::shared_ptr<ewol::Object> _obj) {
for (auto it(m_serializedCallerList.begin()) ; it != m_serializedCallerList.end(); ++it) {
if (it->m_object.lock() == _obj) {
@ -158,8 +214,17 @@ namespace ewol {
it = m_serializedCallerList.begin();
}
}
for (auto it(m_callerList.begin()) ; it != m_callerList.end(); ++it) {
if (it->first.lock() == _obj) {
m_callerList.erase(it);
it = m_callerList.begin();
}
}
}
void emit(const std::shared_ptr<ewol::Object>& _source) {
void emit(const std::shared_ptr<ewol::Object>& _source) __attribute__ ((deprecated)) {
emit();
}
void emit() {
// note : this can not emit on function ....
std::string stringData;
for (auto &it : m_serializedCallerList) {
@ -174,16 +239,25 @@ namespace ewol {
eventId = it.m_enevntId;
}
if (it.m_data.size() <= 0){
ewol::object::Message tmpMsg(_source, eventId, stringData);
ewol::object::Message tmpMsg(eventId, stringData);
EWOL_VERBOSE("send message " << tmpMsg);
destObject->onReceiveMessage(tmpMsg);
} else {
// set the user requested data ...
ewol::object::Message tmpMsg(_source, eventId, it.m_data);
ewol::object::Message tmpMsg(eventId, it.m_data);
EWOL_VERBOSE("send message " << tmpMsg);
destObject->onReceiveMessage(tmpMsg);
}
}
for (auto &it : m_callerList) {
std::shared_ptr<ewol::Object> destObject = it.first.lock();
if (destObject == nullptr) {
// TODO : Remove instance ...
EWOL_VERBOSE(" nullptr dest");
continue;
}
it.second();
}
}
};