From 27cc3d297eb00952558d5e4794282cf86b639c16 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 13 Jan 2015 20:27:38 -0800 Subject: [PATCH] DependencyManager update - Now need a call to DependencyManager::set(...) that support variable arguments number and type - Now support destroy operation via DependencyManager::destroy() - Now support inheritance. All inheritance relationship need to be specified via DependencyManager::registerInheritance() before any call to the DepedencyManager involving Base. - Dependencies should now inherit from the class Dependency as well as using SINGLETON_DEPENDENCY --- libraries/shared/src/DependencyManager.cpp | 6 ++ libraries/shared/src/DependencyManager.h | 86 ++++++++++++++++------ 2 files changed, 70 insertions(+), 22 deletions(-) diff --git a/libraries/shared/src/DependencyManager.cpp b/libraries/shared/src/DependencyManager.cpp index 440c0ac68d..5f78f6bcd5 100644 --- a/libraries/shared/src/DependencyManager.cpp +++ b/libraries/shared/src/DependencyManager.cpp @@ -10,3 +10,9 @@ // #include "DependencyManager.h" + +DependencyManager DependencyManager::_manager; + +QSharedPointer& DependencyManager::safeGet(size_t hashCode) { + return _instanceHash[hashCode]; +} \ No newline at end of file diff --git a/libraries/shared/src/DependencyManager.h b/libraries/shared/src/DependencyManager.h index 9aecb45657..e996e10590 100644 --- a/libraries/shared/src/DependencyManager.h +++ b/libraries/shared/src/DependencyManager.h @@ -12,29 +12,31 @@ #ifndef hifi_DependencyManager_h #define hifi_DependencyManager_h -#include #include +#include +#include +#include #include #define SINGLETON_DEPENDENCY \ -private:\ - void customDeleter() {\ - QObject* thisObject = dynamic_cast(this);\ - if (thisObject && thisObject->parent()) {\ - thisObject->deleteLater();\ - } else {\ - delete this;\ - }\ - }\ friend class DependencyManager; -class QObject; +class Dependency { +protected: + virtual ~Dependency() {} + virtual void customDeleter() { + delete this; + } + + friend class DependencyManager; +}; // usage: -// T* instance = DependencyManager::get(); -// T* instance = DependencyManager::set(Args... args); -// T* instance = DependencyManager::destroy(); +// auto instance = DependencyManager::get(); +// auto instance = DependencyManager::set(Args... args); +// DependencyManager::destroy(); +// DependencyManager::registerInheritance(); class DependencyManager { public: template @@ -46,32 +48,72 @@ public: template static void destroy(); + template + static void registerInheritance(); + private: + static DependencyManager _manager; + template - static QSharedPointer& storage(); + size_t getHashCode(); + + QSharedPointer& safeGet(size_t hashCode); + + QHash> _instanceHash; + QHash _inheritanceHash; }; template QSharedPointer DependencyManager::get() { - return storage(); + static size_t hashCode = _manager.getHashCode(); + static QWeakPointer instance; + + if (instance.isNull()) { + instance = qSharedPointerCast(_manager.safeGet(hashCode)); + + if (instance.isNull()) { + qWarning() << "DependencyManager::get(): No instance available for" << typeid(T).name(); + } + } + + return instance.toStrongRef(); } template QSharedPointer DependencyManager::set(Args&&... args) { + static size_t hashCode = _manager.getHashCode(); + QSharedPointer instance(new T(args...), &T::customDeleter); - storage().swap(instance); - return storage(); + QSharedPointer storedInstance = qSharedPointerCast(instance); + _manager.safeGet(hashCode).swap(storedInstance); + + return instance; } template void DependencyManager::destroy() { - storage().clear(); + static size_t hashCode = _manager.getHashCode(); + _manager.safeGet(hashCode).clear(); +} + +template +void DependencyManager::registerInheritance() { + size_t baseHashCode = typeid(Base).hash_code(); + size_t derivedHashCode = typeid(Derived).hash_code(); + _manager._inheritanceHash.insert(baseHashCode, derivedHashCode); } template -QSharedPointer& DependencyManager::storage() { - static QSharedPointer sharedPointer; - return sharedPointer; +size_t DependencyManager::getHashCode() { + size_t hashCode = typeid(T).hash_code(); + auto derivedHashCode = _inheritanceHash.find(hashCode); + + while (derivedHashCode != _inheritanceHash.end()) { + hashCode = derivedHashCode.value(); + derivedHashCode = _inheritanceHash.find(hashCode); + } + + return hashCode; } #endif // hifi_DependencyManager_h