DeferredList Class
A list that defers add/remove operations until ProcessChanges() is called. Safe for queueing structural changes during iteration.
internal class DeferredList<T>
Type parameters¶
T
The type of items in the list.
Inheritance System.Object → DeferredList\<T>
Remarks¶
Removal uses a double-buffer HashSet pattern: - O(1) amortized queuing per removal - O(n) single-pass application via RemoveAll (vs O(n×m) previously) - New removals queued inside callbacks go to the next ProcessChanges call, preserving deferred semantics and preventing infinite recursion
Contains() is O(1) via a HashSet mirror of the committed list. Add() is idempotent: duplicate queuing is silently dropped to preserve the _items/_itemSet mirror invariant (List allows duplicates, HashSet does not). If the item is committed but pending removal, Add cancels the removal so the net effect of Remove → Add within one frame is "item stays". IsQueuedForRemoval() checks both the pending and active-processing buffers so callers inside a removal callback cannot accidentally re-queue the same item.
| Properties | |
|---|---|
| Count | Gets the current count (excluding pending changes). |
| HasPendingChanges | Gets whether there are pending changes. |
| Methods | |
|---|---|
| Add(T) | Queues an item to be added. If the item is committed and pending removal, the removal is cancelled so the net effect of Remove → Add is "item stays". No-op if the item is already committed (without pending removal) or already queued for add. O(1) via HashSet mirrors. |
| AsReadOnly() | Gets a read-only view of the current committed items. The wrapper is created once and cached; it reflects all live changes to the list. |
| Clear() | Clears all items and pending changes. |
| Contains(T) | Checks if an item exists in the current committed list (not including pending adds). O(1). |
| GetEnumerator() | Gets an enumerator for the current committed items (safe for read-only iteration). |
| IsQueuedForRemoval(T) | Checks if an item is queued for removal or is actively being removed. O(1). Checks both the pending buffer and the active-processing buffer so callers inside a removal callback (e.g., Entity.OnDestroy) cannot accidentally re-queue the same item. |
| ProcessAdds(Action<T>) | Processes pending additions with a callback for each item added. |
| ProcessChanges() | Processes all queued changes: adds first, then removes. |
| ProcessRemovals(Action<T>) | Processes pending removals with a callback for each item removed. New removals queued inside the callback are deferred to the next call. |
| Remove(T) | Queues an item to be removed. O(1) amortized. |
| SortCommitted(Comparison<T>) | Sorts the committed items in-place using a stable sort. Preserves relative order of items with equal keys. Does not affect pending adds or removals. |