UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
PolymorphicNetSerializerImpl.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2#pragma once
3
4#include "NetSerializer.h"
6
7#include "Iris/Core/IrisLog.h"
14
15// NOTE: This file should not be included in a header
16
17namespace UE::Net
18{
19
20class FNetReferenceCollector;
22
23}
24
25namespace UE::Net::Private
26{
27
28// Wrapper to allow access to the internal context
37
38}
39
40namespace UE::Net
41{
42
64template <typename ExternalSourceType, typename ExternalSourceItemType, TSharedPtr<ExternalSourceItemType>&(*GetItem)(ExternalSourceType&)>
66{
72
73 // Traits
74 static constexpr bool bHasDynamicState = true;
75 static constexpr bool bIsForwardingSerializer = true; // Triggers asserts if a function is missing
76 static constexpr bool bHasCustomNetReference = true; // We must support this as we do not know the type
77
81
84
87
90
93
96
98
99protected:
101
104
106 {
107 void operator()(SourceItemType* Object) const
108 {
109 check(Object);
110 UScriptStruct* ScriptStruct = Object->GetScriptStruct();
111 check(ScriptStruct);
112 ScriptStruct->DestroyStruct(Object);
113 FMemory::Free(Object);
114 }
115 };
116
117 template <typename SerializerType>
118 static void InitTypeCache()
119 {
120 FPolymorphicNetSerializerScriptStructCache* Cache = const_cast<FPolymorphicNetSerializerScriptStructCache*>(&SerializerType::DefaultConfig.RegisteredTypes);
121 Cache->InitForType(SerializerType::SourceItemType::StaticStruct());
122 }
123
124private:
125 static void InternalFreeItem(FNetSerializationContext& Context, const ConfigType& Config, QuantizedType& Value);
126};
127
128
137template <typename ExternalSourceType, typename ExternalSourceArrayItemType, TArrayView<TSharedPtr<ExternalSourceArrayItemType>>(*GetArray)(ExternalSourceType& Source), void(*SetArrayNum)(ExternalSourceType& Source, SIZE_T Num)>
139{
140 // Our quantized type
146
152
153 // Traits
154 static constexpr bool bHasDynamicState = true;
155 static constexpr bool bIsForwardingSerializer = true; // Triggers asserts if a function is missing
156 static constexpr bool bHasCustomNetReference = true; // We must support this as we do not know the type
157
162
164
165 static const uint32 ArrayItemBits = 8U;
166 static const uint32 MaxArrayItems = (1U << ArrayItemBits) - 1U;
167
168 static void Serialize(FNetSerializationContext&, const FNetSerializeArgs& Args);
170
173
174 static void Quantize(FNetSerializationContext&, const FNetQuantizeArgs& Args);
175 static void Dequantize(FNetSerializationContext&, const FNetDequantizeArgs& Args);
176
177 static bool IsEqual(FNetSerializationContext&, const FNetIsEqualArgs& Args);
178 static bool Validate(FNetSerializationContext&, const FNetValidateArgs& Args);
179
182
184
186 {
187 inline void operator()(SourceArrayItemType* Object) const
188 {
189 check(Object);
190 UScriptStruct* ScriptStruct = Object->GetScriptStruct();
191 check(ScriptStruct);
192 ScriptStruct->DestroyStruct(Object);
193 FMemory::Free(Object);
194 }
195 };
196
197 template <typename SerializerType>
198 static void InitTypeCache()
199 {
200 FPolymorphicNetSerializerScriptStructCache* Cache = const_cast<FPolymorphicNetSerializerScriptStructCache*>(&SerializerType::DefaultConfig.RegisteredTypes);
201 Cache->InitForType(SerializerType::SourceArrayItemType::StaticStruct());
202 }
203
204private:
206
207 // Allocate storage for the item array
208 static void InternalAllocateItemArray(FNetSerializationContext& Context, QuantizedType& Value, uint32 NumItems);
209
210 // Free allocated storage for the item array, including allocated struct data
211 static void InternalFreeItemArray(FNetSerializationContext& Context, QuantizedType& Value, const FPolymorphicArrayStructNetSerializerConfig& Config);
212};
213
215template <typename ExternalSourceType, typename ExternalSourceItemType, TSharedPtr<ExternalSourceItemType>&(*GetItem)(ExternalSourceType&)>
217{
218 FNetBitStreamWriter& Writer = *Context.GetBitStreamWriter();
219 const QuantizedType& Value = *reinterpret_cast<const QuantizedType*>(Args.Source);
220 const ConfigType& Config = *static_cast<const ConfigType*>(Args.NetSerializerConfig);
221
222 const FTypeInfo* TypeInfo = Config.RegisteredTypes.GetTypeInfo(Value.TypeIndex);
223 if (Writer.WriteBool(TypeInfo != nullptr))
224 {
225 CA_ASSUME(TypeInfo != nullptr);
227 UE::Net::FReplicationStateOperations::Serialize(Context, static_cast<const uint8*>(Value.StructData), TypeInfo->Descriptor);
228 }
229}
230
231template <typename ExternalSourceType, typename ExternalSourceItemType, TSharedPtr<ExternalSourceItemType>&(*GetItem)(ExternalSourceType&)>
233{
234 FNetBitStreamReader& Reader = *Context.GetBitStreamReader();
235 QuantizedType& Target = *reinterpret_cast<QuantizedType*>(Args.Target);
236 const ConfigType& Config = *static_cast<const ConfigType*>(Args.NetSerializerConfig);
237
238 InternalFreeItem(Context, Config, Target);
239
241 if (const bool bIsValidType = Reader.ReadBool())
242 {
244 if (const FTypeInfo* TypeInfo = Config.RegisteredTypes.GetTypeInfo(TypeIndex))
245 {
246 const FReplicationStateDescriptor* Descriptor = TypeInfo->Descriptor;
247
248 // Allocate storage and read struct data
250 TempValue.TypeIndex = TypeIndex;
251
252 FMemory::Memzero(TempValue.StructData, Descriptor->InternalSize);
253 FReplicationStateOperations::Deserialize(Context, static_cast<uint8*>(TempValue.StructData), Descriptor);
254 }
255 else
256 {
258 // Fall through to clear the target
259 }
260 }
261
262 Target = TempValue;
263}
264
265template <typename ExternalSourceType, typename ExternalSourceItemType, TSharedPtr<ExternalSourceItemType>&(*GetItem)(ExternalSourceType&)>
267{
268 FNetBitStreamWriter& Writer = *Context.GetBitStreamWriter();
269 const QuantizedType& Value = *reinterpret_cast<const QuantizedType*>(Args.Source);
270 const QuantizedType& PrevValue = *reinterpret_cast<const QuantizedType*>(Args.Prev);
271 const ConfigType& Config = *static_cast<const ConfigType*>(Args.NetSerializerConfig);
272
273 // If prev has the same type we can delta-compress
274 if (Writer.WriteBool(Value.TypeIndex == PrevValue.TypeIndex))
275 {
276 const FTypeInfo* TypeInfo = Config.RegisteredTypes.GetTypeInfo(Value.TypeIndex);
277 if (TypeInfo != nullptr)
278 {
279 UE::Net::FReplicationStateOperations::SerializeDelta(Context, static_cast<const uint8*>(Value.StructData), static_cast<const uint8*>(PrevValue.StructData), TypeInfo->Descriptor);
280 }
281 }
282 else
283 {
284 const FTypeInfo* TypeInfo = Config.RegisteredTypes.GetTypeInfo(Value.TypeIndex);
285 if (Writer.WriteBool(TypeInfo != nullptr))
286 {
287 CA_ASSUME(TypeInfo != nullptr);
289 UE::Net::FReplicationStateOperations::Serialize(Context, static_cast<const uint8*>(Value.StructData), TypeInfo->Descriptor);
290 }
291 }
292}
293
294template <typename ExternalSourceType, typename ExternalSourceItemType, TSharedPtr<ExternalSourceItemType>&(*GetItem)(ExternalSourceType&)>
296{
297 FNetBitStreamReader& Reader = *Context.GetBitStreamReader();
298 QuantizedType& Target = *reinterpret_cast<QuantizedType*>(Args.Target);
299 const QuantizedType& PrevValue = *reinterpret_cast<const QuantizedType*>(Args.Prev);
300 const ConfigType& Config = *static_cast<const ConfigType*>(Args.NetSerializerConfig);
301
302 InternalFreeItem(Context, Config, Target);
303
305
306 // If prev has the same type we can delta-compress
307 if (const bool bIsSameType = Reader.ReadBool())
308 {
309 const uint32 TypeIndex = PrevValue.TypeIndex;
310 if (const FTypeInfo* TypeInfo = Config.RegisteredTypes.GetTypeInfo(TypeIndex))
311 {
312 const FReplicationStateDescriptor* Descriptor = TypeInfo->Descriptor;
313
314 // Allocate storage and read struct data
316 TempValue.TypeIndex = TypeIndex;
317
318 FMemory::Memzero(TempValue.StructData, Descriptor->InternalSize);
319 FReplicationStateOperations::DeserializeDelta(Context, static_cast<uint8*>(TempValue.StructData), static_cast<uint8*>(PrevValue.StructData), Descriptor);
320 }
321 }
322 else
323 {
324 if (const bool bIsValidType = Reader.ReadBool())
325 {
327 if (const FTypeInfo* TypeInfo = Config.RegisteredTypes.GetTypeInfo(TypeIndex))
328 {
329 const FReplicationStateDescriptor* Descriptor = TypeInfo->Descriptor;
330
331 // Allocate storage and read struct data
333 TempValue.TypeIndex = TypeIndex;
334
335 FMemory::Memzero(TempValue.StructData, Descriptor->InternalSize);
336 FReplicationStateOperations::Deserialize(Context, static_cast<uint8*>(TempValue.StructData), Descriptor);
337 }
338 else
339 {
341 // Fall through to clear the target
342 }
343 }
344 }
345
346 Target = TempValue;
347}
348
349template <typename ExternalSourceType, typename ExternalSourceItemType, TSharedPtr<ExternalSourceItemType>&(*GetItem)(ExternalSourceType&)>
351{
352 SourceType& SourceValue = *reinterpret_cast<SourceType*>(Args.Source);
353 QuantizedType& TargetValue = *reinterpret_cast<QuantizedType*>(Args.Target);
354 const ConfigType& Config = *static_cast<const ConfigType*>(Args.NetSerializerConfig);
355
357
358 const TSharedPtr<SourceItemType>& Item = GetItem(SourceValue);
359 const UScriptStruct* ScriptStruct = Item.IsValid() ? Item->GetScriptStruct() : nullptr;
360 const uint32 TypeIndex = Config.RegisteredTypes.GetTypeIndex(ScriptStruct);
361
362 // Quantize polymorphic data
365 {
366 const FPolymorphicNetSerializerScriptStructCache::FTypeInfo* TypeInfo = Config.RegisteredTypes.GetTypeInfo(TypeIndex);
367 const FReplicationStateDescriptor* Descriptor = TypeInfo->Descriptor;
368
369 TempValue.TypeIndex = TypeIndex;
371 FMemory::Memzero(TempValue.StructData, Descriptor->InternalSize);
372
373 FReplicationStateOperations::Quantize(Context, static_cast<uint8*>(TempValue.StructData), reinterpret_cast<const uint8*>(Item.Get()), Descriptor);
374 }
375 else
376 {
377 if (ScriptStruct)
378 {
380 UE_LOG(LogIris, Warning, TEXT("TPolymorphicStructNetSerializerImpl::Quantize Trying to quantize unregistered ScriptStruct type %s."), ToCStr(ScriptStruct->GetName()));
381 }
382 }
383
384 TargetValue = TempValue;
385}
386
387template <typename ExternalSourceType, typename ExternalSourceItemType, TSharedPtr<ExternalSourceItemType>&(*GetItem)(ExternalSourceType&)>
389{
390 const QuantizedType& SourceValue = *reinterpret_cast<const QuantizedType*>(Args.Source);
391 SourceType& TargetValue = *reinterpret_cast<SourceType*>(Args.Target);
392 const ConfigType& Config = *static_cast<const ConfigType*>(Args.NetSerializerConfig);
393
394 // Dequantize polymorphic data
395 if (const FPolymorphicNetSerializerScriptStructCache::FTypeInfo* TypeInfo = Config.RegisteredTypes.GetTypeInfo(SourceValue.TypeIndex))
396 {
397 const FReplicationStateDescriptor* Descriptor = TypeInfo->Descriptor;
398 const UScriptStruct* ScriptStruct = TypeInfo->ScriptStruct;
399
400 // NOTE: We always allocate new memory in order to behave like the code we are trying to mimic expects, see GameplayEffectContextHandle
401 // this should really be a policy of this class as it is far from optimal.
402
403 // Allocate external struct, owned by external state therefore using global allocator
404 SourceItemType* NewData = static_cast<SourceItemType*>(FMemory::Malloc(ScriptStruct->GetStructureSize(), ScriptStruct->GetMinAlignment()));
405 ScriptStruct->InitializeStruct(NewData);
406
407 FReplicationStateOperations::Dequantize(Context, reinterpret_cast<uint8*>(NewData), static_cast<const uint8*>(SourceValue.StructData), Descriptor);
408
409 GetItem(TargetValue) = MakeShareable(NewData, FSourceItemTypeDeleter());
410 }
411 else
412 {
413 GetItem(TargetValue).Reset();
414 }
415}
416
417template <typename ExternalSourceType, typename ExternalSourceItemType, TSharedPtr<ExternalSourceItemType>&(*GetItem)(ExternalSourceType&)>
419{
420 if (Args.bStateIsQuantized)
421 {
422 const ConfigType& Config = *static_cast<const ConfigType*>(Args.NetSerializerConfig);
423 const QuantizedType& ValueA = *reinterpret_cast<const QuantizedType*>(Args.Source0);
424 const QuantizedType& ValueB = *reinterpret_cast<const QuantizedType*>(Args.Source1);
425
426 if (ValueA.TypeIndex != ValueB.TypeIndex)
427 {
428 return false;
429 }
430
431 const FTypeInfo* TypeInfo = Config.RegisteredTypes.GetTypeInfo(ValueA.TypeIndex);
432 checkSlow(TypeInfo != nullptr);
433 if (TypeInfo != nullptr && !UE::Net::FReplicationStateOperations::IsEqualQuantizedState(Context, static_cast<const uint8*>(ValueA.StructData), static_cast<const uint8*>(ValueB.StructData), TypeInfo->Descriptor))
434 {
435 return false;
436 }
437 }
438 else
439 {
440 const SourceType& ValueA = *reinterpret_cast<const SourceType*>(Args.Source0);
441 const SourceType& ValueB = *reinterpret_cast<const SourceType*>(Args.Source1);
442
443 // Assuming there's a custom operator== because if there's not we would be hitting TSharedRef== which checks if the reference is identical, not the instance data.
444 return ValueA == ValueB;
445 }
446
447 return true;
448}
449
450template <typename ExternalSourceType, typename ExternalSourceItemType, TSharedPtr<ExternalSourceItemType>&(*GetItem)(ExternalSourceType&)>
452{
453 SourceType& SourceValue = *reinterpret_cast<SourceType*>(Args.Source);
454 const ConfigType& Config = *static_cast<const ConfigType*>(Args.NetSerializerConfig);
455
456 const TSharedPtr<SourceItemType>& Item = GetItem(SourceValue);
457 const UScriptStruct* ScriptStruct = Item.IsValid() ? Item->GetScriptStruct() : nullptr;
458 const uint32 TypeIndex = Config.RegisteredTypes.GetTypeIndex(ScriptStruct);
459
460 if (ScriptStruct != nullptr && (TypeIndex == FPolymorphicNetSerializerScriptStructCache::InvalidTypeIndex))
461 {
462 return false;
463 }
464
465 const FTypeInfo* TypeInfo = Config.RegisteredTypes.GetTypeInfo(TypeIndex);
466 if (TypeInfo != nullptr && !UE::Net::FReplicationStateOperations::Validate(Context, reinterpret_cast<const uint8*>(Item.Get()), TypeInfo->Descriptor))
467 {
468 return false;
469 }
470
471 return true;
472}
473
474template <typename ExternalSourceType, typename ExternalSourceItemType, TSharedPtr<ExternalSourceItemType>&(*GetItem)(ExternalSourceType&)>
476{
477 const QuantizedType& SourceValue = *reinterpret_cast<const QuantizedType*>(Args.Source);
478 QuantizedType& TargetValue = *reinterpret_cast<QuantizedType*>(Args.Target);
479 const ConfigType& Config = *static_cast<const ConfigType*>(Args.NetSerializerConfig);
480
481 // Clone polymorphic data
482 const FTypeInfo* TypeInfo = Config.RegisteredTypes.GetTypeInfo(SourceValue.TypeIndex);
483 TargetValue.TypeIndex = SourceValue.TypeIndex;
484
485 if (TypeInfo)
486 {
487 const FReplicationStateDescriptor* Descriptor = TypeInfo->Descriptor;
488
489 // We need some memory to store the state for the polymorphic struct
491 FPolymorphicStructNetSerializerInternal::CloneQuantizedState(Context, static_cast<uint8*>(TargetValue.StructData), static_cast<const uint8*>(SourceValue.StructData), Descriptor);
492 }
493 else
494 {
495 TargetValue.StructData = nullptr;
496 }
497}
498
499template <typename ExternalSourceType, typename ExternalSourceItemType, TSharedPtr<ExternalSourceItemType>&(*GetItem)(ExternalSourceType&)>
501{
502 QuantizedType& SourceValue = *reinterpret_cast<QuantizedType*>(Args.Source);
503 const ConfigType& Config = *static_cast<const ConfigType*>(Args.NetSerializerConfig);
504
505 InternalFreeItem(Context, Config, SourceValue);
506}
507
508template <typename ExternalSourceType, typename ExternalSourceItemType, TSharedPtr<ExternalSourceItemType>&(*GetItem)(ExternalSourceType&)>
510{
511 const ConfigType& Config = *static_cast<const ConfigType*>(Args.NetSerializerConfig);
512 const QuantizedType& Value = *reinterpret_cast<const QuantizedType*>(Args.Source);
513 FNetReferenceCollector& Collector = *reinterpret_cast<UE::Net::FNetReferenceCollector*>(Args.Collector);
514
515 // No references nothing to do
516 if (Value.TypeIndex == FPolymorphicNetSerializerScriptStructCache::InvalidTypeIndex || !Config.RegisteredTypes.CanHaveNetReferences())
517 {
518 return;
519 }
520
521 const FTypeInfo* TypeInfo = Config.RegisteredTypes.GetTypeInfo(Value.TypeIndex);
522 checkSlow(TypeInfo != nullptr);
523 const FReplicationStateDescriptor* Descriptor = TypeInfo ? TypeInfo->Descriptor.GetReference() : nullptr;
524 if (Descriptor != nullptr && EnumHasAnyFlags(Descriptor->Traits, EReplicationStateTraits::HasObjectReference))
525 {
526 FPolymorphicStructNetSerializerInternal::CollectReferences(Context, Collector, Args.ChangeMaskInfo, static_cast<const uint8*>(Value.StructData), Descriptor);
527 }
528}
529
530template <typename ExternalSourceType, typename ExternalSourceItemType, TSharedPtr<ExternalSourceItemType>&(*GetItem)(ExternalSourceType&)>
532{
533 const FTypeInfo* TypeInfo = Config.RegisteredTypes.GetTypeInfo(Value.TypeIndex);
534 const FReplicationStateDescriptor* Descriptor = TypeInfo ? TypeInfo->Descriptor.GetReference() : nullptr;
535
536 if (Value.StructData != nullptr)
537 {
538 checkSlow(Descriptor != nullptr);
540 {
541 FReplicationStateOperations::FreeDynamicState(Context, static_cast<uint8*>(Value.StructData), Descriptor);
542 }
544 Value.StructData = nullptr;
546 }
547}
548
550template <typename ExternalSourceType, typename ExternalSourceArrayItemType, TArrayView<TSharedPtr<ExternalSourceArrayItemType>>(*GetArray)(ExternalSourceType& Source), void(*SetArrayNum)(ExternalSourceType& Source, SIZE_T Num)>
552{
553 FNetBitStreamWriter& Writer = *Context.GetBitStreamWriter();
554 const QuantizedType& SourceValue = *reinterpret_cast<const QuantizedType*>(Args.Source);
555 const ConfigType& Config = *static_cast<const ConfigType*>(Args.NetSerializerConfig);
556
557 // Serialize quantized data
558 Writer.WriteBits(SourceValue.NumItems, ArrayItemBits);
559 for (uint32 It = 0, EndIt = SourceValue.NumItems; It != EndIt; ++It)
560 {
561 UE_NET_TRACE_SCOPE(Element, Writer, Context.GetTraceCollector(), ENetTraceVerbosity::VeryVerbose);
562
563 const FQuantizedItem& Item = SourceValue.Items[It];
564 const FTypeInfo* TypeInfo = Config.RegisteredTypes.GetTypeInfo(Item.TypeIndex);
565 if (Writer.WriteBool(TypeInfo != nullptr))
566 {
567 CA_ASSUME(TypeInfo != nullptr);
569 FReplicationStateOperations::Serialize(Context, static_cast<const uint8*>(Item.StructData), TypeInfo->Descriptor);
570 }
571 }
572}
573
574template <typename ExternalSourceType, typename ExternalSourceArrayItemType, TArrayView<TSharedPtr<ExternalSourceArrayItemType>>(*GetArray)(ExternalSourceType& Source), void(*SetArrayNum)(ExternalSourceType& Source, SIZE_T Num)>
576{
577 FNetBitStreamReader& Reader = *Context.GetBitStreamReader();
578 QuantizedType& TargetValue = *reinterpret_cast<QuantizedType*>(Args.Target);
579 const ConfigType& Config = *static_cast<const ConfigType*>(Args.NetSerializerConfig);
580
581 // Deserialize quantized data
582 const uint32 NumItems = Reader.ReadBits(ArrayItemBits);
583
584 if (Reader.IsOverflown())
585 {
587 return;
588 }
589
590 // Currently we always free all memory even though we in theory could keep it if all types are matching
591 InternalFreeItemArray(Context, TargetValue, Config);
592
593 // Allocate space for the ItemArray
594 InternalAllocateItemArray(Context, TargetValue, NumItems);
595
596 // Read polymorphic state data
597 for (uint32 It = 0, EndIt = TargetValue.NumItems; It != EndIt; ++It)
598 {
599 UE_NET_TRACE_SCOPE(Element, Reader, Context.GetTraceCollector(), ENetTraceVerbosity::VeryVerbose);
600
601 FQuantizedItem& Item = TargetValue.Items[It];
602 if (Reader.ReadBool())
603 {
605 if (const FTypeInfo* TypeInfo = Config.RegisteredTypes.GetTypeInfo(TypeIndex))
606 {
607 const FReplicationStateDescriptor* Descriptor = TypeInfo->Descriptor;
608
609 // Allocate storage and read struct data
611 Item.TypeIndex = TypeIndex;
612
613 FMemory::Memzero(Item.StructData, Descriptor->InternalSize);
615 }
616 else
617 {
618 InternalFreeItemArray(Context, TargetValue, Config);
620 return;
621 }
622 }
623 }
624}
625
626template <typename ExternalSourceType, typename ExternalSourceArrayItemType, TArrayView<TSharedPtr<ExternalSourceArrayItemType>>(*GetArray)(ExternalSourceType& Source), void(*SetArrayNum)(ExternalSourceType& Source, SIZE_T Num)>
628{
629 FNetBitStreamWriter& Writer = *Context.GetBitStreamWriter();
630 const ConfigType& Config = *static_cast<const ConfigType*>(Args.NetSerializerConfig);
631 const QuantizedType& Array = *reinterpret_cast<const QuantizedType*>(Args.Source);
632 const QuantizedType& PrevArray = *reinterpret_cast<const QuantizedType*>(Args.Prev);
633
634 const uint32 NumItems = Array.NumItems;
635 const uint32 PrevNumItems = PrevArray.NumItems;
636 const bool bSameSizeArray = (NumItems == PrevNumItems);
637 Writer.WriteBits(bSameSizeArray, 1U);
638 if (!bSameSizeArray)
639 {
640 Writer.WriteBits(NumItems, ArrayItemBits);
641 }
642
643 // Use delta serialization for elements available in both the previous and current state.
644 if (PrevNumItems)
645 {
647
648 for (uint32 ElementIt = 0, ElementEndIt = FPlatformMath::Min(NumItems, PrevNumItems); ElementIt != ElementEndIt; ++ElementIt)
649 {
650 UE_NET_TRACE_SCOPE(Element, Writer, Context.GetTraceCollector(), ENetTraceVerbosity::VeryVerbose);
651
652 ElementArgs.Source = NetSerializerValuePointer(&Array.Items[ElementIt]);
653 ElementArgs.Prev = NetSerializerValuePointer(&PrevArray.Items[ElementIt]);
654
655 FItemNetSerializer::SerializeDelta(Context, ElementArgs);
656 }
657 }
658
659 // Serialize additional items with standard serialization.
660 if (NumItems > PrevNumItems)
661 {
662 for (uint32 ElementIt = PrevNumItems, ElementEndIt = NumItems; ElementIt < ElementEndIt; ++ElementIt)
663 {
664 UE_NET_TRACE_SCOPE(Element, Writer, Context.GetTraceCollector(), ENetTraceVerbosity::VeryVerbose);
665 const FQuantizedItem& Item = Array.Items[ElementIt];
666 const FTypeInfo* TypeInfo = Config.RegisteredTypes.GetTypeInfo(Item.TypeIndex);
667 if (Writer.WriteBool(TypeInfo != nullptr))
668 {
669 CA_ASSUME(TypeInfo != nullptr);
671 FReplicationStateOperations::Serialize(Context, static_cast<const uint8*>(Item.StructData), TypeInfo->Descriptor);
672 }
673 }
674 }
675}
676
677template <typename ExternalSourceType, typename ExternalSourceArrayItemType, TArrayView<TSharedPtr<ExternalSourceArrayItemType>>(*GetArray)(ExternalSourceType& Source), void(*SetArrayNum)(ExternalSourceType& Source, SIZE_T Num)>
679{
680 FNetBitStreamReader& Reader = *Context.GetBitStreamReader();
681 const ConfigType& Config = *static_cast<const ConfigType*>(Args.NetSerializerConfig);
682 QuantizedType& Array = *reinterpret_cast<QuantizedType*>(Args.Target);
683 const QuantizedType& PrevArray = *reinterpret_cast<const QuantizedType*>(Args.Prev);
684
686 const bool bSameSizeArray = !!Reader.ReadBits(1U);
687 const uint32 NumItems = (bSameSizeArray ? PrevNumItems : Reader.ReadBits(ArrayItemBits));
688
689 if (Reader.IsOverflown())
690 {
692 return;
693 }
694
695 // Currently we always free all memory even though we in theory could keep it if all types are matching
696 InternalFreeItemArray(Context, Array, Config);
697
698 // Allocate space for the ItemArray
699 InternalAllocateItemArray(Context, Array, NumItems);
700
701 // Elements in the current array up to the previous size can use delta serialization.
702 if (PrevNumItems)
703 {
705
706 for (uint32 ElementIt = 0, ElementEndIt = FPlatformMath::Min(NumItems, PrevNumItems); ElementIt != ElementEndIt; ++ElementIt)
707 {
708 UE_NET_TRACE_SCOPE(Element, Reader, Context.GetTraceCollector(), ENetTraceVerbosity::VeryVerbose);
709
710 ElementArgs.Target = NetSerializerValuePointer(&Array.Items[ElementIt]);
711 ElementArgs.Prev = NetSerializerValuePointer(&PrevArray.Items[ElementIt]);
712
713 FItemNetSerializer::DeserializeDelta(Context, ElementArgs);
714 }
715 }
716
717 if (Context.HasError())
718 {
719 InternalFreeItemArray(Context, Array, Config);
720 return;
721 }
722
723 if (Reader.IsOverflown())
724 {
726 InternalFreeItemArray(Context, Array, Config);
727 return;
728 }
729
730 // Deserialize additional items with standard deserialization.
731 if (NumItems > PrevNumItems)
732 {
733 for (uint32 ElementIt = PrevNumItems, ElementEndIt = NumItems; ElementIt < ElementEndIt; ++ElementIt)
734 {
735 UE_NET_TRACE_SCOPE(Element, Reader, Context.GetTraceCollector(), ENetTraceVerbosity::VeryVerbose);
736 FQuantizedItem& Item = Array.Items[ElementIt];
737 if (Reader.ReadBool())
738 {
740 if (const FTypeInfo* TypeInfo = Config.RegisteredTypes.GetTypeInfo(TypeIndex))
741 {
742 const FReplicationStateDescriptor* Descriptor = TypeInfo->Descriptor;
743
744 // Allocate storage and read struct data
746 Item.TypeIndex = TypeIndex;
747
748 FMemory::Memzero(Item.StructData, Descriptor->InternalSize);
750 }
751 else
752 {
753 InternalFreeItemArray(Context, Array, Config);
755 return;
756 }
757 }
758 }
759 }
760
761 if (Reader.IsOverflown())
762 {
764 InternalFreeItemArray(Context, Array, Config);
765 return;
766 }
767}
768
769template <typename ExternalSourceType, typename ExternalSourceArrayItemType, TArrayView<TSharedPtr<ExternalSourceArrayItemType>>(*GetArray)(ExternalSourceType& Source), void(*SetArrayNum)(ExternalSourceType& Source, SIZE_T Num)>
771{
772 SourceType& SourceValue = *reinterpret_cast<SourceType*>(Args.Source);
773 QuantizedType& TargetValue = *reinterpret_cast<QuantizedType*>(Args.Target);
774 const ConfigType& Config = *static_cast<const ConfigType*>(Args.NetSerializerConfig);
775
776 // Make sure we can properly serialize the array.
777 TArrayView<const TSharedPtr<SourceArrayItemType>> ItemArray = GetArray(SourceValue);
778 const uint32 NumItems = static_cast<uint32>(ItemArray.Num());
779 if (NumItems > MaxArrayItems)
780 {
782 return;
783 }
784
785 // First we need to free previously allocated data
786 InternalFreeItemArray(Context, TargetValue, Config);
787
788 // Allocate new array
789 InternalAllocateItemArray(Context, TargetValue, NumItems);
790
791 // Copy polymorphic struct data
793 for (const TSharedPtr<SourceArrayItemType>& SourceItem : ItemArray)
794 {
795 const SIZE_T ArrayIndex = &SourceItem - ItemArrayData;
796 const UScriptStruct* ScriptStruct = SourceItem.IsValid() ? SourceItem->GetScriptStruct() : nullptr;
797 FQuantizedItem& TargetItem = TargetValue.Items[ArrayIndex];
798 const uint32 TypeIndex = Config.RegisteredTypes.GetTypeIndex(ScriptStruct);
799
801 {
802 const FPolymorphicNetSerializerScriptStructCache::FTypeInfo* TypeInfo = Config.RegisteredTypes.GetTypeInfo(TypeIndex);
803 const FReplicationStateDescriptor* Descriptor = TypeInfo->Descriptor;
804
805 TargetItem.TypeIndex = TypeIndex;
807 FMemory::Memzero(TargetItem.StructData, Descriptor->InternalSize);
808
809 // Quantize data
810 FReplicationStateOperations::Quantize(Context, static_cast<uint8*>(TargetItem.StructData), reinterpret_cast<const uint8*>(SourceItem.Get()), Descriptor);
811 }
812 else
813 {
814 if (ScriptStruct)
815 {
817 UE_LOG(LogIris, Warning, TEXT("TPolymorphicArrayStructNetSerializerImpl::Quantize Trying to quantize unregistered ScriptStruct type %s."), ToCStr(ScriptStruct->GetName()));
818 }
819 }
820 }
821}
822
823template <typename ExternalSourceType, typename ExternalSourceArrayItemType, TArrayView<TSharedPtr<ExternalSourceArrayItemType>>(*GetArray)(ExternalSourceType& Source), void(*SetArrayNum)(ExternalSourceType& Source, SIZE_T Num)>
825{
826 SourceType& TargetValue = *reinterpret_cast<SourceType*>(Args.Target);
827 const QuantizedType& SourceValue = *reinterpret_cast<const QuantizedType*>(Args.Source);
828 const ConfigType& Config = *static_cast<const ConfigType*>(Args.NetSerializerConfig);
829
830 SetArrayNum(TargetValue, SourceValue.NumItems);
832 // Dequantize polymorphic data
833 for (uint32 It = 0, EndIt = SourceValue.NumItems; It != EndIt; ++It)
834 {
835 const FQuantizedItem& Item = SourceValue.Items[It];
836
837 if (const FPolymorphicNetSerializerScriptStructCache::FTypeInfo* TypeInfo = Config.RegisteredTypes.GetTypeInfo(Item.TypeIndex))
838 {
839 const FReplicationStateDescriptor* Descriptor = TypeInfo->Descriptor;
840 const UScriptStruct* ScriptStruct = TypeInfo->ScriptStruct;
841
842 // NOTE: We always allocate new memory in order to behave like the code we are trying to mimic expects, see GameplayEffectContextHandle
843 // this should really be a policy of this class as it is far from optimal.
844
845 // Allocate external struct, owned by external state therefore using global allocator
846 SourceArrayItemType* NewData = static_cast<SourceArrayItemType*>(FMemory::Malloc(ScriptStruct->GetStructureSize(), ScriptStruct->GetMinAlignment()));
847 ScriptStruct->InitializeStruct(NewData);
848
849 // Dequantize data
850 FReplicationStateOperations::Dequantize(Context, reinterpret_cast<uint8*>(NewData), static_cast<const uint8*>(Item.StructData), Descriptor);
851
853 }
854 else
855 {
856 TargetArray[It].Reset();
857 }
858 }
859}
860
861template <typename ExternalSourceType, typename ExternalSourceArrayItemType, TArrayView<TSharedPtr<ExternalSourceArrayItemType>>(*GetArray)(ExternalSourceType& Source), void(*SetArrayNum)(ExternalSourceType& Source, SIZE_T Num)>
863{
864 if (Args.bStateIsQuantized)
865 {
866 const ConfigType& Config = *static_cast<const ConfigType*>(Args.NetSerializerConfig);
867 const QuantizedType& ValueA = *reinterpret_cast<const QuantizedType*>(Args.Source0);
868 const QuantizedType& ValueB = *reinterpret_cast<const QuantizedType*>(Args.Source1);
869
870 if (ValueA.NumItems != ValueB.NumItems)
871 {
872 return false;
873 }
874
875 for (uint32 It = 0, EndIt = ValueA.NumItems; It != EndIt; ++It)
876 {
877 const FQuantizedItem& ItemA = ValueA.Items[It];
878 const FQuantizedItem& ItemB = ValueB.Items[It];
879
880 if (ItemA.TypeIndex != ItemB.TypeIndex)
881 {
882 return false;
883 }
884
885 const FTypeInfo* TypeInfo = Config.RegisteredTypes.GetTypeInfo(ItemA.TypeIndex);
886 if (TypeInfo && !UE::Net::FReplicationStateOperations::IsEqualQuantizedState(Context, static_cast<const uint8*>(ItemA.StructData), static_cast<const uint8*>(ItemB.StructData), TypeInfo->Descriptor))
887 {
888 return false;
889 }
890 }
891 }
892 else
893 {
894 const SourceType& ValueA = *reinterpret_cast<const SourceType*>(Args.Source0);
895 const SourceType& ValueB = *reinterpret_cast<const SourceType*>(Args.Source1);
896
897 return ValueA == ValueB;
898 }
899
900 return true;
901}
902
903template <typename ExternalSourceType, typename ExternalSourceArrayItemType, TArrayView<TSharedPtr<ExternalSourceArrayItemType>>(*GetArray)(ExternalSourceType& Source), void(*SetArrayNum)(ExternalSourceType& Source, SIZE_T Num)>
905{
906 SourceType& SourceValue = *reinterpret_cast<SourceType*>(Args.Source);
907 const ConfigType& Config = *static_cast<const ConfigType*>(Args.NetSerializerConfig);
908
909 TArrayView<const TSharedPtr<SourceArrayItemType>> ItemArray = GetArray(SourceValue);
910 const uint32 NumItems = (uint32)ItemArray.Num();
911 if (NumItems > MaxArrayItems)
912 {
913 return false;
914 }
915
916 for (const TSharedPtr<SourceArrayItemType>& Item : ItemArray)
917 {
918 const UScriptStruct* ScriptStruct = Item.IsValid() ? Item->GetScriptStruct() : nullptr;
919 const uint32 TypeIndex = Config.RegisteredTypes.GetTypeIndex(ScriptStruct);
920
921 if (ScriptStruct && (TypeIndex == FPolymorphicNetSerializerScriptStructCache::InvalidTypeIndex))
922 {
923 return false;
924 }
925
926 const FTypeInfo* TypeInfo = Config.RegisteredTypes.GetTypeInfo(TypeIndex);
927 if (TypeInfo && !FReplicationStateOperations::Validate(Context, reinterpret_cast<const uint8*>(Item.Get()), TypeInfo->Descriptor))
928 {
929 return false;
930 }
931 }
932
933 return true;
934}
935
936template <typename ExternalSourceType, typename ExternalSourceArrayItemType, TArrayView<TSharedPtr<ExternalSourceArrayItemType>>(*GetArray)(ExternalSourceType& Source), void(*SetArrayNum)(ExternalSourceType& Source, SIZE_T Num)>
938{
939 const ConfigType& Config = *static_cast<const ConfigType*>(Args.NetSerializerConfig);
940 const QuantizedType& SourceValue = *reinterpret_cast<const QuantizedType*>(Args.Source);
941 FNetReferenceCollector& Collector = *reinterpret_cast<FNetReferenceCollector*>(Args.Collector);
942
943 // No references nothing to do
944 if (SourceValue.NumItems == 0U || !Config.RegisteredTypes.CanHaveNetReferences())
945 {
946 return;
947 }
948
949 for (uint32 It = 0, EndIt = SourceValue.NumItems; It != EndIt; ++It)
950 {
951 const FQuantizedItem& Item = SourceValue.Items[It];
952 const FTypeInfo* TypeInfo = Config.RegisteredTypes.GetTypeInfo(Item.TypeIndex);
953 const FReplicationStateDescriptor* Descriptor = TypeInfo ? TypeInfo->Descriptor.GetReference() : nullptr;
954
956 {
957 FPolymorphicStructNetSerializerInternal::CollectReferences(Context, Collector, Args.ChangeMaskInfo, static_cast<const uint8*>(Item.StructData), Descriptor);
958 }
959 }
960}
961
962template <typename ExternalSourceType, typename ExternalSourceArrayItemType, TArrayView<TSharedPtr<ExternalSourceArrayItemType>>(*GetArray)(ExternalSourceType& Source), void(*SetArrayNum)(ExternalSourceType& Source, SIZE_T Num)>
964{
965 const QuantizedType& SourceValue = *reinterpret_cast<const QuantizedType*>(Args.Source);
966 QuantizedType& TargetValue = *reinterpret_cast<QuantizedType*>(Args.Target);
967 const ConfigType& Config = *static_cast<const ConfigType*>(Args.NetSerializerConfig);
968
969 InternalAllocateItemArray(Context, TargetValue, SourceValue.NumItems);
970
971 // Clone polymorphic data
972 for (uint32 It = 0, EndIt = SourceValue.NumItems; It != EndIt; ++It)
973 {
974 const FQuantizedItem& SourceItem = SourceValue.Items[It];
975 FQuantizedItem& TargetItem = TargetValue.Items[It];
976
977 const FTypeInfo* TypeInfo = Config.RegisteredTypes.GetTypeInfo(SourceItem.TypeIndex);
978 TargetItem.TypeIndex = SourceItem.TypeIndex;
979
980 if (TypeInfo)
981 {
982 const FReplicationStateDescriptor* Descriptor = TypeInfo->Descriptor;
983
984 // We need some memory to store the state for the polymorphic struct
986 FPolymorphicStructNetSerializerInternal::CloneQuantizedState(Context, static_cast<uint8*>(TargetItem.StructData), static_cast<const uint8*>(SourceItem.StructData), Descriptor);
987 }
988 else
989 {
990 TargetItem.StructData = nullptr;
991 }
992 }
993}
994
995template <typename ExternalSourceType, typename ExternalSourceArrayItemType, TArrayView<TSharedPtr<ExternalSourceArrayItemType>>(*GetArray)(ExternalSourceType& Source), void(*SetArrayNum)(ExternalSourceType& Source, SIZE_T Num)>
997{
998 QuantizedType& SourceValue = *reinterpret_cast<QuantizedType*>(Args.Source);
999 const ConfigType& Config = *static_cast<const ConfigType*>(Args.NetSerializerConfig);
1000
1001 InternalFreeItemArray(Context, SourceValue, Config);
1002}
1003
1004template <typename ExternalSourceType, typename ExternalSourceArrayItemType, TArrayView<TSharedPtr<ExternalSourceArrayItemType>>(*GetArray)(ExternalSourceType& Source), void(*SetArrayNum)(ExternalSourceType& Source, SIZE_T Num)>
1006{
1007 const SIZE_T ElementSize = sizeof(FQuantizedItem);
1008 const SIZE_T Alignment = alignof(FQuantizedItem);
1009
1010 if (NumItems > 0)
1011 {
1012 Value.Items = static_cast<FQuantizedItem*>(FPolymorphicStructNetSerializerInternal::Alloc(Context, ElementSize*NumItems, Alignment));
1013 Value.NumItems = NumItems;
1014 FMemory::Memzero(Value.Items, ElementSize*NumItems);
1015 }
1016 else
1017 {
1018 Value.Items = nullptr;
1019 Value.NumItems = 0;
1020 }
1021}
1022
1023template <typename ExternalSourceType, typename ExternalSourceArrayItemType, TArrayView<TSharedPtr<ExternalSourceArrayItemType>>(*GetArray)(ExternalSourceType& Source), void(*SetArrayNum)(ExternalSourceType& Source, SIZE_T Num)>
1024void TPolymorphicArrayStructNetSerializerImpl<ExternalSourceType, ExternalSourceArrayItemType, GetArray, SetArrayNum>::InternalFreeItemArray(FNetSerializationContext& Context, QuantizedType& Value, const FPolymorphicArrayStructNetSerializerConfig& Config)
1025{
1026 for (uint32 It = 0, EndIt = Value.NumItems; It != EndIt; ++It)
1027 {
1028 FQuantizedItem& Item = Value.Items[It];
1029
1030 const FTypeInfo* TypeInfo = Config.RegisteredTypes.GetTypeInfo(Item.TypeIndex);
1031 const FReplicationStateDescriptor* Descriptor = TypeInfo ? TypeInfo->Descriptor.GetReference() : nullptr;
1032
1033 if (Item.StructData)
1034 {
1035 checkSlow(Descriptor != nullptr);
1036 if (Descriptor && EnumHasAnyFlags(Descriptor->Traits, EReplicationStateTraits::HasDynamicState))
1037 {
1038 FReplicationStateOperations::FreeDynamicState(Context, static_cast<uint8*>(Item.StructData), Descriptor);
1039 }
1041 }
1042 }
1044
1045 // Reset the value
1046 Value.Items = nullptr;
1047 Value.NumItems = 0U;
1048}
1049
1050}
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define check(expr)
Definition AssertionMacros.h:314
#define CA_ASSUME(Expr)
Definition CoreMiscDefines.h:126
#define TEXT(x)
Definition Platform.h:1272
FPlatformTypes::SIZE_T SIZE_T
An unsigned integer the same size as a pointer, the same as UPTRINT.
Definition Platform.h:1150
#define RESTRICT
Definition Platform.h:706
SharedPointerInternals::TRawPtrProxy< ObjectType > MakeShareable(ObjectType *InObject)
Definition SharedPointer.h:1947
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
constexpr bool EnumHasAnyFlags(Enum Flags, Enum Contains)
Definition EnumClassFlags.h:35
#define UE_LOG(CategoryName, Verbosity, Format,...)
Definition LogMacros.h:270
#define UE_NET_TRACE_SCOPE(...)
Definition NetTrace.h:135
UE_FORCEINLINE_HINT const UE_STRING_CLASS::ElementType * ToCStr(const UE_STRING_CLASS &Str)
Definition UnrealString.h.inl:2326
uint32 Size
Definition VulkanMemory.cpp:4034
uint8_t uint8
Definition binka_ue_file_header.h:8
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition NameTypes.h:617
Definition ArrayView.h:139
UE_FORCEINLINE_HINT constexpr ElementType * GetData() const
Definition ArrayView.h:295
UE_FORCEINLINE_HINT constexpr SizeType Num() const
Definition ArrayView.h:380
Definition SharedPointer.h:692
UE_FORCEINLINE_HINT ObjectType * Get() const
Definition SharedPointer.h:1065
UE_FORCEINLINE_HINT const bool IsValid() const
Definition SharedPointer.h:1085
Definition NetBitStreamReader.h:11
bool IsOverflown() const
Definition NetBitStreamReader.h:67
IRISCORE_API uint32 ReadBits(uint32 BitCount)
Definition NetBitStreamReader.cpp:54
bool ReadBool()
Definition NetBitStreamReader.h:34
Definition NetBitStreamWriter.h:11
bool WriteBool(bool Value)
Definition NetBitStreamWriter.h:110
IRISCORE_API void WriteBits(uint32 Value, uint32 BitCount)
Definition NetBitStreamWriter.cpp:59
Definition NetReferenceCollector.h:25
Definition NetSerializationContext.h:31
UE_FORCEINLINE_HINT FString GetName() const
Definition UObjectBaseUtility.h:439
Definition Class.h:1720
virtual COREUOBJECT_API void InitializeStruct(void *Dest, int32 ArrayDim=1) const override
Definition Class.cpp:3782
virtual COREUOBJECT_API void DestroyStruct(void *Dest, int32 ArrayDim=1) const override
Definition Class.cpp:3940
UE_FORCEINLINE_HINT int32 GetStructureSize() const
Definition Class.h:775
UE_FORCEINLINE_HINT int32 GetMinAlignment() const
Definition Class.h:769
@ VeryVerbose
Definition NetTraceConfig.h:25
Definition NetworkVersion.cpp:28
Definition NetworkVersion.cpp:28
const FName GNetError_ArraySizeTooLarge("Array size is too large")
Definition NetErrorContext.h:15
const FName GNetError_BitStreamOverflow("BitStream overflow")
Definition NetErrorContext.h:13
UPTRINT NetSerializerValuePointer
Definition NetSerializer.h:139
const FName NetError_PolymorphicStructNetSerializer_InvalidStructType(TEXT("Invalid struct type"))
Definition PolymorphicNetSerializerImpl.h:21
@ Config
Property should be loaded/saved to ini file as permanent profile.
Definition ObjectMacros.h:1053
static FORCENOINLINE CORE_API void Free(void *Original)
Definition UnrealMemory.cpp:685
static UE_FORCEINLINE_HINT void * Memzero(void *Dest, SIZE_T Count)
Definition UnrealMemory.h:131
Definition PolymorphicNetSerializer.h:56
Definition PolymorphicNetSerializer.h:48
Definition NetSerializer.h:308
NetSerializerValuePointer Target
Definition NetSerializer.h:312
NetSerializerValuePointer Source
Definition NetSerializer.h:310
Definition NetSerializer.h:170
NetSerializerValuePointer Source
Definition NetSerializer.h:172
NetSerializerValuePointer Collector
Definition NetSerializer.h:174
Definition NetSerializer.h:259
NetSerializerValuePointer Source
Definition NetSerializer.h:261
NetSerializerValuePointer Target
Definition NetSerializer.h:263
Definition NetSerializer.h:194
NetSerializerValuePointer Target
Definition NetSerializer.h:195
Definition NetSerializer.h:222
NetSerializerValuePointer Prev
Definition NetSerializer.h:224
Definition NetSerializer.h:325
NetSerializerValuePointer Source
Definition NetSerializer.h:327
Definition NetSerializer.h:274
NetSerializerValuePointer Source1
Definition NetSerializer.h:278
NetSerializerValuePointer Source0
Definition NetSerializer.h:276
bool bStateIsQuantized
Definition NetSerializer.h:280
Definition NetSerializer.h:243
NetSerializerValuePointer Target
Definition NetSerializer.h:247
NetSerializerValuePointer Source
Definition NetSerializer.h:245
Definition NetSerializer.h:183
NetSerializerValuePointer Source
Definition NetSerializer.h:185
Definition NetSerializer.h:207
NetSerializerValuePointer Prev
Definition NetSerializer.h:209
FNetSerializerChangeMaskParam ChangeMaskInfo
Definition NetSerializer.h:159
NetSerializerConfigParam NetSerializerConfig
Definition NetSerializer.h:157
Definition NetSerializer.h:143
Definition NetSerializer.h:292
NetSerializerValuePointer Source
Definition NetSerializer.h:294
TRefCountPtr< const FReplicationStateDescriptor > Descriptor
Definition PolymorphicNetSerializer.h:30
Definition PolymorphicNetSerializer.h:22
@ InvalidTypeIndex
Definition PolymorphicNetSerializer.h:25
@ RegisteredTypeBits
Definition PolymorphicNetSerializer.h:23
Definition ReplicationStateDescriptor.h:199
uint32 InternalSize
Definition ReplicationStateDescriptor.h:242
EReplicationStateTraits Traits
Definition ReplicationStateDescriptor.h:274
uint16 InternalAlignment
Definition ReplicationStateDescriptor.h:244
static IRISCORE_API void FreeDynamicState(FNetSerializationContext &Context, uint8 *RESTRICT StateInternalBuffer, const FReplicationStateDescriptor *Descriptor)
Definition ReplicationOperations.cpp:209
static IRISCORE_API bool IsEqualQuantizedState(FNetSerializationContext &Context, const uint8 *RESTRICT Source0, const uint8 *RESTRICT Source1, const FReplicationStateDescriptor *Descriptor)
Definition ReplicationOperations.cpp:214
static IRISCORE_API bool Validate(FNetSerializationContext &Context, const uint8 *RESTRICT SrcExternalBuffer, const FReplicationStateDescriptor *Descriptor)
Definition ReplicationOperations.cpp:244
static IRISCORE_API void Quantize(FNetSerializationContext &Context, uint8 *RESTRICT DstInternalBuffer, const uint8 *RESTRICT SrcExternalBuffer, const FReplicationStateDescriptor *Descriptor)
Definition ReplicationOperations.cpp:85
static IRISCORE_API void SerializeDelta(FNetSerializationContext &Context, const uint8 *RESTRICT SrcInternalBuffer, const uint8 *RESTRICT PrevInternalBuffer, const FReplicationStateDescriptor *Descriptor)
Definition ReplicationOperations.cpp:422
static IRISCORE_API void Serialize(FNetSerializationContext &Context, const uint8 *RESTRICT SrcInternalBuffer, const FReplicationStateDescriptor *Descriptor)
Definition ReplicationOperations.cpp:371
static IRISCORE_API void Deserialize(FNetSerializationContext &Context, uint8 *RESTRICT DstInternalBuffer, const FReplicationStateDescriptor *Descriptor)
Definition ReplicationOperations.cpp:396
static IRISCORE_API void Dequantize(FNetSerializationContext &Context, uint8 *RESTRICT DstExternalBuffer, const uint8 *RESTRICT SrcInternalBuffer, const FReplicationStateDescriptor *Descriptor)
Definition ReplicationOperations.cpp:185
static IRISCORE_API void DeserializeDelta(FNetSerializationContext &Context, uint8 *RESTRICT DstInternalBuffer, const uint8 *RESTRICT PrevInternalBuffer, const FReplicationStateDescriptor *Descriptor)
Definition ReplicationOperations.cpp:447
Definition PolymorphicNetSerializerImpl.h:30
static IRISCORE_API void Free(FNetSerializationContext &Context, void *Ptr)
Definition PolymorphicNetSerializer.cpp:99
static IRISCORE_API void * Alloc(FNetSerializationContext &Context, SIZE_T Size, SIZE_T Alignment)
Definition PolymorphicNetSerializer.cpp:94
static IRISCORE_API void CollectReferences(FNetSerializationContext &Context, UE::Net::FNetReferenceCollector &Collector, const FNetSerializerChangeMaskParam &OuterChangeMaskInfo, const uint8 *RESTRICT SrcInternalBuffer, const FReplicationStateDescriptor *Descriptor)
Definition PolymorphicNetSerializer.cpp:104
static IRISCORE_API void CloneQuantizedState(FNetSerializationContext &Context, uint8 *RESTRICT DstInternalBuffer, const uint8 *RESTRICT SrcInternalBuffer, const FReplicationStateDescriptor *Descriptor)
Definition PolymorphicNetSerializer.cpp:109
Definition PolymorphicNetSerializerImpl.h:148
uint32 NumItems
Definition PolymorphicNetSerializerImpl.h:150
FQuantizedItem * Items
Definition PolymorphicNetSerializerImpl.h:149
Definition PolymorphicNetSerializerImpl.h:142
uint32 TypeIndex
Definition PolymorphicNetSerializerImpl.h:144
void * StructData
Definition PolymorphicNetSerializerImpl.h:143
void operator()(SourceArrayItemType *Object) const
Definition PolymorphicNetSerializerImpl.h:187
Definition PolymorphicNetSerializerImpl.h:139
static void CollectNetReferences(FNetSerializationContext &, const FNetCollectReferencesArgs &)
Definition PolymorphicNetSerializerImpl.h:937
static constexpr bool bIsForwardingSerializer
Definition PolymorphicNetSerializerImpl.h:155
static void SerializeDelta(FNetSerializationContext &, const FNetSerializeDeltaArgs &Args)
Definition PolymorphicNetSerializerImpl.h:627
static void Dequantize(FNetSerializationContext &, const FNetDequantizeArgs &Args)
Definition PolymorphicNetSerializerImpl.h:824
static void Quantize(FNetSerializationContext &, const FNetQuantizeArgs &Args)
Definition PolymorphicNetSerializerImpl.h:770
static void DeserializeDelta(FNetSerializationContext &, const FNetDeserializeDeltaArgs &Args)
Definition PolymorphicNetSerializerImpl.h:678
static const uint32 MaxArrayItems
Definition PolymorphicNetSerializerImpl.h:166
static constexpr bool bHasCustomNetReference
Definition PolymorphicNetSerializerImpl.h:156
static void InitTypeCache()
Definition PolymorphicNetSerializerImpl.h:198
FPolymorphicArrayStructNetSerializerConfig ConfigType
Definition PolymorphicNetSerializerImpl.h:161
static void FreeDynamicState(FNetSerializationContext &, const FNetFreeDynamicStateArgs &)
Definition PolymorphicNetSerializerImpl.h:996
static const uint32 ArrayItemBits
Definition PolymorphicNetSerializerImpl.h:165
static bool IsEqual(FNetSerializationContext &, const FNetIsEqualArgs &Args)
Definition PolymorphicNetSerializerImpl.h:862
static void Deserialize(FNetSerializationContext &, const FNetDeserializeArgs &Args)
Definition PolymorphicNetSerializerImpl.h:575
static bool Validate(FNetSerializationContext &, const FNetValidateArgs &Args)
Definition PolymorphicNetSerializerImpl.h:904
FPolymorphicNetSerializerScriptStructCache::FTypeInfo FTypeInfo
Definition PolymorphicNetSerializerImpl.h:163
static void CloneDynamicState(FNetSerializationContext &, const FNetCloneDynamicStateArgs &)
Definition PolymorphicNetSerializerImpl.h:963
ExternalSourceArrayItemType SourceArrayItemType
Definition PolymorphicNetSerializerImpl.h:160
static constexpr bool bHasDynamicState
Definition PolymorphicNetSerializerImpl.h:154
ExternalSourceType SourceType
Definition PolymorphicNetSerializerImpl.h:158
static void Serialize(FNetSerializationContext &, const FNetSerializeArgs &Args)
Definition PolymorphicNetSerializerImpl.h:551
FQuantizedArray QuantizedType
Definition PolymorphicNetSerializerImpl.h:159
Definition PolymorphicNetSerializerImpl.h:68
uint32 TypeIndex
Definition PolymorphicNetSerializerImpl.h:70
void * StructData
Definition PolymorphicNetSerializerImpl.h:69
void operator()(SourceItemType *Object) const
Definition PolymorphicNetSerializerImpl.h:107
Definition PolymorphicNetSerializerImpl.h:66
static void DeserializeDelta(FNetSerializationContext &, const FNetDeserializeDeltaArgs &)
Definition PolymorphicNetSerializerImpl.h:295
static constexpr bool bHasCustomNetReference
Definition PolymorphicNetSerializerImpl.h:76
static constexpr bool bHasDynamicState
Definition PolymorphicNetSerializerImpl.h:74
static void Quantize(FNetSerializationContext &, const FNetQuantizeArgs &)
Definition PolymorphicNetSerializerImpl.h:350
static void CollectNetReferences(FNetSerializationContext &, const FNetCollectReferencesArgs &)
Definition PolymorphicNetSerializerImpl.h:509
FPolymorphicStructNetSerializerConfig ConfigType
Definition PolymorphicNetSerializerImpl.h:80
static void SerializeDelta(FNetSerializationContext &, const FNetSerializeDeltaArgs &)
Definition PolymorphicNetSerializerImpl.h:266
FPolymorphicNetSerializerScriptStructCache::FTypeInfo FTypeInfo
Definition PolymorphicNetSerializerImpl.h:103
static void Deserialize(FNetSerializationContext &, const FNetDeserializeArgs &)
Definition PolymorphicNetSerializerImpl.h:232
static bool Validate(FNetSerializationContext &, const FNetValidateArgs &)
Definition PolymorphicNetSerializerImpl.h:451
FQuantizedData QuantizedType
Definition PolymorphicNetSerializerImpl.h:79
TPolymorphicStructNetSerializerImpl< ExternalSourceType, ExternalSourceItemType, GetItem > ThisType
Definition PolymorphicNetSerializerImpl.h:100
ExternalSourceType SourceType
Definition PolymorphicNetSerializerImpl.h:78
static void CloneDynamicState(FNetSerializationContext &, const FNetCloneDynamicStateArgs &)
Definition PolymorphicNetSerializerImpl.h:475
static void Dequantize(FNetSerializationContext &, const FNetDequantizeArgs &)
Definition PolymorphicNetSerializerImpl.h:388
static void InitTypeCache()
Definition PolymorphicNetSerializerImpl.h:118
static void FreeDynamicState(FNetSerializationContext &, const FNetFreeDynamicStateArgs &)
Definition PolymorphicNetSerializerImpl.h:500
static bool IsEqual(FNetSerializationContext &, const FNetIsEqualArgs &)
Definition PolymorphicNetSerializerImpl.h:418
static void Serialize(FNetSerializationContext &, const FNetSerializeArgs &)
Definition PolymorphicNetSerializerImpl.h:216
ExternalSourceItemType SourceItemType
Definition PolymorphicNetSerializerImpl.h:102
static constexpr bool bIsForwardingSerializer
Definition PolymorphicNetSerializerImpl.h:75