UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
ReplicationFiltering.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreTypes.h"
13#include "Containers/Array.h"
15
18namespace UE::Net
19{
21 namespace Private
22 {
24 class FNetObjectGroups;
27 }
28}
29
30namespace UE::Net::Private
31{
32
34{
35private:
37 TArrayView<FNetObjectFilteringInfo> GetNetObjectFilteringInfos(UReplicationSystem* ReplicationSystem) const;
38
39private:
40 // Friends
41 friend UNetObjectFilter;
42};
43
44
54
56{
57public:
59
61 void Deinit();
62
65
68
74 void Filter();
75
78 {
79 return MakeNetBitArrayView(ConnectionInfos[ConnectionId].ObjectsInScope);
80 }
81
83 {
84 return MakeNetBitArrayView(ConnectionInfos[ConnectionId].GroupExcludedObjects);
85 }
86
87 // Who owns what
88 void SetOwningConnection(FInternalNetRefIndex ObjectIndex, uint32 ConnectionId);
89 uint32 GetOwningConnection(FInternalNetRefIndex ObjectIndex) const { return !bHasDirtyOwner ? ObjectIndexToOwningConnection[ObjectIndex] : GetOwningConnectionIfDirty(ObjectIndex); }
90
98
103 bool IsUsingSpatialFilter(FInternalNetRefIndex ObjectIndex) const;
104
105 FNetObjectFilterHandle GetFilterHandle(const FName FilterName) const;
106 UNetObjectFilter* GetFilter(const FName FilterName) const;
107
110
113
116
117 // Connection handling
118 void AddConnection(uint32 ConnectionId);
119 void RemoveConnection(uint32 ConnectionId);
120
121 // Group based filtering
124
126 bool IsExclusionFilterGroup(FNetObjectGroupHandle GroupHandle) const { return GroupHandle.IsValid() && ExclusionFilterGroups.GetBit(GroupHandle.GetGroupIndex()); }
127 bool IsInclusionFilterGroup(FNetObjectGroupHandle GroupHandle) const { return GroupHandle.IsValid() && InclusionFilterGroups.GetBit(GroupHandle.GetGroupIndex()); }
128
133
136
139
140 // SubObjectFilter status
143 bool IsSubObjectFilterGroup(FNetObjectGroupHandle GroupHandle) const { return GroupHandle.IsValid() && SubObjectFilterGroups.GetBit(GroupHandle.GetGroupIndex()); }
144
147
149 FString PrintFilterObjectInfo(FInternalNetRefIndex ObjectIndex, uint32 ConnectionId) const;
150
151private:
152 struct FPerConnectionInfo
153 {
154 void Deinit();
155
156 // Objects filtered depending on owning connection or user set connection filtering
157 FNetBitArray ConnectionFilteredObjects;
158 // Objects filtered out due to one or more exclusion groups it belongs to is filtered out
159 FNetBitArray GroupExcludedObjects;
160 // Connection and group exclusion filtering is assumed to happen seldom. Avoid recalculating from scratch every frame.
161 FNetBitArray ObjectsInScopeBeforeDynamicFiltering;
162 // Group inclusion filtering is assumed to happen seldom. Applied after dynamic filtering, but before dependent objects.
163 FNetBitArray GroupIncludedObjects;
164 // Objects in scope after all kinds of filtering, including dynamic filtering, has been applied
165 FNetBitArray ObjectsInScope;
166 // Which objects are filtered out after dynamic filters have been processed.
167 FNetBitArray DynamicFilteredOutObjects;
168 // List of objects currently filtered out after processing dynamic filter passes. This could be temporary allocations in UpdateDynamicFiltering() but does require one bitarray per connection.
169 FNetBitArray InProgressDynamicFilteredOutObjects;
170 // Which objects are filtered out after dynamic filters, inclusion groups and hysteresis have been processed.
171 FNetBitArray DynamicFilteredOutObjectsHysteresisAdjusted;
172 // Updater of hysteresis for objects being dynamically filtered out
173 FObjectScopeHysteresisUpdater HysteresisUpdater;
174 };
175
176 struct FPerObjectInfo
177 {
178 // Note: Array is likely larger than one element.
179 uint32 ConnectionIds[1];
180 };
181
182 static constexpr uint32 UsedPerObjectInfoStorageGrowSize = 32; // 256 bytes, 1024 indices
183 typedef uint32 PerObjectInfoIndexType;
184
185 struct FPerGroupInfo
186 {
187 PerObjectInfoIndexType ConnectionStateIndex;
188 };
189
190 class FPerSubObjectFilterGroupInfo
191 {
192 public:
193 // Tracks parent and child connection filter status. Necessary for splitscreen support.
194 FSharedConnectionFilterStatusCollection ConnectionFilterStatus;
195 // Index to storage for parent connection bit array.
196 PerObjectInfoIndexType ConnectionStateIndex = 0;
197 };
198
199 struct FFilterInfo
200 {
202 FName Name;
203 uint32 ObjectCount = 0;
204 };
205
206private:
207 class FUpdateDirtyObjectsBatchHelper;
208 friend FNetObjectFilteringInfoAccessor;
209 friend FPerSubObjectFilterGroupInfo;
210
211 static void StaticChecks();
212
213 void InitFilters();
214 void InitObjectScopeHysteresis();
215
216 void SetNetObjectListsSize(FInternalNetRefIndex MaxInternalIndex);
217 void SetPerConnectionListsSize(FPerConnectionInfo& ConnectionInfo, FInternalNetRefIndex NewMaxInternalIndex);
218
219 void InitNewConnections();
220 void ResetRemovedConnections();
221 void UpdateObjectsInScope();
222 void UpdateOwnerFiltering();
223 void UpdateGroupExclusionFiltering();
224 void UpdateGroupInclusionFiltering();
225 void UpdateSubObjectFilters();
226
227 void UpdateDynamicFilters();
228 void PreUpdateDynamicFiltering();
229 void UpdateDynamicFiltering();
230 void PostUpdateDynamicFiltering();
231
232 void PreUpdateObjectScopeHysteresis();
233 void PostUpdateObjectScopeHysteresis();
234 void ClearObjectsFromHysteresis();
235
237 void FilterNonRelevantObjects();
238
239 bool HasDynamicFilters() const;
240
241 void UpdateCreationDependentParent(uint32 ChildIndex, const FNetBitArrayView ObjectsWithCreationDependencies, FNetBitArrayView OutConnectionObjectsInScope, bool bIsRecursive) const;
242
243 // Helper to update and reset group exclusion filter effects if objects are removed from a filter or after a filter status change, returns true if the group filter was changed
244 bool ClearGroupExclusionFilterEffectsForObject(uint32 ObjectIndex, uint32 ConnectionId);
245 // Helper to update and reset group inclusion filter effects if objects are removed from a filter or after a filter status change, returns true if the group filter was changed
246 bool ClearGroupInclusionFilterEffectsForObject(uint32 ObjectIndex, uint32 ConnectionId);
247 bool HasOwnerFilter(uint32 ObjectIndex) const;
248
249 PerObjectInfoIndexType AllocPerObjectInfo();
250 void FreePerObjectInfo(PerObjectInfoIndexType Index);
251
252 FPerObjectInfo* AllocPerObjectInfoForObject(uint32 ObjectIndex);
253 void FreePerObjectInfoForObject(uint32 ObjectIndex);
254
255 FPerObjectInfo* GetPerObjectInfo(PerObjectInfoIndexType Index);
256 const FPerObjectInfo* GetPerObjectInfo(PerObjectInfoIndexType Index) const;
257
258 void SetPerObjectInfoFilterStatus(FPerObjectInfo& ObjectInfo, ENetFilterStatus ReplicationStatus);
259
260 // SubObjectGroup filtering support
261 FPerSubObjectFilterGroupInfo& CreatePerSubObjectGroupFilterInfo(FNetObjectGroupHandle::FGroupIndexType GroupIndex);
262 void DestroyPerSubObjectGroupFilterInfo(FNetObjectGroupHandle::FGroupIndexType GroupIndex);
263 FPerSubObjectFilterGroupInfo* GetPerSubObjectFilterGroupInfo(FNetObjectGroupHandle::FGroupIndexType GroupIndex);
264 const FPerSubObjectFilterGroupInfo* GetPerSubObjectFilterGroupInfo(FNetObjectGroupHandle::FGroupIndexType GroupIndex) const;
265
266 ENetFilterStatus GetConnectionFilterStatus(const FPerObjectInfo& ObjectInfo, uint32 ConnectionId) const;
267 bool IsAnyConnectionFilterStatusAllowed(const FPerObjectInfo& ObjectInfo) const;
268 bool IsAnyConnectionFilterStatusDisallowed(const FPerObjectInfo& ObjectInfo) const;
269 void SetConnectionFilterStatus(FPerObjectInfo& ObjectInfo, uint32 ConnectionId, ENetFilterStatus ReplicationStatus);
270 // Returns true if object is filtered out by any exclusion group.
271 bool IsExcludedByAnyGroup(uint32 ObjectInternalIndex, uint32 ConnectionId) const;
272 // Returns true if object is allowed to replicate by any inclusion group.
273 bool IsIncludedByAnyGroup(uint32 ObjectInternalIndex, uint32 ConnectionId) const;
274 void InternalSetExclusionGroupFilterStatus(FNetObjectGroupHandle GroupHandle, uint32 ConnectionId, ENetFilterStatus ReplicationStatus);
275 void InternalSetInclusionGroupFilterStatus(FNetObjectGroupHandle GroupHandle, ENetFilterStatus ReplicationStatus);
276 void InternalSetInclusionGroupFilterStatus(FNetObjectGroupHandle GroupHandle, uint32 ConnectionId, ENetFilterStatus ReplicationStatus);
277
278 uint32 GetOwningConnectionIfDirty(uint32 ObjectIndex) const;
279
280 void RemoveFromDynamicFilter(uint32 ObjectIndex, uint32 FilterIndex);
281
282 void NotifyFiltersOfDirtyObjects();
283 void BatchNotifyFiltersOfDirtyObjects(FUpdateDirtyObjectsBatchHelper& BatchHelper, const uint32* ObjectIndices, uint32 ObjectCount);
284
286 TArrayView<FNetObjectFilteringInfo> GetNetObjectFilteringInfos();
287
288 uint8 GetObjectScopeHysteresisFrameCount(FName Profile) const;
289
290 bool HasSubObjectInScopeWithFilteredOutRootObject(FNetBitArrayView Objects) const;
291 bool HasSubObjectInScopeWithFilteredOutRootObject(uint32 connectionId) const;
292
293private:
294 enum EHysteresisProcessingMode : uint32
295 {
296 Disabled,
297 Enabled,
298 };
299
300 // Scope hysteresis state. Hysteresis is applied to objects going out of scope for objects that so desire.
301 struct FObjectScopeHysteresisState
302 {
303 public:
304 void ClearFromHysteresis(FInternalNetRefIndex NetRefIndex);
305
306 // Processing mode
307 EHysteresisProcessingMode Mode = EHysteresisProcessingMode::Disabled;
308 // Which connection ID to start with for updating.
309 uint32 ConnectionStartId = 0;
310 // Stride for connection update throttling.
311 uint32 ConnectionIdStride = 1;
312
313 // Approximate number of objects that should be cleared from hysteresis.
314 uint32 ObjectsToClearCount = 0;
315
316 // Objects to clear from hysteresis due to being destroyed or removed from dynamic filtering.
317 FNetBitArray ObjectsToClear;
318
319 // Objects that should not be added to hysteresis this frame. Example use case is newly added objects that become filtered out on the first frame.
320 FNetBitArray ObjectsExemptFromHysteresis;
321 };
322
323 // Used for ObjectIndexToDynamicFilterIndex lookup
324 static constexpr uint8 InvalidDynamicFilterIndex = 255U;
325
326 // Config
328
329 // General
330 TObjectPtr<UReplicationSystem> ReplicationSystem = nullptr;
331 const FNetRefHandleManager* NetRefHandleManager = nullptr;
332 uint32 FrameIndex = 0;
333
334 // Groups
335 FNetObjectGroups* Groups = nullptr;
336
337 // Connection specifics
338 FReplicationConnections* Connections = nullptr;
339 TArray<FPerConnectionInfo> ConnectionInfos;
340 FNetBitArray ValidConnections;
341 FNetBitArray NewConnections;
342
343 // Object specifics
344 FInternalNetRefIndex MaxInternalNetRefIndex = 0;
345 uint32 WordCountForObjectBitArrays = 0;
346
347 // Filter specifics
348 FNetBitArray ObjectsWithDirtyOwnerFilter;
349 FNetBitArray ObjectsWithDirtyOwner;
350
351 FNetBitArray ObjectsWithOwnerFilter;
352
353 //$TODO: This should be a on-demand data allocation. Very few objects have an owner and the memory usage would be minimal
354 TArray<uint16> ObjectIndexToOwningConnection;
355
356 // For non-owner filtered objects
357 // The storage for PerObjectInfo.
358 TArray<uint32> PerObjectInfoStorage;
359 // Storage for bit array indicating used/free status of PerObjectInfos
360 TArray<uint32> UsedPerObjectInfoStorage;
361
362 FNetBitArray ObjectsWithPerObjectInfo;
363
364 // Groups
365 TArray<FPerGroupInfo> GroupInfos;
366 uint32 MaxGroupCount = 0;
367
368 // SubObject filter groups
369 TMap<uint32, FPerSubObjectFilterGroupInfo> SubObjectFilterGroupInfos;
370
371 // Hysteresis frame counts for dynamically filtered objects
372 TArray<uint8> ObjectScopeHysteresisFrameCounts;
373
375 FNetBitArray ExclusionFilterGroups;
376
378 FNetBitArray InclusionFilterGroups;
379
381 FNetBitArray DirtyExclusionFilterGroups;
382
384 FNetBitArray DirtyInclusionFilterGroups;
385
386 // Group indices which are subobject filter groups
387 FNetBitArray SubObjectFilterGroups;
388 // Group indices which are subobject filter groups and in need of updating
389 FNetBitArray DirtySubObjectFilterGroups;
390 // Object indices with a connection filter
391 FNetBitArray AllConnectionFilteredObjects;
392
393 TArray<PerObjectInfoIndexType> ObjectIndexToPerObjectInfoIndex;
394 uint32 PerObjectInfoStorageCountForConnections = 0;
395 // How many elements from UsedPerObjectInfoStorage is needed to hold a FPerObjectInfo
396 uint32 PerObjectInfoStorageCountPerItem = 0;
397
398 // Dynamic filters
399 TArray<FNetObjectFilteringInfo> NetObjectFilteringInfos;
400 TArray<uint8> ObjectIndexToDynamicFilterIndex;
401 TArray<FFilterInfo> DynamicFilterInfos;
402
403 FNetBitArray DynamicFilterEnabledObjects;
404 FNetBitArray ObjectsRequiringDynamicFilterUpdate;
405
406 // Object scope hystereris
407 FObjectScopeHysteresisState HysteresisState;
408
409 uint32 bHasNewConnection : 1;
410 uint32 bHasRemovedConnection : 1;
411 uint32 bHasDirtyOwnerFilter: 1;
412 uint32 bHasDirtyOwner : 1;
413 uint32 bHasDynamicFilters : 1;
414 uint32 bHasDirtyExclusionFilterGroup : 1;
415 uint32 bHasDirtyInclusionFilterGroup : 1;
416 // Is true if any initialized DynamicFilter has the NeedsUpdate trait
417 uint32 bHasDynamicFiltersWithUpdateTrait : 1;
418};
419
420inline bool FReplicationFiltering::HasDynamicFilters() const
421{
422 return bHasDynamicFilters;
423}
424
425}
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
void Init()
Definition LockFreeList.h:4
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
Definition Array.h:670
Definition UnrealString.h.inl:34
Definition StrongObjectPtrTemplates.h:26
Definition ConnectionHandle.h:17
Definition NetBitArray.h:337
Definition NetBitArray.h:74
bool GetBit(uint32 Index) const
Definition NetBitArray.h:1253
Definition NetObjectGroupHandle.h:22
uint32 FGroupIndexType
Definition NetObjectGroupHandle.h:24
FGroupIndexType GetGroupIndex() const
Definition NetObjectGroupHandle.h:49
bool IsValid() const
Definition NetObjectGroupHandle.h:46
Definition ReplicationFiltering.h:34
Definition NetObjectGroups.h:52
Definition NetRefHandleManager.h:72
Definition ObjectScopeHysteresisUpdater.h:19
Definition ReplicationConnections.h:32
Definition ReplicationFiltering.h:56
void RemoveGroupFilter(FNetObjectGroupHandle GroupHandle)
Definition ReplicationFiltering.cpp:2042
bool AddInclusionFilterGroup(FNetObjectGroupHandle GroupHandle)
Definition ReplicationFiltering.cpp:2011
void BuildAlwaysRelevantList(FNetBitArrayView OutAlwaysRelevantList, const FNetBitArrayView ScopeList) const
Definition ReplicationFiltering.cpp:409
void NotifyRemovedDependentObject(FInternalNetRefIndex ObjectIndex)
Definition ReplicationFiltering.cpp:2558
uint32 GetOwningConnection(FInternalNetRefIndex ObjectIndex) const
Definition ReplicationFiltering.h:89
bool IsExclusionFilterGroup(FNetObjectGroupHandle GroupHandle) const
Definition ReplicationFiltering.h:126
void NotifyObjectRemovedFromGroup(FNetObjectGroupHandle GroupHandle, FInternalNetRefIndex ObjectIndex)
Definition ReplicationFiltering.cpp:2499
void RemoveConnection(uint32 ConnectionId)
Definition ReplicationFiltering.cpp:642
bool IsUsingSpatialFilter(FInternalNetRefIndex ObjectIndex) const
Definition ReplicationFiltering.cpp:575
void SetOwningConnection(FInternalNetRefIndex ObjectIndex, uint32 ConnectionId)
Definition ReplicationFiltering.cpp:442
void RemoveSubObjectFilter(FNetObjectGroupHandle GroupHandle)
Definition ReplicationFiltering.cpp:1897
FNetObjectFilterHandle GetFilterHandle(const FName FilterName) const
Definition ReplicationFiltering.cpp:588
void AddConnection(uint32 ConnectionId)
Definition ReplicationFiltering.cpp:626
void NotifyAddedDependentObject(FInternalNetRefIndex ObjectIndex)
Definition ReplicationFiltering.cpp:2543
bool GetGroupFilterStatus(FNetObjectGroupHandle GroupHandle, uint32 ConnectionId, ENetFilterStatus &OutReplicationStatus) const
Definition ReplicationFiltering.cpp:2450
bool IsInclusionFilterGroup(FNetObjectGroupHandle GroupHandle) const
Definition ReplicationFiltering.h:127
void NotifyObjectAddedToGroup(FNetObjectGroupHandle GroupHandle, FInternalNetRefIndex ObjectIndex)
Definition ReplicationFiltering.cpp:2463
void OnMaxInternalNetRefIndexIncreased(FInternalNetRefIndex NewMaxInternalIndex)
Definition ReplicationFiltering.cpp:292
void SetSubObjectFilterStatus(FNetObjectGroupHandle GroupHandle, FConnectionHandle ConnectionHandle, ENetFilterStatus ReplicationStatus)
Definition ReplicationFiltering.cpp:1936
void OnInternalNetRefIndicesFreed(const TConstArrayView< FInternalNetRefIndex > &FreedIndices)
Definition ReplicationFiltering.cpp:321
void SetGroupFilterStatus(FNetObjectGroupHandle GroupHandle, ENetFilterStatus ReplicationStatus)
Definition ReplicationFiltering.cpp:2089
void AddSubObjectFilter(FNetObjectGroupHandle GroupHandle)
Definition ReplicationFiltering.cpp:1873
FReplicationFiltering()
Definition ReplicationFiltering.cpp:173
void Filter()
Definition ReplicationFiltering.cpp:330
bool SetFilter(FInternalNetRefIndex ObjectIndex, FNetObjectFilterHandle Filter, FName FilterConfigProfile)
Definition ReplicationFiltering.cpp:465
bool GetSubObjectFilterStatus(FNetObjectGroupHandle GroupHandle, uint32 ParentConnectionId, ENetFilterStatus &OutReplicationStatus) const
Definition ReplicationFiltering.cpp:1961
FName GetFilterName(FNetObjectFilterHandle Filter) const
Definition ReplicationFiltering.cpp:614
bool IsSubObjectFilterGroup(FNetObjectGroupHandle GroupHandle) const
Definition ReplicationFiltering.h:143
const FNetBitArrayView GetRelevantObjectsInScope(uint32 ConnectionId) const
Definition ReplicationFiltering.h:77
bool AddExclusionFilterGroup(FNetObjectGroupHandle GroupHandle)
Definition ReplicationFiltering.cpp:1980
UNetObjectFilter * GetFilter(const FName FilterName) const
Definition ReplicationFiltering.cpp:601
void BuildObjectsInFilterList(FNetBitArrayView OutObjectsInFilter, FName FilterName) const
Definition ReplicationFiltering.cpp:2805
void Deinit()
Definition ReplicationFiltering.cpp:237
const FNetBitArrayView GetGroupFilteredOutObjects(uint32 ConnectionId) const
Definition ReplicationFiltering.h:82
FString PrintFilterObjectInfo(FInternalNetRefIndex ObjectIndex, uint32 ConnectionId) const
Definition ReplicationFiltering.cpp:2708
Definition NetObjectFilter.h:178
Definition ReplicationFilteringConfig.h:48
Definition ReplicationSystem.h:70
Mode
Definition AnimNode_TransitionPoseEvaluator.h:28
const TCHAR * Name
Definition OodleDataCompression.cpp:30
Definition OverriddenPropertySet.cpp:45
Definition NetworkVersion.cpp:28
uint32 FInternalNetRefIndex
Definition ReplicationStateStorage.h:20
Definition NetworkVersion.cpp:28
uint32 FNetObjectFilterHandle
Definition ReplicationFiltering.h:20
FNetBitArrayView MakeNetBitArrayView(const FNetBitArrayView::StorageWordType *Storage, uint32 BitCount)
Definition NetBitArray.h:1677
ENetFilterStatus
Definition NetObjectFilter.h:37
U16 Index
Definition radfft.cpp:71
Definition ObjectPtr.h:488
Definition ReplicationFiltering.h:46
uint32 MaxGroupCount
Definition ReplicationFiltering.h:52
TObjectPtr< UReplicationSystem > ReplicationSystem
Definition ReplicationFiltering.h:47
FNetObjectGroups * Groups
Definition ReplicationFiltering.h:49
const FNetRefHandleManager * NetRefHandleManager
Definition ReplicationFiltering.h:48
FInternalNetRefIndex MaxInternalNetRefIndex
Definition ReplicationFiltering.h:51
FReplicationConnections * Connections
Definition ReplicationFiltering.h:50