UE网络-WithIdenticalViaEquality详解

WithIdenticalViaEquality是什么

在属性同步时候, 如果想自定义比较函数应该怎么处理呢? WithIdenticalViaEquality就是表明该结构体使用Operator ==进行比较. 注意它和WithIdentical互斥.

自定义结构体指定WithIdenticalViaEquality

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
USTRUCT()
struct FTestNetSerializeSharedPtrContainer
{
GENERATED_USTRUCT_BODY()

uint32 CounterUniqueID = 0;
TSharedPtr<FTestNetSerializeSharedPtrBase> Data;

/** Serialize the root motion sources and their states for this group */
bool NetSerialize(FArchive& Ar, UPackageMap* Map, bool& bOutSuccess);

bool Identical(const FTestNetSerializeSharedPtrContainer* Other, uint32 PortFlags) const;
bool operator==(const FTestNetSerializeSharedPtrContainer &Other) const;
bool operator!=(const FTestNetSerializeSharedPtrContainer& Other) const;

void AddStructReferencedObjects(class FReferenceCollector& Collector);
};

template<>
struct TStructOpsTypeTraits< FTestNetSerializeSharedPtrContainer > : public TStructOpsTypeTraitsBase2< FTestNetSerializeSharedPtrContainer >
{
enum
{
WithNetSerializer = true,
WithIdenticalViaEquality = true,
WithCopy = true,
WithAddStructReferencedObjects = true
};
};

WithIdenticalViaEquality映射到EStructFlags::STRUCT_IdenticalNative

构建UScriptStruct

在PreInit时候,构建UScriptStruct

img

WithIdenticalViaEquality属性映射到EStructFlags::STRUCT_IdenticalNative

构建UScriptStruct, 通过模板, 指定WithIdenticalViaEquality属性.

img
img

好了, 到此为止, 已经将我们指定的WithIdenticalViaEquality映射到EStructFlags::STRUCT_IdenticalNative上了. 即UScriptStruct.StructFlags已经包含EStructFlags::STRUCT_IdenticalNative属性.

在比较中使用自定义比较函数

堆栈:

img
1
2
3
4
5
6
7
8
9
10
--UActorChannel.ReplicateActor.if.{ 
|--FObjectReplicator.ReplicateProperties
| |--FNetSerializeCB.UpdateChangelistMgr
| | |--FRepLayout.UpdateChangelistMgr
| | | |--FRepLayout.CompareProperties.else
| | | | |--CompareParentProperties.if.else
| | | | | |--UE4_RepLayout_Private.CompareParentPropertyHelper
| | | | | | |--CompareParentProperty
| | | | | | | |--CompareProperties_r.for
| | | | | | | | |--FStructProperty.Identical

在进行属性比较的时候调用PropertiesAreIdentical:

img

调用Struct的比较函数:UScriptStruct::CompareScriptStruct, 因为有标志位:STRUCT_IdenticalNative, 所以进行自定义比较.

调用UScriptStruct.TCppStructOps.Identical, 因为是类型WithIdenticalViaEquality, 所以最终调用了operator==

image-20240418173609829

最终调用了自定义operator==函数.