UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
ReplicationReader.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5// This class will never be included from public headers
13#include "Containers/Map.h"
14#include "Misc/MemStack.h"
15
16// Forward declaration
18
20
21namespace UE::Net
22{
23 class FNetSerializationContext;
24 class FNetTokenStoreState;
25 class FReplicationStateStorage;
26 class FNetBitStreamReader;
27 class FNetBitStreamWriter;
28
29 namespace Private
30 {
31 class FReplicationSystemInternal;
32 class FResolveAndCollectUnresolvedAndResolvedReferenceCollector;
33 class FNetBlobHandlerManager;
34 class FNetRefHandleManager;
35 }
36}
37
38namespace UE::Net::Private
39{
40
42{
43 None = 0,
44 Reliable = 1U << 0U,
45 Unreliable = Reliable << 1U,
46};
48
51{
52public:
55
56 // Init
57 void Init(const FReplicationParameters& Parameters);
58 void Deinit();
59
60 // Read incoming replication data
62
63 // Mark objects pending destroy as unresolvable.
65
66 // Process queued batches
68
69 [[nodiscard]] FString PrintObjectInfo(FInternalNetRefIndex ObjectIndex, FNetRefHandle NetRefHandle) const;
70
71private:
72 // ChangeMaskOffset -> FNetRefHandle
73 enum EConstants : uint32
74 {
75 FakeInitChangeMaskOffset = 0xFFFFFFFFU,
76 };
77 typedef TMultiMap<uint32, FNetRefHandle> FObjectReferenceTracker;
79
80 struct FReplicatedObjectInfo
81 {
82 FReplicatedObjectInfo();
83
84 // We accumulate unresolved changes in this changemask
85 FChangeMaskStorageOrPointer UnresolvedChangeMaskOrPointer;
86
87 /* In order to be able to do partial updates the changemask bit is stored with the reference.
88 * That also means a reference can have many entries, but at most one per changemask bit. */
89 FObjectReferenceTracker UnresolvedObjectReferences;
90 FObjectReferenceTracker ResolvedDynamicObjectReferences;
91
92 // These maps provide a O(1) lookup for the number of handles referenced in
93 // UnresolvedObjectReferences and ResolvedDynamicObjectReferences.
94 TMap<FNetRefHandle, int16> UnresolvedHandleCount;
95 TMap<FNetRefHandle, int16> ResolvedDynamicHandleCount;
96
97 // Baselines
98 uint8* StoredBaselines[2];
99
100 uint32 InternalIndex; // InternalIndex
101 union
102 {
103 uint32 Value;
104 struct
105 {
106 uint32 ChangeMaskBitCount : 16; // This is cached to avoid having to look it up in the protocol
107 uint32 bHasUnresolvedReferences : 1; // Do we have unresolved references in the changemask?
108 uint32 bHasUnresolvedInitialReferences : 1; // Do we have unresolved initial only references
109 uint32 bHasAttachments : 1;
110 uint32 bDestroy : 1;
111 uint32 bTearOff : 1;
112 uint32 bIsDeltaCompressionEnabled : 1;
113 uint32 LastStoredBaselineIndex : 2; // Last stored baseline, as soon as we receive data compressed against the baseline we know that we can release older baselines
114 uint32 PrevStoredBaselineIndex : 2; // Previous stored baselines index
115 uint32 Padding : 7;
116 };
117 };
118
119 bool RemoveUnresolvedHandleCount(FNetRefHandle RefHandle);
120 bool RemoveResolvedDynamicHandleCount(FNetRefHandle RefHandle);
121 };
122
123 // Temporary Data to dispatch
124 struct FDispatchObjectInfo;
125
126 enum : uint32
127 {
128 ObjectIndexForOOBAttachment = 0U,
129 // Try to avoid reallocations for dispatch in the case we need to process a huge object
130 ObjectsToDispatchSlackCount = 32U,
131 };
132
133 bool IsObjectIndexForOOBAttachment(uint32 InternalIndex) const { return InternalIndex == ObjectIndexForOOBAttachment; }
134
135 // Read index part of handle
136 FNetRefHandle ReadNetRefHandleId(FNetSerializationContext& Context, FNetBitStreamReader& Reader) const;
137
138 enum EReadObjectFlag : unsigned
139 {
140 ReadObjectFlag_IsReadingHugeObjectBatch = 1U,
141 };
142
143 // Read a new or updated object
145
146 // Read object or subobject
148
150 uint32 ReadObjectsInBatchWithoutSizes(FNetSerializationContext& Context, FNetRefHandle InCompleteHandle, bool bHasBatchOwnerData, uint32 BatchEndBitPosition);
151 uint32 ReadObjectsInBatchWithSizes(FNetSerializationContext& Context, FNetRefHandle InCompleteHandle, bool bHasBatchOwnerData, uint32 BatchEndBitPosition);
152
153
154 // Read stream debug features. Use StreamDebugFeatures to see if a feature is enabled.
155 void ReadStreamDebugFeatures(FNetSerializationContext& Context);
156 // Read objects pending destroy. This will call ReadObjectsAndSubObjectsPendingDestroy or ReadRootObjectsPendingDestroy depending on sending side settings.
157 uint32 ReadObjectsPendingDestroy(FNetSerializationContext& Context);
158 // Receive both objects and subobject destruction. Legacy Iris behavior.
159 uint32 ReadObjectsAndSubObjectsPendingDestroy(FNetSerializationContext& Context);
160 // Receive only root object destruction and destroy all existing subobjects with them atomically.
161 uint32 ReadRootObjectsPendingDestroy(FNetSerializationContext& Context);
162
163 // Read state data for all incoming objects
165
166 // Process a single huge object attachment
167 void ProcessHugeObjectAttachment(FNetSerializationContext& Context, const TRefCountPtr<FNetBlob>& Attachment);
168
169 // Assemble and deserialize huge object if present
170 void ProcessHugeObject(FNetSerializationContext& Context);
171
172 // Resolve and dispatch unresolved references
173 void ResolveAndDispatchUnresolvedReferencesForObject(FNetSerializationContext& Context, uint32 InternalIndex);
174
175 // Resolve and dispatch unresolved references
176 void ResolveAndDispatchUnresolvedReferences();
177
178 // Dispatch all data received for the frame, this includes trying to resolve object references
179 void DispatchStateData(FNetSerializationContext& Context);
180
181 // Dispatch resolved attachments
182 void ResolveAndDispatchAttachments(FNetSerializationContext& Context, FReplicatedObjectInfo* ReplicationInfo, ENetObjectAttachmentDispatchFlags DispatchFlags);
183
184 // End replication for all objects that the server has told us to destroy or tear off
185 void DispatchEndReplication(FNetSerializationContext& Context);
186
187 // Create tracking info for the object with the given InternalInfo
188 FReplicatedObjectInfo& StartReplication(uint32 InternalIndex);
189
190 // Remove tracking info for the object with InternalIndex
191 void EndReplication(FInternalNetRefIndex InternalIndex, bool bTearOff, bool bDestroyInstance);
192
193 // Free any data allocated per object
194 void CleanupObjectData(FReplicatedObjectInfo& ObjectInfo);
195
196 // Lookup the tracking info for the object with IntnernalIndex
197 FReplicatedObjectInfo* GetReplicatedObjectInfo(uint32 InternalIndex);
198 const FReplicatedObjectInfo* GetReplicatedObjectInfo(uint32 InternalIndex) const;
199
200 // Update reference tracking maps for the current object
201 void UpdateObjectReferenceTracking(FReplicatedObjectInfo* ReplicationInfo, FNetBitArrayView ChangeMask, bool bIncludeInitState, FResolvedNetRefHandlesArray& OutNewResolvedRefHandles, const FObjectReferenceTracker& NewUnresolvedReferences, const FObjectReferenceTracker& NewMappedDynamicReferences);
202
203 // An optimized version of UpdateObjectReferenceTracking().
204 void UpdateObjectReferenceTracking_Fast(FReplicatedObjectInfo* ReplicationInfo, FNetBitArrayView ChangeMask, bool bIncludeInitState, FResolvedNetRefHandlesArray& OutNewResolvedRefHandles, const FObjectReferenceTracker& NewUnresolvedReferences, const FObjectReferenceTracker& NewMappedDynamicReferences);
205
206 // Remove all references for object
207 void CleanupReferenceTracking(FReplicatedObjectInfo* ObjectInfo);
208
209 // Update ReplicationInfo and OutUnresolvedChangeMask based on data collected by the Collector
211
212 void RemoveUnresolvedObjectReferenceInReplicationInfo(FReplicatedObjectInfo* ReplicationInfo, FNetRefHandle Handle);
213 void RemoveResolvedObjectReferenceInReplicationInfo(FReplicatedObjectInfo* ReplicationInfo, FNetRefHandle Handle);
214
215 // A previously resolved dynamic reference is now unresolvable. The ReplicationInfo needs to be updated to reflect this.
216 // Returns true if the reference was found.
217 bool MoveResolvedObjectReferenceToUnresolvedInReplicationInfo(FReplicatedObjectInfo* ReplicationInfo, FNetRefHandle UnresolvableHandle);
218
219 void DeserializeObjectStateDelta(FNetSerializationContext& Context, uint32 InternalIndex, FDispatchObjectInfo& Info, FReplicatedObjectInfo& ObjectInfo, const FNetRefHandleManager::FReplicatedObjectData& ObjectData, uint32& OutNewBaselineIndex);
220
221 // If async loading is enabled this function will verify if we can resolve all PendingMustBeMappedReferences
222 FPendingBatchData* UpdateUnresolvedMustBeMappedReferences(FNetRefHandle OwnerHandle, TArray<FNetRefHandle>& MustBeMappedReferences, EIrisAsyncLoadingPriority InIrisAsyncLoadingPriority);
223
224 // Returns true if the object assigned to this handle has been instantiated locally
225 bool DoesParentExist(FNetRefHandle ObjectHandle) const;
226
227 // If we are queuing data for a batch we must also defer calls to EndReplication
228 // This method writes this method in the form of a QueuedChunk
230
231 // Remove a handle from the hot and cold unresolved caches used by ResolveAndDispatchUnresolvedReferences(). If this handle is marked as unresolved
232 // again, it will be added to the hot cache.
233 void RemoveFromUnresolvedCache(const FNetRefHandle Handle);
234
235 // Reads and verifies the sentinel was read properly. If an error is detected the context will have an error set. The function will return true if the sentinel matches, false otherwise.
236 bool ReadSentinel(FNetSerializationContext& Context, const TCHAR* DebugName);
237
238private:
239
241
242 FReplicationParameters Parameters;
243
244 FMemStackBase TempLinearAllocator;
245 FMemStackChangeMaskAllocator TempChangeMaskAllocator;
246
247 FGlobalChangeMaskAllocator PersistentChangeMaskAllocator;
248
249 FReplicationSystemInternal* ReplicationSystemInternal;
250 FNetRefHandleManager* NetRefHandleManager;
251 FReplicationStateStorage* StateStorage;
252 UObjectReplicationBridge* ReplicationBridge;
253
254 // A cache holding unresolved handles that should be resolved each time ResolveAndDispatchUnresolvedReferences() is called.
255 TMap<FNetRefHandle, uint32> HotUnresolvedHandleCache;
256
257 // A cache holding unresolved handles that should be resolved by ResolveAndDispatchUnresolvedReferences() at fixed intervals.
258 TMap<FNetRefHandle, uint32> ColdUnresolvedHandleCache;
259
260 // Temporary buffers used by ResolveAndDispatchUnresolvedReferences().
261 TSet<FNetRefHandle> VisitedUnresolvedHandles;
262 TSet<FInternalNetRefIndex> InternalObjectsToResolve;
263
264 // We track some data about incoming objects
265 // Stored in a map for now
266 TMap<uint32, FReplicatedObjectInfo> ReplicatedObjects;
267
268 // Temporary data valid during receive
269 FObjectsToDispatchArray* ObjectsToDispatchArray;
270
271 // We need to keep some data around for objects with pending dependencies
272 // For now just use array and brute force the updates
273 TArray<uint32> ObjectsWithAttachmentPendingResolve;
274
275 // Track all objects waiting for this handle to be resolvable
276 TMultiMap<FNetRefHandle, FInternalNetRefIndex /*OwnerInternalIndex*/> UnresolvedHandleToDependents;
277
278 // Track all objects with a dynamic handle in case it becomes unresolvable
279 TMultiMap<FNetRefHandle, uint32> ResolvedDynamicHandleToDependents;
280
281 // We do not expect to have many objects in this state
282 FPendingBatchHolder PendingBatchHolder;
283
284 // We do not expect many objects to be broken
285 TArray<FNetRefHandle> BrokenObjects;
286
287 // Keep track of the last time we warned about an object blocked by this must be mapped reference
288 // Prevents spamming errors for multiple objects all waiting on the same asset
289 TMap<FNetRefHandle, double> BlockedMustBeMappedLastWarningTime;
290
291 // Used during receive and processing of pending batches
292 TArray<FNetRefHandle> TempMustBeMappedReferences;
293
294 // Preallocate the arrays used by BuildUnresolvedChangeMaskAndUpdateObjectReferenceTracking() to
295 // avoid memory allocations during the frame.
296 FObjectReferenceTracker UnresolvedReferencesCache;
297 FObjectReferenceTracker MappedDynamicReferencesCache;
298
299 FNetBlobHandlerManager* NetBlobHandlerManager;
300 FNetBlobType NetObjectBlobType;
301 FNetObjectAttachmentsReader Attachments;
302 FObjectReferenceCache* ObjectReferenceCache;
303 FNetObjectResolveContext ResolveContext;
304
305 IConsoleVariable const* DelayAttachmentsWithUnresolvedReferences;
306 uint32 NumHandlesPendingResolveLastUpdate = 0U;
307
308 // Features that can aid in tracking down bitstream errors etc.
310};
311
312}
FPlatformTypes::TCHAR TCHAR
Either ANSICHAR or WIDECHAR, depending on whether the platform supports wide characters or the requir...
Definition Platform.h:1135
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define ENUM_CLASS_FLAGS(Enum)
Definition EnumClassFlags.h:6
void Init()
Definition LockFreeList.h:4
EIrisAsyncLoadingPriority
Definition ObjectReferenceTypes.h:14
int32 InternalIndex
Definition VulkanMemory.cpp:4036
uint8_t uint8
Definition binka_ue_file_header.h:8
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition MemStack.h:78
Definition IConsoleManager.h:558
Definition Array.h:670
Definition UnrealString.h.inl:34
Definition RefCounting.h:454
Definition NetBitArray.h:337
Definition NetBitStreamReader.h:11
Definition NetRefHandle.h:25
Definition NetSerializationContext.h:31
Definition ReplicationStateStorage.h:48
Definition ChangeMaskUtil.h:29
Definition NetBlobHandlerManager.h:11
Definition AttachmentReplication.h:219
Definition NetRefHandleManager.h:72
Definition ObjectReferenceCache.h:38
Definition ReplicationReader.h:51
void UpdateUnresolvableReferenceTracking()
Definition ReplicationReader.cpp:2525
void ProcessQueuedBatches()
Definition ReplicationReader.cpp:2764
FString PrintObjectInfo(FInternalNetRefIndex ObjectIndex, FNetRefHandle NetRefHandle) const
Definition ReplicationReader.cpp:3341
void Deinit()
Definition ReplicationReader.cpp:394
~FReplicationReader()
Definition ReplicationReader.cpp:354
FReplicationReader()
Definition ReplicationReader.cpp:341
Definition ReplicationSystemInternal.h:46
Definition ObjectReplicationBridge.h:83
Definition OverriddenPropertySet.cpp:45
Definition NetworkVersion.cpp:28
EReplicationDataStreamDebugFeatures
Definition ReplicationDataStreamDebug.h:24
@ None
Definition ReplicationDataStreamDebug.h:25
uint32 FInternalNetRefIndex
Definition ReplicationStateStorage.h:20
ENetObjectAttachmentDispatchFlags
Definition ReplicationReader.h:42
Definition NetworkVersion.cpp:28
uint32 FNetBlobType
Definition NetBlob.h:46
Definition ObjectReferenceCacheFwd.h:30
Definition ChangeMaskUtil.h:14
Definition PendingBatchData.h:41
Definition PendingBatchData.h:74
Definition ReplicationTypes.h:17