diff --git a/external/etk b/external/etk index d2997292..b6032492 160000 --- a/external/etk +++ b/external/etk @@ -1 +1 @@ -Subproject commit d2997292a5c1204d8f38a2d751c5fb416058dc10 +Subproject commit b60324928a7d69d2abc7afe4ab726676f560d317 diff --git a/sources/ewol/object/Manager.cpp b/sources/ewol/object/Manager.cpp index a2230a64..42cd0c65 100644 --- a/sources/ewol/object/Manager.cpp +++ b/sources/ewol/object/Manager.cpp @@ -48,7 +48,7 @@ void ewol::object::Manager::unInit() { iii++; } else { EWOL_WARNING("Un-INIT : remove Object type=\"" << m_eObjectList[iii]->getObjectType() << "\""); - delete(m_eObjectList[iii]); + m_eObjectList[iii].reset(); m_eObjectList[iii] = NULL; } } else { @@ -63,8 +63,7 @@ void ewol::object::Manager::unInit() { iii++; } else { EWOL_WARNING("Un-INIT : remove Object type=\"" << m_eObjectList[iii]->getObjectType() << "\""); - delete(m_eObjectList[iii]); - m_eObjectList[iii] = NULL; + m_eObjectList[iii].reset(); } } else { m_eObjectList.erase(m_eObjectList.begin()+iii); @@ -75,8 +74,7 @@ void ewol::object::Manager::unInit() { while(iii < m_eObjectList.size()) { if (m_eObjectList[iii] != NULL) { EWOL_WARNING("Un-INIT : remove Object type=\"" << m_eObjectList[iii]->getObjectType() << "\""); - delete(m_eObjectList[iii]); - m_eObjectList[iii] = NULL; + m_eObjectList[iii].reset(); } else { m_eObjectList.erase(m_eObjectList.begin()+iii); } @@ -84,11 +82,11 @@ void ewol::object::Manager::unInit() { } void ewol::object::Manager::add(ewol::Object* _object) { - if (NULL != _object) { - m_eObjectList.push_back(_object); - } else { + if (_object == NULL) { EWOL_ERROR("try to add an inexistant Object in manager"); } + // ! < it might benerate a shared object !!! + m_eObjectList.push_back(_object); } int32_t ewol::object::Manager::getNumberObject() { @@ -181,11 +179,8 @@ void ewol::object::Manager::removeAllAutoRemove() { while(0getId() << "]type='" << m_eObjectAutoRemoveList[0]->getObjectType() << "'"); - delete(m_eObjectAutoRemoveList[0]); - m_eObjectAutoRemoveList[0] = NULL; - } else { - m_eObjectAutoRemoveList.erase(m_eObjectAutoRemoveList.begin()); } + m_eObjectAutoRemoveList.erase(m_eObjectAutoRemoveList.begin()); } m_eObjectAutoRemoveList.clear(); } @@ -197,7 +192,7 @@ ewol::Object* ewol::object::Manager::get(const std::string& _name) { for (size_t iii=0; iiigetName() == _name) { - return m_eObjectList[iii]; + return m_eObjectList[iii].get(); } } } diff --git a/sources/ewol/object/Manager.h b/sources/ewol/object/Manager.h index 669f5610..bb779820 100644 --- a/sources/ewol/object/Manager.h +++ b/sources/ewol/object/Manager.h @@ -17,8 +17,8 @@ namespace ewol { namespace object { class Manager { private: - std::vector m_eObjectList; // all widget allocated == > all time increment ... never removed ... - std::vector m_eObjectAutoRemoveList; // all widget allocated + std::vector> m_eObjectList; // all widget allocated == > all time increment ... never removed ... + std::vector> m_eObjectAutoRemoveList; // all widget allocated public: Manager(); ~Manager(); diff --git a/sources/ewol/object/Object.cpp b/sources/ewol/object/Object.cpp index 0b2fec99..043391ca 100644 --- a/sources/ewol/object/Object.cpp +++ b/sources/ewol/object/Object.cpp @@ -19,7 +19,36 @@ const char* const ewol::Object::configName = "name"; size_t ewol::Object::m_valUID = 0; + +void ewol::Object::objRefCountIncrement() { + m_objRefCount++; +} + +void ewol::Object::objRefCountDecrement() { + m_objRefCount--; +} + +void ewol::Object::operator delete(void* _ptr, std::size_t _sz) { + EWOL_DEBUG("custom delete for size " << _sz); + ewol::Object* obj = (ewol::Object*)_ptr; + obj->objRefCountDecrement(); + if (obj->m_objRefCount <= 0) { + EWOL_DEBUG(" ==> real remove"); + ::operator delete(_ptr); + } else { + EWOL_DEBUG(" ==> Some user is link on it ..."); + } +} + +void ewol::Object::operator delete[](void* _ptr, std::size_t _sz) { + EWOL_CRITICAL("custom delete for size ==> not implemented ..." << _sz); + ::operator delete(_ptr); +} + + + ewol::Object::Object() : + m_objRefCount(1), m_static(false), m_isResource(false) { // note this is nearly atomic ... (but it is enough) @@ -29,6 +58,7 @@ ewol::Object::Object() : registerConfig(configName, "string", NULL, "Object name, might be a unique reference in all the program"); } ewol::Object::Object(const std::string& _name) : + m_objRefCount(1), m_static(false), m_name(_name), m_isResource(false) { diff --git a/sources/ewol/object/Object.h b/sources/ewol/object/Object.h index 8884ed0f..9fbb5013 100644 --- a/sources/ewol/object/Object.h +++ b/sources/ewol/object/Object.h @@ -47,6 +47,92 @@ namespace ewol { * this class mermit at every Object to communicate between them. */ class Object { + public: + template::value>::type> + class Shared { + private: + T* m_pointer; + public: + Shared() : + m_pointer(nullptr) { + // nothing to do ... + } + Shared(T* _pointer) : + m_pointer(_pointer) { + if (m_pointer == nullptr) { + return; + } + m_pointer->objRefCountIncrement(); + } + ~Shared() { + reset(); + } + // copy constructor + Shared(const Shared& _obj) : + m_pointer(nullptr) { + m_pointer = _obj.get(); + if (m_pointer == nullptr) { + return; + } + m_pointer->objRefCountIncrement(); + } + // Move Constructor + Shared(Shared&& _obj) : + m_pointer(nullptr) { + // transfert pointer + m_pointer = _obj.m_pointer; + _obj.m_pointer = nullptr; + } + Shared& operator=(const Shared& _obj) noexcept { + if(this == &_obj) { + return *this; + } + reset(); + m_pointer = _obj.get(); + if (m_pointer != nullptr) { + m_pointer->objRefCountIncrement(); + } + return *this; + } + + void reset() { + if (m_pointer == nullptr) { + return; + } + if (m_pointer->m_objRefCount <= 0) { + TK_ERROR("Object is already removed"); + } else if (m_pointer->m_objRefCount == 1) { + TK_ERROR("Remove object (in shared)"); + 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; + } + }; + template Shared makeShared(T* _pointer) { + return Shared(_pointer); + } + private: + // TODO : Lock Refcounting ... + int32_t m_objRefCount; + public: + void objRefCountIncrement(); + void objRefCountDecrement(); + static void operator delete(void* _ptr, std::size_t _sz); + static void operator delete[](void* _ptr, std::size_t _sz); private: static size_t m_valUID; //!< stic used for the unique ID definition public: @@ -302,6 +388,91 @@ namespace ewol { return m_isResource; } }; + + // section to compare shared pointer of an object with an other + + //! @not in doc + template + inline bool operator==(const Object::Shared& _obj, const Object::Shared& _obj2) noexcept { + return _obj.get() == _obj2.get(); + } + //! @not in doc + template + inline bool operator==(const Object::Shared& _obj, std::nullptr_t) noexcept { + return _obj.get() == NULL; + } + //! @not in doc + template + inline bool operator==(std::nullptr_t, const Object::Shared& _obj) noexcept { + return _obj.get() == NULL; + } + //! @not in doc + template::value>::type> + inline bool operator==(const Object::Shared& _obj, const T2* _obj2) noexcept { + return _obj.get() == _obj2; + } + //! @not in doc + template::value>::type> + inline bool operator==(const T* _obj, const Object::Shared& _obj2) noexcept { + return _obj == _obj2.get(); + } + + //! @not in doc + template + inline bool operator!=(const Object::Shared& _obj, const Object::Shared& _obj2) noexcept { + return _obj.get() != _obj2.get(); + } + //! @not in doc + template + inline bool operator!=(const Object::Shared& _obj, std::nullptr_t) noexcept { + return _obj.get() != NULL; + } + //! @not in doc + template + inline bool operator!=(std::nullptr_t, const Object::Shared& _obj) noexcept { + return _obj.get() != NULL; + } + //! @not in doc + template::value>::type> + inline bool operator!=(const Object::Shared& _obj, const T2* _obj2) noexcept { + return _obj.get() != _obj2; + } + //! @not in doc + template::value>::type> + inline bool operator!=(const T* _obj, const Object::Shared& _obj2) noexcept { + return _obj != _obj2.get(); + } + + //! @not in doc + template + inline void swap(Object::Shared& _obj, Object::Shared& _obj2) noexcept { + _obj2.swap(_obj); + } + + //! @not in doc + template + inline Object::Shared static_pointer_cast(const Object::Shared& _obj) noexcept { + return Object::Shared(_obj, static_cast(_obj.get())); + } + + //! @not in doc + template + inline Object::Shared const_pointer_cast(const Object::Shared& _obj) noexcept { + return Object::Shared(_obj, const_cast(_obj.get())); + } + + //! @not in doc + template + inline Object::Shared dynamic_pointer_cast(const Object::Shared& _obj) noexcept { + if (T2* obj = dynamic_cast(_obj.get())) { + return Object::Shared(_obj, obj); + } + return Object::Shared(); + } }; #endif