//UObjectBase.h
...
private:
/** Flags used to track and report various object states. This needs to be 8 byte aligned on 32-bit
platforms to reduce memory waste */
EObjectFlags ObjectFlags;
/** Index into GObjectArray...very private. */
int32 InternalIndex;
/** Class the object belongs to. */
UClass* ClassPrivate;
/** Name of this object */
FName NamePrivate;
/** Object this object resides in. */
UObject* OuterPrivate;
...
public:
FORCEINLINE uint32 GetUniqueID() const
{
return (uint32)InternalIndex;
}
/** Returns the UClass that defines the fields of this object */
FORCEINLINE UClass* GetClass() const
{
return ClassPrivate;
}
/** Returns the UObject this object resides in */
FORCEINLINE UObject* GetOuter() const
{
return OuterPrivate;
}
/** Returns the logical name of this object */
FORCEINLINE FName GetFName() const
{
return NamePrivate;
}
...
비트플래그의 일종으로 UObject의 다양한 상태를 나타내기 위해서 사용한다.
UObject가 생성되면 GUObjectArray에 등록되며 그 곳의 인덱스 역할을 한다.
//UObjectHash.cpp
...
FUObjectArray GUObjectArray; //Global로 선언되어 있다.
...
//UObjectArray.h
class COREUOBJECT_API FUObjectArray
{
public:
...
//ObjAvailableList에서 할당 가능한 Index를 찾아서 할당
void AllocateUObjectIndex(class UObjectBase* Object, bool bMergingThreads = false);
//ObjAvailableList에 Index를 반환하여 할당 가능한 Index로 만들어 준다.
void FreeUObjectIndex(class UObjectBase* Object);
...
private:
...
/** First index into objects array taken into account for GC. */
int32 ObjFirstGCIndex;
/** Index pointing to last object created in range disregarded for GC. */
int32 ObjLastNonGCIndex;
...
/** Array of all live objects. */
TUObjectArray ObjObjects;
/** Available object indices. */
TLockFreePointerListUnordered<int32, PLATFORM_CACHE_LINE_SIZE> ObjAvailableList;
}
UObject가 어느 클래스에 속하는지 알려주는 포인터
인스턴스의 이름이며 다음과 같은 함수의 호출로 Unique한 이름이 만들어진다.
//UObjectGlobals.cpp
FName MakeUniqueObjectName
(UObject* Parent, const UClass* Class, FName InBaseName/*=NAME_None*/);
새로운 Object의 생성에서 관여하는 StaticAlloacateObject함수 내에서 사용된다.
UObject* StaticAllocateObject
(
const UClass* InClass,
UObject* InOuter,
FName InName,
EObjectFlags InFlags,
EInternalObjectFlags InternalSetFlags,
bool bCanRecycleSubobjects,
bool* bOutRecycledSubobject,
UPackage* ExternalPackage
)
{
...
if(InName == NAME_None)
{
#if WITH_EDITOR
if ( GOutputCookingWarnings && GetTransientPackage() != InOuter->GetOutermost() )
{
static const FName NAME_UniqueObjectNameForCooking(TEXT("UniqueObjectNameForCooking"));
InName = MakeUniqueObjectName(InOuter, InClass, NAME_UniqueObjectNameForCooking);
}
else
#endif
{
InName = MakeUniqueObjectName(InOuter, InClass);
}
}
...
}
object resides in OuterPrivate
//obj.cpp
UObject* UObject::CreateDefaultSubobject(FName SubobjectFName, UClass* ReturnType, UClass* ClassToCreateByDefault, bool bIsRequired, bool bIsTransient)
{
FObjectInitializer* CurrentInitializer = FUObjectThreadContext::Get().TopInitializer();
...
return CurrentInitializer->CreateDefaultSubobject(this, SubobjectFName, ReturnType, ClassToCreateByDefault, bIsRequired, bIsTransient);
}
//UObejctGlobals.cpp
UObject* FObjectInitializer::CreateDefaultSubobject(UObject* Outer, FName SubobjectFName, UClass* ReturnType, UClass* ClassToCreateByDefault, bool bIsRequired, bool bIsTransient) const
{
...
UObject* Result = NULL;
...
Params.Outer = Outer;
Params.Name = SubobjectFName;
Params.SetFlags = SubobjectFlags;
...
Result = StaticConstructObject_Internal(Params);
...
return Result;
}