【ue4】【架构】对象系统

对象系统

UE4 的对象系统是实现反射系统的基础

而反射系统又支撑着 GC 蓝图编辑器 网络通信 等各个模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// Engine\Source\Runtime\Core\Public\UObject\UObjectHierarchyFwd.h

class UObjectBase;
class UObjectBaseUtility;
class UObject;
class UField;
class UEnum;
class UProperty;
class UByteProperty;
class UUInt16Property;
class UUInt32Property;
class UUInt64Property;
class UInt8Property;
class UInt16Property;
class UIntProperty;
class UInt64Property;
class UBoolProperty;
class UFloatProperty;
class UDoubleProperty;
class UObjectPropertyBase;
class UObjectProperty;
class UClassProperty;
class UInterfaceProperty;
class UWeakObjectProperty;
class ULazyObjectProperty;
class USoftObjectProperty;
class USoftClassProperty;
class UNameProperty;
class UStructProperty;
class UStrProperty;
class UTextProperty;
class UArrayProperty;
class UDelegateProperty;
class UMulticastDelegateProperty;
class UMapProperty;
class USetProperty;
class UEnumProperty;
class UStruct;
class UFunction;
class UClass;
class UScriptStruct;
class FLinker;
class FLinkerLoad;
class FLinkerSave;
class UPackage;
class USystem;
class UTextBuffer;
class UPackageMap;
class UObjectRedirector;

UObject

是 UE 所有对象的基类

对象标记 ObjectFlags

类型信息 ObjectClass

对象引用管理 --增删改查

序列化

GC

UE4 中有一个全局的列表 GUObjectArray 用来保存当前引擎实例中所有继承自 UObject 的对象, 实现了一个全局的对象管理。

序列化

序列化是指将对象转换成__字节流__, 从到存储对象 (或传输对象) 到其他地方 (内存或磁盘等)

用于保存对象的 结构 或 状态

UE4 使用 访问者模式 (Vistor Pattern) 实现序列化机制

FArchive 作为 Vistor, 是真正进行序列化操作的地方

UObject 的 Serialize(FArchive& Ar) 作为 Client 供 Vistor 访问

【Tips】 FArchive 通过重载 << 来实现对 UObject 中数据的访问

GC

触发条件

入口函数 UEngine::ConditionalCollectGarbage() 每帧都会执行

默认情况下每 60 秒(可修改)执行 TryCollectGarbage 尝试进行一次 GC

主动触发函数

UEngine::ForceGarbageCollection() -- 下一帧将强制执行GC

UEngine::DelayGarbageCollection() -- 下一帧一定不执行GC

执行流程

第一步, 可达性检查

维护一个可达列表 -- RootSet

全置为不可达

从根节点出发遍历所有对象

如果是 PendingKill,则不加入RootSet, 否则加入

【Tips】 省略了一些细节

第二步, 对象销毁

所有不可达的对象, 都要被销毁

销毁的过程即是回收内存的过程

这个过程是 分时分帧 进行处理的 -- 使用了许多全局变量保存状态

UProperty

原子型成员变量

描述了成员变量在类内存中的偏移量, 字节大小, 类型等信息

UStruct

复合型成员变量

同 UProperty 作用类似, 但是用更多的字段以描述复合型的成员变量

其子类中最重要的就是 UClass 和 UFunction

UClass

用于描述一个类的反射信息

不仅可以用来描述 原生的c++类 (NativeClass), 也可以用来描述蓝图使用的类 (BluprintClass)

UFunction

用于描述一个 UObject 对象的成员函数

包括 Native Function 和 Script Function

函数名

参数

返回值

局部变量

代码块

【Tips】 UScriptStruct 为 c++ 的 struct

UHT 和 UBT

UHT (UnrealHeaderTool) 会根据我们在声明类型时打的标签宏解析并生成对的的 c++ 反射代码

这些生成的代码文件大部分名为 xx.generated.hxx.gen.cpp

位于 Intermediate\Build\Win64\UE4Editor\Inc 文件夹下

而 UBT (UnrealBuildTool) 会首先调用 UHT 来生成反射代码, 然后根据再逐个编译 (选择不同平台配置进行编译) 每个 Module 并根据每个 Module 的 Build.csTarget.cs 来处理依赖关系