[DEV] Better shared pointer management (nearly work)

This commit is contained in:
Edouard DUPIN 2014-05-22 21:44:15 +02:00
parent 5e861e002c
commit 699935e482
10 changed files with 111 additions and 429 deletions

2
external/etk vendored

@ -1 +1 @@
Subproject commit b60324928a7d69d2abc7afe4ab726676f560d317
Subproject commit 3cf514f7c7b00abe6a262e41a0847afc12ded207

View File

@ -390,8 +390,10 @@ ewol::Context::~Context() {
// unset all windows
m_msgSystem.clean();
m_objectManager.unInit();
// Resource is an lower element as objects ...
m_resourceManager.unInit();
// now All must be removed !!!
m_objectManager.unInit();
// release the curent interface :
unLockContext();
EWOL_INFO(" == > Ewol system Un-Init (END)");
@ -580,11 +582,7 @@ bool ewol::Context::OS_Draw(bool _displayEveryTime) {
}
}
// call all the widget that neded to do something periodicly
//! ewol::widgetManager::periodicCall(currentTime);
m_widgetManager.periodicCall(currentTime);
// remove all widget that they are no more usefull (these who decided to destroy themself)
//! ewol::object::Shared<ewol::Object>Manager::removeAllAutoRemove();
m_objectManager.removeAllAutoRemove();
// check if the user selected a windows
if (nullptr != m_windowsCurrent) {
// Redraw all needed elements
@ -647,6 +645,9 @@ bool ewol::Context::OS_Draw(bool _displayEveryTime) {
m_FpsSystem.draw();
m_FpsFlush.draw();
}
// while The Gui is drawing in OpenGl, we do some not realTime things
m_objectManager.removeAllRemovedObject();
return hasDisplayDone;
}

View File

@ -16,14 +16,11 @@
ewol::object::Manager::Manager() {
EWOL_DEBUG(" == > init Object-Manager");
// Can create mlemory leak ... == > but not predictable comportement otherwise ...
m_eObjectAutoRemoveList.clear();
m_eObjectList.clear();
}
ewol::object::Manager::~Manager() {
bool hasError = false;
if (m_eObjectAutoRemoveList.size()!=0) {
if (m_eObjectListActive.size()!=0) {
EWOL_ERROR("Must not have anymore eObject to auto-remove !!!");
hasError = true;
}
@ -38,147 +35,70 @@ ewol::object::Manager::~Manager() {
void ewol::object::Manager::unInit() {
EWOL_DEBUG(" == > Un-Init Object-Manager");
removeAllAutoRemove();
EWOL_INFO(" remove missing user widget");
removeAllRemovedObject();
EWOL_INFO(" remove missing user object");
size_t iii=0;
while(iii < m_eObjectList.size()) {
if (m_eObjectList[iii] != nullptr) {
if ( m_eObjectList[iii]->getStatic() == true
|| m_eObjectList[iii]->getStatusResource() == true) {
iii++;
} else {
EWOL_WARNING("Un-INIT : remove Object type=\"" << m_eObjectList[iii]->getObjectType() << "\"");
m_eObjectList[iii].reset();
m_eObjectList[iii] = nullptr;
}
} else {
m_eObjectList.erase(m_eObjectList.begin()+iii);
}
}
removeAllAutoRemove();
EWOL_INFO(" remove resources user widgets");
while(iii < m_eObjectList.size()) {
if (m_eObjectList[iii] != nullptr) {
if (m_eObjectList[iii]->getStatic() == true) {
iii++;
} else {
EWOL_WARNING("Un-INIT : remove Object type=\"" << m_eObjectList[iii]->getObjectType() << "\"");
m_eObjectList[iii].reset();
}
} else {
m_eObjectList.erase(m_eObjectList.begin()+iii);
}
}
removeAllAutoRemove();
EWOL_INFO(" remove static user widgets");
while(iii < m_eObjectList.size()) {
if (m_eObjectList[iii] != nullptr) {
EWOL_WARNING("Un-INIT : remove Object type=\"" << m_eObjectList[iii]->getObjectType() << "\"");
m_eObjectList[iii].reset();
} else {
m_eObjectList.erase(m_eObjectList.begin()+iii);
if (m_eObjectListActive.size() != 0) {
EWOL_ERROR("Have " << m_eObjectListActive.size() << " active Object");
}
while(iii < m_eObjectListActive.size()) {
if (m_eObjectListActive[iii] != nullptr) {
m_eObjectListActive.erase(m_eObjectListActive.begin()+iii);
}
}
removeAllRemovedObject();
}
void ewol::object::Manager::add(const ewol::object::Shared<ewol::Object>& _object) {
if (_object == nullptr) {
EWOL_ERROR("try to add an inexistant Object in manager");
}
// ! < it might benerate a shared object !!!
m_eObjectList.push_back(_object);
m_eObjectListActive.push_back(_object);
}
void ewol::object::Manager::rm(const ewol::object::Shared<ewol::Object>& _object) {
if (_object == nullptr) {
EWOL_ERROR("Try to remove (nullptr) Object");
return;
}
for (size_t iii=0; iii<m_eObjectList.size(); iii++) {
if (m_eObjectList[iii] == _object) {
// remove Element
m_eObjectList[iii] = nullptr;
m_eObjectList.erase(m_eObjectList.begin()+iii);
informOneObjectIsRemoved(_object);
return;
}
}
// check if the object has not been auto removed ... or remove in defered time ...
for (size_t iii=0; iii<m_eObjectAutoRemoveList.size(); iii++) {
if( m_eObjectAutoRemoveList[iii] != nullptr
&& m_eObjectAutoRemoveList[iii] == _object) {
return;
}
}
// in this case, we have an error ...
EWOL_ERROR("Try to remove Object that is not referenced ...");
}
void ewol::object::Manager::addOwned(const ewol::object::Shared<ewol::Object>& _object) {
// What I need to do ...
}
void ewol::object::Manager::rmOwned(const ewol::object::Shared<ewol::Object>& _object) {
// What I need to do ...
}
int32_t ewol::object::Manager::getNumberObject() {
return m_eObjectList.size() + m_eObjectAutoRemoveList.size();
return m_eObjectList.size();
}
void ewol::object::Manager::informOneObjectIsRemoved(const ewol::object::Shared<ewol::Object>& _object) {
size_t mbElement = m_eObjectList.size();
for (int64_t iii=0; iii<(int64_t)m_eObjectList.size(); ++iii) {
if ( m_eObjectList[iii] != nullptr
&& m_eObjectList[iii] != _object) {
//EWOL_DEBUG("inform " << iii+1 << "/" << m_eObjectList.size());
//EWOL_DEBUG(" id=" << m_eObjectList[iii]->getId() << " named '" << m_eObjectList[iii]->getName() << "' type=" << m_eObjectList[iii]->getObjectType());
m_eObjectList[iii]->onObjectRemove(_object);
if (mbElement != m_eObjectList.size()) {
iii = -1;
mbElement = m_eObjectList.size();
}
for (auto &it : m_eObjectList) {
if ( it != nullptr
&& it != _object) {
it->onObjectRemove(_object);
}
}
//EWOL_DEBUG("inform active done");
mbElement = m_eObjectAutoRemoveList.size();
for (size_t iii=0; iii<m_eObjectAutoRemoveList.size(); iii++) {
if( m_eObjectAutoRemoveList[iii] != nullptr
&& m_eObjectAutoRemoveList[iii] != _object) {
//EWOL_DEBUG("inform2 " << iii+1 << "/" << m_eObjectAutoRemoveList.size());
m_eObjectAutoRemoveList[iii]->onObjectRemove(_object);
if (mbElement != m_eObjectAutoRemoveList.size()) {
iii = -1;
mbElement = m_eObjectAutoRemoveList.size();
}
}
}
//EWOL_DEBUG("inform in-active done");
// call input event manager to remove linked widget ...
// inform the context ...
ewol::getContext().onObjectRemove(_object);
}
void ewol::object::Manager::autoRespown(const ewol::object::Shared<ewol::Object>& _object){
void ewol::object::Manager::respown(const ewol::object::Shared<ewol::Object>& _object){
if (_object == nullptr) {
EWOL_ERROR("Try to respown nullptr Object");
return;
}
for (auto it : m_eObjectListActive) {
if (it == _object) {
EWOL_ERROR("try to respawn an existing active Object : [" << _object->getId() << "] type='" << _object->getObjectType() << "'");
return;
}
}
m_eObjectListActive.push_back(_object);
}
void ewol::object::Manager::autoRemove(const ewol::object::Shared<ewol::Object>& _object) {
if (nullptr == _object) {
void ewol::object::Manager::remove(const ewol::object::Shared<ewol::Object>& _object) {
if (_object == nullptr) {
EWOL_ERROR("Try to Auto-Remove (nullptr) Object");
return;
}
for (size_t iii=0; iii<m_eObjectList.size(); iii++) {
if (m_eObjectList[iii] == _object) {
for (int64_t iii = (int64_t)m_eObjectListActive.size()-1; iii>=0; --iii) {
if (m_eObjectListActive[iii] == _object) {
// remove Element
m_eObjectList[iii] = nullptr;
m_eObjectList.erase(m_eObjectList.begin()+iii);
m_eObjectListActive.erase(m_eObjectListActive.begin()+iii);
EWOL_DEBUG("Auto-Remove Object : [" << _object->getId() << "] type='" << _object->getObjectType() << "'");
if (_object->getStatusResource() == false) {
informOneObjectIsRemoved(_object);
}
m_eObjectAutoRemoveList.push_back(_object);
ewol::getContext().forceRedrawAll();
EWOL_DEBUG("Auto-Remove Object ... done");
return;
@ -188,15 +108,18 @@ void ewol::object::Manager::autoRemove(const ewol::object::Shared<ewol::Object>&
}
// clean all Object that request an autoRemove ...
void ewol::object::Manager::removeAllAutoRemove() {
void ewol::object::Manager::removeAllRemovedObject() {
//EWOL_DEBUG("Auto-Remove Object section : " << m_eObjectAutoRemoveList.size() << " elemeents");
while(0<m_eObjectAutoRemoveList.size()) {
if (m_eObjectAutoRemoveList[0] != nullptr) {
EWOL_DEBUG("Real Auto-Remove Object [" << m_eObjectAutoRemoveList[0]->getId() << "]type='" << m_eObjectAutoRemoveList[0]->getObjectType() << "'");
for (int64_t iii = (int64_t)m_eObjectList.size()-1; iii>=0; --iii) {
if (m_eObjectList[iii] == nullptr) {
continue;
}
m_eObjectAutoRemoveList.erase(m_eObjectAutoRemoveList.begin());
if (m_eObjectList[iii]->getRefCount() >= 1) {
continue;
}
EWOL_DEBUG("remove definitly : [" << m_eObjectList[iii]->getId() << "] type='" << m_eObjectList[iii]->getObjectType() << "'");
m_eObjectList.erase(m_eObjectList.begin() + iii);
}
m_eObjectAutoRemoveList.clear();
}
ewol::object::Shared<ewol::Object> ewol::object::Manager::get(const std::string& _name) {
@ -206,7 +129,7 @@ ewol::object::Shared<ewol::Object> ewol::object::Manager::get(const std::string&
for (size_t iii=0; iii<m_eObjectList.size(); iii++) {
if (m_eObjectList[iii] != nullptr) {
if (m_eObjectList[iii]->getName() == _name) {
return m_eObjectList[iii].get();
return m_eObjectList[iii];
}
}
}

View File

@ -18,7 +18,7 @@ namespace ewol {
class Manager {
private:
std::vector<ewol::object::Shared<ewol::Object>> m_eObjectList; // all widget allocated == > all time increment ... never removed ...
std::vector<ewol::object::Shared<ewol::Object>> m_eObjectAutoRemoveList; // all widget allocated
std::vector<ewol::object::Shared<ewol::Object>> m_eObjectListActive; // all active widget
public:
Manager();
~Manager();
@ -26,16 +26,31 @@ namespace ewol {
* @brief remove all resources (un-init) out of the destructor (due to the system implementation)
*/
void unInit();
void add(const ewol::object::Shared<ewol::Object>& _object);
void rm(const ewol::object::Shared<ewol::Object>& _object);
void addOwned(const ewol::object::Shared<ewol::Object>& _object);
void rmOwned(const ewol::object::Shared<ewol::Object>& _object);
/**
* @brief Get the number of loaded object in the system
* @return number of Object
*/
int32_t getNumberObject();
void autoRemove(const ewol::object::Shared<ewol::Object>& _object);
void autoRespown(const ewol::object::Shared<ewol::Object>& _object);
void removeAllAutoRemove();
private:
friend class ewol::Object;
/**
* @brief Internal API that used only with Object toi reference itself in the manager.
* @note The manager remove the object when the refecence Low down 1 (last keeper)
* @param[in] _object Reference shared pointer on the object
*/
void add(const ewol::object::Shared<ewol::Object>& _object);
/**
* @brief Called when an object request to be removed
* @param[in] _object Reference shared pointer on the object
*/
void remove(const ewol::object::Shared<ewol::Object>& _object);
/**
* @brief Called when a user want to reuse an object that have been removed previously
* @param[in] _object Reference shared pointer on the object
*/
void respown(const ewol::object::Shared<ewol::Object>& _object);
public:
void removeAllRemovedObject();
ewol::object::Shared<ewol::Object> get(const std::string& _name);
private:

View File

@ -30,38 +30,16 @@ void ewol::Object::objRefCountDecrement() {
m_objRefCount--;
}
bool ewol::Object::setRefOwner(bool _haveOwner) {
std::unique_lock<std::mutex> lock(m_lockRefCount);
if (_haveOwner == true) {
if (m_hasReferenceOwner == true) {
EWOL_CRITICAL("Object have already an owner");
return false;;
}
m_hasReferenceOwner = true;
getObjectManager().addOwned(this);
return true;
}
if (m_hasReferenceOwner == false) {
EWOL_CRITICAL("Object have already NO owner");
return false;
}
getObjectManager().rmOwned(this);
m_hasReferenceOwner = false;
return true;
}
void ewol::Object::operator delete(void* _ptr, std::size_t _sz) {
EWOL_DEBUG("custom delete for size " << _sz);
ewol::object::Shared<ewol::Object> obj = (ewol::Object*)_ptr;
obj->objRefCountDecrement();
if (obj->m_objRefCount <= 0) {
EWOL_DEBUG(" ==> real remove");
if (obj->m_hasReferenceOwner == true) {
EWOL_ERROR(" ==> Remove ofject that have not a reference owner removed");
}
::operator delete(_ptr);
} else {
EWOL_DEBUG(" ==> Some user is link on it ...");
EWOL_DEBUG(" ==> Some user is link on it : " << obj->m_objRefCount);
etk::log::displayBacktrace();
}
}
@ -79,7 +57,7 @@ void ewol::Object::autoDestroy() {
}
m_isDestroyed = true;
}
getObjectManager().autoRemove(this);
getObjectManager().remove(this);
}
void ewol::Object::removeObject() {
@ -93,12 +71,12 @@ void ewol::Object::respownObject() {
return;
}
m_isDestroyed = false;
getObjectManager().autoRespown(this);
getObjectManager().respown(this);
}
ewol::Object::Object() :
m_objRefCount(1),
m_hasReferenceOwner(false),
m_isDestroyed(false),
m_static(false),
m_isResource(false) {
// note this is nearly atomic ... (but it is enough)
@ -109,6 +87,7 @@ ewol::Object::Object() :
}
ewol::Object::Object(const std::string& _name) :
m_objRefCount(1),
m_isDestroyed(false),
m_static(false),
m_name(_name),
m_isResource(false) {
@ -121,10 +100,9 @@ ewol::Object::Object(const std::string& _name) :
ewol::Object::~Object() {
EWOL_DEBUG("delete Object : [" << m_uniqueId << "] : " << getTypeDescription());
getObjectManager().rm(this);
getMultiCast().rm(this);
for (size_t iii=0; iii<m_externEvent.size(); iii++) {
if (nullptr!=m_externEvent[iii]) {
for (size_t iii=0; iii<m_externEvent.size(); ++iii) {
if (m_externEvent[iii] != nullptr) {
delete(m_externEvent[iii]);
m_externEvent[iii] = nullptr;
}
@ -179,7 +157,7 @@ void ewol::Object::generateEventId(const char * _generateEventId, const std::str
int32_t nbObject = getObjectManager().getNumberObject();
EWOL_VERBOSE("try send message '" << _generateEventId << "'");
// for every element registered ...
for (size_t iii=0; iii<m_externEvent.size(); iii++) {
for (size_t iii=0; iii<m_externEvent.size(); ++iii) {
if (nullptr==m_externEvent[iii]) {
EWOL_VERBOSE(" Null pointer");
continue;
@ -317,8 +295,7 @@ void ewol::Object::unRegisterOnEvent(const ewol::object::Shared<ewol::Object>& _
void ewol::Object::onObjectRemove(const ewol::object::Shared<ewol::Object>& _object) {
for(int32_t iii=m_externEvent.size()-1; iii >= 0; iii--) {
if ( m_externEvent[iii] != nullptr
&& m_externEvent[iii]->destObject.hasOwner() == false) {
if (m_externEvent[iii] != nullptr) {
m_externEvent.erase(m_externEvent.begin()+iii);
}
}

View File

@ -14,7 +14,6 @@
#include <vector>
#include <exml/exml.h>
#include <mutex>
#include <ewol/object/Owner.h>
#include <ewol/object/Shared.h>
namespace ewol {
@ -51,24 +50,18 @@ namespace ewol {
*/
class Object {
template<typename T> friend class ewol::object::Shared;
template<typename T> friend class ewol::object::Owner;
private:
//! @not-in-doc
std::mutex m_lockRefCount;
//! @not-in-doc
int32_t m_objRefCount;
//! @not-in-doc
bool m_hasReferenceOwner;
public:
//! @not-in-doc
void objRefCountIncrement();
//! @not-in-doc
void objRefCountDecrement();
//! @not-in-doc
bool setRefOwner(bool haveOwner);
//! @not-in-doc
bool getRefOwner() {
return m_hasReferenceOwner;
int32_t getRefCount() {
return m_objRefCount;
}
//! @not-in-doc
static void operator delete(void* _ptr, std::size_t _sz);

View File

@ -1,182 +0,0 @@
/**
* @author Edouard DUPIN
*
* @copyright 2011, Edouard DUPIN, all right reserved
*
* @license BSD 3 clauses (see license file)
*/
#ifndef __EWOL_OBJECT_OWNER_H__
#define __EWOL_OBJECT_OWNER_H__
#include <ewol/debug.h>
namespace ewol {
namespace object {
template<typename T>
class Owner {
private:
T* m_pointer;
public:
Owner() :
m_pointer(nullptr) {
// nothing to do ...
}
Owner(T* _pointer) :
m_pointer(_pointer) {
if (m_pointer == nullptr) {
return;
}
if (m_pointer->setRefOwner(true) == false) {
m_pointer = nullptr;
return;
}
m_pointer->objRefCountIncrement();
}
~Owner() {
reset();
}
// copy constructor
Owner(const Owner& _obj) :
m_pointer(nullptr) {
EWOL_CRITICAL("You can not user copy operator for Owner reference...");
}
// Move Constructor
Owner(Owner&& _obj) :
m_pointer(nullptr) {
// transfert pointer
m_pointer = _obj.m_pointer;
_obj.m_pointer = nullptr;
}
Owner& operator=(const Owner<T>& _obj) noexcept {
if(this == &_obj) {
return *this;
}
reset();
m_pointer = _obj.get();
if (m_pointer != nullptr) {
if (m_pointer->setRefOwner(true) == false) {
m_pointer = nullptr;
return *this;
}
m_pointer->objRefCountIncrement();
}
return *this;
}
void reset() {
if (m_pointer == nullptr) {
return;
}
m_pointer->setRefOwner(false);
if (m_pointer->m_objRefCount <= 0) {
EWOL_ERROR("Object is already removed");
} else if (m_pointer->m_objRefCount == 1) {
EWOL_ERROR("Remove object (in Owner)");
delete m_pointer;
} else {
m_pointer->objRefCountDecrement();
}
m_pointer = nullptr;
}
T* get() noexcept {
return m_pointer;
}
T* get() const noexcept {
return m_pointer;
}
T& operator*() const noexcept {
return *m_pointer;
}
T* operator->() const noexcept {
return m_pointer;
}
};
};
// section to compare Owner pointer of an object with an other
//! @not in doc
template<typename T, typename T2>
inline bool operator==(const object::Owner<T>& _obj, const object::Owner<T2>& _obj2) noexcept {
return _obj.get() == _obj2.get();
}
//! @not in doc
template<typename T2>
inline bool operator==(const object::Owner<T2>& _obj, std::nullptr_t) noexcept {
return _obj.get() == nullptr;
}
//! @not in doc
template<typename T2>
inline bool operator==(std::nullptr_t, const object::Owner<T2>& _obj) noexcept {
return _obj.get() == nullptr;
}
//! @not in doc
template<typename T, typename T2, typename = typename
std::enable_if<std::is_convertible<T*, T2*>::value>::type>
inline bool operator==(const object::Owner<T>& _obj, const T2* _obj2) noexcept {
return _obj.get() == _obj2;
}
//! @not in doc
template<typename T, typename T2, typename = typename
std::enable_if<std::is_convertible<T*, T2*>::value>::type>
inline bool operator==(const T* _obj, const object::Owner<T2>& _obj2) noexcept {
return _obj == _obj2.get();
}
//! @not in doc
template<typename T, typename T2>
inline bool operator!=(const object::Owner<T>& _obj, const object::Owner<T2>& _obj2) noexcept {
return _obj.get() != _obj2.get();
}
//! @not in doc
template<typename T>
inline bool operator!=(const object::Owner<T>& _obj, std::nullptr_t) noexcept {
return _obj.get() != nullptr;
}
//! @not in doc
template<typename T>
inline bool operator!=(std::nullptr_t, const object::Owner<T>& _obj) noexcept {
return _obj.get() != nullptr;
}
//! @not in doc
template<typename T, typename T2, typename = typename
std::enable_if<std::is_convertible<T*, T2*>::value>::type>
inline bool operator!=(const object::Owner<T>& _obj, const T2* _obj2) noexcept {
return _obj.get() != _obj2;
}
//! @not in doc
template<typename T, typename T2, typename = typename
std::enable_if<std::is_convertible<T*, T2*>::value>::type>
inline bool operator!=(const T* _obj, const object::Owner<T2>& _obj2) noexcept {
return _obj != _obj2.get();
}
//! @not in doc
template<typename T>
inline void swap(object::Owner<T>& _obj, object::Owner<T>& _obj2) noexcept {
_obj2.swap(_obj);
}
//! @not in doc
template<typename T2, typename T>
inline object::Owner<T2> static_pointer_cast(const object::Owner<T>& _obj) noexcept {
return object::Owner<T2>(_obj, static_cast<T2*>(_obj.get()));
}
//! @not in doc
template<typename T2, typename T>
inline object::Owner<T2> const_pointer_cast(const object::Owner<T>& _obj) noexcept {
return object::Owner<T2>(_obj, const_cast<T2*>(_obj.get()));
}
//! @not in doc
template<typename T2, typename T>
inline object::Owner<T2> dynamic_pointer_cast(const object::Owner<T>& _obj) noexcept {
if (T2* obj = dynamic_cast<T2*>(_obj.get())) {
return object::Owner<T2>(_obj, obj);
}
return object::Owner<T2>();
}
};
#endif

View File

@ -32,15 +32,6 @@ namespace ewol {
~Shared() {
reset();
}
// shared to private constructor
Shared(const Owner<T>& _obj) :
m_pointer(nullptr) {
m_pointer = _obj.get();
if (m_pointer == nullptr) {
return;
}
m_pointer->objRefCountIncrement();
}
// copy constructor
Shared(const Shared& _obj) :
m_pointer(nullptr) {
@ -57,13 +48,6 @@ namespace ewol {
m_pointer = _obj.m_pointer;
_obj.m_pointer = nullptr;
}
bool hasOwner() {
if (m_pointer == nullptr) {
return false;
}
return m_pointer->getRefOwner();
}
Shared& operator=(const Shared<T>& _obj) noexcept {
if(this == &_obj) {
return *this;
@ -99,9 +83,6 @@ namespace ewol {
T* operator->() const noexcept {
return m_pointer;
}
operator ewol::object::Owner<T>() const noexcept {
return m_pointer;
}
template<typename T2> operator ewol::object::Shared<T2>() const noexcept {
return m_pointer;
}
@ -146,16 +127,6 @@ namespace ewol {
inline bool operator==(const T* _obj, const object::Shared<T2>& _obj2) noexcept {
return _obj == _obj2.get();
}
//! @not in doc
template<typename T, typename T2>
inline bool operator==(const object::Owner<T>& _obj, const object::Shared<T2>& _obj2) noexcept {
return _obj.get() == _obj2.get();
}
//! @not in doc
template<typename T, typename T2>
inline bool operator==(const object::Shared<T>& _obj, const object::Owner<T2>& _obj2) noexcept {
return _obj.get() == _obj2.get();
}
//! @not in doc
template<typename T, typename T2>
@ -184,16 +155,6 @@ namespace ewol {
inline bool operator!=(const T* _obj, const object::Shared<T2>& _obj2) noexcept {
return _obj != _obj2.get();
}
//! @not in doc
template<typename T, typename T2>
inline bool operator!=(const object::Owner<T>& _obj, const object::Shared<T2>& _obj2) noexcept {
return _obj.get() != _obj2.get();
}
//! @not in doc
template<typename T, typename T2>
inline bool operator!=(const object::Shared<T>& _obj, const object::Owner<T2>& _obj2) noexcept {
return _obj.get() != _obj2.get();
}
//! @not in doc
template<typename T>

View File

@ -21,7 +21,6 @@
ewol::widget::Menu::Menu() {
addObjectType("ewol::widget::Menu");
m_staticId = 0;
m_widgetContextMenu = nullptr;
}
ewol::widget::Menu::~Menu() {
@ -68,8 +67,8 @@ int32_t ewol::widget::Menu::add(int32_t _parent,
std::string _image,
const char *_generateEvent,
const std::string _message) {
ewol::widget::MenuElement *tmpObject = new ewol::widget::MenuElement();
if (nullptr == tmpObject) {
ewol::widget::MenuElement* tmpObject = new ewol::widget::MenuElement();
if (tmpObject == nullptr) {
EWOL_ERROR("Allocation problem");
return -1;
}
@ -82,9 +81,8 @@ int32_t ewol::widget::Menu::add(int32_t _parent,
tmpObject->m_message = _message;
m_listElement.push_back(tmpObject);
if (-1 == tmpObject->m_parentId) {
ewol::widget::Button *myButton = nullptr;
myButton = new ewol::widget::Button();
if (nullptr == myButton) {
ewol::object::Shared<ewol::widget::Button> myButton = ewol::object::makeShared(new ewol::widget::Button());
if (myButton == nullptr) {
EWOL_ERROR("Allocation button error");
return tmpObject->m_localId;
}
@ -97,9 +95,9 @@ int32_t ewol::widget::Menu::add(int32_t _parent,
}
composeString+=" <label>" + tmpObject->m_label + "</label>\n";
composeString+="</sizer>\n";
myButton->setSubWidget(new ewol::widget::Composer(widget::Composer::String, composeString));
myButton->setSubWidget(ewol::object::makeShared(new ewol::widget::Composer(widget::Composer::String, composeString)));
} else {
myButton->setSubWidget(new ewol::widget::Label(tmpObject->m_label) );
myButton->setSubWidget(ewol::object::makeShared(new ewol::widget::Label(tmpObject->m_label)) );
}
// add it in the widget list
@ -158,23 +156,20 @@ void ewol::widget::Menu::onReceiveMessage(const ewol::object::Message& _msg) {
}
// get the button widget :
vec2 newPosition;
// TODO : Set it back :
/*
ewol::object::Shared<ewol::Widget> eventFromWidget = static_cast<ewol::object::Shared<ewol::Widget>>(_msg.getCaller());
if (nullptr != eventFromWidget) {
ewol::object::Shared<ewol::Widget> eventFromWidget = dynamic_pointer_cast<ewol::Widget>(_msg.getCaller());
if (eventFromWidget != nullptr) {
vec2 tmpOri = eventFromWidget->getOrigin();
vec2 tmpSize = eventFromWidget->getSize();
// calculate the correct position
newPosition.setValue(tmpOri.x() + tmpSize.x()/2,
tmpOri.y() );
}
*/
m_widgetContextMenu->setPositionMark(ewol::widget::ContextMenu::markTop, newPosition );
ewol::widget::Sizer * mySizer = nullptr;
ewol::widget::Button * myButton = nullptr;
ewol::object::Shared<ewol::widget::Sizer> mySizer;
ewol::object::Shared<ewol::widget::Button> myButton;
mySizer = new ewol::widget::Sizer(widget::Sizer::modeVert);
mySizer = ewol::object::makeShared(new ewol::widget::Sizer(widget::Sizer::modeVert));
if (nullptr != mySizer) {
mySizer->lockExpand(vec2(true,true));
// set it in the pop-up-system :
@ -194,7 +189,7 @@ void ewol::widget::Menu::onReceiveMessage(const ewol::object::Message& _msg) {
for (int64_t jjj=m_listElement.size()-1; jjj >= 0; jjj--) {
if (m_listElement[iii]!=nullptr) {
if (m_listElement[iii]->m_localId == m_listElement[jjj]->m_parentId) {
myButton = new ewol::widget::Button();
myButton = ewol::object::makeShared(new ewol::widget::Button());
if (nullptr == myButton) {
EWOL_ERROR("Allocation Error");
} else {
@ -210,20 +205,20 @@ void ewol::widget::Menu::onReceiveMessage(const ewol::object::Message& _msg) {
composeString+=" <label exand=\"true,true\" fill=\"true,true\">" + m_listElement[jjj]->m_label + "</label>\n";
composeString+=" </sizer>\n";
composeString+="</composer>\n";
myButton->setSubWidget(new ewol::widget::Composer(widget::Composer::String, composeString));
myButton->setSubWidget(ewol::object::makeShared(new ewol::widget::Composer(widget::Composer::String, composeString)));
} else {
if (true == menuHaveImage) {
myButton->setSubWidget(
myButton->setSubWidget(ewol::object::makeShared(
new ewol::widget::Composer(widget::Composer::String,
std::string("<composer expand=\"true,false\" fill=\"true,true\">\n") +
" <sizer mode=\"hori\" expand=\"true,false\" fill=\"true,true\" lock=\"true\">\n"
" <spacer min-size=\"8,0mm\"/>\n"
" <label exand=\"true,true\" fill=\"true,true\"><![CDATA[" + m_listElement[jjj]->m_label + "]]></label>\n"
" </sizer>\n"
"</composer>\n"));
"</composer>\n")));
} else {
ewol::widget::Label* tmpLabel = new widget::Label(std::string("<left>") + m_listElement[jjj]->m_label + "</left>\n");
if (nullptr != tmpLabel) {
ewol::object::Shared<ewol::widget::Label> tmpLabel = ewol::object::makeShared(new widget::Label(std::string("<left>") + m_listElement[jjj]->m_label + "</left>\n"));
if (tmpLabel != nullptr) {
tmpLabel->setExpand(bvec2(true,false));
tmpLabel->setFill(bvec2(true,true));
myButton->setSubWidget(tmpLabel);
@ -261,11 +256,10 @@ void ewol::widget::Menu::onReceiveMessage(const ewol::object::Message& _msg) {
void ewol::widget::Menu::onObjectRemove(const ewol::object::Shared<ewol::Object>& _removeObject) {
ewol::widget::Sizer::onObjectRemove(_removeObject);
if (m_widgetContextMenu == _removeObject) {
delete(m_widgetContextMenu);
m_widgetContextMenu = nullptr;
m_widgetContextMenu.reset();
}
for (size_t jjj=0; jjj<m_listElement.size(); jjj++) {
if (nullptr != m_listElement[jjj]) {
if (m_listElement[jjj] != nullptr) {
if (m_listElement[jjj]->m_widgetPointer == _removeObject) {
m_listElement[jjj]->m_widgetPointer.reset();
}

View File

@ -20,13 +20,13 @@ namespace ewol {
namespace widget {
class MenuElement {
public :
MenuElement() : m_widgetPointer(nullptr) { };
MenuElement() { };
int32_t m_localId;
int32_t m_parentId;
ewol::object::Shared<ewol::Object> m_widgetPointer;
ewol::object::Shared<ewol::Widget> m_widgetPointer;
std::string m_label;
std::string m_image;
const char *m_generateEvent;
const char* m_generateEvent;
std::string m_message;
};
/**
@ -44,7 +44,7 @@ namespace ewol {
private:
std::vector<ewol::widget::MenuElement*> m_listElement;
int32_t m_staticId; // unique ID for every element of the menu ...
ewol::widget::ContextMenu* m_widgetContextMenu;
ewol::object::Shared<ewol::widget::ContextMenu> m_widgetContextMenu;
public:
void clear();
int32_t addTitle(std::string _label, std::string _image="", const char * _generateEvent = nullptr, const std::string _message = "");