LkEngine 0.1.2
 
Loading...
Searching...
No Matches
ObjectPtr.h
1/******************************************************************
2 * TObjectPtr
3 *
4 *******************************************************************/
5#pragma once
6
12#include <unordered_set>
13
16
17#include "ObjectPtrHelpers.h"
18
19namespace LkEngine {
20
31 template<typename T>
32 class TObjectPtr;
33
41 namespace TObjectPtr_Internal
42 {
49 extern std::unordered_set<void*> LiveReferences;
50
57 extern std::mutex LiveReferenceMutex;
58
63 void AddToLiveReferences(void* InObject);
64
69 void RemoveFromLiveReferences(void* InObject);
70
75 bool IsLive(void* InObject);
76
81 int GetLiveReferences(std::unordered_set<void*>& InSet);
82
87 int GetLiveObjects(std::vector<TObjectPtr<LObject>>& ObjectArray, const bool FilterByStaticClass = true);
88 }
100 template<typename T>
102 {
103 public:
104 TObjectPtr(T* Instance = nullptr)
105 : ObjectPtr(Instance)
106 {
107 LK_DEBUG_PTR_LOG("Copy Constructor (T* Instance = nullptr)");
108 static_assert(std::is_base_of<LObject, T>::value, "TObject is only usable on objects that derive from LObject");
109 if (ObjectPtr)
110 {
111 TObjectPtr_IncrementReferenceCount();
112 }
113 }
114
115 TObjectPtr(T& Object)
116 : ObjectPtr(&Object)
117 {
118 LK_DEBUG_PTR_LOG("Copy(T&)");
119 if (ObjectPtr)
120 {
121 TObjectPtr_IncrementReferenceCount();
122 }
123 }
124
125 TObjectPtr(const T& Object)
126 : ObjectPtr(const_cast<std::remove_const_t<T>*>(&Object))
127 {
128 LK_DEBUG_PTR_LOG("Copy(const T&)");
129 if (ObjectPtr)
130 {
131 TObjectPtr_IncrementReferenceCount();
132 }
133 }
134
135 TObjectPtr(const TObjectPtr<T>& Other)
136 : ObjectPtr(Other.ObjectPtr)
137 {
138 LK_DEBUG_PTR_LOG("Copy(TObjectPtr<T>&)");
139 if (ObjectPtr)
140 {
141 TObjectPtr_IncrementReferenceCount();
142 }
143 }
144
145 template<typename R>
146 TObjectPtr(const TObjectPtr<R>& Other)
147 : ObjectPtr((T*)Other.ObjectPtr)
148 {
149 LK_DEBUG_PTR_LOG("Copy(const TObjectPtr<R>&)");
150 if (ObjectPtr)
151 {
152 TObjectPtr_IncrementReferenceCount();
153 }
154 }
155
156 TObjectPtr(TObjectPtr<T>&& Other) noexcept
157 : ObjectPtr(Other.ObjectPtr)
158 {
159 LK_DEBUG_PTR_LOG("Move(TObjectPtr<T>&&)");
160 Other.ObjectPtr = nullptr;
161 }
162
163 template<typename R>
165 : ObjectPtr((T*)Other.ObjectPtr)
166 {
167 LK_DEBUG_PTR_LOG("Move(TObjectPtr<R>&&)");
168 Other.ObjectPtr = nullptr;
169 }
170
172 {
173 LK_DEBUG_PTR_LOG("Destructor");
174 if (ObjectPtr)
175 {
176 TObjectPtr_DecrementReferenceCount();
177 }
178 }
179
180 TObjectPtr& operator=(std::nullptr_t)
181 {
182 LK_DEBUG_PTR_LOG("&operator=(std::nullptr_t)");
183 if (ObjectPtr)
184 {
185 TObjectPtr_DecrementReferenceCount();
186 }
187 ObjectPtr = nullptr;
188
189 return *this;
190 }
191
192 TObjectPtr& operator=(const TObjectPtr<T>& Other)
193 {
194 LK_DEBUG_PTR_LOG("&operator=(const TObjectPtr<T>&)");
195 if (this == &Other)
196 {
197 return *this;
198 }
199
200 if (Other.ObjectPtr)
201 {
202 Other.TObjectPtr_IncrementReferenceCount();
203 }
204 if (ObjectPtr)
205 {
206 TObjectPtr_DecrementReferenceCount();
207 }
208
209 ObjectPtr = Other.ObjectPtr;
210
211 return *this;
212 }
213
214 template<typename R>
215 FORCEINLINE TObjectPtr& operator=(const TObjectPtr<R>& Other)
216 {
217 LK_DEBUG_PTR_LOG("&operator=(const TObjectPtr<R>&)");
218 if (Other.ObjectPtr)
219 {
220 Other.TObjectPtr_IncrementReferenceCount();
221 }
222 if (ObjectPtr)
223 {
224 TObjectPtr_DecrementReferenceCount();
225 }
226
227 ObjectPtr = Other.ObjectPtr;
228
229 return *this;
230 }
231
232 template<typename R>
233 FORCEINLINE TObjectPtr& operator=(TObjectPtr<R>&& Other)
234 {
235 LK_DEBUG_PTR_LOG("&operator=(TObjectPtr<R>&&)");
236 if (ObjectPtr)
237 {
238 TObjectPtr_DecrementReferenceCount();
239 }
240
241 ObjectPtr = Other.ObjectPtr;
242 Other.ObjectPtr = nullptr;
243
244 return *this;
245 }
246
247 FORCEINLINE operator bool() { return ObjectPtr != nullptr; }
248 FORCEINLINE operator bool() const { return ObjectPtr != nullptr; }
249
250 FORCEINLINE bool operator==(std::nullptr_t) const { return (ObjectPtr == nullptr); }
251 FORCEINLINE bool operator==(const T* Other) const { return (Get() == Other); }
252
253 FORCEINLINE T* operator->()
254 {
255 LK_PTR_ASSERT(ObjectPtr, "TObjectPtr::operator-> failed, ObjectPtr is nullptr");
256 return ObjectPtr;
257 }
258
259 FORCEINLINE const T* operator->() const
260 {
261 LK_PTR_ASSERT(ObjectPtr, "TObjectPtr::operator-> failed, ObjectPtr is nullptr");
262 return ObjectPtr;
263 }
264
265 FORCEINLINE T& operator*()
266 {
267 LK_PTR_ASSERT(ObjectPtr, "TObjectPtr::operator* failed, ObjectPtr is nullptr");
268 return *ObjectPtr;
269 }
270
271 FORCEINLINE const T& operator*() const
272 {
273 LK_PTR_ASSERT(ObjectPtr, "TObjectPtr::operator* failed, ObjectPtr is nullptr");
274 return *ObjectPtr;
275 }
276
277 FORCEINLINE T* Get()
278 {
279 LK_PTR_ASSERT(ObjectPtr, "TObjectPtr::Get failed, ObjectPtr is nullptr");
280 return static_cast<T*>(ObjectPtr);
281 }
282
283 FORCEINLINE const T* Get() const
284 {
285 LK_PTR_ASSERT(ObjectPtr, "TObjectPtr::Get failed, ObjectPtr is nullptr");
286 return static_cast<T*>(ObjectPtr);
287 }
288
289 template<typename R>
290 FORCEINLINE TObjectPtr<R> As() const
291 {
292 static_assert(std::disjunction_v<std::is_base_of<T, R>, std::is_base_of<R, T>>, "Cannot cast TObjectPtr to that type");
293 return TObjectPtr<R>(*this);
294 }
295
296 FORCEINLINE void Reset(T* ObjectRef = nullptr)
297 {
298 TObjectPtr_DecrementReferenceCount();
299 ObjectPtr = ObjectRef;
300 }
301
302 FORCEINLINE void Release()
303 {
304 TObjectPtr_DecrementReferenceCount();
305 ObjectPtr = nullptr;
306 }
307
312 template<typename ...TArgs>
313 static TObjectPtr<T> Create(TArgs&&... Args);
314
315 FORCEINLINE bool IsEqual(const TObjectPtr<T>& Other) const
316 {
317 if ((ObjectPtr == nullptr) || (Other.ObjectPtr == nullptr))
318 {
319 return false;
320 }
321
322 return (*ObjectPtr == *Other.ObjectPtr);
323 }
324
325 private:
329 FORCEINLINE void TObjectPtr_IncrementReferenceCount() const
330 {
331 LK_PTR_ASSERT(ObjectPtr, "IncrementReferenceCount failed, invalid ObjectPtr");
332 ((LObject*)ObjectPtr)->IncrementReferenceCount();
334 }
335
339 FORCEINLINE void TObjectPtr_DecrementReferenceCount() const
340 {
341 ((LObject*)ObjectPtr)->DecrementReferenceCount();
342
343 if (((LObject*)ObjectPtr)->GetReferenceCount() == 0)
344 {
346
347 delete ObjectPtr;
348 ObjectPtr = nullptr;
349 }
350 }
351
352 private:
353 mutable T* ObjectPtr;
354
355 template<class R>
356 friend class TObjectPtr;
357 };
358
366 template<typename T>
368 {
369 public:
370 TWeakPtr(T* InObject = nullptr)
371 {
372 ObjectPtr = InObject;
373 }
374
375 TWeakPtr(TObjectPtr<T> InObjectPtr)
376 {
377 ObjectPtr = InObjectPtr.Get();
378 }
379
380 FORCEINLINE T* operator->() { return ObjectPtr; }
381 FORCEINLINE const T* operator->() const { return ObjectPtr; }
382
383 FORCEINLINE T& operator*() { return *ObjectPtr; }
384 FORCEINLINE const T& operator*() const { return *ObjectPtr; }
385
389 FORCEINLINE bool IsValid() const
390 {
391 return ObjectPtr ? TObjectPtr_Internal::IsLive(ObjectPtr) : false;
392 }
393
394 FORCEINLINE operator bool() const { return IsValid(); }
395
396 template<typename R>
397 FORCEINLINE TWeakPtr<R> As() const
398 {
399 return TWeakPtr<R>(dynamic_cast<R*>(ObjectPtr));
400 }
401
402 private:
403 T* ObjectPtr = nullptr;
404 };
405
406 /* TObjectPtr */
407 /* LObject */
408
409}
410
411 /* Core */
412
413#include "ObjectPtr.tpp"
Core macros used by the entire engine.
LObject implementation.
Definition ObjectPtr.h:102
static TObjectPtr< T > Create(TArgs &&... Args)
Create new pointer instance of type T.
Definition ObjectPtr.h:368
FORCEINLINE bool IsValid() const
Check if the pointer holds a valid reference.
Definition ObjectPtr.h:389
bool IsLive(void *InObject)
Check if a LObject instance is alive.
Definition ObjectPtr.cpp:51
int GetLiveObjects(std::vector< TObjectPtr< LObject > > &ObjectArray, const bool FilterByStaticClass=true)
Populare a vector with live objects.
Definition ObjectPtr.cpp:66
std::unordered_set< void * > LiveReferences
Definition ObjectPtr.cpp:9
int GetLiveReferences(std::unordered_set< void * > &InSet)
Populate a set with all live references.
Definition ObjectPtr.cpp:57
void RemoveFromLiveReferences(void *InObject)
Remove a LObject instance from the live references.
Definition ObjectPtr.cpp:29
void AddToLiveReferences(void *InObject)
Add a LObject instance to the live references.
Definition ObjectPtr.cpp:13
std::mutex LiveReferenceMutex
Definition ObjectPtr.cpp:10
Definition Asset.h:11