[DEV] Start dev of the signal system (nearly compatible with old system)

This commit is contained in:
Edouard DUPIN 2014-08-19 23:26:51 +02:00
parent e1a0b972cd
commit 749b7a09c0
12 changed files with 422 additions and 74 deletions

View File

@ -57,8 +57,6 @@ ewol::Object::Object() :
ewol::Object::~Object() {
EWOL_DEBUG("delete Object : [" << m_uniqueId << "] : " << getTypeDescription());
m_externEvent.clear();
m_availlableEventId.clear();
m_uniqueId = -1;
}
@ -109,6 +107,8 @@ bool ewol::Object::isTypeCompatible(const std::string& _type) {
return false;
}
/*
void ewol::Object::addEventId(const char * _generateEventId) {
for (auto &it : m_availlableEventId) {
if (std::string(it) == _generateEventId) {
@ -155,6 +155,7 @@ void ewol::Object::generateEventId(const char * _generateEventId, const std::str
EWOL_CRITICAL("It if really dangerous ro remove (delete) element inside a callback ... use ->removObject() which is asynchronous");
}
}
*/
void ewol::Object::sendMultiCast(const char* const _messageId, const std::string& _data) {
if (m_objectHasBeenInit == false) {
@ -175,7 +176,7 @@ void ewol::Object::registerMultiCast(const char* const _messageId) {
}
getMultiCast().add(shared_from_this(), _messageId);
}
/*
void ewol::Object::registerOnEvent(const std::shared_ptr<ewol::Object>& _destinationObject,
const char * _eventId,
const char * _eventIdgenerated,
@ -263,6 +264,7 @@ void ewol::Object::unRegisterOnEvent(const std::shared_ptr<ewol::Object>& _desti
}
}
}
*/
bool ewol::Object::loadXML(exml::Element* _node) {
if (nullptr == _node) {
@ -313,7 +315,7 @@ ewol::object::MultiCast& ewol::Object::getMultiCast() const {
ewol::Context& ewol::Object::getContext() const {
return ewol::getContext();
}
/*
void ewol::Object::registerOnObjectEvent(const std::shared_ptr<ewol::Object>& _destinationObject,
const std::string& _objectName,
const char * _eventId,
@ -327,7 +329,7 @@ void ewol::Object::registerOnObjectEvent(const std::shared_ptr<ewol::Object>& _d
EWOL_WARNING("[" << getId() << "] {" << getObjectType() << "} Can not register event : \"" << _eventId << "\" the object named=\"" << _objectName << "\" does not exist");
}
}
*/
std::shared_ptr<ewol::Object> ewol::Object::getObjectNamed(const std::string& _objectName) const {
return getObjectManager().getObjectNamed(_objectName);
}

View File

@ -31,6 +31,7 @@ namespace ewol {
#include <ewol/object/Param.h>
#include <ewol/object/ParamRange.h>
#include <ewol/object/ParamList.h>
#include <ewol/object/SignalList.h>
#define DECLARE_FACTORY(className) \
template<typename ... T> static std::shared_ptr<className> create( T&& ... all ) { \
@ -47,24 +48,13 @@ namespace ewol {
}
namespace ewol {
namespace object {
/**
* local class for event generation
* @not-in-doc
*/
class EventExtGen {
public:
const char* localEventId; //!< local event Id generation
std::weak_ptr<ewol::Object> destObject; //!< destination widget that might be call
const char* destEventId; //!< generated event ID on the distant widget
std::string overloadData; //!< sometimes the user prefer to receive some specific data on an event (instead of the one sed by the widget)
};
}
/**
* @brief Basic message classes for ewol system
* this class mermit at every Object to communicate between them.
*/
class Object : public std::enable_shared_from_this<Object>, public ewol::object::ParameterList {
class Object : public std::enable_shared_from_this<Object>,
public ewol::object::ParameterList,
public ewol::object::SignalList {
private:
static size_t m_valUID; //!< Static used for the unique ID definition
private:
@ -148,58 +138,23 @@ namespace ewol {
int32_t getId(){
return m_uniqueId;
};
private:
std::vector<object::EventExtGen> m_externEvent; //!< Generic list of event generation for output link
std::vector<const char*> m_availlableEventId; //!< List of all event availlable for this widget
// TODO : Remove this section :
protected:
/**
* @brief add a specific event Id in the list to prevent wrong link on a Object
* @param[in] _generateEventId event Id to add
*/
void addEventId(const char * _generateEventId);
/**
* @brief generate event on all registered Object
* @param[in] _generateEventId event Id that is curetly generated
* @param[in] _data data associated with the event
*/
void generateEventId(const char * _generateEventId, const std::string& _data = "");
/**
* @brief generate Multicast event on all Object requested the event
* @param[in] _messageId Event Id that is generated
* @param[in] _data String that is send at all the destinations
*/
// TODO : Remove this ... Not really needed : user can simply create an object and send event with it ...
void sendMultiCast(const char* const _messageId, const std::string& _data = "");
/**
* @brief Register of the arrival of a Multicast message
* @param[in] _messageId Event Id waiting for...
*/
// TODO : Remove this ...
void registerMultiCast(const char* const _messageId);
public:
/**
* @brief Register an Object over an other to get event on the second...
* @param[in] _destinationObject pointer on the object that might be call when an event is generated
* @param[in] _eventId Event generate inside the object (note : "*" event register on all event generated )
* @param[in] _eventIdgenerated event generated when call the distant Object.onReceiveMessage(...)
* @param[in] _overloadData When the user prever to receive a data specificly for this event ...
*/
void registerOnEvent(const std::shared_ptr<ewol::Object>& _destinationObject,
const char * _eventId,
const char * _eventIdgenerated = nullptr,
const std::string& _overloadData = "");
/**
* @brief Un-Register an Object over an other.
* @param[in] _destinationObject pointer on the object that might be call when an event is generated
* @param[in] _eventId Event generate inside the object (nullptr to remove all event on this object)
*/
void unRegisterOnEvent(const std::shared_ptr<ewol::Object>& _destinationObject,
const char * _eventId = nullptr);
/**
* @brief Receive a message from an other Object with a specific eventId and data
* @param[in] _msg Message handle
*/
virtual void onReceiveMessage(const ewol::object::Message& _msg) { };
public:
// TODO : Rework the position on this function ...
// TODO : Rework the position on this function ... This is a convignet function ...
bool parameterSetOnWidgetNamed(const std::string& _objectName, const std::string& _config, const std::string& _value);
protected:
ewol::object::Param<std::string> m_name; //!< name of the element ...
@ -267,20 +222,6 @@ namespace ewol {
bool getStatusResource() const {
return m_isResource;
}
/**
* @brief Register an Event an named widget. @see registerOnEvent
* @param[in] _destinationObject pointer on the object that might be call when an event is generated
* @param[in] _objectName Name of the object.
* @param[in] _eventId Event generate inside the object.
* @param[in] _eventIdgenerated event generated when call the distant EObject.onReceiveMessage(...)
* @param[in] _overloadData When the user prever to receive a data specificly for this event ...
* @note : To used when NOT herited from this object.
*/
void registerOnObjectEvent(const std::shared_ptr<ewol::Object>& _destinationObject,
const std::string& _objectName,
const char * _eventId,
const char * _eventIdgenerated = nullptr,
const std::string& _overloadData="");
/**
* @brief Retrive an object with his name (in the global list)
* @param[in] _name Name of the object
@ -291,6 +232,8 @@ namespace ewol {
};
//#include <ewol/object/Signal.h>
#endif

View File

@ -135,7 +135,7 @@ namespace ewol {
}
};
template<typename MY_TYPE> std::ostream& operator <<(std::ostream& _os, const ewol::object::Param<MY_TYPE>& _obj) {
template<typename MY_TYPE, bool isEventReceiving=false> std::ostream& operator <<(std::ostream& _os, const ewol::object::Param<MY_TYPE, isEventReceiving>& _obj) {
_os << _obj.get();
return _os;
}

View File

View File

@ -0,0 +1,125 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <ewol/object/Object.h>
#ifndef __EWOL_SIGNAL_H__
#define __EWOL_SIGNAL_H__
#include <ewol/object/ParameterList.h>
#include <ewol/object/SignalBase.h>
#include <ewol/object/Object.h>
namespace ewol {
namespace object {
template<typename T> class Signal : public SignalBase {
private:
//std::vector<std::funtion<void(const T&)>> m_callerList;
std::vector<std::tuple<std::weak_ptr<ewol::Object>, const char*, std::string>> m_serializedCallerList;
public:
/**
* @brief Create a parameter with a specific type.
* @param[in] _objectLink reference on the parameter lister.
* @param[in] _name Static name of the parameter.
* @param[in] _defaultValue Default value of the parameter.
* @param[in] _min Minumum value.
* @param[in] _max Maximum value.
* @param[in] _description description of the parameter.
*/
Signal(ewol::object::SignalList& _objectLink,
const std::string& _name,
const std::string& _description = "") :
SignalBase(_objectLink, _name, _description) {
};
/**
* @brief Destructor.
*/
virtual ~Signal() { };
const std::string& getName() {
return m_name;
}
const std::string& getDescription() {
return m_description;
}
bool connect(std::shared_ptr<ewol::Object> _obj, const char* _destId=nullptr, const std::string& _data="" ) {
m_serializedCallerList.push_back(std::make_tuple(_obj, _destId, _data));
}
bool release(std::shared_ptr<ewol::Object> _obj) {
for (auto it(m_serializedCallerList.begin()) ; it != m_serializedCallerList.end(); ++it) {
if (std::get<0>(it) == _obj) {
m_serializedCallerList.erase(it);
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);
}
}
}
*/
bool emit(const std::shared_ptr<ewol::Object>& _source, const T& _data) {
// note : this can not emit on function ....
std::string stringData;
if (m_serializedCallerList.size()>0 ) {
stringData = etk::to_string(_data);
}
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, stringData);
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);
}
}
}
};
};
};
#endif

View File

@ -0,0 +1,23 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <memory>
#include <ewol/debug.h>
#include <ewol/object/Object.h>
#include <ewol/object/SignalList.h>
#include <ewol/object/SignalBase.h>
ewol::object::SignalBase::SignalBase(ewol::object::SignalList& _objectLink,
const std::string& _name,
const std::string& _description) :
m_objectLink(_objectLink),
m_name(_name),
m_description(_description) {
// add a reference on the current signal ...
m_objectLink.signalAdd(this);
}

View File

@ -0,0 +1,48 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __EWOL_SIGNAL_BASE_H__
#define __EWOL_SIGNAL_BASE_H__
#include <ewol/object/SignalList.h>
#include <ewol/object/SignalBase.h>
#include <ewol/object/Object.h>
namespace ewol {
namespace object {
class SignalBase {
protected:
ewol::object::SignalList& m_objectLink;
std::string m_name;
std::string m_description;
public:
/**
* @brief Create a parameter with a specific type.
* @param[in] _objectLink reference on the parameter lister.
* @param[in] _name Static name of the parameter.
* @param[in] _description description of the parameter.
*/
SignalBase(ewol::object::SignalList& _objectLink,
const std::string& _name,
const std::string& _description = "");
/**
* @brief Destructor.
*/
virtual ~SignalBase() { };
const std::string& getName() {
return m_name;
}
const std::string& getDescription() {
return m_description;
}
};
};
};
#endif

View File

@ -0,0 +1,88 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#include <memory>
#include <ewol/debug.h>
#include <ewol/object/Object.h>
#include <ewol/object/SignalList.h>
#include <ewol/object/SignalBase.h>
ewol::object::SignalList::SignalList() {
}
ewol::object::SignalList::~SignalList() {
m_list.clear();
}
// note this pointer is not allocated and not free at the end of the class
void ewol::object::SignalList::signalAdd(SignalBase* _pointerOnSignal) {
if (_pointerOnSignal == nullptr) {
EWOL_ERROR("Try to link a nullptr parameters");
return;
}
m_list.push_back(_pointerOnSignal);
}
#if 0
// Note no lock is needed at this level, because the lock is done is the upper elements ...
// the parameter set might be done with a pool of parameter, allone, the overhed is bigger ...
bool ewol::object::SignalList::parameterSet(const std::string& _parameter, const std::string& _value) {
for (auto &it : m_list) {
if( it != nullptr
&& it->getName() == _parameter) {
it->setString(_value);
return true;
}
}
// can not find the parameters :
return false;
}
std::string ewol::object::SignalList::parameterGet(const std::string& _parameter) const {
for (auto &it : m_list) {
if( it != nullptr
&& it->getName() == _parameter) {
return it->getString();
}
}
return "???";
}
void ewol::object::SignalList::parameterDisplay(bool _changeOnly) const {
EWOL_INFO(" Object parameters:");
for (auto &it : m_list) {
if(it != nullptr) {
std::string paramName = it->getName();
std::string paramVal = it->getString();
std::string paramInfo = it->getInfo();
if ( _changeOnly == false
|| it->isDefault() == false) {
EWOL_INFO(" | param='" << paramName << "' value=" << paramVal << " (" << paramInfo << ")");
}
} else {
EWOL_INFO(" | param=nullptr");
}
}
}
std::map<std::string, std::string> ewol::object::SignalList::parameterGetAll(bool _notIfDefault) const {
std::map<std::string, std::string> out;
for (auto &it : m_list) {
if(it != nullptr) {
std::string paramName = it->getName();
std::string paramVal = it->getString();
if ( _notIfDefault == false
|| it->isDefault() == false) {
out.insert(std::make_pair(paramName, paramVal));
}
}
}
return out;
}
#endif

View File

@ -0,0 +1,113 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license APACHE v2.0 (see license file)
*/
#ifndef __EWOL_SIGNAL_LIST_H__
#define __EWOL_SIGNAL_LIST_H__
#include <vector>
#include <map>
namespace ewol {
namespace object {
class SignalBase;
class SignalList {
friend class ewol::object::SignalBase; // to register parameter in the list.
private:
std::vector<ewol::object::SignalBase*> m_list; //!< list of availlable Parameters
public:
/**
* @brief Constructor.
*/
SignalList();
/**
* @brief Destructor.
*/
virtual ~SignalList();
/**
* @brief Register a parameter class pointer in the List of parameters
* @note This class does not destroy the parameter pointer!!!
* @param[in] pointerOnParameter Pointer on the parameter that might be added.
*/
void signalAdd(SignalBase* _pointerOnParameter);
#if 0
/**
* @brief Set a specific value to the parameter reference name.
* @param[in] parameter The parameter string name.
* @param[in] value The new value of the parameter (string).
* @return true Parameter update.
* @return false Parameter not update.
*/
bool parameterSet(const std::string& _parameter, const std::string& _value);
/**
* @brief Get a specific value of the parameter reference name.
* @param[in] parameter The parameter string name.
* @return The value of the parameter (string).
*/
std::string parameterGet(const std::string& _parameter) const;
/**
* @brief Display all the parameter value with there name.
* @param[in] changeOnly check at true if the user want to display only parameter that are not at default value.
*/
void parameterDisplay(bool _changeOnly = false) const;
/**
* @brief Called when a parameter change value.
* @param[in] _paramPointer Pointer on the parameter (to know which parameter have change);
*/
virtual void onParameterChangeValue(const ewol::object::ParameterRef& _paramPointer) { };
/**
* @brief Get All the parameter configuration:
* @return map on the parameters
*/
std::map<std::string, std::string> parameterGetAll(bool _notIfDefault=true) const;
#endif
/**
* @brief Register an Event an named widget. @see registerOnEvent
* @param[in] _destinationObject pointer on the object that might be call when an event is generated
* @param[in] _objectName Name of the object.
* @param[in] _eventId Event generate inside the object.
* @param[in] _eventIdgenerated event generated when call the distant EObject.onReceiveMessage(...)
* @param[in] _overloadData When the user prever to receive a data specificly for this event ...
* @note : To used when NOT herited from this object.
*/
// TODO : Change name : registerOnSignal
void registerOnObjectEvent(const std::shared_ptr<ewol::Object>& _destinationObject,
const std::string& _objectName,
const char * _eventId,
const char * _eventIdgenerated = nullptr,
const std::string& _overloadData="");
public:
/**
* @brief Register an Object over an other to get event on the second...
* @param[in] _destinationObject pointer on the object that might be call when an event is generated
* @param[in] _eventId Event generate inside the object (note : "*" event register on all event generated )
* @param[in] _eventIdgenerated event generated when call the distant Object.onReceiveMessage(...)
* @param[in] _overloadData When the user prever to receive a data specificly for this event ...
*/
void registerOnEvent(const std::shared_ptr<ewol::Object>& _destinationObject,
const char * _eventId,
const char * _eventIdgenerated = nullptr,
const std::string& _overloadData = "");
/**
* @brief Un-Register an Object over an other.
* @param[in] _destinationObject pointer on the object that might be call when an event is generated
* @param[in] _eventId Event generate inside the object (nullptr to remove all event on this object)
*/
void unRegisterOnEvent(const std::shared_ptr<ewol::Object>& _destinationObject,
const char * _eventId = nullptr);
/**
* @brief Receive a message from an other Object with a specific eventId and data
* @param[in] _msg Message handle
*/
virtual void onReceiveMessage(const ewol::object::Message& _msg) { };
};
};
};
#endif

View File

@ -29,6 +29,7 @@ const char* const ewol::widget::Button::eventValue = "value";
#define STATUS_DOWN (3)
ewol::widget::Button::Button() :
signalPressed(*this, "pressed", "Button is pressed"),
m_shaper(*this, "shaper", "The display name for config file"),
m_value(*this, "value", false, "Value of the Button"),
m_lock(*this, "lock", lockNone, "Lock the button in a special state to permit changing state only by the coder"),

View File

@ -17,6 +17,7 @@
#include <ewol/compositing/Shaper.h>
#include <ewol/widget/Container2.h>
#include <ewol/widget/Manager.h>
#include <ewol/object/Signal.h>
@ -29,6 +30,7 @@ namespace ewol {
class Button : public ewol::widget::Container2 {
public:
// Event list of properties
ewol::object::Signal<int> signalPressed;
static const char* const eventPressed;
static const char* const eventDown;
static const char* const eventUp;

View File

@ -97,7 +97,10 @@ def create(target):
'ewol/object/ParameterList.cpp',
'ewol/object/ParamList.cpp',
'ewol/object/Param.cpp',
'ewol/object/ParamRange.cpp'
'ewol/object/ParamRange.cpp',
'ewol/object/SignalList.cpp',
'ewol/object/SignalBase.cpp',
'ewol/object/Signal.cpp'
])
# OpenGL interface :