mirror of
https://github.com/overte-org/overte.git
synced 2025-04-23 15:13:41 +02:00
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<Base, Derived>() before any call to the DepedencyManager involving Base. - Dependencies should now inherit from the class Dependency as well as using SINGLETON_DEPENDENCY
This commit is contained in:
parent
4429e144f4
commit
27cc3d297e
2 changed files with 70 additions and 22 deletions
|
@ -10,3 +10,9 @@
|
|||
//
|
||||
|
||||
#include "DependencyManager.h"
|
||||
|
||||
DependencyManager DependencyManager::_manager;
|
||||
|
||||
QSharedPointer<Dependency>& DependencyManager::safeGet(size_t hashCode) {
|
||||
return _instanceHash[hashCode];
|
||||
}
|
|
@ -12,29 +12,31 @@
|
|||
#ifndef hifi_DependencyManager_h
|
||||
#define hifi_DependencyManager_h
|
||||
|
||||
#include <QSharedPointer>
|
||||
#include <QDebug>
|
||||
#include <QHash>
|
||||
#include <QSharedPointer>
|
||||
#include <QWeakPointer>
|
||||
|
||||
#include <typeinfo>
|
||||
|
||||
#define SINGLETON_DEPENDENCY \
|
||||
private:\
|
||||
void customDeleter() {\
|
||||
QObject* thisObject = dynamic_cast<QObject*>(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>();
|
||||
// T* instance = DependencyManager::set<T>(Args... args);
|
||||
// T* instance = DependencyManager::destroy<T>();
|
||||
// auto instance = DependencyManager::get<T>();
|
||||
// auto instance = DependencyManager::set<T>(Args... args);
|
||||
// DependencyManager::destroy<T>();
|
||||
// DependencyManager::registerInheritance<Base, Derived>();
|
||||
class DependencyManager {
|
||||
public:
|
||||
template<typename T>
|
||||
|
@ -46,32 +48,72 @@ public:
|
|||
template<typename T>
|
||||
static void destroy();
|
||||
|
||||
template<typename Base, typename Derived>
|
||||
static void registerInheritance();
|
||||
|
||||
private:
|
||||
static DependencyManager _manager;
|
||||
|
||||
template<typename T>
|
||||
static QSharedPointer<T>& storage();
|
||||
size_t getHashCode();
|
||||
|
||||
QSharedPointer<Dependency>& safeGet(size_t hashCode);
|
||||
|
||||
QHash<size_t, QSharedPointer<Dependency>> _instanceHash;
|
||||
QHash<size_t, size_t> _inheritanceHash;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
QSharedPointer<T> DependencyManager::get() {
|
||||
return storage<T>();
|
||||
static size_t hashCode = _manager.getHashCode<T>();
|
||||
static QWeakPointer<T> instance;
|
||||
|
||||
if (instance.isNull()) {
|
||||
instance = qSharedPointerCast<T>(_manager.safeGet(hashCode));
|
||||
|
||||
if (instance.isNull()) {
|
||||
qWarning() << "DependencyManager::get(): No instance available for" << typeid(T).name();
|
||||
}
|
||||
}
|
||||
|
||||
return instance.toStrongRef();
|
||||
}
|
||||
|
||||
template <typename T, typename ...Args>
|
||||
QSharedPointer<T> DependencyManager::set(Args&&... args) {
|
||||
static size_t hashCode = _manager.getHashCode<T>();
|
||||
|
||||
QSharedPointer<T> instance(new T(args...), &T::customDeleter);
|
||||
storage<T>().swap(instance);
|
||||
return storage<T>();
|
||||
QSharedPointer<Dependency> storedInstance = qSharedPointerCast<Dependency>(instance);
|
||||
_manager.safeGet(hashCode).swap(storedInstance);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void DependencyManager::destroy() {
|
||||
storage<T>().clear();
|
||||
static size_t hashCode = _manager.getHashCode<T>();
|
||||
_manager.safeGet(hashCode).clear();
|
||||
}
|
||||
|
||||
template<typename Base, typename Derived>
|
||||
void DependencyManager::registerInheritance() {
|
||||
size_t baseHashCode = typeid(Base).hash_code();
|
||||
size_t derivedHashCode = typeid(Derived).hash_code();
|
||||
_manager._inheritanceHash.insert(baseHashCode, derivedHashCode);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
QSharedPointer<T>& DependencyManager::storage() {
|
||||
static QSharedPointer<T> 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
|
||||
|
|
Loading…
Reference in a new issue