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
76 ~UObjectBase() {};
77
84 virtual void ShivaUObject() { this->~UObjectBase(); }
85
92 UPackage* GetPackage() const;
93
98 UPackage* GetExternalPackage() const;
99
106 bool IsUnreachable() const;
107
113 FORCEINLINE void SetInternalIndex(uint32_t StoreIndex) { m_InternalIndex = StoreIndex; }
114
120 FORCEINLINE uint32_t GetInternalIndex() const { return m_InternalIndex; }
121
122 private:
123
130 EObjectFlags m_ObjectFlags;
131
138 uint32_t m_InternalIndex;
139
146 UObject* m_OuterPrivate;
147
149 UClass* m_ClassPrivate;
150
152 std::string m_NamePrivate;
153
155 static bool m_bPendingKillDisabled;
156
157 private:
169 void AddObject(const std::string& name, EInternalObjectFlags inSetInternalFlags);
170
171 public:
178 void MarkAsGarbage();
179
186 void ClearGarbage();
187
193 FORCEINLINE const std::string& GetName() const
194 {
195 return m_NamePrivate;
196 }
197
203 FORCEINLINE void SetObjectName(const std::string& aName)
204 {
205 m_NamePrivate = aName;
206 }
207
217 {
218 return m_OuterPrivate;
219 }
220
229 UObject* GetTypedOuter(UClass* Target) const;
230
239 template<typename T>
240 T* GetTypedOuter() const
241 {
242 return (T*)GetTypedOuter(T::StaticClass());
243 }
244
253 bool IsValidLowLevel() const;
254
262 {
263 //PRAGMA_DISABLE_DEPRECATION_WARNINGS
264 if (!(int32_t(InFlags) & (int32_t(EInternalObjectFlags::Garbage) | int32_t(EInternalObjectFlags::PendingKill))))
265 {
266 // Pass through
267 return InFlags;
268 }
269 else
270 {
271 return m_bPendingKillDisabled ?
272 EInternalObjectFlags(((int32_t(InFlags) & ~int32_t(EInternalObjectFlags::PendingKill)) | int32_t(EInternalObjectFlags::Garbage))) : // Replace PK with Garbage
273 EInternalObjectFlags(((int32_t(InFlags) & ~int32_t(EInternalObjectFlags::Garbage)) | int32_t(EInternalObjectFlags::PendingKill))); // Replace Garbage with PK
274 }
275 //PRAGMA_ENABLE_DEPRECATION_WARNINGS
276 }
277
278 public:
287 template <typename OtherClassType>
288 FORCEINLINE bool IsA(OtherClassType SomeBase) const
289 {
290 // Atm we don't have the cyclic dependency therefore we have forward declared
291 // UClass. Maybe we will have some dependency in future, then
292 // when we have a cyclic dependency between UObjectBase and UClass,
293 // we use a template to allow inlining of something we haven't yet seen, because it delays compilation until the function is called.
294
295 // 'static_assert' that this thing is actually a UClass pointer or convertible to it.
296 const UClass* SomeBaseClass = SomeBase;
297
298 KR_CORE_ASSERT(SomeBaseClass, "IsA(NULL) cannot yield meaningful results");
299
300 const UClass* ThisClass = GetClass();
301
302 // Stop the compiler doing some unnecessary branching for nullptr checks
303 // Would be interesting to write the analog of this
304 KR_CORE_ASSERT(ThisClass, "Couldn't find UClass of {0}. Comparing with null is useless", this->GetName());
305
306 return IsChildOfWorkaround(ThisClass, SomeBaseClass);
307 }
308
315 {
316 return m_ClassPrivate;
317 }
318
319 /*-------------------
320 Flags
321 -------------------*/
322
330 {
331 KR_CORE_ASSERT((m_ObjectFlags & ~RF_AllFlags) == 0, "{0} flagged as RF_ALLFlags", GetName());
332 return m_ObjectFlags;
333 }
334
344 {
345 KR_CORE_ASSERT(!(NewFlags & (RF_MarkAsNative | RF_MarkAsRootSet | RF_PendingKill | RF_Garbage)), "These flags can't be used outside of constructors / internal code");
346 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");
347
348 SetFlagsTo(EObjectFlags (GetFlags() | NewFlags));
349 }
350
358 {
359 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");
360 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");
361
362 SetFlagsTo(EObjectFlags (GetFlags() & ~FlagsToClear));
363 }
364
373 FORCEINLINE bool HasAnyFlags(EObjectFlags FlagsToCheck) const
374 {
375 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
376 return (GetFlags() & FlagsToCheck) != 0;
377 }
378
388 {
389 return GUObjectStore.IndexToObject(m_InternalIndex)->HasAnyFlags(FlagsToCheck);
390 }
391
399 {
400 FUObjectItem* ObjectItem = GUObjectStore.IndexToObject(m_InternalIndex);
401 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))), "");
402
403 ObjectItem->SetFlags(FlagsToSet);
404 }
405
413 {
414 // Need to understand the logic of GC first
415 //GUObjectStore.IndexToObject(InternalIndex)->SetRootSet();
416 }
417
418 /*-------------------
419 Class
420 -------------------*/
421
422 private:
423
432 static bool IsChildOfWorkaround(const UClass* ObjClass, const UClass* TestClass);
433 };
434}
#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:170
#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:203
FORCEINLINE void SetFlagsTo(EObjectFlags NewFlags)
Definition UObjectBase.h:57
FORCEINLINE const std::string & GetName() const
Definition UObjectBase.h:193
static FORCEINLINE EInternalObjectFlags FixGarbageOrPendingKillInternalObjectFlags(const EInternalObjectFlags InFlags)
Definition UObjectBase.h:261
FORCEINLINE UObject * GetOuter() const
Definition UObjectBase.h:216
virtual void ShivaUObject()
One function to destroy them.
Definition UObjectBase.h:84
FORCEINLINE void ClearFlags(EObjectFlags FlagsToClear)
Definition UObjectBase.h:357
T * GetTypedOuter() const
Definition UObjectBase.h:240
FORCEINLINE UClass * GetClass() const
Definition UObjectBase.h:314
UObject * GetTypedOuter(UClass *Target) const
Definition UObjectBase.cpp:124
FORCEINLINE uint32_t GetInternalIndex() const
Definition UObjectBase.h:120
FORCEINLINE bool HasAnyFlags(EObjectFlags FlagsToCheck) const
Definition UObjectBase.h:373
FORCEINLINE void SetInternalIndex(uint32_t StoreIndex)
Definition UObjectBase.h:113
FORCEINLINE void SetFlags(EObjectFlags NewFlags)
Definition UObjectBase.h:343
FORCEINLINE void SetInternalFlags(EInternalObjectFlags FlagsToSet) const
Definition UObjectBase.h:398
FORCEINLINE EObjectFlags GetFlags() const
Definition UObjectBase.h:329
FORCEINLINE bool IsA(OtherClassType SomeBase) const
Definition UObjectBase.h:288
UObjectBase()
Providing a default constructor.
Definition UObjectBase.cpp:15
FORCEINLINE void AddToRoot()
Definition UObjectBase.h:412
FORCEINLINE bool HasAnyInternalFlags(EInternalObjectFlags FlagsToCheck) const
Definition UObjectBase.h:387
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:22
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