From 749b7a09c09d659415831464ab9503f620aeff3c Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Tue, 19 Aug 2014 23:26:51 +0200 Subject: [PATCH] [DEV] Start dev of the signal system (nearly compatible with old system) --- sources/ewol/object/Object.cpp | 12 +-- sources/ewol/object/Object.h | 77 +++--------------- sources/ewol/object/Param.h | 2 +- sources/ewol/object/Signal.cpp | 0 sources/ewol/object/Signal.h | 125 +++++++++++++++++++++++++++++ sources/ewol/object/SignalBase.cpp | 23 ++++++ sources/ewol/object/SignalBase.h | 48 +++++++++++ sources/ewol/object/SignalList.cpp | 88 ++++++++++++++++++++ sources/ewol/object/SignalList.h | 113 ++++++++++++++++++++++++++ sources/ewol/widget/Button.cpp | 1 + sources/ewol/widget/Button.h | 2 + sources/lutin_ewol.py | 5 +- 12 files changed, 422 insertions(+), 74 deletions(-) create mode 100644 sources/ewol/object/Signal.cpp create mode 100644 sources/ewol/object/Signal.h create mode 100644 sources/ewol/object/SignalBase.cpp create mode 100644 sources/ewol/object/SignalBase.h create mode 100644 sources/ewol/object/SignalList.cpp create mode 100644 sources/ewol/object/SignalList.h diff --git a/sources/ewol/object/Object.cpp b/sources/ewol/object/Object.cpp index 66f5754a..60c77947 100644 --- a/sources/ewol/object/Object.cpp +++ b/sources/ewol/object/Object.cpp @@ -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& _destinationObject, const char * _eventId, const char * _eventIdgenerated, @@ -263,6 +264,7 @@ void ewol::Object::unRegisterOnEvent(const std::shared_ptr& _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& _destinationObject, const std::string& _objectName, const char * _eventId, @@ -327,7 +329,7 @@ void ewol::Object::registerOnObjectEvent(const std::shared_ptr& _d EWOL_WARNING("[" << getId() << "] {" << getObjectType() << "} Can not register event : \"" << _eventId << "\" the object named=\"" << _objectName << "\" does not exist"); } } - +*/ std::shared_ptr ewol::Object::getObjectNamed(const std::string& _objectName) const { return getObjectManager().getObjectNamed(_objectName); } diff --git a/sources/ewol/object/Object.h b/sources/ewol/object/Object.h index 0ee75c03..1e7d4407 100644 --- a/sources/ewol/object/Object.h +++ b/sources/ewol/object/Object.h @@ -31,6 +31,7 @@ namespace ewol { #include #include #include +#include #define DECLARE_FACTORY(className) \ template static std::shared_ptr 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 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, public ewol::object::ParameterList { + class Object : public std::enable_shared_from_this, + 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 m_externEvent; //!< Generic list of event generation for output link - std::vector 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& _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& _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 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& _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 + #endif diff --git a/sources/ewol/object/Param.h b/sources/ewol/object/Param.h index f2da9ff4..77bcee18 100644 --- a/sources/ewol/object/Param.h +++ b/sources/ewol/object/Param.h @@ -135,7 +135,7 @@ namespace ewol { } }; - template std::ostream& operator <<(std::ostream& _os, const ewol::object::Param& _obj) { + template std::ostream& operator <<(std::ostream& _os, const ewol::object::Param& _obj) { _os << _obj.get(); return _os; } diff --git a/sources/ewol/object/Signal.cpp b/sources/ewol/object/Signal.cpp new file mode 100644 index 00000000..e69de29b diff --git a/sources/ewol/object/Signal.h b/sources/ewol/object/Signal.h new file mode 100644 index 00000000..11c1d4f0 --- /dev/null +++ b/sources/ewol/object/Signal.h @@ -0,0 +1,125 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ + +#include + +#ifndef __EWOL_SIGNAL_H__ +#define __EWOL_SIGNAL_H__ + +#include +#include +#include + + +namespace ewol { + namespace object { + template class Signal : public SignalBase { + private: + //std::vector> m_callerList; + std::vector, 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 _obj, const char* _destId=nullptr, const std::string& _data="" ) { + m_serializedCallerList.push_back(std::make_tuple(_obj, _destId, _data)); + } + bool release(std::shared_ptr _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& _source, const std::string& _data) { + // note : this can not emit on function .... + for (auto &it : m_serializedCallerList) { + std::shared_ptr 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& _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 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 diff --git a/sources/ewol/object/SignalBase.cpp b/sources/ewol/object/SignalBase.cpp new file mode 100644 index 00000000..66cd59a9 --- /dev/null +++ b/sources/ewol/object/SignalBase.cpp @@ -0,0 +1,23 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ + +#include +#include +#include +#include +#include + +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); +} diff --git a/sources/ewol/object/SignalBase.h b/sources/ewol/object/SignalBase.h new file mode 100644 index 00000000..535ed751 --- /dev/null +++ b/sources/ewol/object/SignalBase.h @@ -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 +#include +#include + + +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 diff --git a/sources/ewol/object/SignalList.cpp b/sources/ewol/object/SignalList.cpp new file mode 100644 index 00000000..ce1c8498 --- /dev/null +++ b/sources/ewol/object/SignalList.cpp @@ -0,0 +1,88 @@ +/** + * @author Edouard DUPIN + * + * @copyright 2011, Edouard DUPIN, all right reserved + * + * @license APACHE v2.0 (see license file) + */ + +#include +#include +#include +#include +#include + +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 ewol::object::SignalList::parameterGetAll(bool _notIfDefault) const { + std::map 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 diff --git a/sources/ewol/object/SignalList.h b/sources/ewol/object/SignalList.h new file mode 100644 index 00000000..38924010 --- /dev/null +++ b/sources/ewol/object/SignalList.h @@ -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 +#include + +namespace ewol { + namespace object { + class SignalBase; + class SignalList { + friend class ewol::object::SignalBase; // to register parameter in the list. + private: + std::vector 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 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& _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& _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& _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 diff --git a/sources/ewol/widget/Button.cpp b/sources/ewol/widget/Button.cpp index 13b59cab..86197e9e 100644 --- a/sources/ewol/widget/Button.cpp +++ b/sources/ewol/widget/Button.cpp @@ -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"), diff --git a/sources/ewol/widget/Button.h b/sources/ewol/widget/Button.h index 3a8498e5..ed6a8cbe 100644 --- a/sources/ewol/widget/Button.h +++ b/sources/ewol/widget/Button.h @@ -17,6 +17,7 @@ #include #include #include +#include @@ -29,6 +30,7 @@ namespace ewol { class Button : public ewol::widget::Container2 { public: // Event list of properties + ewol::object::Signal signalPressed; static const char* const eventPressed; static const char* const eventDown; static const char* const eventUp; diff --git a/sources/lutin_ewol.py b/sources/lutin_ewol.py index 3044e27d..aed548ef 100755 --- a/sources/lutin_ewol.py +++ b/sources/lutin_ewol.py @@ -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 :