Ark Server API (ASA) - Wiki
Loading...
Searching...
No Matches
WeakObjectPtrTemplates.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreTypes.h"
6#include "Templates/IsPointer.h"
7#include "Templates/PointerIsConvertibleFromTo.h"
8#include "Templates/AndOrNot.h"
9#include "Templates/LosesQualifiersFromTo.h"
10#include "Containers/Map.h"
11
12#include <type_traits>
13
14/**
15 * FWeakObjectPtr is a weak pointer to a UObject.
16 * It can return nullptr later if the object is garbage collected.
17 * It has no impact on if the object is garbage collected or not.
18 * It can't be directly used across a network.
19 *
20 * Most often it is used when you explicitly do NOT want to prevent something from being garbage collected.
21 */
22struct FWeakObjectPtr;
23
24template<class T=UObject, class TWeakObjectPtrBase=FWeakObjectPtr>
25struct TWeakObjectPtr;
26
27/**
28 * TWeakObjectPtr is the templated version of the generic FWeakObjectPtr
29 */
30template<class T, class TWeakObjectPtrBase>
31struct TWeakObjectPtr : private TWeakObjectPtrBase
32{
33 friend struct FFieldPath;
34
35 // Although templated, these parameters are not intended to be anything other than the default,
36 // and are only templates for module organization reasons.
37 static_assert(std::is_same_v<TWeakObjectPtrBase, FWeakObjectPtr>, "TWeakObjectPtrBase should not be overridden");
38
39public:
40 using ElementType = T;
41
42 TWeakObjectPtr() = default;
43 TWeakObjectPtr(const TWeakObjectPtr&) = default;
44 TWeakObjectPtr& operator=(const TWeakObjectPtr&) = default;
45 ~TWeakObjectPtr() = default;
46
47 /**
48 * Construct from a null pointer
49 */
50 FORCEINLINE TWeakObjectPtr(TYPE_OF_NULLPTR) :
51 TWeakObjectPtrBase((UObject*)nullptr)
52 {
53 }
54
55 /**
56 * Construct from an object pointer
57 * @param Object object to create a weak pointer to
58 */
59 template <
60 typename U,
61 decltype(ImplicitConv<T*>(std::declval<U>()))* = nullptr
62 >
64 TWeakObjectPtrBase((const UObject*)Object)
65 {
66 // This static assert is in here rather than in the body of the class because we want
67 // to be able to define TWeakObjectPtr<UUndefinedClass>.
68 static_assert(TPointerIsConvertibleFromTo<T, const volatile UObject>::Value, "TWeakObjectPtr can only be constructed with UObject types");
69 }
70
71 /**
72 * Construct from another weak pointer of another type, intended for derived-to-base conversions
73 * @param Other weak pointer to copy from
74 */
75 template <
76 typename OtherT,
77 typename = decltype(ImplicitConv<T*>((OtherT*)nullptr))
78 >
79 FORCEINLINE TWeakObjectPtr(const TWeakObjectPtr<OtherT, TWeakObjectPtrBase>& Other) :
80 TWeakObjectPtrBase(*(TWeakObjectPtrBase*)&Other) // we do a C-style cast to private base here to avoid clang 3.6.0 compilation problems with friend declarations
81 {
82 }
83
84 /**
85 * Reset the weak pointer back to the null state
86 */
88 {
89 TWeakObjectPtrBase::Reset();
90 }
91
92 /**
93 * Copy from an object pointer
94 * @param Object object to create a weak pointer to
95 */
96 template<class U>
97 FORCEINLINE typename TEnableIf<!TLosesQualifiersFromTo<U, T>::Value, TWeakObjectPtr&>::Type operator=(U* Object)
98 {
99 T* TempObject = Object;
100 TWeakObjectPtrBase::operator=(TempObject);
101 return *this;
102 }
103
104 /**
105 * Assign from another weak pointer, intended for derived-to-base conversions
106 * @param Other weak pointer to copy from
107 */
108 template <
109 typename OtherT,
110 typename = decltype(ImplicitConv<T*>((OtherT*)nullptr))
111 >
112 FORCEINLINE TWeakObjectPtr& operator=(const TWeakObjectPtr<OtherT, TWeakObjectPtrBase>& Other)
113 {
114 *(TWeakObjectPtrBase*)this = *(TWeakObjectPtrBase*)&Other; // we do a C-style cast to private base here to avoid clang 3.6.0 compilation problems with friend declarations
115
116 return *this;
117 }
118
119 /**
120 * Dereference the weak pointer
121 * @param bEvenIfPendingKill if this is true, pendingkill objects are considered valid
122 * @return nullptr if this object is gone or the weak pointer is explicitly null, otherwise a valid uobject pointer
123 */
124 FORCEINLINE T* Get(bool bEvenIfPendingKill) const
125 {
126 return (T*)TWeakObjectPtrBase::Get(bEvenIfPendingKill);
127 }
128
129 /**
130 * Dereference the weak pointer. This is an optimized version implying bEvenIfPendingKill=false.
131 */
132 FORCEINLINE T* Get(/*bool bEvenIfPendingKill = false*/) const
133 {
134 return (T*)TWeakObjectPtrBase::Get();
135 }
136
137 /** Deferences the weak pointer even if its marked RF_Unreachable. This is needed to resolve weak pointers during GC (such as ::AddReferenceObjects) */
139 {
140 return (T*)TWeakObjectPtrBase::GetEvenIfUnreachable();
141 }
142
143 /**
144 * Dereference the weak pointer
145 */
147 {
148 return *Get();
149 }
150
151 /**
152 * Dereference the weak pointer
153 */
155 {
156 return Get();
157 }
158
159 // This is explicitly not added to avoid resolving weak pointers too often - use Get() once in a function.
160 explicit operator bool() const = delete;
161
162 /**
163 * Test if this points to a live UObject.
164 * This should be done only when needed as excess resolution of the underlying pointer can cause performance issues.
165 *
166 * @param bEvenIfPendingKill if this is true, pendingkill objects are considered valid
167 * @param bThreadsafeTest if true then function will just give you information whether referenced
168 * UObject is gone forever (return false) or if it is still there (return true, no object flags checked).
169 * This is required as without it IsValid can return false during the mark phase of the GC
170 * due to the presence of the Unreachable flag.
171 * @return true if Get() would return a valid non-null pointer
172 */
173 FORCEINLINE bool IsValid(bool bEvenIfPendingKill, bool bThreadsafeTest = false) const
174 {
175 return TWeakObjectPtrBase::IsValid(bEvenIfPendingKill, bThreadsafeTest);
176 }
177
178 /**
179 * Test if this points to a live UObject. This is an optimized version implying bEvenIfPendingKill=false, bThreadsafeTest=false.
180 * This should be done only when needed as excess resolution of the underlying pointer can cause performance issues.
181 * Note that IsValid can not be used on another thread as it will incorrectly return false during the mark phase of the GC
182 * due to the Unreachable flag being set. (see bThreadsafeTest above)
183 * @return true if Get() would return a valid non-null pointer
184 */
185 FORCEINLINE bool IsValid(/*bool bEvenIfPendingKill = false, bool bThreadsafeTest = false*/) const
186 {
187 return TWeakObjectPtrBase::IsValid();
188 }
189
190 /**
191 * Slightly different than !IsValid(), returns true if this used to point to a UObject, but doesn't any more and has not been assigned or reset in the mean time.
192 * @param bIncludingIfPendingKill if this is true, pendingkill objects are considered stale
193 * @param bThreadsafeTest set it to true when testing outside of Game Thread. Results in false if WeakObjPtr point to an existing object (no flags checked)
194 * @return true if this used to point at a real object but no longer does.
195 */
196 FORCEINLINE bool IsStale(bool bIncludingIfPendingKill = true, bool bThreadsafeTest = false) const
197 {
198 return TWeakObjectPtrBase::IsStale(bIncludingIfPendingKill, bThreadsafeTest);
199 }
200
201 /**
202 * Returns true if this pointer was explicitly assigned to null, was reset, or was never initialized.
203 * If this returns true, IsValid() and IsStale() will both return false.
204 */
206 {
207 return TWeakObjectPtrBase::IsExplicitlyNull();
208 }
209
210 /**
211 * Returns true if two weak pointers were originally set to the same object, even if they are now stale
212 * @param Other weak pointer to compare to
213 */
214 FORCEINLINE bool HasSameIndexAndSerialNumber(const TWeakObjectPtr& Other) const
215 {
216 return static_cast<const TWeakObjectPtrBase&>(*this).HasSameIndexAndSerialNumber(static_cast<const TWeakObjectPtrBase&>(Other));
217 }
218
219 /**
220 * Weak object pointer serialization, this forwards to FArchive::operator<<(struct FWeakObjectPtr&) or an override
221 */
223 {
224 Ar << static_cast<TWeakObjectPtrBase&>(*this);
225 }
226
227 /** Hash function. */
229 {
230 return static_cast<const TWeakObjectPtrBase&>(*this).GetTypeHash();
231 }
232
233 /**
234 * Compare weak pointers for equality.
235 * If both pointers would return nullptr from Get() they count as equal even if they were not initialized to the same object.
236 * @param Other weak pointer to compare to
237 */
238 template <typename RhsT, typename = decltype((T*)nullptr == (RhsT*)nullptr)>
239 FORCENOINLINE bool operator==(const TWeakObjectPtr<RhsT, TWeakObjectPtrBase>& Rhs) const
240 {
241 return (const TWeakObjectPtrBase&)*this == (const TWeakObjectPtrBase&)Rhs;
242 }
243
244 template <typename RhsT, typename = decltype((T*)nullptr == (RhsT*)nullptr)>
245 FORCENOINLINE bool operator==(const RhsT* Rhs) const
246 {
247 // NOTE: this constructs a TWeakObjectPtrBase, which has some amount of overhead, so this may not be an efficient operation
248 return (const TWeakObjectPtrBase&)*this == TWeakObjectPtrBase(Rhs);
249 }
250
251 FORCENOINLINE bool operator==(TYPE_OF_NULLPTR) const
252 {
253 return !IsValid();
254 }
255
257 /**
258 * Compare weak pointers for inequality
259 * @param Other weak pointer to compare to
260 */
261 template <typename RhsT, typename = decltype((T*)nullptr != (RhsT*)nullptr)>
262 FORCENOINLINE bool operator!=(const TWeakObjectPtr<RhsT, TWeakObjectPtrBase>& Rhs) const
263 {
264 return (const TWeakObjectPtrBase&)*this != (const TWeakObjectPtrBase&)Rhs;
265 }
266
267 template <typename RhsT, typename = decltype((T*)nullptr != (RhsT*)nullptr)>
268 FORCENOINLINE bool operator!=(const RhsT* Rhs) const
269 {
270 // NOTE: this constructs a TWeakObjectPtrBase, which has some amount of overhead, so this may not be an efficient operation
271 return (const TWeakObjectPtrBase&)*this != TWeakObjectPtrBase(Rhs);
272 }
273
274 FORCENOINLINE bool operator!=(TYPE_OF_NULLPTR) const
275 {
276 return IsValid();
277 }
278#endif
279};
280
282/**
283 * Compare weak pointers for equality.
284 * If both pointers would return nullptr from Get() they count as equal even if they were not initialized to the same object.
285 * @param Other weak pointer to compare to
286 */
287template <typename LhsT, typename RhsT, typename OtherTWeakObjectPtrBase, typename = decltype((LhsT*)nullptr == (RhsT*)nullptr)>
288FORCENOINLINE bool operator==(const LhsT* Lhs, const TWeakObjectPtr<RhsT, OtherTWeakObjectPtrBase>& Rhs)
289{
290 // NOTE: this constructs a TWeakObjectPtrBase, which has some amount of overhead, so this may not be an efficient operation
291 return OtherTWeakObjectPtrBase(Lhs) == (const OtherTWeakObjectPtrBase&)Rhs;
292}
293template <typename RhsT, typename OtherTWeakObjectPtrBase>
294FORCENOINLINE bool operator==(TYPE_OF_NULLPTR, const TWeakObjectPtr<RhsT, OtherTWeakObjectPtrBase>& Rhs)
295{
296 return !Rhs.IsValid();
297}
298
299/**
300 * Compare weak pointers for inequality
301 * @param Other weak pointer to compare to
302 */
303template <typename LhsT, typename RhsT, typename OtherTWeakObjectPtrBase, typename = decltype((LhsT*)nullptr != (RhsT*)nullptr)>
304FORCENOINLINE bool operator!=(const LhsT* Lhs, const TWeakObjectPtr<RhsT, OtherTWeakObjectPtrBase>& Rhs)
305{
306 // NOTE: this constructs a TWeakObjectPtrBase, which has some amount of overhead, so this may not be an efficient operation
307 return OtherTWeakObjectPtrBase(Lhs) != (const OtherTWeakObjectPtrBase&)Rhs;
308}
309template <typename RhsT, typename OtherTWeakObjectPtrBase>
310FORCENOINLINE bool operator!=(TYPE_OF_NULLPTR, const TWeakObjectPtr<RhsT, OtherTWeakObjectPtrBase>& Rhs)
311{
312 return Rhs.IsValid();
313}
314#endif
315
316// Helper function which deduces the type of the initializer
317template <typename T>
319{
320 return TWeakObjectPtr<T>(Ptr);
321}
322
323template<class T> struct TIsPODType<TWeakObjectPtr<T> > { enum { Value = true }; };
324template<class T> struct TIsZeroConstructType<TWeakObjectPtr<T> > { enum { Value = true }; };
325template<class T> struct TIsWeakPointerType<TWeakObjectPtr<T> > { enum { Value = true }; };
326
327
328/**
329 * SetKeyFuncs for TWeakObjectPtrs which allow the key to become stale without invalidating the set.
330 */
331template <typename ElementType, bool bInAllowDuplicateKeys = false>
332struct TWeakObjectPtrSetKeyFuncs : DefaultKeyFuncs<ElementType, bInAllowDuplicateKeys>
333{
334 typedef typename DefaultKeyFuncs<ElementType, bInAllowDuplicateKeys>::KeyInitType KeyInitType;
335
337 {
339 }
340
342 {
343 return GetTypeHash(Key);
344 }
345};
346
347/**
348 * MapKeyFuncs for TWeakObjectPtrs which allow the key to become stale without invalidating the map.
349 */
350template <typename KeyType, typename ValueType, bool bInAllowDuplicateKeys = false>
351struct TWeakObjectPtrMapKeyFuncs : public TDefaultMapKeyFuncs<KeyType, ValueType, bInAllowDuplicateKeys>
352{
353 typedef typename TDefaultMapKeyFuncs<KeyType, ValueType, bInAllowDuplicateKeys>::KeyInitType KeyInitType;
354
356 {
358 }
359
361 {
362 return GetTypeHash(Key);
363 }
364};
365
366/**
367 * Automatic version of the weak object pointer
368 */
369template<class T>
371{
372public:
373 /** NULL constructor **/
374 UE_DEPRECATED(4.15, "TAutoWeakObjectPtr has been deprecated - use TWeakObjectPtr instead")
376 {
377 }
378 /** Construct from a raw pointer **/
379 UE_DEPRECATED(4.15, "TAutoWeakObjectPtr has been deprecated - use TWeakObjectPtr instead")
382 {
383 }
384 /** Construct from the base type **/
385 UE_DEPRECATED(4.15, "TAutoWeakObjectPtr has been deprecated - use TWeakObjectPtr instead")
386 FORCEINLINE TAutoWeakObjectPtr(const TWeakObjectPtr<T>& Other)
388 {
389 }
390 UE_DEPRECATED(4.15, "Implicit conversion from TAutoWeakObjectPtr to the pointer type has been deprecated - use Get() instead")
392 {
393 return this->Get();
394 }
395 UE_DEPRECATED(4.15, "Implicit conversion from TAutoWeakObjectPtr to the pointer type has been deprecated - use Get() instead")
396 FORCEINLINE operator const T* () const
397 {
398 return (const T*)this->Get();
399 }
400
401 UE_DEPRECATED(4.15, "Implicit conversion from TAutoWeakObjectPtr to the pointer type has been deprecated - use Get() instead")
402 FORCEINLINE explicit operator bool() const
403 {
404 return this->Get() != nullptr;
405 }
406};
407
408template<class T> struct TIsPODType<TAutoWeakObjectPtr<T> > { enum { Value = true }; };
409template<class T> struct TIsZeroConstructType<TAutoWeakObjectPtr<T> > { enum { Value = true }; };
410template<class T> struct TIsWeakPointerType<TAutoWeakObjectPtr<T> > { enum { Value = true }; };
411
412/** Utility function to fill in a TArray<ClassName*> from a TArray<TWeakObjectPtr<ClassName>> */
413template<typename DestArrayType, typename SourceArrayType>
414void CopyFromWeakArray(DestArrayType& Dest, const SourceArrayType& Src)
415{
416 Dest.Empty(Src.Num());
417 for (int32 Index = 0; Index < Src.Num(); Index++)
418 {
419 if (auto Value = Src[Index].Get())
420 {
421 Dest.Add(Value);
422 }
423 }
424}
425
426/** Hash function. */
427template <typename T>
428FORCEINLINE uint32 GetTypeHash(const TWeakObjectPtr<T>& WeakObjectPtr)
429{
430 return WeakObjectPtr.GetWeakPtrTypeHash();
431}
432
433
434/**
435* Weak object pointer serialization, this forwards to FArchive::operator<<(struct FWeakObjectPtr&) or an override
436*/
437template<class T, class TWeakObjectPtrBase>
438FArchive& operator<<( FArchive& Ar, TWeakObjectPtr<T, TWeakObjectPtrBase>& WeakObjectPtr )
439{
440 WeakObjectPtr.Serialize(Ar);
441 return Ar;
442}
#define UE_DEPRECATED(Version, Message)
#define FORCENOINLINE
Definition Platform.h:647
#define FORCEINLINE
Definition Platform.h:644
#define PLATFORM_COMPILER_HAS_GENERATED_COMPARISON_OPERATORS
Definition Platform.h:250
FORCEINLINE uint32 GetTypeHash(const TWeakObjectPtr< T > &WeakObjectPtr)
FORCENOINLINE bool operator!=(const LhsT *Lhs, const TWeakObjectPtr< RhsT, OtherTWeakObjectPtrBase > &Rhs)
FORCENOINLINE bool operator!=(TYPE_OF_NULLPTR, const TWeakObjectPtr< RhsT, OtherTWeakObjectPtrBase > &Rhs)
FORCENOINLINE bool operator==(const LhsT *Lhs, const TWeakObjectPtr< RhsT, OtherTWeakObjectPtrBase > &Rhs)
void CopyFromWeakArray(DestArrayType &Dest, const SourceArrayType &Src)
FORCENOINLINE bool operator==(TYPE_OF_NULLPTR, const TWeakObjectPtr< RhsT, OtherTWeakObjectPtrBase > &Rhs)
FORCEINLINE TWeakObjectPtr< T > MakeWeakObjectPtr(T *Ptr)
FORCEINLINE TAutoWeakObjectPtr(const TWeakObjectPtr< T > &Other)
FORCEINLINE operator T*() const
FORCEINLINE operator const T *() const
FORCEINLINE operator bool() const
FORCEINLINE TAutoWeakObjectPtr(const T *Target)
Definition json.hpp:4518
FORCENOINLINE bool operator!=(const TWeakObjectPtr< RhsT, TWeakObjectPtrBase > &Rhs) const
FORCENOINLINE bool operator==(const RhsT *Rhs) const
FORCEINLINE bool IsValid(bool bEvenIfPendingKill, bool bThreadsafeTest=false) const
FORCEINLINE T * operator->() const
~TWeakObjectPtr()=default
FORCEINLINE void Serialize(FArchive &Ar)
FORCEINLINE T & operator*() const
FORCEINLINE uint32 GetWeakPtrTypeHash() const
TWeakObjectPtr(const TWeakObjectPtr &)=default
FORCEINLINE void Reset()
FORCEINLINE T * Get() const
FORCENOINLINE bool operator==(const TWeakObjectPtr< RhsT, TWeakObjectPtrBase > &Rhs) const
FORCEINLINE TWeakObjectPtr(TYPE_OF_NULLPTR)
FORCEINLINE TEnableIf<!TLosesQualifiersFromTo< U, T >::Value, TWeakObjectPtr & >::Type operator=(U *Object)
FORCEINLINE bool IsValid() const
FORCEINLINE bool IsStale(bool bIncludingIfPendingKill=true, bool bThreadsafeTest=false) const
FORCENOINLINE bool operator==(TYPE_OF_NULLPTR) const
FORCEINLINE TWeakObjectPtr(U Object)
TWeakObjectPtr()=default
TWeakObjectPtr & operator=(const TWeakObjectPtr &)=default
FORCENOINLINE bool operator!=(const RhsT *Rhs) const
FORCEINLINE T * Get(bool bEvenIfPendingKill) const
operator bool() const =delete
FORCEINLINE TWeakObjectPtr(const TWeakObjectPtr< OtherT, TWeakObjectPtrBase > &Other)
FORCEINLINE T * GetEvenIfUnreachable() const
FORCEINLINE bool IsExplicitlyNull() const
FORCEINLINE bool HasSameIndexAndSerialNumber(const TWeakObjectPtr &Other) const
FORCEINLINE TWeakObjectPtr & operator=(const TWeakObjectPtr< OtherT, TWeakObjectPtrBase > &Other)
FORCENOINLINE bool operator!=(TYPE_OF_NULLPTR) const
static FORCEINLINE uint32 GetKeyHash(KeyInitType Key)
TDefaultMapKeyFuncs< KeyType, ValueType, bInAllowDuplicateKeys >::KeyInitType KeyInitType
static FORCEINLINE bool Matches(KeyInitType A, KeyInitType B)
static FORCEINLINE uint32 GetKeyHash(KeyInitType Key)
static FORCEINLINE bool Matches(KeyInitType A, KeyInitType B)
DefaultKeyFuncs< ElementType, bInAllowDuplicateKeys >::KeyInitType KeyInitType
Definition UE.h:432