KarmaEngine
Game Engine for practical learning and research purposes
Loading...
Searching...
No Matches
UObjectBase.h
Go to the documentation of this file.
1
10
11/*=============================================================================
12 UObjectBase.h: Base class for UObject, defines low level functionality
13=============================================================================*/
14
15#pragma once
16
17#include "Core/UObjectGlobals.h"
18
19namespace Karma
20{
21 class UObject;
22 class UClass;
23
24 class UPackage;
25
27 #define RF_AllFlags (EObjectFlags)0xffffffff
28
36 {
37 protected:
48
58 {
59 KR_CORE_ASSERT((NewFlags & ~RF_AllFlags) == 0, "%s flagged as 0x%x but is trying to set flags to RF_AllFlags");
60 m_ObjectFlags = NewFlags;
61 }
62
63 public:
74 UObjectBase(UClass* inClass, EObjectFlags inFlags, EInternalObjectFlags inInternalFlags, UObject* inOuter, const std::string& inName);
75
82 UPackage* GetPackage() const;
83
88 UPackage* GetExternalPackage() const;
89
96 bool IsUnreachable() const;
97
103 FORCEINLINE void SetInternalIndex(uint32_t StoreIndex) { m_InternalIndex = StoreIndex; }
104
110 FORCEINLINE uint32_t GetInternalIndex() const { return m_InternalIndex; }
111
112 private:
113
120 EObjectFlags m_ObjectFlags;
121
128 uint32_t m_InternalIndex;
129
136 UObject* m_OuterPrivate;
137
139 UClass* m_ClassPrivate;
140
142 std::string m_NamePrivate;
143
145 static bool m_bPendingKillDisabled;
146
147 private:
159 void AddObject(const std::string& name, EInternalObjectFlags inSetInternalFlags);
160
161 public:
168 void MarkAsGarbage();
169
176 void ClearGarbage();
177
183 FORCEINLINE const std::string& GetName() const
184 {
185 return m_NamePrivate;
186 }
187
193 FORCEINLINE void SetObjectName(const std::string& aName)
194 {
195 m_NamePrivate = aName;
196 }
197
207 {
208 return m_OuterPrivate;
209 }
210
219 UObject* GetTypedOuter(UClass* Target) const;
220
229 template<typename T>
230 T* GetTypedOuter() const
231 {
232 return (T*)GetTypedOuter(T::StaticClass());
233 }
234
243 bool IsValidLowLevel() const;
244
252 {
253 //PRAGMA_DISABLE_DEPRECATION_WARNINGS
254 if (!(int32_t(InFlags) & (int32_t(EInternalObjectFlags::Garbage) | int32_t(EInternalObjectFlags::PendingKill))))
255 {
256 // Pass through
257 return InFlags;
258 }
259 else
260 {
261 return m_bPendingKillDisabled ?
262 EInternalObjectFlags(((int32_t(InFlags) & ~int32_t(EInternalObjectFlags::PendingKill)) | int32_t(EInternalObjectFlags::Garbage))) : // Replace PK with Garbage
263 EInternalObjectFlags(((int32_t(InFlags) & ~int32_t(EInternalObjectFlags::Garbage)) | int32_t(EInternalObjectFlags::PendingKill))); // Replace Garbage with PK
264 }
265 //PRAGMA_ENABLE_DEPRECATION_WARNINGS
266 }
267
268 public:
277 template <typename OtherClassType>
278 FORCEINLINE bool IsA(OtherClassType SomeBase) const
279 {
280 // Atm we don't have the cyclic dependency therefore we have forward declared
281 // UClass. Maybe we will have some dependency in future, then
282 // when we have a cyclic dependency between UObjectBase and UClass,
283 // we use a template to allow inlining of something we haven't yet seen, because it delays compilation until the function is called.
284
285 // 'static_assert' that this thing is actually a UClass pointer or convertible to it.
286 const UClass* SomeBaseClass = SomeBase;
287
288 KR_CORE_ASSERT(SomeBaseClass, "IsA(NULL) cannot yield meaningful results");
289
290 const UClass* ThisClass = GetClass();
291
292 // Stop the compiler doing some unnecessary branching for nullptr checks
293 // Would be interesting to write the analog of this
294 KR_CORE_ASSERT(ThisClass, "Couldn't find UClass of {0}. Comparing with null is useless", this->GetName());
295
296 return IsChildOfWorkaround(ThisClass, SomeBaseClass);
297 }
298
305 {
306 return m_ClassPrivate;
307 }
308
309 /*-------------------
310 Flags
311 -------------------*/
312
320 {
321 KR_CORE_ASSERT((m_ObjectFlags & ~RF_AllFlags) == 0, "{0} flagged as RF_ALLFlags", GetName());
322 return m_ObjectFlags;
323 }
324
334 {
335 KR_CORE_ASSERT(!(NewFlags & (RF_MarkAsNative | RF_MarkAsRootSet | RF_PendingKill | RF_Garbage)), "These flags can't be used outside of constructors / internal code");
336 KR_CORE_ASSERT(!(NewFlags & (EObjectFlags)(RF_PendingKill | RF_Garbage)) || (GetFlags() & (NewFlags & (EObjectFlags)(RF_PendingKill | RF_Garbage))) == (NewFlags & (EObjectFlags)(RF_PendingKill | RF_Garbage)), "RF_PendingKill and RF_garbage can not be set through SetFlags function. Use MarkAsGarbage() instead");
337
338 SetFlagsTo(EObjectFlags (GetFlags() | NewFlags));
339 }
340
348 {
349 KR_CORE_ASSERT(!(FlagsToClear & (RF_MarkAsNative | RF_MarkAsRootSet | RF_PendingKill | RF_Garbage)) || FlagsToClear == RF_AllFlags, "These flags can't be used outside of constructors / internal code");
350 KR_CORE_ASSERT(!(FlagsToClear & (EObjectFlags)(RF_PendingKill | RF_Garbage)) || (GetFlags() & (FlagsToClear & (EObjectFlags)(RF_PendingKill | RF_Garbage))) == RF_NoFlags, "RF_PendingKill and RF_garbage can not be cleared through ClearFlags function. Use ClearGarbage() instead");
351
352 SetFlagsTo(EObjectFlags (GetFlags() & ~FlagsToClear));
353 }
354
363 FORCEINLINE bool HasAnyFlags(EObjectFlags FlagsToCheck) const
364 {
365 KR_CORE_ASSERT(!(FlagsToCheck & (RF_MarkAsNative | RF_MarkAsRootSet)) || FlagsToCheck == RF_AllFlags, "Illegal flags being used"); // These flags can't be used outside of constructors / internal code
366 return (GetFlags() & FlagsToCheck) != 0;
367 }
368
378 {
379 return GUObjectStore.IndexToObject(m_InternalIndex)->HasAnyFlags(FlagsToCheck);
380 }
381
389 {
390 FUObjectItem* ObjectItem = GUObjectStore.IndexToObject(m_InternalIndex);
391 KR_CORE_ASSERT(!(int32_t(FlagsToSet) & (int32_t(EInternalObjectFlags::PendingKill) | int32_t(EInternalObjectFlags::Garbage))) || (int32_t(FlagsToSet) & (int32_t(EInternalObjectFlags::PendingKill) | int32_t(EInternalObjectFlags::Garbage))) == (int32_t(ObjectItem->GetFlags()) & (int32_t(EInternalObjectFlags::PendingKill) | int32_t(EInternalObjectFlags::Garbage))), "");
392
393 ObjectItem->SetFlags(FlagsToSet);
394 }
395
403 {
404 // Need to understand the logic of GC first
405 //GUObjectStore.IndexToObject(InternalIndex)->SetRootSet();
406 }
407
408 /*-------------------
409 Class
410 -------------------*/
411
412 private:
413
422 static bool IsChildOfWorkaround(const UClass* ObjClass, const UClass* TestClass);
423 };
424}
#define KARMA_API
Defining Karma's API macro for storage class information.
Definition Core.h:41
#define FORCEINLINE
Typical inlining macro for clarity.
Definition Core.h:157
#define RF_AllFlags
All flags, used mainly for error checking.
Definition UObjectBase.h:27
This file contains some commonly used game code macros.
EObjectFlags
Flags describing an object instance.
Definition UObjectGlobals.h:183
@ RF_MarkAsNative
Object (UField) will be marked as native on construction (DO NOT USE THIS FLAG in HasAnyFlags() etc)
Definition UObjectGlobals.h:192
@ RF_MarkAsRootSet
Object will be marked as root set on construction and not be garbage collected, even if unreferenced ...
Definition UObjectGlobals.h:199
@ RF_PendingKill
Objects that are pending destruction (invalid for gameplay but valid objects). This flag is mirrored ...
Definition UObjectGlobals.h:231
@ RF_Garbage
Garbage from logical point of view and should not be referenced. This flag is mirrored in EInternalOb...
Definition UObjectGlobals.h:232
@ RF_NoFlags
No flags, used to avoid a cast.
Definition UObjectGlobals.h:186
EInternalObjectFlags
Objects flags for internal use (GC, low level UObject code)
Definition UObjectGlobals.h:243
@ PendingKill
Objects that are pending destruction (invalid for gameplay but valid objects). This flag is mirrored ...
Definition UObjectGlobals.h:255
@ Garbage
Garbage from logical point of view and should not be referenced. This flag is mirrored in EObjectFlag...
Definition UObjectGlobals.h:247
An object class.
Definition Class.h:158
Low level implementation of UObject, should not be used directly in game code.
Definition UObjectBase.h:36
FORCEINLINE void SetObjectName(const std::string &aName)
Definition UObjectBase.h:193
FORCEINLINE void SetFlagsTo(EObjectFlags NewFlags)
Definition UObjectBase.h:57
FORCEINLINE const std::string & GetName() const
Definition UObjectBase.h:183
static FORCEINLINE EInternalObjectFlags FixGarbageOrPendingKillInternalObjectFlags(const EInternalObjectFlags InFlags)
Definition UObjectBase.h:251
FORCEINLINE UObject * GetOuter() const
Definition UObjectBase.h:206
FORCEINLINE void ClearFlags(EObjectFlags FlagsToClear)
Definition UObjectBase.h:347
T * GetTypedOuter() const
Definition UObjectBase.h:230
FORCEINLINE UClass * GetClass() const
Definition UObjectBase.h:304
UObject * GetTypedOuter(UClass *Target) const
Definition UObjectBase.cpp:124
FORCEINLINE uint32_t GetInternalIndex() const
Definition UObjectBase.h:110
FORCEINLINE bool HasAnyFlags(EObjectFlags FlagsToCheck) const
Definition UObjectBase.h:363
FORCEINLINE void SetInternalIndex(uint32_t StoreIndex)
Definition UObjectBase.h:103
FORCEINLINE void SetFlags(EObjectFlags NewFlags)
Definition UObjectBase.h:333
FORCEINLINE void SetInternalFlags(EInternalObjectFlags FlagsToSet) const
Definition UObjectBase.h:388
FORCEINLINE EObjectFlags GetFlags() const
Definition UObjectBase.h:319
FORCEINLINE bool IsA(OtherClassType SomeBase) const
Definition UObjectBase.h:278
UObjectBase()
Providing a default constructor.
Definition UObjectBase.cpp:15
FORCEINLINE void AddToRoot()
Definition UObjectBase.h:402
FORCEINLINE bool HasAnyInternalFlags(EInternalObjectFlags FlagsToCheck) const
Definition UObjectBase.h:377
The base class of all the game code relevant objects.
Definition Object.h:106
A generic outer for UObjects, for instance UWorld.
Definition Package.h:23
Single item in UObjectStore.
Definition UObjectGlobals.h:270
FORCEINLINE void SetFlags(EInternalObjectFlags FlagsToSet)
Set the internal flags.
Definition UObjectGlobals.h:307
FORCEINLINE EInternalObjectFlags GetFlags() const
Getter for internal flags.
Definition UObjectGlobals.h:320