Plasma Engine  2.0
Loading...
Searching...
No Matches
Singleton.h
1#pragma once
2
3#include <Foundation/Basics.h>
4#include <Foundation/Containers/Map.h>
5#include <Foundation/Strings/String.h>
6
7#include <typeinfo>
8
10
11
19class PL_FOUNDATION_DLL plSingletonRegistry
20{
21public:
23 {
24 plString m_sName;
25 void* m_pInstance = nullptr;
26 };
27
29
31 template <typename Interface>
32 inline static Interface* GetSingletonInstance() // [tested]
33 {
34 return static_cast<Interface*>(s_Singletons.GetValueOrDefault(GetHash<Interface>(), {"", nullptr}).m_pInstance);
35 }
36
38 template <typename Interface>
39 inline static Interface* GetRequiredSingletonInstance() // [tested]
40 {
41 auto value = GetSingletonInstance<Interface>();
42 PL_ASSERT_ALWAYS(value, "No instance of singleton type \"{0}\" has been registered!", typeid(Interface).name());
43 return value;
44 }
45
47 static const plMap<size_t, SingletonEntry>& GetAllRegisteredSingletons();
48
50 template <typename Interface>
51 inline static void Register(Interface* pSingletonInstance) // [tested]
52 {
53 PL_ASSERT_DEV(pSingletonInstance != nullptr, "Invalid singleton instance pointer");
54 PL_ASSERT_DEV(
55 s_Singletons[GetHash<Interface>()].m_pInstance == nullptr, "Singleton for type '{0}' has already been registered", typeid(Interface).name());
56
57 s_Singletons[GetHash<Interface>()] = {typeid(Interface).name(), pSingletonInstance};
58 }
59
61 template <typename Interface>
62 inline static void Unregister() // [tested]
63 {
64 PL_ASSERT_DEV(
65 s_Singletons[GetHash<Interface>()].m_pInstance != nullptr, "Singleton for type '{0}' is currently not registered", typeid(Interface).name());
66
67 s_Singletons.Remove(GetHash<Interface>());
68 }
69
70private:
71 template <typename>
72 friend class plSingletonRegistrar;
73
74 template <typename Interface>
75 inline static size_t GetHash()
76 {
77 static const size_t hash = typeid(Interface).hash_code();
78 return hash;
79 }
80
81 static plMap<size_t, SingletonEntry> s_Singletons;
82};
83
84
99#define PL_DECLARE_SINGLETON(self) \
100public: \
101 PL_ALWAYS_INLINE static self* GetSingleton() \
102 { \
103 return s_pSingleton; \
104 } \
105 \
106private: \
107 PL_DISALLOW_COPY_AND_ASSIGN(self); \
108 void RegisterSingleton() \
109 { \
110 s_pSingleton = this; \
111 plSingletonRegistry::Register<self>(this); \
112 } \
113 static void UnregisterSingleton() \
114 { \
115 if (s_pSingleton) \
116 { \
117 plSingletonRegistry::Unregister<self>(); \
118 s_pSingleton = nullptr; \
119 } \
120 } \
121 friend class plSingletonRegistrar<self>; \
122 plSingletonRegistrar<self> m_SingletonRegistrar; \
123 static self* s_pSingleton
124
139#define PL_DECLARE_SINGLETON_OF_INTERFACE(self, interface) \
140public: \
141 PL_ALWAYS_INLINE static self* GetSingleton() \
142 { \
143 return s_pSingleton; \
144 } \
145 \
146private: \
147 PL_DISALLOW_COPY_AND_ASSIGN(self); \
148 void RegisterSingleton() \
149 { \
150 s_pSingleton = this; \
151 plSingletonRegistry::Register<self>(this); \
152 plSingletonRegistry::Register<interface>(this); \
153 } \
154 static void UnregisterSingleton() \
155 { \
156 if (s_pSingleton) \
157 { \
158 plSingletonRegistry::Unregister<interface>(); \
159 plSingletonRegistry::Unregister<self>(); \
160 s_pSingleton = nullptr; \
161 } \
162 } \
163 friend class plSingletonRegistrar<self>; \
164 plSingletonRegistrar<self> m_SingletonRegistrar; \
165 static self* s_pSingleton
166
167
169#define PL_IMPLEMENT_SINGLETON(self) self* self::s_pSingleton = nullptr
170
171
172
177template <class TYPE>
179{
180public:
181 PL_ALWAYS_INLINE plSingletonRegistrar(TYPE* pType) // [tested]
182 {
183 pType->RegisterSingleton();
184 }
185
186 PL_ALWAYS_INLINE ~plSingletonRegistrar() // [tested]
187 {
188 TYPE::UnregisterSingleton();
189 }
190};
Definition Map.h:408
[internal] Helper class to implement plSingletonRegistry and PL_DECLARE_SINGLETON
Definition Singleton.h:179
plSingletonRegistry knows about all singleton instances of classes that use PL_DECLARE_SINGLETON.
Definition Singleton.h:20
static Interface * GetRequiredSingletonInstance()
Retrieves a singleton instance by type name. Asserts if no singleton instance is available.
Definition Singleton.h:39
static void Unregister()
Unregisters a singleton instance. This is automatically called by plSingletonRegistrar.
Definition Singleton.h:62
static void Register(Interface *pSingletonInstance)
Registers a singleton instance under a given type name. This is automatically called by plSingletonRe...
Definition Singleton.h:51
static Interface * GetSingletonInstance()
Retrieves a singleton instance by type name. Returns nullptr if no singleton instance is available.
Definition Singleton.h:32
Definition Singleton.h:23