UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
ReplicationWriter.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
17#include "Iris/Stats/NetStats.h"
18#include "Containers/Array.h"
19#include "Containers/Map.h"
20#include "Containers/List.h"
21#include "Containers/Set.h"
22#include "Misc/EnumClassFlags.h"
23
24// Forward declaration
29
30namespace UE::Net
31{
32 class FNetBitStreamReader;
33 class FNetBitStreamWriter;
34 class FNetObjectAttachment;
35 class FNetSerializationContext;
36 struct FReplicationProtocol;
37
38 namespace Private
39 {
40 struct FChangeMaskCache;
41 class FNetRefHandleManager;
42 class FReliableNetBlobQueue;
43 class FReplicationConditionals;
44 class FReplicationFiltering;
45 class FReplicationSystemInternal;
46 class FDeltaCompressionBaselineManager;
47 class FDeltaCompressionBaseline;
48 }
49}
50
51namespace UE::Net::Private
52{
53
55{
56public:
57 // Scheduling constants
58 static constexpr float CreatePriority = 1.f;
59 static constexpr float TearOffPriority = 1.f;
60 static constexpr float LostStatePriorityBump = 1.f;
61 static constexpr float SchedulingThresholdPriority = 1.f;
62
63 // When scheduling there is no point in scheduling more objects than we can fit in a packet
64 static const uint32 PartialSortObjectCount = 128u;
65
66public:
67
68 // State
70 {
71 Invalid = 0,
72
73 // Special states
74 AttachmentToObjectNotInScope, // Special state for object index used for sending attachments to remote owned objects
75 HugeObject, // Special state for object index used for sending parts of huge object payloads
76
77 // Normal states
78 PendingCreate, // Not yet created, no data in flight
79 WaitOnCreateConfirmation, // Waiting for confirmation from remote, we can send state data, but if we do we must also include creation info until the object is Created
80 Created, // Confirmed by remote, this is the normal replicating state
81 WaitOnFlush, // Pending flush, we are waiting for all in-flight state data to be acknowledged
82 PendingTearOff, // TearOff should be sent
83 SubObjectPendingDestroy, // SubObject destroy should be sent
84 CancelPendingDestroy, // Destroy was sent but object wants to start replicating again
85 PendingDestroy, // Object is set to be destroyed
86 WaitOnDestroyConfirmation, // Destroy has been sent, waiting for response from client
87 Destroyed, // Confirmed as Destroyed,
88 PermanentlyDestroyed, // DestructionInfo has been confirmed as received
89
90 Count
91 };
92
93 static_assert((uint8)(EReplicatedObjectState::Count) <= 32, "EReplicatedObjectState must fit in 5 bits. See FReplicationInfo::State and FReplicationRecord::FRecordInfo::ReplicatedObjectState members.");
94
95 static const TCHAR* LexToString(const EReplicatedObjectState State);
96
98 {
100 FlushFlags_FlushState = 1U << 0U, // Make sure that all current state data is acknowledged before we stop replicating the object
101 FlushFlags_FlushReliable = FlushFlags_FlushState << 1U, // Make sure that all enqueued Reliable RPCs are delivered before we stop replicating the object
102 FlushFlags_FlushTornOffSubObjects = FlushFlags_FlushReliable << 1U, // Make sure that we flush TearOff and replicated destroy properly
105 };
106
107 // Bookkeeping info required for a replicated object
108 // Keep as small as possible since there is one per replicated object per connection
109 // Changemask can and will most likely be replaced by a smaller index into a pool to reduce overhead
111 {
112 inline FReplicationInfo();
113
114 FChangeMaskStorageOrPointer ChangeMaskOrPtr; // Changemask storage or pointer to storage
115 union
116 {
118 struct
119 {
120 uint64 ChangeMaskBitCount : 16; // This is cached to avoid having to look it up in the protocol
121 uint64 State : 5; // Current state
122 uint64 HasDirtySubObjects : 1; // Set if this object has dirty subobjects
123 uint64 IsSubObject : 1; // Set if this object is a subobject
124 uint64 HasDirtyChangeMask : 1; // Set if the ChangeMask might be dirty, if not set the changemask should be zero!
125 uint64 HasAttachments : 1; // Set if there are attachments, such as RPCs, waiting to be sent
126 uint64 HasChangemaskFilter : 1; // Do we need to filter our changemask or not
127 uint64 IsDestructionInfo : 1; // If this is a destruction info
128 uint64 IsCreationConfirmed : 1; // We know that this object has been created on the receiving end
129 uint64 TearOff : 1; // This object should be torn off
130 uint64 SubObjectPendingDestroy : 1; // This object is a subobject that should be destroyed when we replicate owner
131 uint64 IsDeltaCompressionEnabled : 1; // Set to 1 if deltacompression is enabled for this object
132 uint64 LastAckedBaselineIndex : 2; // Last acknowledged baseline index which we can use for deltacompresion
133 uint64 PendingBaselineIndex : 2; // Baseline index pending acknowledgment from client
134 uint64 FlushFlags : 3; // Flags indicating what we are waiting for when flushing
135 uint64 HasDirtyConditionals : 1; // If this flag is set, we must update conditionals.
136 mutable uint64 HasCannotSendInfo : 1; // If this flag is set, the object has been prevented from being sent at least once.
137 };
138 };
139
141
143
146 };
147
148 static_assert(sizeof(FReplicationInfo) == 16, "Expected sizeof FReplicationInfo to be 16 bytes");
149
155
156public:
158
159 // Init
161
162 void Deinit();
163
164 // Update new or existing/destroyed
166
167 // Force update DirtyChangeMasks and mark objects for flush and/or tearoff depending on flags
169
170 // Called if an object first being teared-off/flushed and then explicitly destroyed before it has been removed from scope
172
173 // Called to propagate changes to global lifetime conditionals
175
176 // Propagate dirty changemasks
178
179 // Returns objects that are in need of a priority update. It could be dirty, new or objects in need of resending.
181
182 // UpdatedPriorities contains priorities for all objects. Objects in need of a priority update should use the newly calculated priorities.
183 void UpdatePriorities(const float* UpdatedPriorities);
184
186
187 // WriteData to Packet, returns true for now if data was written
189
190 void EndWrite();
191
192 // Deal with processing of lost and delivered data.
194
196 bool IsReplicationEnabled() const;
197
199
200 // Attachments
201 // Queue NetObjectAttachments, returns whether the attachments was enqueued or not.
203
205
206 void Update(const UDataStream::FUpdateParameters& Params);
207
208 [[nodiscard]] FString PrintObjectInfo(FInternalNetRefIndex ObjectIndex) const;
209
210private:
211 // Various types
212
213 enum : uint32
214 {
215 ObjectIndexForOOBAttachment = 0U,
216 };
217
218 // Propagate dirty changemasks
219 void InternalUpdateDirtyChangeMasks(const FChangeMaskCache& CachedChangeMasks, EFlushFlags ExtraFlushFlags, bool bTearOff);
220
221 struct FScheduleObjectInfo
222 {
224 float SortKey;
225 };
226
227 // We persist some information during write so that we can support writing multiple packets with data without re-doing scheduling work.
228 struct FWriteContext
229 {
230 FWriteContext() : bIsValid(0) {}
231
232 // Objects we have written in this packet batch to avoid sending same object multiple times
233 FNetBitArray ObjectsWrittenThisPacket;
234 // DependentObjets that we should try to write this packet batch, aka. allow overcommit if we have pending DependentObjects when the packet is full
235 TArray<uint32, TInlineAllocator<32>> DependentObjectsPendingSend;
236 // Scheduled objects
237 FScheduleObjectInfo* ScheduledObjectInfos;
238 uint32 ScheduledObjectCount;
239
240 // For performance sake we do partial sorting so we need to track how many object we have sorted.
241 uint32 SortedObjectCount;
242 // The index into the scheduled objects array to attempt to replicate next.
243 uint32 CurrentIndex;
244
245 // Written batch count, which excludes objects pending destroy and subobjects
246 uint32 WrittenBatchCount;
247
248 // How many objects that were attempted to be replicated but which ultimately didn't fit in the packet.
249 uint32 FailedToWriteSmallObjectCount;
250
251 // How many root object destroys and destruction infos have been replicated.
252 uint32 WrittenDestroyObjectCount;
253
254 // How many packets have we written to?
255 uint32 NumWrittenPacketsInThisBatch = 0U;
256
257 // How many packets are we allowed to send in this batch. Based off the netspeed limit. When 0 = unlimited packets
258 uint32 MaxPacketsToSend = 1U;
259
261
262 // Whether we're running low on ReplicationRecords or not. If starving only OOB and huge objects are sent, if at all possible.
263 uint32 bIsInReplicationRecordStarvation : 1;
264 // Whether there are destroyed objects to send or not
265 uint32 bHasDestroyedObjectsToSend : 1;
266 // Whether there are dirty objects to send or not
267 uint32 bHasUpdatedObjectsToSend : 1;
268 // Whether there is at least one huge object to send or not
269 uint32 bHasHugeObjectToSend : 1;
270 // Whether there are OOB attachments to send or not
271 uint32 bHasOOBAttachmentsToSend : 1;
272 // Whether this packet is mainly intended for OOB and HugeObject data
273 uint32 bIsOOBPacket : 1;
274 // Whether this context is valid or not
275 uint32 bIsValid : 1;
276
277 FNetSendStats Stats;
278 };
279
280 struct FBatchObjectInfo
281 {
282 FNetRefHandle Handle;
285 ENetObjectAttachmentType AttachmentType;
286 bool bHasUnsentAttachments;
287 uint32 NewBaselineIndex : 2;
288 uint32 bIsInitialState : 1;
289 uint32 bSentState : 1;
290 uint32 bSentAttachments : 1;
291 uint32 bHasDirtySubObjects : 1;
292 uint32 bSentTearOff : 1;
293 uint32 bSentDestroySubObject : 1;
294 uint32 bSentBatchData : 1;
295 };
296
297 enum class EBatchInfoType : uint32
298 {
299 Object,
301 OOBAttachment,
302 Internal,
303 // Currently unused as destruction infos don't create a BatchInfo.
304 DestructionInfo,
305 };
306
307 struct FBatchInfo
308 {
310 uint32 ParentInternalIndex;
311 EBatchInfoType Type;
312 };
313
314 struct FObjectRecord
315 {
316 FReplicationRecord::FRecordInfo Record;
318 };
319
320 struct FBatchRecord
321 {
322 TArray<FObjectRecord, TInlineAllocator<16>> ObjectReplicationRecords;
323 uint32 BatchCount = 0U;
324 };
325
326 struct FBitStreamInfo
327 {
328 uint32 ReplicationStartPos;
329 uint32 BatchStartPos;
330 uint32 ReplicationCapacity;
331 };
332
333 enum class EHugeObjectSendStatus : uint32
334 {
335 Idle,
336 Sending,
337 };
338
339 struct FHugeObjectContext
340 {
341 FHugeObjectContext();
342 ~FHugeObjectContext();
343
344 FInternalNetRefIndex RootObjectInternalIndex = 0;
345 FBatchRecord BatchRecord;
346 FNetExportContext::FBatchExports BatchExports;
347
348 // The entire payload. When refcount reaches one for all blobs the object has been fully acked.
350 };
351
352 class FHugeObjectSendQueue
353 {
354 public:
355 FHugeObjectSendQueue();
356 ~FHugeObjectSendQueue();
357
358 // If the queue is full we can't start another send.
359 bool IsFull() const;
360 bool IsEmpty() const;
361 uint32 NumRootObjectsInTransit() const;
362
363 // Enqueue huge object info and return true if it can be sent.
364 bool EnqueueHugeObject(const FHugeObjectContext& Context);
365
366 // Returns true if the object is a huge object root object or part of any huge object's payload. The latter is an expensive operation.
367 bool IsObjectInQueue(FInternalNetRefIndex ObjectIndex, bool bFullSearch) const;
368
369 // Best effort implementation of getting a valid index for trace.
370 FInternalNetRefIndex GetRootObjectInternalIndexForTrace() const;
371
372 // Call AckHugeObject on all objects determined to have been fully processed.
373 void AckObjects(TFunctionRef<void (const FHugeObjectContext& Context)> AckHugeObject);
374
375 void FreeContexts(TFunctionRef<void (const FHugeObjectContext& Context)> FreeHugeObject);
376
377 public:
378 // Public members
379 struct FStats
380 {
381 // Cycle counter for when the huge object context went from idle to sending.
383 // Cycle counter for when the last part of huge object was sent.
385 // Cycle counter for when it was detected that no more parts of the huge object could be sent until some of the first parts have been acked.
387 };
388
389 FStats Stats;
390
391 FNetTraceCollector* TraceCollector = nullptr;
392 const FNetDebugName* DebugName = nullptr;
393
394 private:
395 TSet<FInternalNetRefIndex> RootObjectsInTransit;
397 };
398
399 enum EWriteObjectFlag : unsigned
400 {
401 WriteObjectFlag_State = 1U,
402 WriteObjectFlag_Attachments = WriteObjectFlag_State << 1U,
403 WriteObjectFlag_HugeObject = WriteObjectFlag_Attachments << 1U,
404 WriteObjectFlag_IsWritingHugeObjectBatch = WriteObjectFlag_HugeObject << 1U,
405 };
406
407 enum class EWriteObjectRetryMode : unsigned
408 {
409 // Stop trying to write more object this frame.
410 Abort,
411 // Continue with something smaller, it might succeed.
412 TrySmallObject,
413 // The object is probably huge. Enter special mode for huge objects.
414 SplitHugeObject,
415 };
416
417 enum class EWriteObjectStatus : unsigned
418 {
419 Success,
420
421 // The object is in an invalid state and won't be written. This is not considered a failure.
422 InvalidState,
423
424 // BitStream overflow.
425 BitStreamOverflow,
426
427 // A detached instance, which no longer has an instance protocol. This object cannot be replicated.
428 NoInstanceProtocol,
429
430 // A subobject with an invalid owner.
431 InvalidOwner,
432
433 // Some error occurred while serializing the object.
434 Error,
435
436 };
437
438private:
439
440 void SetNetObjectListsSize(FInternalNetRefIndex NewMaxInternalIndex);
441 void OnMaxInternalNetRefIndexIncreased(FInternalNetRefIndex NewMaxInternalIndex);
442
443 uint32 GetDefaultFlushFlags() const;
444 uint32 GetFlushStatus(uint32 InternalIndex, const FReplicationInfo& Info, uint32 FlushFlagsToTest = EFlushFlags::FlushFlags_Default) const;
445 void SetPendingDestroyOrSubObjectPendingDestroyState(uint32 Index, FReplicationInfo& Info);
446
447 bool IsObjectIndexForOOBAttachment(uint32 InternalIndex) const { return InternalIndex == ObjectIndexForOOBAttachment; }
448
449 void GetInitialChangeMask(ChangeMaskStorageType* ChangeMaskStorage, const FReplicationProtocol* Protocol);
450
451 // Start replication of new object with the specified InternalIndex
452 void StartReplication(uint32 InternalIndex);
453
454 // Stop replication object with the specified InternalIndex
455 void StopReplication(uint32 InternalIndex);
456
457 // Get ReplicationInfo for specified InternalIndex, prefer to use this method over direct access.
458 FReplicationInfo& GetReplicationInfo(uint32 InternalIndex);
459 const FReplicationInfo& GetReplicationInfo(uint32 InternalIndex) const;
460
461 // Set the state of a ReplicatedObject, prefer this method to enable logging
462 void SetState(uint32 InternalIndex, EReplicatedObjectState NewState);
463
464 // Write index part of handle
465 void WriteNetRefHandleId(FNetSerializationContext& Context, FNetRefHandle RefHandle);
466
467 // Create new ObjectRecord
468 // Note: be aware that it will allocate a copy of the ChangeMask that needs to be handled if the record is not Committed
469 void CreateObjectRecord(const FNetBitArrayView* ChangeMask, const FReplicationInfo& Info, const FBatchObjectInfo& ObjectInfo, FObjectRecord& OutRecord);
470
471 // Push and link info for written object to ReplicationRecord
472 void CommitObjectRecord(uint32 InternalObjectIndex, const FObjectRecord& Record);
473 // Push and link info for destroyed root object
474 void CommitObjectDestroyRecord(uint32 InternalObjectIndex, const FObjectRecord& ObjectRecord, const FReplicationRecord::FSubObjectRecord& SubObjectRecord);
475
476 void CommitBatchRecord(const FBatchRecord& BatchRecord);
477
478 void ScheduleDependentObjects(uint32 Index, float ParentPriority, TArray<float>& LocalPriorities, FScheduleObjectInfo* ScheduledObjectIndices, uint32& OutScheduledObjectCount);
479
480 uint32 ScheduleObjects(FScheduleObjectInfo* ScheduledObjectIndices);
481
482 // Partial sort of OutScheduledObjectIndices, will sort at most PartialSortObjectCount objects
483 uint32 SortScheduledObjects(FScheduleObjectInfo* ScheduledObjectIndices, uint32 ScheduledObjectCount, uint32 StartIndex);
484
485 // Update the active set of stream debug features based on cvars, build configuration etc. Enabling certain debug features can help track down bitstream errors.
486 void UpdateStreamDebugFeatures();
487 // Write stream debug features.
488 void WriteStreamDebugFeatures(FNetSerializationContext& Context);
489 // Write all objects pending destroy (or as many as we fit in the current packet). Will call one of WriteObjectsAndSubObjectsPendingDestroy and WriteRootObjectsPendingDestroy depending on cvar net.Iris.DestroyRootAndSubObjectsIndividually
490 uint32 WriteObjectsPendingDestroy(FNetSerializationContext& Context);
491 // Used when net.Iris.DestroyRootAndSubObjectsIndividually is true. Will send destroy for every root and subobject. Leagcy Iris behavior.
492 uint32 WriteObjectsAndSubObjectsPendingDestroy(FNetSerializationContext& Context);
493 // Used when net.Iris.DestroyRootAndSubObjectsIndividually is false. Will only send destroy for root objects and subobjects will be gathered on the client side and destroyed. This guarantees atomic object hierarchy destroys.
494 uint32 WriteRootObjectsPendingDestroy(FNetSerializationContext& Context);
495
496 // Write object and SubObjects
497 EWriteObjectStatus WriteObjectAndSubObjects(FNetSerializationContext& Context, uint32 InternalIndex, uint32 WriteObjectFlags, FBatchInfo& OutBatchInfo);
498
499 // Write objects recursive
500 EWriteObjectStatus WriteObjectInBatch(FNetSerializationContext& Context, uint32 InternalIndex, uint32 WriteObjectFlags, FBatchInfo& OutBatchInfo);
501
502 enum class EWriteStatus : int32
503 {
504 // Stream is full and we should stop serializing more objects
505 Abort = -1,
506 // Object was skipped and won't be retried again. Ex: failed dependency, waiting for creation confirmation or buffer won't fit the object and its the last packet to send.
507 Skipped = 0,
508 // Object was successfully written
509 Written = 1,
510 };
511
512 // Write destruction info for an object that should be destroyed
513 // returns > 1 if Objects was written, 0 if the objects was skipped (failed dependency or waiting for creation confirmation) -1 if the stream is full and we should stop
514 EWriteStatus WriteDestructionInfo(FNetSerializationContext& Context, uint32 InternalIndex);
515
516 bool WriteNetRefHandleDestructionInfo(FNetSerializationContext& Context, FNetRefHandle Handle);
517
518 struct FWriteBatchResult
519 {
520 EWriteStatus Status = EWriteStatus::Skipped;
521 uint32 NumWritten = 0;
522 };
523
524 // Write Object and any subobject(s) to stream as an atomic batch
525 // returns > 1 if Objects was written, 0 if the objects was skipped (failed dependency or waiting for creation confirmation) -1 if the stream is full and we should stop
526 FWriteBatchResult WriteObjectBatch(FNetSerializationContext& Context, FInternalNetRefIndex InternalIndex, uint32 WriteObjectFlags);
527
528 EWriteStatus PrepareAndSendHugeObjectPayload(FNetSerializationContext& Context, FInternalNetRefIndex InternalIndex);
529
530 // Write OOBAttachments
531 uint32 WriteOOBAttachments(FNetSerializationContext& Context);
532
533 // Write as many scheduled objects to stream as we can fit.
534 uint32 WriteObjects(FNetSerializationContext& Context);
535
536 // Updates ReplicationInfos, pushes ReplicationRecords etc after a successful call to WriteObjectInBatch() on a top level object
537 uint32 HandleObjectBatchSuccess(const FBatchInfo& BatchInfo, FBatchRecord& OutRecord);
538
539 // Determines the best course of action after a WriteObjectBatch() call failed.
540 EWriteObjectRetryMode HandleObjectBatchFailure(EWriteObjectStatus WriteObjectStatus, const FBatchInfo& BatchInfo, const FBitStreamInfo& BatchBitStreamInfo);
541
542 // Update logic for dropped RecordInfo
543 void HandleDroppedRecord(const FReplicationRecord::FRecordInfo& RecordInfo, FReplicationInfo& Info, const FNetObjectAttachmentsWriter::FReliableReplicationRecord& AttachmentRecord);
544 template<EReplicatedObjectState LostState> void HandleDroppedRecord(EReplicatedObjectState CurrentState, const FReplicationRecord::FRecordInfo& RecordInfo, FReplicationInfo& Info, const FNetObjectAttachmentsWriter::FReliableReplicationRecord& AttachmentRecord);
545
546 // Update logic for delivered RecordInfo
547 void HandleDeliveredRecord(const FReplicationRecord::FRecordInfo& RecordInfo, FReplicationInfo& Info, const FNetObjectAttachmentsWriter::FReliableReplicationRecord& AttachmentRecord);
548
549 // Update logic for discarded RecordInfo, for preventing memory leaks on disconnect and shutdown.
550 void HandleDiscardedRecord(const FReplicationRecord::FRecordInfo& RecordInfo, FReplicationInfo& Info, const FNetObjectAttachmentsWriter::FReliableReplicationRecord& AttachmentRecord);
551
552 // Setup replication info to be able to send attachments to objects not in scope
553 void SetupReplicationInfoForAttachmentsToObjectsNotInScope();
554
555 void ApplyFilterToChangeMask(uint32 ParentInternalIndex, uint32 InternalIndex, FReplicationInfo& Info, const FReplicationProtocol* Protocol, const uint8* InternalStateBuffer, bool bIsInitialState);
556
557 // Patchup changemask to include any in-flight changes. Returns true if in-flight changes were added.
558 bool PatchupObjectChangeMaskWithInflightChanges(uint32 InternalIndex, FReplicationInfo& Info);
559
560 // Invalidate all inflight baseline information
561 void InvalidateBaseline(uint32 InternalIndex, FReplicationInfo& Info);
562
563 // Returns true if the record chain starting from the provided RecordInfo contains any records with statedata
564 // Note: Does not check if it is part of a huge object
565 bool HasInFlightStateChanges(uint32 InternalIndex, const FReplicationInfo& Info) const;
566
567 // Returns true if object has pending state changes in flight
568 // Note: Does not check if it is part of a huge object
569 bool HasInFlightStateChanges(const FReplicationRecord::FRecordInfo* RecordInfo) const;
570
571 // Returns true object and subobjects can be created on remote
572 bool CanSendObject(uint32 InternalIndex) const;
573
575
576 bool IsActiveHugeObject(uint32 InternalIndex) const;
577 bool IsObjectPartOfActiveHugeObject(uint32 InternalIndex) const;
578
579 bool CanQueueHugeObject() const;
580
581 void FreeHugeObjectSendQueue();
582
583 bool HasDataToSend(const FWriteContext& Context) const;
584
585 void CollectAndAppendExports(FNetSerializationContext& Context, uint8* RESTRICT InternalBuffer, const FReplicationProtocol* Protocol) const;
586
587 bool IsWriteObjectSuccess(EWriteObjectStatus Status) const;
588
589 void SerializeObjectStateDelta(FNetSerializationContext& Context, uint32 InternalIndex, const FReplicationInfo& Info, const FNetRefHandleManager::FReplicatedObjectData& ObjectData, const uint8* RESTRICT ReplicatedObjectStateBuffer, FDeltaCompressionBaseline& CurrentBaseline, uint32 CreatedBaselineIndex);
590
591 void DiscardAllRecords();
592 void StopAllReplication();
593
594 void MarkObjectDirty(FInternalNetRefIndex InternalIndex, const char* Caller);
595
596 // Writes a sentinel naking it easier for the receiver to detect bitstream errors.
597 void WriteSentinel(FNetBitStreamWriter* Writer, const TCHAR* DebugName);
598
599 // Returns a valid FCannotSendInfo if we should start tracking how long we are blocked from sending.
600 FCannotSendInfo* ShouldWarnIfCannotSend(const FReplicationInfo& Info, FInternalNetRefIndex InternalIndex) const;
601
602private:
603 // Replication parameters
604 FReplicationParameters Parameters;
605
606 // Record of all in-flight data
607 FReplicationRecord ReplicationRecord;
608
609 // Tracking information for the state of all objects
610 TArray<FReplicationInfo> ReplicatedObjects;
611
612 // Tracking information linking all in-flight data per object
613 TArray<FReplicationRecord::FRecordInfoList> ReplicatedObjectsRecordInfoLists;
614
615 // Each replicated object has a scheduling priority that is bumped every time we have a chance to send and zeroed out every time the object is successfully sent
616 TArray<float> SchedulingPriorities;
617
618 // Track Objects Pending Destroy?
619 FNetBitArray ObjectsPendingDestroy;
620
621 // Objects in this bitArray with dirty change masks
622 FNetBitArray ObjectsWithDirtyChanges;
623
624 // Track Objects That is in scope for this connection
625 FNetBitArray ObjectsInScope;
626
627 // Handles logic for all attachments to objects.
628 FNetObjectAttachmentsWriter Attachments;
629
630 // Cached internal systems
631 FReplicationSystemInternal* ReplicationSystemInternal = nullptr;
632 FNetRefHandleManager* NetRefHandleManager = nullptr;
633 UObjectReplicationBridge* ReplicationBridge = nullptr;
634 FDeltaCompressionBaselineManager* BaselineManager = nullptr;
635 FObjectReferenceCache* ObjectReferenceCache = nullptr;
636 const FReplicationFiltering* ReplicationFiltering = nullptr;
637 FReplicationConditionals* ReplicationConditionals = nullptr;
638 const UPartialNetObjectAttachmentHandler* PartialNetObjectAttachmentHandler = nullptr;
639 const UNetObjectBlobHandler* NetObjectBlobHandler = nullptr;
640 FNetExports* NetExports = nullptr;
641 FNetTypeStats* NetTypeStats = nullptr;
642
643 FWriteContext WriteContext;
644 FBitStreamInfo WriteBitStreamInfo;
645 FHugeObjectSendQueue HugeObjectSendQueue;
646 // Features that can aid in tracking down bitstream errors etc.
648
649 // Is replication enabled?
650 bool bReplicationEnabled = false;
651
652 // Should we use high prio create?
653 const bool bHighPrioCreate = false;
654
655 mutable TMap<FInternalNetRefIndex, FCannotSendInfo> CannotSendInfos;
656};
657
662
663template<FReplicationWriter::EReplicatedObjectState LostState> void FReplicationWriter::HandleDroppedRecord(FReplicationWriter::EReplicatedObjectState CurrentState, const FReplicationRecord::FRecordInfo& RecordInfo, FReplicationWriter::FReplicationInfo& Info, const FNetObjectAttachmentsWriter::FReliableReplicationRecord& AttachmentRecord)
664{
665 //static_assert(false, "Expected specialization to exist.");
666}
667
668}
FPlatformTypes::TCHAR TCHAR
Either ANSICHAR or WIDECHAR, depending on whether the platform supports wide characters or the requir...
Definition Platform.h:1135
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
#define RESTRICT
Definition Platform.h:706
FPlatformTypes::uint64 uint64
A 64-bit unsigned integer.
Definition Platform.h:1117
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
void Init()
Definition LockFreeList.h:4
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 ArrayView.h:139
Definition Array.h:670
Definition List.h:439
Definition AssetRegistryState.h:50
Definition UnrealString.h.inl:34
Definition RefCounting.h:454
EWriteResult
Definition DataStream.h:65
Definition NetBitArray.h:337
Definition NetBitArray.h:74
Definition NetSerializationContext.h:31
Definition ChangeMaskUtil.h:29
StorageWordType * GetPointer(uint32 BitCount)
Definition ChangeMaskUtil.h:72
Definition NetExports.h:17
FNetObjectAttachmentSendQueue::FReliableReplicationRecord FReliableReplicationRecord
Definition AttachmentReplication.h:113
FNetObjectAttachmentSendQueue::FCommitRecord FCommitRecord
Definition AttachmentReplication.h:112
Definition ReplicationWriter.h:55
FString PrintObjectInfo(FInternalNetRefIndex ObjectIndex) const
Definition ReplicationWriter.cpp:4255
bool AreAllReliableAttachmentsSentAndAcked() const
Definition ReplicationWriter.cpp:341
void Deinit()
Definition ReplicationWriter.cpp:463
bool QueueNetObjectAttachments(FInternalNetRefIndex OwnerInternalIndex, FInternalNetRefIndex SubObjectInternalIndex, TArrayView< const TRefCountPtr< FNetBlob > > Attachments, ENetObjectAttachmentSendPolicyFlags SendFlags)
Definition ReplicationWriter.cpp:287
static const uint32 PartialSortObjectCount
Definition ReplicationWriter.h:64
void UpdateDirtyChangeMasks(const FChangeMaskCache &CachedChangeMasks)
Definition ReplicationWriter.h:177
bool IsReplicationEnabled() const
Definition ReplicationWriter.cpp:280
static constexpr float LostStatePriorityBump
Definition ReplicationWriter.h:60
void UpdatePriorities(const float *UpdatedPriorities)
Definition ReplicationWriter.cpp:1092
void ProcessDeliveryNotification(EPacketDeliveryStatus PacketDeliveryStatus)
Definition ReplicationWriter.cpp:1793
static const TCHAR * LexToString(const EReplicatedObjectState State)
Definition ReplicationWriter.cpp:122
EReplicatedObjectState
Definition ReplicationWriter.h:70
const FNetBitArray & GetObjectsRequiringPriorityUpdate() const
Definition ReplicationWriter.cpp:1087
void EndWrite()
Definition ReplicationWriter.cpp:3811
void SetNetExports(FNetExports &InNetExports)
Definition ReplicationWriter.cpp:4110
void NotifyDestroyedObjectPendingEndReplication(FInternalNetRefIndex ObjectInternalIndex)
Definition ReplicationWriter.cpp:1078
void UpdateDirtyGlobalLifetimeConditionals(TArrayView< FInternalNetRefIndex > ObjectsWithDirtyConditionals)
Definition ReplicationWriter.cpp:949
EFlushFlags
Definition ReplicationWriter.h:98
@ FlushFlags_FlushTornOffSubObjects
Definition ReplicationWriter.h:102
@ FlushFlags_FlushReliable
Definition ReplicationWriter.h:101
@ FlushFlags_None
Definition ReplicationWriter.h:99
@ FlushFlags_All
Definition ReplicationWriter.h:103
@ FlushFlags_Default
Definition ReplicationWriter.h:104
@ FlushFlags_FlushState
Definition ReplicationWriter.h:100
static constexpr float CreatePriority
Definition ReplicationWriter.h:58
UDataStream::EWriteResult BeginWrite(const UDataStream::FBeginWriteParameters &Params)
Definition ReplicationWriter.cpp:3723
static constexpr float SchedulingThresholdPriority
Definition ReplicationWriter.h:61
~FReplicationWriter()
Definition ReplicationWriter.cpp:265
void UpdateScope(const FNetBitArrayView &ScopedObjects)
Definition ReplicationWriter.cpp:758
void SetReplicationEnabled(bool bInReplicationEnabled)
Definition ReplicationWriter.cpp:275
static constexpr float TearOffPriority
Definition ReplicationWriter.h:59
void ForceUpdateDirtyChangeMasks(const FChangeMaskCache &CachedChangeMasks, EFlushFlags ExtraFlushFlags, bool bMarkForTearOff)
Definition ReplicationWriter.h:168
Definition NetObjectBlobHandler.h:32
Definition ObjectReplicationBridge.h:83
Definition PartialNetObjectAttachmentHandler.h:44
Definition ReplicationSystem.h:70
@ Object
Definition TokenizedMessage.h:43
@ Idle
Definition PathFollowingComponent.h:39
Type
Definition PawnAction_Move.h:11
Definition ByteSwap.h:14
Definition OverriddenPropertySet.cpp:45
State
Definition PacketHandler.h:88
Definition NetworkVersion.cpp:28
EReplicationDataStreamDebugFeatures
Definition ReplicationDataStreamDebug.h:24
@ None
Definition ReplicationDataStreamDebug.h:25
uint32 FInternalNetRefIndex
Definition ReplicationStateStorage.h:20
ENetObjectAttachmentType
Definition AttachmentReplication.h:22
FNetBitArrayView::StorageWordType ChangeMaskStorageType
Definition ChangeMaskUtil.h:11
Definition NetworkVersion.cpp:28
EPacketDeliveryStatus
Definition PacketNotification.h:12
EDataStreamWriteMode
Definition DataStream.h:22
ENetObjectAttachmentSendPolicyFlags
Definition ReplicationSystemTypes.h:52
U16 Index
Definition radfft.cpp:71
Definition DataStream.h:124
Definition DataStream.h:132
Definition NetDebugName.h:17
Definition ChangeMaskCache.h:17
Definition ReplicationTypes.h:17
Definition ReplicationRecord.h:47
uint64 StartCycles
Definition ReplicationWriter.h:152
uint32 SuppressWarningCounter
Definition ReplicationWriter.h:153
uint64 StartStallTime
Definition ReplicationWriter.h:386
uint64 StartSendingTime
Definition ReplicationWriter.h:382
uint64 EndSendingTime
Definition ReplicationWriter.h:384
FChangeMaskStorageOrPointer ChangeMaskOrPtr
Definition ReplicationWriter.h:114
uint64 IsSubObject
Definition ReplicationWriter.h:123
uint64 FlushFlags
Definition ReplicationWriter.h:134
uint64 Value
Definition ReplicationWriter.h:117
static const uint32 LocalChangeMaskMaxBitCount
Definition ReplicationWriter.h:140
uint64 HasDirtyChangeMask
Definition ReplicationWriter.h:124
ChangeMaskStorageType * GetChangeMaskStoragePointer()
Definition ReplicationWriter.h:144
uint64 HasChangemaskFilter
Definition ReplicationWriter.h:126
uint64 State
Definition ReplicationWriter.h:121
uint64 LastAckedBaselineIndex
Definition ReplicationWriter.h:132
uint64 IsDestructionInfo
Definition ReplicationWriter.h:127
const ChangeMaskStorageType * GetChangeMaskStoragePointer() const
Definition ReplicationWriter.h:145
uint64 SubObjectPendingDestroy
Definition ReplicationWriter.h:130
uint64 ChangeMaskBitCount
Definition ReplicationWriter.h:120
EReplicatedObjectState GetState() const
Definition ReplicationWriter.h:142
uint64 PendingBaselineIndex
Definition ReplicationWriter.h:133
uint64 IsDeltaCompressionEnabled
Definition ReplicationWriter.h:131
FReplicationInfo()
Definition ReplicationWriter.h:658
uint64 HasDirtyConditionals
Definition ReplicationWriter.h:135
uint64 HasDirtySubObjects
Definition ReplicationWriter.h:122
uint64 TearOff
Definition ReplicationWriter.h:129
uint64 IsCreationConfirmed
Definition ReplicationWriter.h:128
uint64 HasAttachments
Definition ReplicationWriter.h:125
uint64 HasCannotSendInfo
Definition ReplicationWriter.h:136