diff --git a/Assets/Mirror/Core/SyncList.cs b/Assets/Mirror/Core/SyncList.cs index 20775ad91..6f4952e4e 100644 --- a/Assets/Mirror/Core/SyncList.cs +++ b/Assets/Mirror/Core/SyncList.cs @@ -27,6 +27,14 @@ public enum Operation : byte /// This is called after the item is removed with index and OLD Value public Action OnRemove; + /// + /// This is called for all changes to the List. + /// For OP_ADD and OP_INSERT, T is the NEW value of the entry. + /// For OP_SET and OP_REMOVE, T is the OLD value of the entry. + /// For OP_CLEAR, T is default. + /// + public Action OnChange; + /// This is called before the list is cleared so the list can be iterated public Action OnClear; @@ -106,18 +114,23 @@ void AddOperation(Operation op, int itemIndex, T oldItem, T newItem, bool checkA { case Operation.OP_ADD: OnAdd?.Invoke(itemIndex); + OnChange?.Invoke(op, itemIndex, newItem); break; case Operation.OP_INSERT: OnInsert?.Invoke(itemIndex); + OnChange?.Invoke(op, itemIndex, newItem); break; case Operation.OP_SET: OnSet?.Invoke(itemIndex, oldItem); + OnChange?.Invoke(op, itemIndex, oldItem); break; case Operation.OP_REMOVEAT: OnRemove?.Invoke(itemIndex, oldItem); + OnChange?.Invoke(op, itemIndex, oldItem); break; case Operation.OP_CLEAR: OnClear?.Invoke(); + OnChange?.Invoke(op, itemIndex, default); break; } diff --git a/Assets/Mirror/Tests/Editor/SyncCollections/SyncListTest.cs b/Assets/Mirror/Tests/Editor/SyncCollections/SyncListTest.cs index 752237979..c87da8cc4 100644 --- a/Assets/Mirror/Tests/Editor/SyncCollections/SyncListTest.cs +++ b/Assets/Mirror/Tests/Editor/SyncCollections/SyncListTest.cs @@ -463,10 +463,20 @@ public void CallbackTest() Assert.That(clientSyncList[index], Is.EqualTo("yay")); }; + bool changeActionCalled = false; + clientSyncList.OnChange = (op, index, oldItem) => + { + changeActionCalled = true; + Assert.That(op, Is.EqualTo(SyncList.Operation.OP_ADD)); + Assert.That(index, Is.EqualTo(3)); + Assert.That(oldItem, Is.EqualTo("yay")); + }; + serverSyncList.Add("yay"); SerializeDeltaTo(serverSyncList, clientSyncList); Assert.That(called, Is.True); Assert.That(actionCalled, Is.True); + Assert.That(changeActionCalled, Is.True); } [Test] @@ -492,10 +502,20 @@ public void CallbackRemoveTest() Assert.That(oldItem, Is.EqualTo("World")); }; + bool changeActionCalled = false; + clientSyncList.OnChange = (op, index, oldItem) => + { + changeActionCalled = true; + Assert.That(op, Is.EqualTo(SyncList.Operation.OP_REMOVEAT)); + Assert.That(index, Is.EqualTo(1)); + Assert.That(oldItem, Is.EqualTo("World")); + }; + serverSyncList.Remove("World"); SerializeDeltaTo(serverSyncList, clientSyncList); Assert.That(called, Is.True); Assert.That(actionCalled, Is.True); + Assert.That(changeActionCalled, Is.True); } [Test] @@ -522,10 +542,20 @@ public void CallbackRemoveAtTest() Assert.That(oldItem, Is.EqualTo("World")); }; + bool changeActionCalled = false; + clientSyncList.OnChange = (op, index, oldItem) => + { + changeActionCalled = true; + Assert.That(op, Is.EqualTo(SyncList.Operation.OP_REMOVEAT)); + Assert.That(index, Is.EqualTo(1)); + Assert.That(oldItem, Is.EqualTo("World")); + }; + serverSyncList.RemoveAt(1); SerializeDeltaTo(serverSyncList, clientSyncList); Assert.That(called, Is.True); Assert.That(actionCalled, Is.True); + Assert.That(changeActionCalled, Is.True); } [Test]