|
|
@@ -5,8 +5,7 @@
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
-#include <AnKi/Util/Assert.h>
|
|
|
-#include <AnKi/Util/Thread.h>
|
|
|
+#include <AnKi/Util/StdTypes.h>
|
|
|
#include <utility>
|
|
|
|
|
|
namespace anki {
|
|
|
@@ -14,173 +13,37 @@ namespace anki {
|
|
|
/// @addtogroup util_patterns
|
|
|
/// @{
|
|
|
|
|
|
-/// This template makes a class singleton
|
|
|
+/// If class inherits that it will become a singleton.
|
|
|
template<typename T>
|
|
|
-class Singleton
|
|
|
+class MakeSingleton
|
|
|
{
|
|
|
public:
|
|
|
- using Value = T;
|
|
|
-
|
|
|
- // Non copyable
|
|
|
- Singleton(const Singleton&) = delete;
|
|
|
- Singleton& operator=(const Singleton&) = delete;
|
|
|
-
|
|
|
- // Non constructable
|
|
|
- Singleton() = delete;
|
|
|
- ~Singleton() = delete;
|
|
|
-
|
|
|
- /// Get instance
|
|
|
- static Value& get()
|
|
|
+ static T& getSingleton()
|
|
|
{
|
|
|
- return *(m_instance ? m_instance : (m_instance = new Value));
|
|
|
+ return *m_global;
|
|
|
}
|
|
|
|
|
|
- /// Cleanup
|
|
|
- static void destroy()
|
|
|
- {
|
|
|
- if(m_instance)
|
|
|
- {
|
|
|
- delete m_instance;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-private:
|
|
|
- static Value* m_instance;
|
|
|
-};
|
|
|
-
|
|
|
-template<typename T>
|
|
|
-typename Singleton<T>::Value* Singleton<T>::m_instance = nullptr;
|
|
|
-
|
|
|
-/// This template makes a class with a destructor with arguments singleton
|
|
|
-template<typename T>
|
|
|
-class SingletonInit
|
|
|
-{
|
|
|
-public:
|
|
|
- using Value = T;
|
|
|
-
|
|
|
- // Non copyable
|
|
|
- SingletonInit(const SingletonInit&) = delete;
|
|
|
- SingletonInit& operator=(const SingletonInit&) = delete;
|
|
|
-
|
|
|
- // Non constructable
|
|
|
- SingletonInit() = delete;
|
|
|
- ~SingletonInit() = delete;
|
|
|
-
|
|
|
- /// Init the singleton
|
|
|
template<typename... TArgs>
|
|
|
- static void init(TArgs... args)
|
|
|
- {
|
|
|
- ANKI_ASSERT(m_instance == nullptr);
|
|
|
- m_instance = new Value(std::forward<TArgs>(args)...);
|
|
|
- }
|
|
|
-
|
|
|
- /// Get instance
|
|
|
- static Value& get()
|
|
|
- {
|
|
|
- ANKI_ASSERT(m_instance != nullptr);
|
|
|
- return *m_instance;
|
|
|
- }
|
|
|
-
|
|
|
- /// Cleanup
|
|
|
- static void destroy()
|
|
|
+ static void allocateSingleton(TArgs&&... args)
|
|
|
{
|
|
|
- if(m_instance)
|
|
|
+ if(m_global == nullptr)
|
|
|
{
|
|
|
- delete m_instance;
|
|
|
+ m_global = new T(std::forward<TArgs>(args)...);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- static Bool isInitialized()
|
|
|
+ static void freeSingleton()
|
|
|
{
|
|
|
- return m_instance != nullptr;
|
|
|
+ delete m_global;
|
|
|
+ m_global = nullptr;
|
|
|
}
|
|
|
|
|
|
private:
|
|
|
- static Value* m_instance;
|
|
|
+ static T* m_global;
|
|
|
};
|
|
|
|
|
|
template<typename T>
|
|
|
-typename SingletonInit<T>::Value* SingletonInit<T>::m_instance = nullptr;
|
|
|
-
|
|
|
-/// This template makes a class singleton with thread local instance
|
|
|
-template<typename T>
|
|
|
-class SingletonThreadLocal
|
|
|
-{
|
|
|
-public:
|
|
|
- using Value = T;
|
|
|
-
|
|
|
- // Non copyable
|
|
|
- SingletonThreadLocal(const SingletonThreadLocal&) = delete;
|
|
|
- SingletonThreadLocal& operator=(const SingletonThreadLocal&) = delete;
|
|
|
-
|
|
|
- // Non constructable
|
|
|
- SingletonThreadLocal() = delete;
|
|
|
- ~SingletonThreadLocal() = delete;
|
|
|
-
|
|
|
- /// Get instance
|
|
|
- static Value& get()
|
|
|
- {
|
|
|
- return *(m_instance ? m_instance : (m_instance = new Value));
|
|
|
- }
|
|
|
-
|
|
|
- /// Cleanup
|
|
|
- void destroy()
|
|
|
- {
|
|
|
- if(m_instance)
|
|
|
- {
|
|
|
- delete m_instance;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-private:
|
|
|
- static thread_local Value* m_instance;
|
|
|
-};
|
|
|
-
|
|
|
-template<typename T>
|
|
|
-thread_local typename SingletonThreadLocal<T>::Value* SingletonThreadLocal<T>::m_instance = nullptr;
|
|
|
-
|
|
|
-/// This template makes a class with a destructor with arguments singleton
|
|
|
-template<typename T>
|
|
|
-class SingletonThreadsafe
|
|
|
-{
|
|
|
-public:
|
|
|
- using Value = T;
|
|
|
-
|
|
|
- // Non copyable
|
|
|
- SingletonThreadsafe(const SingletonThreadsafe&) = delete;
|
|
|
- SingletonThreadsafe& operator=(const SingletonThreadsafe&) = delete;
|
|
|
-
|
|
|
- // Non constructable
|
|
|
- SingletonThreadsafe() = delete;
|
|
|
- ~SingletonThreadsafe() = delete;
|
|
|
-
|
|
|
- /// Get instance
|
|
|
- static Value& get()
|
|
|
- {
|
|
|
- LockGuard<Mutex> lock(m_mtx);
|
|
|
- return *(m_instance ? m_instance : (m_instance = new Value));
|
|
|
- }
|
|
|
-
|
|
|
- /// Cleanup
|
|
|
- static void destroy()
|
|
|
- {
|
|
|
- LockGuard<Mutex> lock(m_mtx);
|
|
|
- if(m_instance)
|
|
|
- {
|
|
|
- delete m_instance;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-private:
|
|
|
- static Value* m_instance;
|
|
|
- static Mutex m_mtx;
|
|
|
-};
|
|
|
-
|
|
|
-template<typename T>
|
|
|
-typename SingletonThreadsafe<T>::Value* SingletonThreadsafe<T>::m_instance = nullptr;
|
|
|
-
|
|
|
-template<typename T>
|
|
|
-Mutex SingletonThreadsafe<T>::m_mtx;
|
|
|
+T* MakeSingleton<T>::m_global = nullptr;
|
|
|
/// @}
|
|
|
|
|
|
} // end namespace anki
|