UE网络-WithIdentical详解

WithIdentical是什么

在属性同步时候, 如果想自定义比较函数应该怎么处理呢? WithIdentical就是表明该结构体使用自定义比较函数.

自定义结构体指定WithIdentical

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
USTRUCT()
struct FExampleStruct
{
GENERATED_USTRUCT_BODY()
public:
UPROPERTY()
int32 ExampleIntProperty;

/**
* @param Ar FArchive to read or write from.
* @param Map PackageMap used to resolve references to UObject*
* @param bOutSuccess return value to signify if the serialization was succesfull (if false, an error will be logged by the calling function)
*
* @return return true if the serialization was fully mapped. If false, the property will be considered 'dirty' and will replicate again on the next update.
* This is needed for UActor* properties. If an actor's Actorchannel is not fully mapped, properties referencing it must stay dirty.
* Note that UPackageMap::SerializeObject returns false if an object is unmapped. Generally, you will want to return false from your ::NetSerialize
* if you make any calls to ::SerializeObject that return false.
*
*/
bool NetSerialize(FArchive& Ar, class UPackageMap* Map, bool& bOutSuccess);

bool Identical(const FExampleStruct* Other, uint32 PortFlags) const
{
return ExampleIntProperty == Other->ExampleIntProperty;
}
};

template<>
struct TStructOpsTypeTraits< FExampleStruct > : public TStructOpsTypeTraitsBase2< FExampleStruct >
{
enum
{
WithNetSerializer = true,
WithIdentical = true,
WithNetSharedSerialization = true,
};
};

将WithIdentical映射到EStructFlags::STRUCT_IdenticalNative

构建UScriptStruct

在PreInit时候,构建UScriptStruct

img

将WithNetSharedSerialization属性映射到EStructFlags::STRUCT_IdenticalNative

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

img
img

好了, 到此为止, 已经将我们指定的WithNetSharedSerialization映射到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, 所以进行自定义比较.

通过使用Cmd.Property->Identical(A, B)

img

最终调用了自定义Identical函数.

img