ewol/sources/ewol/object/Object.cpp

448 lines
14 KiB
C++

/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD v3 (see license file)
*/
#include <ewol/object/Object.h>
#include <ewol/object/Manager.h>
#include <ewol/debug.h>
#include <ewol/context/Context.h>
#include <ewol/object/MultiCast.h>
#undef __class__
#define __class__ "Object"
const char* const ewol::Object::configName = "name";
size_t ewol::Object::m_valUID = 0;
void ewol::Object::autoDestroy() {
if (m_objectHasBeenInit == false) {
EWOL_WARNING("try to auto destroy inside a constructor");
return;
}
EWOL_VERBOSE("Destroy object : [" << getId() << "] type:" << getObjectType());
std::shared_ptr<ewol::Object> parent = m_parent.lock();
// TODO : set a signal to do this ...
if (parent != nullptr) {
parent->requestDestroyFromChild(shared_from_this());
}
//if no parent ==> noting to do ...
}
void ewol::Object::requestDestroyFromChild(const std::shared_ptr<ewol::Object>& _child) {
EWOL_CRITICAL("Call From Child with no effects ==> must implement : requestDestroyFromChild(...)");
}
void ewol::Object::setParent(const std::shared_ptr<ewol::Object>& _newParent) {
// TODO : Implement change of parent ...
m_parent = _newParent;
}
void ewol::Object::removeParent() {
m_parent.reset();
}
ewol::Object::Object() :
m_objectHasBeenInit(false),
m_static(false),
m_isResource(false) {
// note this is nearly atomic ... (but it is enough)
m_uniqueId = m_valUID++;
EWOL_DEBUG("new Object : [" << m_uniqueId << "]");
registerConfig(configName, "string", nullptr, "Object name, might be a unique reference in all the program");
}
ewol::Object::~Object() {
EWOL_DEBUG("delete Object : [" << m_uniqueId << "] : " << getTypeDescription());
m_externEvent.clear();
m_availlableEventId.clear();
m_uniqueId = -1;
}
void ewol::Object::init() {
getObjectManager().add(shared_from_this());
m_objectHasBeenInit = true;
}
void ewol::Object::init(const std::string& _name) {
init();
m_name = _name;
}
const char * const ewol::Object::getObjectType() {
if (m_listType.size() == 0) {
return "ewol::Object";
}
return m_listType.back();
}
void ewol::Object::addObjectType(const char* _type) {
if (_type == nullptr) {
EWOL_ERROR(" try to add a type with no value...");
return;
}
m_listType.push_back(_type);
}
std::string ewol::Object::getTypeDescription() {
std::string ret("ewol::Object");
for(auto element : m_listType) {
ret += "|";
ret += element;
}
return ret;
}
bool ewol::Object::isTypeCompatible(const std::string& _type) {
if (_type == "ewol::Object") {
return true;
}
for(auto element : m_listType) {
if (_type == element) {
return true;
}
}
return false;
}
void ewol::Object::addEventId(const char * _generateEventId) {
for (auto &it : m_availlableEventId) {
if (std::string(it) == _generateEventId) {
EWOL_WARNING("Event already existed : '" << it << "' == '" << _generateEventId << "'");
return;
}
}
if (_generateEventId != nullptr) {
m_availlableEventId.push_back(_generateEventId);
}
}
void ewol::Object::generateEventId(const char * _generateEventId, const std::string& _data) {
if (m_objectHasBeenInit == false) {
EWOL_WARNING("try to generate an event inside a constructor");
return;
}
int32_t nbObject = getObjectManager().getNumberObject();
EWOL_VERBOSE("try send message '" << _generateEventId << "'");
// for every element registered ...
for (auto &it : m_externEvent) {
// if we find the event ...
if (it.localEventId != _generateEventId) {
EWOL_VERBOSE(" wrong event '" << it.localEventId << "' != '" << _generateEventId << "'");
continue;
}
std::shared_ptr<ewol::Object> destObject = it.destObject.lock();
if (destObject == nullptr) {
EWOL_VERBOSE(" nullptr dest");
continue;
}
if (it.overloadData.size() <= 0){
ewol::object::Message tmpMsg(shared_from_this(), it.destEventId, _data);
EWOL_VERBOSE("send message " << tmpMsg);
destObject->onReceiveMessage(tmpMsg);
} else {
// set the user requested data ...
ewol::object::Message tmpMsg(shared_from_this(), it.destEventId, it.overloadData);
EWOL_VERBOSE("send message " << tmpMsg);
destObject->onReceiveMessage(tmpMsg);
}
}
if (nbObject > getObjectManager().getNumberObject()) {
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) {
EWOL_WARNING("try to generate an multicast event inside a constructor");
return;
}
int32_t nbObject = getObjectManager().getNumberObject();
getMultiCast().send(shared_from_this(), _messageId, _data);
if (nbObject > getObjectManager().getNumberObject()) {
EWOL_CRITICAL("It if really dangerous ro remove (delete) element inside a callback ... use ->removObject() which is asynchronous");
}
}
void ewol::Object::registerMultiCast(const char* const _messageId) {
if (m_objectHasBeenInit == false) {
EWOL_WARNING("try to generate an event inside a constructor");
return;
}
getMultiCast().add(shared_from_this(), _messageId);
}
void ewol::Object::registerOnEvent(const std::shared_ptr<ewol::Object>& _destinationObject,
const char * _eventId,
const char * _eventIdgenerated,
const std::string& _overloadData) {
if (nullptr == _destinationObject) {
EWOL_ERROR("Input ERROR nullptr pointer Object ...");
return;
}
if (nullptr == _eventId) {
EWOL_ERROR("Input ERROR nullptr pointer Event Id...");
return;
}
if ( _eventId[0] == '*'
&& _eventId[1] == '\0') {
EWOL_VERBOSE("Register on all event ...");
for(auto &it : m_availlableEventId) {
ewol::object::EventExtGen tmpEvent;
tmpEvent.localEventId = it;
tmpEvent.destObject = _destinationObject;
tmpEvent.overloadData = _overloadData;
if (nullptr != _eventIdgenerated) {
tmpEvent.destEventId = _eventIdgenerated;
} else {
tmpEvent.destEventId = it;
}
m_externEvent.push_back(tmpEvent);
}
return;
}
// check if event existed :
bool findIt = false;
for(auto &it : m_availlableEventId) {
if (it == _eventId) {
findIt = true;
break;
}
}
if (false == findIt) {
EWOL_VERBOSE("Try to register with a NON direct string name");
for(auto &it : m_availlableEventId) {
if (0 == strncmp(it, _eventId, 1024)) {
findIt = true;
_eventId = it;
EWOL_VERBOSE("find event ID : '" << _eventId << "' ==> '" << _eventIdgenerated << "'");
break;
}
}
}
if (false == findIt) {
EWOL_ERROR("Can not register event on this Type=" << getObjectType() << " event=\"" << _eventId << "\" == > unknow event");
return;
}
ewol::object::EventExtGen tmpEvent;
tmpEvent.localEventId = _eventId;
tmpEvent.destObject = _destinationObject;
tmpEvent.overloadData = _overloadData;
if (nullptr != _eventIdgenerated) {
tmpEvent.destEventId = _eventIdgenerated;
} else {
tmpEvent.destEventId = _eventId;
}
m_externEvent.push_back(tmpEvent);
}
void ewol::Object::unRegisterOnEvent(const std::shared_ptr<ewol::Object>& _destinationObject,
const char * _eventId) {
if (_destinationObject == nullptr) {
EWOL_ERROR("Input ERROR nullptr pointer Object ...");
return;
}
// check if event existed :
auto it(m_externEvent.begin());
while(it != m_externEvent.end()) {
std::shared_ptr<ewol::Object> obj = it->destObject.lock();
if (obj == nullptr) {
m_externEvent.erase(it);
it = m_externEvent.begin();
} else if ( obj == _destinationObject
&& it->localEventId == _eventId) {
m_externEvent.erase(it);
it = m_externEvent.begin();
EWOL_INFO("[" << getId() << "] Remove extern event : to object id=" << _destinationObject->getId() << " event=" << _eventId);
} else {
++it;
}
}
}
void ewol::Object::onObjectRemove(const std::shared_ptr<ewol::Object>& _object) {
EWOL_VERBOSE("[" << getId() << "] onObjectRemove(" << _object->getId() << ")");
auto it(m_externEvent.begin());
while(it != m_externEvent.end()) {
std::shared_ptr<ewol::Object> obj = it->destObject.lock();
if (obj == nullptr) {
m_externEvent.erase(it);
it = m_externEvent.begin();
} else if (obj == _object) {
m_externEvent.erase(it);
it = m_externEvent.begin();
EWOL_INFO("[" << getId() << "] Remove extern event : to object id=" << _object->getId());
} else {
++it;
}
}
}
void ewol::Object::registerConfig(const char* _config,
const char* _type,
const char* _control,
const char* _description,
const char* _default) {
if (nullptr == _config) {
EWOL_ERROR("Try to add nullptr config");
return;
}
for(size_t iii=0 ; iii<m_listConfig.size() ; iii++) {
if (nullptr != m_listConfig[iii].getConfig()) {
if (0 == strcmp(m_listConfig[iii].getConfig(), _config) ) {
EWOL_ERROR("Try to add config already added : " << _config << " at pos=" << iii);
}
}
}
m_listConfig.push_back(ewol::object::ConfigElement(_config, _type, _control, _description, _default));
}
bool ewol::Object::loadXML(exml::Element* _node) {
if (nullptr == _node) {
return false;
}
bool errorOccured = true;
for(size_t iii=0 ; iii<m_listConfig.size() ; iii++) {
if (m_listConfig[iii].getConfig() == nullptr) {
continue;
}
if (_node->existAttribute(m_listConfig[iii].getConfig()) == false) {
continue;
}
std::string value = _node->getAttribute(m_listConfig[iii].getConfig());
if (false == setConfig(ewol::object::Config(m_listConfig[iii].getConfig(), value) ) ) {
errorOccured = false;
}
}
return errorOccured;
}
bool ewol::Object::storeXML(exml::Element* _node) const {
if (nullptr == _node) {
return false;
}
bool errorOccured = true;
for(size_t iii=0 ; iii<m_listConfig.size() ; iii++) {
if (m_listConfig[iii].getConfig() == nullptr) {
continue;
}
std::string value = getConfig(m_listConfig[iii].getConfig());
if (nullptr != m_listConfig[iii].getDefault() ) {
if (value == m_listConfig[iii].getDefault() ) {
// nothing to add on the XML :
continue;
}
}
// add attribute ... == > note : add special element when '"' element detected ...
_node->setAttribute(m_listConfig[iii].getConfig(), value);
}
return errorOccured;
}
bool ewol::Object::onSetConfig(const ewol::object::Config& _conf) {
EWOL_VERBOSE("[" << getId() << "] {" << getObjectType() << "} set config : " << _conf);
if (_conf.getConfig() == configName) {
EWOL_VERBOSE("[" << getId() << "] {" << getObjectType() << "} set config name : \"" << _conf.getData() << "\"");
setName(_conf.getData());
return true;
}
return false;
}
bool ewol::Object::onGetConfig(const char* _config, std::string& _result) const {
if (_config == configName) {
_result = getName();
return true;
}
return false;
}
bool ewol::Object::setConfig(const std::string& _config, const std::string& _value) {
for(size_t iii=0 ; iii<m_listConfig.size() ; iii++) {
if (nullptr != m_listConfig[iii].getConfig()) {
if (_config == m_listConfig[iii].getConfig() ) {
// call config with standard parameter
return setConfig(ewol::object::Config(m_listConfig[iii].getConfig(), _value));
}
}
}
EWOL_ERROR(" parameter is not in the list : \"" << _config << "\"" );
return false;
}
std::string ewol::Object::getConfig(const char* _config) const {
std::string res="";
if (nullptr != _config) {
onGetConfig(_config, res);
}
return res;
}
std::string ewol::Object::getConfig(const std::string& _config) const {
for(size_t iii=0 ; iii<m_listConfig.size() ; iii++) {
if (nullptr != m_listConfig[iii].getConfig()) {
if (_config == m_listConfig[iii].getConfig() ) {
// call config with standard parameter
return getConfig(m_listConfig[iii].getConfig());
}
}
}
EWOL_ERROR(" parameter is not in the list : \"" << _config << "\"" );
return "";
}
bool ewol::Object::setConfigNamed(const std::string& _objectName, const ewol::object::Config& _conf) {
std::shared_ptr<ewol::Object> object = getObjectManager().get(_objectName);
if (object == nullptr) {
return false;
}
return object->setConfig(_conf);
}
bool ewol::Object::setConfigNamed(const std::string& _objectName, const std::string& _config, const std::string& _value) {
std::shared_ptr<ewol::Object> object = getObjectManager().get(_objectName);
if (object == nullptr) {
return false;
}
return object->setConfig(_config, _value);
}
ewol::object::Manager& ewol::Object::getObjectManager() const {
ewol::object::Manager& tmp = ewol::getContext().getEObjectManager();
return tmp;
}
ewol::object::MultiCast& ewol::Object::getMultiCast() const {
return ewol::getContext().getEObjectManager().multiCast();
}
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,
const char * _eventIdgenerated,
const std::string& _overloadData) {
std::shared_ptr<ewol::Object> tmpObject = getObjectManager().getObjectNamed(_objectName);
if (nullptr != tmpObject) {
EWOL_DEBUG("Find widget named : '" << _objectName << "' register event='" << _eventId << "'");
tmpObject->registerOnEvent(_destinationObject, _eventId, _eventIdgenerated, _overloadData);
} else {
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);
}