新手,有错请指出,大家共同进步
Object
UObjectBase
说明
Unreal中UObject的基类
属性
类型 | 名字 | 说明 |
---|---|---|
EObjectFlags | ObjectFlags | ObjectFlags是用于跟踪和记录对象的各种状态,它被引擎用于表示对象加载、保存、编辑、垃圾回收和对象作用标识时候使用。简单地说,就是一个标记信息。 |
int32 | InternalIndex | 全局对象数组的下标,unreal在运行时候会维护一个全局的对象数组,每当创建一个对象的时候便放到数组里面 |
UClass* | ClassPrivate | 类型信息 |
FName | NamePrivate | 对象名字 |
UObject* | OuterPrivate | Outer对象的指针,暂时没弄明白是啥意思。(update)一个对象A的"Outer"是拥有A的对象。例如,Component由其Actor或父组件拥有,Actors由其Levels拥有。 无论何时构造从UObject派生的类的对象,都要为它提供外部。 (CreateDefaultSubobject隐式提供当前对象作为外部。)可不可以这样说,人是一个对象,手是一个对象,而手的outer是人? 看这里解释 |
构造函数
UObjectBase
()
这个构造函数,只把NamePrivate
设置为NoInit
,其他啥事都没有做
UObjectBase
( EObjectFlags InFlags )
Constructor used for bootstrapping
这时候对象并没有加入到全局对象数组中,感觉有特殊用途
UObjectBase
(UClass* InClass, EObjectFlags InFlags, EInternalObjectFlags InInternalFlags, UObject *InOuter, FName InName)
UObjectBase::UObjectBase(UClass* InClass, EObjectFlags InFlags, EInternalObjectFlags InInternalFlags, UObject *InOuter, FName InName)
: ObjectFlags (InFlags)
, InternalIndex (INDEX_NONE)
, ClassPrivate (InClass)
, OuterPrivate (InOuter)
#if ENABLE_STATNAMEDEVENTS_UOBJECT
, StatIDStringStorage(nullptr)
#endif
{
check(ClassPrivate);
// Add to global table.
AddObject(InName, InInternalFlags);
}
这个构造函数是用于创建静态分配的对象,应该是一般的对象,构造函数把属性都赋值了,但是值得注意的是,InternalIndex
的值为INDEX_NONE
,也就是-1
,并没有马上就把对象加入了全局对象数组中。是不是说,创建该对象前,不能知道InternalIndex
? EInternalObjectFlags标记存放在全局对象管理数组的元素中(这是为了提高Cache命中率)
后面调用check(ClassPrivate)
来判断classPrivate是否为NULL
最后AddObject(InName, InInternalFlags)
把对象加入到全局对象数组中
析构函数
~UObjectBase()
/**
* Final destructor, removes the object from the object array, and indirectly, from any annotations
**/
UObjectBase::~UObjectBase()
{
// If not initialized, skip out.
if( UObjectInitialized() && ClassPrivate && !GIsCriticalError )
{
// Validate it.
check(IsValidLowLevel());
LowLevelRename(NAME_None);
GUObjectArray.FreeUObjectIndex(this);
}
#if ENABLE_STATNAMEDEVENTS_UOBJECT
delete[] StatIDStringStorage;
StatIDStringStorage = nullptr;
#endif
}
通过LowLevelRename(NAME_None)
改掉名字,通过GUObjectArray.FreeUObjectIndex(this)
把对象从全局对象数组中去掉
函数
void AtomicallyClearFlags
(EObjectFlags FlagsToClear)
/**
* Atomically clears the specified flags.
* Do not use unless you know what you are doing.
* Designed to be used only by parallel GC and UObject loading thread.
*/
FORCENOINLINE void AtomicallyClearFlags( EObjectFlags FlagsToClear )
{
int32 OldFlags = 0;
int32 NewFlags = 0;
do
{
OldFlags = ObjectFlags;
NewFlags = OldFlags & ~FlagsToClear;
}
while( FPlatformAtomics::InterlockedCompareExchange( (int32*)&ObjectFlags, NewFlags, OldFlags) != OldFlags );
}
原子级别上清理flags,是不是能理解成在flags上的位上进行清理操作呢?为什么要这样操作?
void AtomicallySetFlags
(EObjectFlags FlagsToAdd)
/**
* Atomically adds the specified flags.
* Do not use unless you know what you are doing.
* Designed to be used only by parallel GC and UObject loading thread.
*/
FORCENOINLINE void AtomicallySetFlags( EObjectFlags FlagsToAdd )
{
int32 OldFlags = 0;
int32 NewFlags = 0;
do
{
OldFlags = ObjectFlags;
NewFlags = OldFlags | FlagsToAdd;
}
while( FPlatformAtomics::InterlockedCompareExchange( (int32*)&ObjectFlags, NewFlags, OldFlags) != OldFlags );
}
原子级别上清理flags,***是不是能理解成在flags上的位上进行清理操作呢?***为什么要这样操作?
void DeferredRegister
(
UClass * UClassStaticClass,
const TCHAR * PackageName,
const TCHAR * Name
)
/**
* Convert a boot-strap registered class into a real one, add to uobject array, etc
*
* @param UClassStaticClass Now that it is known, fill in UClass::StaticClass() as the class
*/
void UObjectBase::DeferredRegister(UClass *UClassStaticClass,const TCHAR* PackageName,const TCHAR* InName)
{
//检查该对象是否已经初始化,当UObjectBaseInit()调用后,就初始化了。
check(Internal::GObjInitialized);
// Set object properties.
//根据PackageName找到Outer,然后设置本对象的Outer
UPackage* Package = CreatePackage(nullptr, PackageName);
check(Package);
Package->SetPackageFlags(PKG_CompiledIn);
OuterPrivate = Package;
ch