[DOC] update documentation
This commit is contained in:
parent
87f4aedb95
commit
d5bd35d0a4
16
doc/faq.bb
Normal file
16
doc/faq.bb
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
== Why we use "DECLARE_FACTORY" Macro ? ==
|
||||||
|
|
||||||
|
For some reason!!! But everything might be clear:
|
||||||
|
:** In ewol we masively use std::shared_ptr<xxx> (I have create my own but it is not "standard" (I like when we use genecic system)).
|
||||||
|
:** The main class : [class[ewol::Object]] herited from [i]std::enable_shared_from_this<Object>[/i] to permit to access at his own [i]std::shared_ptr[/i].
|
||||||
|
:** Acces At his own [i]std::shared_ptr[/i] is not allowed in the class contructor/destructor.
|
||||||
|
:** Many time for meta-widget we need to propagate our [i]std::shared_ptr[/i] in child.
|
||||||
|
|
||||||
|
Then for all these reasons, I have create a simple MACRO that create a static template funtion that create the object and just after
|
||||||
|
creation call the init(...) function to permit to create a complex widget or others with some writing convinience.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -48,7 +48,7 @@ Compile software in debug for the curent platform :
|
|||||||
|
|
||||||
You can specify the platform with:
|
You can specify the platform with:
|
||||||
[code style=shell]
|
[code style=shell]
|
||||||
./ewol/build/lutin.py -mdebug -tAndroid
|
./ewol/build/lutin.py -tAndroid -mdebug
|
||||||
[/code]
|
[/code]
|
||||||
|
|
||||||
It coud be usefull to disable the package generation in local debug :
|
It coud be usefull to disable the package generation in local debug :
|
||||||
|
@ -110,16 +110,7 @@ For this point we will create a class that herited form the basic [class[ewol::w
|
|||||||
#endif
|
#endif
|
||||||
[/code]
|
[/code]
|
||||||
|
|
||||||
At this point you will ask an important question : [b]Why we use this really bad "DECLARE_FACTORY" Macro ?[/b]
|
See [tutorial[010_ObjectModel | Next: Object model]] to understand why this structure is so complex.
|
||||||
|
|
||||||
For some reason!!! But everything might be clear:
|
|
||||||
:** In ewol we masively use std::shared_ptr<xxx> (I have create my own but it is not "standard" (I like when we use genecic system)).
|
|
||||||
:** The main class : [class[ewol::Object]] herited from [i]std::enable_shared_from_this<Object>[/i] to permit to access at his own [i]std::shared_ptr[/i].
|
|
||||||
:** Acces At his own [i]std::shared_ptr[/i] is not allowed in the class contructor/destructor.
|
|
||||||
:** Many time for meta-widget we need to propagate our [i]std::shared_ptr[/i] in child.
|
|
||||||
|
|
||||||
Then for all these reasons, I have create a simple MACRO that create a static template funtion that create the object and just after
|
|
||||||
creation call the init(...) function to permit to create a complex widget or others with some writing convinience.
|
|
||||||
|
|
||||||
[b]Windows.cpp[/b]
|
[b]Windows.cpp[/b]
|
||||||
[code style=c++]
|
[code style=c++]
|
||||||
|
@ -6,17 +6,18 @@ __________________________________________________
|
|||||||
:** Understand ewol basic [class[ewol::Object]]
|
:** Understand ewol basic [class[ewol::Object]]
|
||||||
:** Use [class[ewol::Object]] correctly
|
:** Use [class[ewol::Object]] correctly
|
||||||
|
|
||||||
== Basis of the Object ==
|
== Basis of the ewol::Object ==
|
||||||
|
|
||||||
An object in Ewol is a simple class : [class[ewol::Object]] This object is the basis of all element in the ewol system.
|
An object in Ewol is a simple class : [class[ewol::Object]] This object is the basis of all element in the ewol system.
|
||||||
This is designed to manage basis element of complexe structure:
|
This is designed to manage many common things:
|
||||||
|
|
||||||
:** Unique ID
|
:** Unique ID
|
||||||
:** Name
|
:** Name
|
||||||
:** Configuration (decriptive naming of parameters)
|
:** Parameters
|
||||||
:** Event generation and receving
|
:** Signal generation
|
||||||
:** Xml configuration
|
:** Xml configuration
|
||||||
:** Delayed removing
|
:** Removing
|
||||||
|
:** Perodic calling
|
||||||
|
|
||||||
[note]
|
[note]
|
||||||
Please do not compare with the gObject basic class...
|
Please do not compare with the gObject basic class...
|
||||||
@ -25,130 +26,86 @@ Please do not compare with the gObject basic class...
|
|||||||
|
|
||||||
== Create an Object: ==
|
== Create an Object: ==
|
||||||
|
|
||||||
In theory you can use a simple new on an object, but you need to remove the refcounting of this one by yoursef ... really awfull.
|
Creating an object is really simple:
|
||||||
|
|
||||||
It is really better to use the ewol::object::Shared<> declaration to auto manage it. (same as std::shared_ptr)
|
|
||||||
[code style=c++]
|
[code style=c++]
|
||||||
ewol::object::Shared<widget::Label> tmpObject = ewol::object::makeShared(new widget::Label());
|
std::shared_ptr<ewol::Button> tmpButon = ewol::Button::create();
|
||||||
if (tmpObject == NULL) {
|
APPL_INFO("We just create a button widget with unique ID=" << tmpButon->getId() << " name='" << tmpButon->getName() << "'");
|
||||||
APPL_ERROR("An error occured");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
[/code]
|
[/code]
|
||||||
|
|
||||||
The object register itself on the object manager, now it will have a specific Id and no name
|
Note that all object created are std::shared_ptr.
|
||||||
|
|
||||||
Force the set of the name :
|
|
||||||
|
Set the name of the object:
|
||||||
|
|
||||||
[code style=c++]
|
[code style=c++]
|
||||||
tmpObject->setName("my widget name");
|
tmpButon->setName("my widget name");
|
||||||
APPL_INFO("We just create an Object with ID=" << tmpObject->getId() << " name='" << tmpObject->getName() << "'");
|
APPL_INFO("We just create an Object with ID=" << tmpButon->getId() << " name='" << tmpButon->getName() << "'");
|
||||||
[/code]
|
[/code]
|
||||||
|
|
||||||
|
|
||||||
== Remove an Object: ==
|
== Remove an Object: ==
|
||||||
|
|
||||||
This is important to note that many element can have a reference on the Object.
|
Simply use the function:
|
||||||
|
|
||||||
Then we need to use the fuction:
|
|
||||||
[b]removeObject()[/b] to remove the Object, This will notify avery object in the system that this
|
|
||||||
specific object has been removed.
|
|
||||||
|
|
||||||
|
|
||||||
Then to remove an object call:
|
|
||||||
[code style=c++]
|
[code style=c++]
|
||||||
tmpObject->removeObject();
|
tmpButon->destroy();
|
||||||
[/code]
|
[/code]
|
||||||
|
|
||||||
On every object we can have an herited function: [b]virtual void onObjectRemove(const ewol::object::Shared<ewol::Object>& _removeObject);[/b]
|
This function request his parrent to remove the std::shared_ptr it keep on it.
|
||||||
|
And when all std::shared_ptr is removed the object will be really removed.
|
||||||
|
|
||||||
|
At his point we can think an object is allive all the time someone keep a reference on it, then when you are not a parrent of the object, do not keep a std::shared_ptr but a std::weak_ptr.
|
||||||
We need to implement this fuction to be notify an object is removed:
|
|
||||||
[code style=c++]
|
|
||||||
void namespeceName::ClassName::onObjectRemove(const ewol::object::Shared<ewol::Object>& _removeObject) {
|
|
||||||
// Never forget to call upper Object (otherwise many object will keep theire reference)
|
|
||||||
upperClass::onObjectRemove(_removeObject);
|
|
||||||
if (_removeObject == m_object) {
|
|
||||||
m_object.reset();
|
|
||||||
markToRedraw(); // set only for graphical object ...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
[/code]
|
|
||||||
|
|
||||||
[note]
|
[note]
|
||||||
If you have well follow the idea, you will never declare an object in local, just use shared pointer on them.
|
If some Object is not removed when you close the application, the system inform you with displaying all object already alive.
|
||||||
[/note]
|
[/note]
|
||||||
|
|
||||||
[note]
|
|
||||||
For some case it could be interesting to see the [class[ewol::object::Owner<T>]] class that provide an automatic auto remove of object.
|
|
||||||
|
|
||||||
See [class[ewol::widget::Container]] for an example.
|
|
||||||
[/note]
|
|
||||||
|
|
||||||
|
|
||||||
=== Particularity ===
|
|
||||||
|
|
||||||
An object can remove itself, just use the function:
|
|
||||||
[code style=c++]
|
|
||||||
autoDestroy();
|
|
||||||
[/code]
|
|
||||||
|
|
||||||
|
|
||||||
== Retrieve an Object: ==
|
== Retrieve an Object: ==
|
||||||
|
|
||||||
In Ewol this is possible to get a object with his name.
|
In Ewol this is possible to get a object with his name.
|
||||||
This is really simple.
|
|
||||||
|
|
||||||
=== In an Object ===
|
=== Find a global Object (ouside an Object) ===
|
||||||
|
|
||||||
Call a simple function define in the Object:
|
|
||||||
|
|
||||||
[code style=c++]
|
[code style=c++]
|
||||||
#include <ewol/object/Manager.h>
|
|
||||||
|
|
||||||
...
|
|
||||||
|
|
||||||
ewol::object::Shared<ewol::Object> tmpObject = getObjectManager().get("name of the object");
|
|
||||||
if (tmpObject == NULL) {
|
|
||||||
APPL_ERROR("The Object does not exist");
|
|
||||||
}
|
|
||||||
[/code]
|
|
||||||
|
|
||||||
=== Not in an Object ===
|
|
||||||
|
|
||||||
In this case, we need to get the context manager and after the object manager:
|
|
||||||
|
|
||||||
[code style=c++]
|
|
||||||
#include <ewol/object/Manager.h>
|
|
||||||
#include <ewol/context/Context.h>
|
#include <ewol/context/Context.h>
|
||||||
|
|
||||||
...
|
std::shared_ptr<ewol::Object> tmpObject = ewol::getContext().getEObjectManager().getObjectNamed("obj Name");
|
||||||
|
|
||||||
ewol::object::Shared<ewol::Object> tmpObject = ewol::getContext().getObjectManager().get("name of the object");
|
|
||||||
if (tmpObject == NULL) {
|
if (tmpObject == NULL) {
|
||||||
APPL_ERROR("The Object does not exist");
|
APPL_ERROR("The Object does not exist");
|
||||||
}
|
}
|
||||||
[/code]
|
[/code]
|
||||||
|
|
||||||
=== Casting your object ===
|
=== Find a global Object (inside an Object) ===
|
||||||
|
|
||||||
|
[code style=c++]
|
||||||
|
std::shared_ptr<ewol::Object> tmpObject = getObjectNamed("obj Name");
|
||||||
|
if (tmpObject == NULL) {
|
||||||
|
APPL_ERROR("The Object does not exist");
|
||||||
|
}
|
||||||
|
[/code]
|
||||||
|
|
||||||
|
=== Find a sub-object ===
|
||||||
|
|
||||||
|
[code style=c++]
|
||||||
|
std::shared_ptr<ewol::Object> tmpObject = getSubObjectNamed("obj Name");
|
||||||
|
if (tmpObject == NULL) {
|
||||||
|
APPL_ERROR("The Object does not exist");
|
||||||
|
}
|
||||||
|
[/code]
|
||||||
|
|
||||||
|
=== retriving your object type ===
|
||||||
|
|
||||||
It could be really interesting to retrive your own instance:
|
It could be really interesting to retrive your own instance:
|
||||||
|
|
||||||
[code style=c++]
|
[code style=c++]
|
||||||
ewol::object::Shared<ewol::Object> tmpObject ...;
|
std::shared_ptr<ewol::Object> tmpObject ...;
|
||||||
|
|
||||||
ewol::object::Shared<appl::MyOwnObject> myObject = ewol::dynamic_pointer_cast<appl::MyOwnObject>(tmpObject);
|
std::shared_ptr<appl::MyOwnObject> myObject = std::dynamic_pointer_cast<appl::MyOwnObject>(tmpObject);
|
||||||
[/code]
|
[/code]
|
||||||
|
|
||||||
== conclusion ==
|
== conclusion ==
|
||||||
|
|
||||||
If you follow these rules, you will not have memory leek and no segmentation fault on the ewol system.
|
TODO ...
|
||||||
|
|
||||||
[note]
|
|
||||||
To be sure that the name is unique, just add the current creator object Id in the name.
|
|
||||||
|
|
||||||
See [class[ewol::widget::FileChooser]] class for an example.
|
|
||||||
[/note]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,153 +1,101 @@
|
|||||||
=?= Tutorial 3: Object Config =?=
|
=?= Tutorial 3: Object Config =?=
|
||||||
__________________________________________________
|
__________________________________________________
|
||||||
[left][tutorial[010_ObjectModel | Previous: Object model]][/left] [right][tutorial[012_ObjectMessage | Next: Object message]][/right]
|
[left][tutorial[010_ObjectModel | Previous: Object model]][/left] [right][tutorial[012_ObjectMessage | Next: Object signals]][/right]
|
||||||
|
|
||||||
=== Objectif ===
|
=== Objectif ===
|
||||||
:** Understand ewol::Object configuration parameter
|
:** Understand ewol::Object configuration parameter
|
||||||
:** Create an configurable object
|
:** Create an configurable object
|
||||||
|
|
||||||
== Use of Configuration ==
|
== Configuration using ==
|
||||||
|
|
||||||
Configuration are parameters to set some property on an object,
|
All [class[ewol::Object]] have a configuration of parameters (the object name is a parameter), Then we need to set get and use xml to update parameters.
|
||||||
this is a really generic use in many system,
|
|
||||||
this is the reason why we implement one.
|
|
||||||
|
|
||||||
|
=== Set a Parameter ===
|
||||||
|
|
||||||
This is a generic interface to set and get parameter,
|
[note]
|
||||||
when you did not really know it,
|
Using getter and setter is really better, and faster.
|
||||||
but it generate many convertion to string search and many other things...
|
[/note]
|
||||||
|
|
||||||
If you know the object just interact with it with his own accessors (faster ond conpilation check).
|
==== With a string configuration ====
|
||||||
|
|
||||||
|
|
||||||
=== Set config ===
|
|
||||||
|
|
||||||
When you have the pointer on the object:
|
|
||||||
[code style=c++]
|
[code style=c++]
|
||||||
if (tmpObject->setConfig("name", "new name of object") == false) {
|
if (tmpObject->parameterSet("name", "new name of object") == false) {
|
||||||
APPL_ERROR("Can not set object property");
|
APPL_ERROR("Can not set object parameter");
|
||||||
}
|
}
|
||||||
[/code]
|
[/code]
|
||||||
|
|
||||||
A second methode is to request the name with his direct config name:
|
==== whith the object name ====
|
||||||
[code style=c++]
|
|
||||||
// to be sure that the name exist:
|
|
||||||
if (tmpObject->setConfig(ewol::Object::configName, "new name of object") == false) {
|
|
||||||
APPL_ERROR("Can not set object property");
|
|
||||||
}
|
|
||||||
[/code]
|
|
||||||
The only aventage here is to have an automatic update on the name of the parameter.
|
|
||||||
|
|
||||||
It is possible to configure an object whitout knowing his name:
|
|
||||||
[code style=c++]
|
[code style=c++]
|
||||||
// in an ewol::Object only ...
|
if (parameterSetOnWidgetNamed("objectName", "value", "16.2") == false) {
|
||||||
if (setConfigNamed("object name", "ewol::Object::configName, "new name of object") == false) {
|
APPL_ERROR("Can not set object parameter");
|
||||||
APPL_ERROR("Can not set object property");
|
|
||||||
}
|
}
|
||||||
[/code]
|
[/code]
|
||||||
|
|
||||||
|
=== Get Parameter ===
|
||||||
|
|
||||||
=== Get config ===
|
|
||||||
|
|
||||||
Direct get the configuration:
|
|
||||||
[code style=c++]
|
[code style=c++]
|
||||||
std::string val = tmpObject->getConfig("name");
|
std::string val = tmpObject->parameterGet("name");
|
||||||
APPL_INFO("Get Object property : name='" << val << "'");
|
APPL_INFO("Get Object property : name='" << val << "'");
|
||||||
[/code]
|
[/code]
|
||||||
|
|
||||||
Get with his direct definition name:
|
|
||||||
[code style=c++]
|
|
||||||
std::string val = tmpObject->getConfig(ewol::Object::configName);
|
|
||||||
APPL_INFO("Get Object property : " << ewol::Object::configName << "'" << val << "'");
|
|
||||||
[/code]
|
|
||||||
|
|
||||||
|
|
||||||
== Implement configuration ==
|
== Implement configuration ==
|
||||||
|
|
||||||
=== Declare config ===
|
|
||||||
|
|
||||||
In the header file:
|
|
||||||
[code style=c++]
|
[code style=c++]
|
||||||
#include <ewol/object/Object.h>
|
#include <ewol/object/Object.h>
|
||||||
namespace appl {
|
namespace appl {
|
||||||
class MyObj : public ewol::Object {
|
class MyObj : public ewol::Object {
|
||||||
public:
|
protected:
|
||||||
// Config list of properties
|
|
||||||
static const char* const configValue;
|
|
||||||
public:
|
|
||||||
//! @brief Constructor
|
//! @brief Constructor
|
||||||
MyObj(void);
|
MyObj(void) :
|
||||||
|
m_value(*this, "value", false, "Value of the parameter (descrition string)") {
|
||||||
|
// nothing to do..
|
||||||
|
}
|
||||||
|
void init() {
|
||||||
|
ewol::Object::init();
|
||||||
|
}
|
||||||
|
public:
|
||||||
//! @brief Destructor
|
//! @brief Destructor
|
||||||
virtual ~MyObj(void);
|
virtual ~MyObj(void) { }
|
||||||
|
DECLARE_FACTORY(MyObj);
|
||||||
private:
|
private:
|
||||||
bool m_value; //!< Internal Object value
|
ewol::object::Param<bool> m_value; //!< Internal Object value
|
||||||
public:
|
public:
|
||||||
//! @brief Setter
|
//! @brief Setter
|
||||||
void setValue(bool _val) {
|
void setValue(bool _val) {
|
||||||
m_value = _val;
|
m_value.set(_val);
|
||||||
}
|
}
|
||||||
//! @brief Getter
|
//! @brief Getter
|
||||||
bool getValue(void) const {
|
bool getValue() const {
|
||||||
return m_value;
|
return m_value.get();
|
||||||
}
|
}
|
||||||
public: // herited function:
|
public: // herited function:
|
||||||
bool onSetConfig(const ewol::object::Config& _conf);
|
void onParameterChangeValue(const ewol::object::ParameterRef& _paramPointer) {
|
||||||
|
if (_paramPointer == m_value) {
|
||||||
|
APPL_DEBUG("The internal value has change, new value is : '" << m_value.get() << "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[/code]
|
[/code]
|
||||||
|
|
||||||
[note]
|
In the contructor we need to add:
|
||||||
By convention declare config started with "configXXXXXX"
|
|
||||||
[/note]
|
|
||||||
|
|
||||||
In the source file:
|
|
||||||
[code style=c++]
|
[code style=c++]
|
||||||
// Declare the configuration Name:
|
m_value(*this, "value", false, "Value of the parameter (descrition string)")
|
||||||
const char* const appl::MyObj::configValue = "value";
|
|
||||||
|
|
||||||
appl::MyObj::MyObj(void) {
|
|
||||||
// declare the configuration on this object:
|
|
||||||
registerConfig(configValue, "bool", NULL, "object configuration description");
|
|
||||||
// Note : This API is not compleately define ...
|
|
||||||
}
|
|
||||||
appl::MyObj::~MyObj(void) {
|
|
||||||
// nothing to do ...
|
|
||||||
}
|
|
||||||
[/code]
|
[/code]
|
||||||
Now an extern Object can register configure these parameter, otherwise, they will be rejected!!!
|
:** [b]'*this':[/b] Reference the main class to call it chen value change.
|
||||||
|
:** [b]"value":[/b] Is the name of the parameter.
|
||||||
|
:** [b]false:[/b] The default value.
|
||||||
|
:** [b]"....."[/b] Description of the parameter (optionnal).
|
||||||
|
|
||||||
|
|
||||||
=== Get and Set config ===
|
The function [b]onParameterChangeValue[/b] is called only the parameter change (no historic has been registered)
|
||||||
|
|
||||||
You can see in these implementation that we not compare the string but just the pointer.
|
The last point is that the m_value.get() is an inline fuction then it take no more CPU cycle to access the value than normal variable.
|
||||||
The ewol::Object convert the string in the correct pointer to be faster in many case.
|
|
||||||
|
|
||||||
==== Set configuration ====
|
Some other parameter are availlable :
|
||||||
|
:** ewol::object::Param<T> Basic parameter.
|
||||||
|
:** ewol::object::ParamRange<T> For numeric parameter that range value are check befor setting new value.
|
||||||
|
:** ewol::object::ParamList<T> For List of parameter values.
|
||||||
|
|
||||||
[code style=c++]
|
|
||||||
bool appl::MyObj::onSetConfig(const ewol::object::Config& _conf) {
|
|
||||||
APPL_VERBOSE("[" << getId() << "] {" << getObjectType() << "} set config : " << _conf);
|
|
||||||
if (_conf.getConfig() == configValue) {
|
|
||||||
setValue(std::stob(_conf.getData()));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
[/code]
|
|
||||||
|
|
||||||
==== Get configuration ====
|
|
||||||
|
|
||||||
[code style=c++]
|
|
||||||
bool appl::MyObj::onGetConfig(const char* _config, std::string& _result) const {
|
|
||||||
if (_config == configValue) {
|
|
||||||
_result = std::to_string(getValue());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
[/code]
|
|
||||||
|
|
||||||
== Conclusion ==
|
|
||||||
|
|
||||||
Now you can choice the methode you want in your application to implement your basic configuration feature.
|
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
=?= Tutorial 4: Object Message =?=
|
=?= Tutorial 4: Object Signals =?=
|
||||||
__________________________________________________
|
__________________________________________________
|
||||||
[left][tutorial[011_ObjectConfig | Previous: Object config]][/left] [right][tutorial[020_FileAccess | Next: File Access]][/right]
|
[left][tutorial[011_ObjectConfig | Previous: Object config]][/left] [right][tutorial[020_FileAccess | Next: File Access]][/right]
|
||||||
|
|
||||||
@ -8,123 +8,164 @@ __________________________________________________
|
|||||||
|
|
||||||
== Message system ==
|
== Message system ==
|
||||||
|
|
||||||
The message system is a simple message sending between Object.
|
Message system is based on generic std::funtion and std::bind methode:
|
||||||
This is composed with a pointer (const char* const) that represent the mesage ID (pointer, then unique)
|
|
||||||
and a value (std::string)
|
|
||||||
|
|
||||||
The message are broadcast or multicast on object watcher.
|
It permit to an object to generate some [b]'signals'[/b].
|
||||||
|
|
||||||
== Receive Message from other object ==
|
All signal are synchronous
|
||||||
|
|
||||||
=== Register on message ===
|
|
||||||
|
|
||||||
We will se an example on the widget : [class[ewol::widget::Button]]
|
== Receive signals from other object ==
|
||||||
|
|
||||||
By default the messageID is the event generated, But to overwrite this message Id just create a new one:
|
[todo]
|
||||||
|
Link with the signal name
|
||||||
|
[/todo]
|
||||||
|
|
||||||
|
Register on the 'up' and 'value' signal of a button:
|
||||||
|
|
||||||
|
Button header :
|
||||||
[code style=c++]
|
[code style=c++]
|
||||||
// on the global on the file or in private class member:
|
...
|
||||||
static const char* const g_backMessage = "local-event-button-pressed";
|
public:
|
||||||
static const char* const g_backMessageValue = "local-event-button-value";
|
ewol::object::Signal<void> signalDown;
|
||||||
static const char* const g_backMessageDataOverWritte = "local-event-button-data";
|
ewol::object::Signal<void> signalUp;
|
||||||
|
...
|
||||||
|
ewol::object::Signal<bool> signalValue;
|
||||||
|
...
|
||||||
[/code]
|
[/code]
|
||||||
|
|
||||||
|
=== simple signal connection: ===
|
||||||
|
|
||||||
Register with his name:
|
|
||||||
[code style=c++]
|
|
||||||
registerOnEvent(this, "pressed", g_backMessage);
|
|
||||||
[/code]
|
|
||||||
|
|
||||||
Register with his direct name:
|
|
||||||
[code style=c++]
|
|
||||||
registerOnEvent(this, ewol::widget::Button::eventValue, g_backMessageValue);
|
|
||||||
[/code]
|
|
||||||
|
|
||||||
It is possible to overwrote the data send by the Object :
|
|
||||||
[code style=c++]
|
|
||||||
registerOnEvent(this, ewol::widget::Button::eventPressed, g_backMessageDataOverWritte, "Data we want to receive");
|
|
||||||
[/code]
|
|
||||||
|
|
||||||
|
|
||||||
=== Receive message ===
|
|
||||||
|
|
||||||
To receive message from other widget, just implement this function:
|
|
||||||
|
|
||||||
[code style=c++]
|
|
||||||
|
|
||||||
void appl::ObjectName::onReceiveMessage(const ewol::object::Message& _msg) {
|
|
||||||
APPL_INFO("Receive Event : " << _msg);
|
|
||||||
if (_msg.getMessage() == g_backMessage) {
|
|
||||||
// process here
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (_msg.getMessage() == g_backMessageValue) {
|
|
||||||
APPL_INFO("message value: '" << _msg.getData() << "'");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (_msg.getMessage() == g_backMessageDataOverWritte) {
|
|
||||||
APPL_INFO("Overwrite message data: '" << _msg.getData() << "'");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
[/code]
|
|
||||||
|
|
||||||
|
|
||||||
== Declare Extern Message ==
|
|
||||||
|
|
||||||
=== Declare Message ===
|
|
||||||
|
|
||||||
In the header file:
|
|
||||||
[code style=c++]
|
[code style=c++]
|
||||||
#include <ewol/object/Object.h>
|
#include <ewol/object/Object.h>
|
||||||
|
#include <ewol/widget/Button.h>
|
||||||
|
namespace appl {
|
||||||
|
class MyObj : public ewol::Object {
|
||||||
|
private:
|
||||||
|
std::shared_ptr<ewol::widget::Button> m_button;
|
||||||
|
protected:
|
||||||
|
//! @brief Constructor
|
||||||
|
MyObj(void) {
|
||||||
|
// nothing to do..
|
||||||
|
}
|
||||||
|
void init() {
|
||||||
|
ewol::Object::init();
|
||||||
|
m_button = ewol::widget::Button::Create();
|
||||||
|
if (m_button == nullptr) {
|
||||||
|
APPL_ERROR("Can not create button...");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// We connect signals here :
|
||||||
|
m_button->signalUp.bind(shared_from_this(), &appl::MyObj::onCallbackUp);
|
||||||
|
m_button->signalValue.bind(shared_from_this(), &appl::MyObj::onCallbackValue);
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
//! @brief Destructor
|
||||||
|
virtual ~MyObj(void) { }
|
||||||
|
DECLARE_FACTORY(MyObj);
|
||||||
|
private:
|
||||||
|
void onCallbackUp() {
|
||||||
|
APPL_INFO("button pressed: UP);
|
||||||
|
}
|
||||||
|
void onCallbackValue(const bool& _value) {
|
||||||
|
APPL_INFO("button value: " << _value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[/code]
|
||||||
|
|
||||||
|
|
||||||
|
=== Advenced signal connection: ===
|
||||||
|
|
||||||
|
Here we will see how to connect an advance function on a signal
|
||||||
|
|
||||||
|
[code style=c++]
|
||||||
|
#include <ewol/object/Object.h>
|
||||||
|
#include <ewol/widget/Button.h>
|
||||||
|
namespace appl {
|
||||||
|
class MyObj : public ewol::Object {
|
||||||
|
private:
|
||||||
|
std::shared_ptr<ewol::widget::Button> m_button;
|
||||||
|
protected:
|
||||||
|
//! @brief Constructor
|
||||||
|
MyObj(void) {
|
||||||
|
// nothing to do..
|
||||||
|
}
|
||||||
|
void init() {
|
||||||
|
ewol::Object::init();
|
||||||
|
m_button = ewol::widget::Button::Create();
|
||||||
|
if (m_button == nullptr) {
|
||||||
|
APPL_ERROR("Can not create button...");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// We connect signals here :
|
||||||
|
m_button->signalUp.register(shared_from_this(), std::bind(&appl::MyObj::onCallbackUp, this, std::string("tmpVariableToSend")));
|
||||||
|
m_button->signalValue.register(shared_from_this(), std::bind(&appl::MyObj::onCallbackValue, this));
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
//! @brief Destructor
|
||||||
|
virtual ~MyObj(void) { }
|
||||||
|
DECLARE_FACTORY(MyObj);
|
||||||
|
private:
|
||||||
|
void onCallbackUp(const std::string& _value) {
|
||||||
|
APPL_INFO("button pressed: UP inputMessage: " << _value);
|
||||||
|
}
|
||||||
|
void onCallbackValue() {
|
||||||
|
APPL_INFO("button value: " << _value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[/code]
|
||||||
|
|
||||||
|
=== Connect to a signal with a named widget ===
|
||||||
|
|
||||||
|
TODO: documentation :
|
||||||
|
:** subBind(_type, _name, _event, _obj, _func)
|
||||||
|
:** globalBind(_type, _name, _event, _obj, _func)
|
||||||
|
:** externSubBind(_object, _type, _name, _event, _obj, _func)
|
||||||
|
|
||||||
|
|
||||||
|
== Declare Signal ==
|
||||||
|
|
||||||
|
=== source ===
|
||||||
|
|
||||||
|
[code style=c++]
|
||||||
|
#include <ewol/object/Object.h>
|
||||||
|
#include <ewol/widget/Button.h>
|
||||||
namespace appl {
|
namespace appl {
|
||||||
class MyObj : public ewol::Object {
|
class MyObj : public ewol::Object {
|
||||||
public:
|
public:
|
||||||
// Event list of properties
|
ewol::object::Signal<void> signalEmpty;
|
||||||
static const char* const eventValue;
|
ewol::object::Signal<bool> signalBoolean;
|
||||||
public:
|
ewol::object::Signal<std::string> signalString;
|
||||||
|
protected:
|
||||||
//! @brief Constructor
|
//! @brief Constructor
|
||||||
MyObj(void);
|
MyObj(void) :
|
||||||
|
signalEmpty(*this, "empty"),
|
||||||
|
signalBoolean(*this, "boolean"),
|
||||||
|
signalString(*this, "string") {
|
||||||
|
// nothing to do..
|
||||||
|
}
|
||||||
|
void init() {
|
||||||
|
ewol::Object::init();
|
||||||
|
}
|
||||||
|
public:
|
||||||
//! @brief Destructor
|
//! @brief Destructor
|
||||||
virtual ~MyObj(void);
|
virtual ~MyObj(void) { }
|
||||||
|
DECLARE_FACTORY(MyObj);
|
||||||
|
private:
|
||||||
|
void process() {
|
||||||
|
signalEmpty.emit();
|
||||||
|
signalBoolean.emit(false);
|
||||||
|
signalString.emit("plop... plop");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[/code]
|
[/code]
|
||||||
|
|
||||||
[note]
|
|
||||||
By convention declare events started with "eventXXXXXX"
|
|
||||||
[/note]
|
|
||||||
|
|
||||||
In the source file:
|
|
||||||
[code style=c++]
|
|
||||||
// Declare the configuration Name:
|
|
||||||
const char* const appl::MyObj::eventValue = "value";
|
|
||||||
|
|
||||||
appl::MyObj::MyObj(void) {
|
|
||||||
// declare Event generated on this object:
|
|
||||||
addEventId(eventValue);
|
|
||||||
}
|
|
||||||
appl::MyObj::~MyObj(void) {
|
|
||||||
// nothing to do ...
|
|
||||||
}
|
|
||||||
[/code]
|
|
||||||
Now an extern Object can register event on this object, otherwise, they will be rejected!!!
|
|
||||||
|
|
||||||
|
|
||||||
=== Generate Message ===
|
|
||||||
|
|
||||||
Now we have register object message, We need to have generated it, This is really simple :
|
|
||||||
|
|
||||||
[code style=c++]
|
|
||||||
// with no data:
|
|
||||||
generateEventId(eventValue);
|
|
||||||
// With a custom data:
|
|
||||||
generateEventId(eventValue, "My sring custom data ...");
|
|
||||||
[/code]
|
|
||||||
|
|
||||||
|
|
||||||
== Conclusion ==
|
== Conclusion ==
|
||||||
|
|
||||||
You will now able to generate event between objects...
|
You will now able to reise signals between objects...
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
=?= Tutorial 5: File Access =?=
|
=?= Tutorial 5: File Access =?=
|
||||||
__________________________________________________
|
__________________________________________________
|
||||||
[left][tutorial[012_ObjectMessage | Previous: Object message]][/left] [right][tutorial[021_Resources | Next: Resources management]][/right]
|
[left][tutorial[012_ObjectMessage | Previous: Object signal]][/left] [right][tutorial[021_Resources | Next: Resources management]][/right]
|
||||||
|
|
||||||
=== Objectif ===
|
=== Objectif ===
|
||||||
:** Understand why we wrap interface on file system
|
:** Understand why we wrap interface on file system
|
||||||
|
@ -138,7 +138,7 @@ namespace ewol {
|
|||||||
return m_uniqueId;
|
return m_uniqueId;
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
// TODO : Rework the position on this function ... This is a convignet function ...
|
// TODO : Rework the position on this function ... This is a convignent function ...
|
||||||
bool parameterSetOnWidgetNamed(const std::string& _objectName, const std::string& _config, const std::string& _value);
|
bool parameterSetOnWidgetNamed(const std::string& _objectName, const std::string& _config, const std::string& _value);
|
||||||
protected:
|
protected:
|
||||||
ewol::object::Param<std::string> m_name; //!< name of the element ...
|
ewol::object::Param<std::string> m_name; //!< name of the element ...
|
||||||
|
Loading…
x
Reference in New Issue
Block a user