From aecc8f258739006ddb261619fdf18f5ccdf08de3 Mon Sep 17 00:00:00 2001 From: MrGadget <9826063+MrGadget1024@users.noreply.github.com> Date: Sat, 23 Mar 2024 12:09:00 -0400 Subject: [PATCH] fix(SyncList): Clear after Callback Allows users to iterate the list before it's wiped --- Assets/Mirror/Core/SyncList.cs | 8 ++++++-- .../Tests/Editor/SyncCollections/SyncListTest.cs | 10 ++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Assets/Mirror/Core/SyncList.cs b/Assets/Mirror/Core/SyncList.cs index c8d9c653f..81d0e4066 100644 --- a/Assets/Mirror/Core/SyncList.cs +++ b/Assets/Mirror/Core/SyncList.cs @@ -192,12 +192,14 @@ public override void OnDeserializeDelta(NetworkReader reader) case Operation.OP_CLEAR: if (apply) { - objects.Clear(); // add dirty + changes. // ClientToServer needs to set dirty in server OnDeserialize. // no access check: server OnDeserialize can always // write, even for ClientToServer (for broadcasting). AddOperation(Operation.OP_CLEAR, 0, default, default, false); + // clear after invoking the callback so users can iterate the list + // and take appropriate action on the items before they are wiped. + objects.Clear(); } break; @@ -267,8 +269,10 @@ public void AddRange(IEnumerable range) public void Clear() { - objects.Clear(); AddOperation(Operation.OP_CLEAR, 0, default, default, true); + // clear after invoking the callback so users can iterate the list + // and take appropriate action on the items before they are wiped. + objects.Clear(); } public bool Contains(T item) => IndexOf(item) >= 0; diff --git a/Assets/Mirror/Tests/Editor/SyncCollections/SyncListTest.cs b/Assets/Mirror/Tests/Editor/SyncCollections/SyncListTest.cs index 429d33001..7596f1897 100644 --- a/Assets/Mirror/Tests/Editor/SyncCollections/SyncListTest.cs +++ b/Assets/Mirror/Tests/Editor/SyncCollections/SyncListTest.cs @@ -97,9 +97,19 @@ public void TestAddRange() [Test] public void TestClear() { + bool called = false; + clientSyncList.Callback = (op, index, oldItem, newItem) => + { + called = true; + + Assert.That(op, Is.EqualTo(SyncList.Operation.OP_CLEAR)); + Assert.That(clientSyncList.Count, Is.EqualTo(3)); + }; + serverSyncList.Clear(); SerializeDeltaTo(serverSyncList, clientSyncList); Assert.That(clientSyncList, Is.EquivalentTo(new string[] {})); + Assert.That(called, Is.True); } [Test]