feat(SyncList): Add individual Actions for operations (#3794)

This commit is contained in:
MrGadget 2024-03-23 14:54:38 -04:00 committed by GitHub
parent c69e13df2a
commit 5e1c80255c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 154 additions and 6 deletions

View File

@ -15,6 +15,23 @@ public enum Operation : byte
OP_CLEAR OP_CLEAR
} }
/// <summary>This is called after the item is added with index</summary>
public Action<int> OnAdd;
/// <summary>This is called after the item is inserted with inedx</summary>
public Action<int> OnInsert;
/// <summary>This is called after the item is set with index and OLD Value</summary>
public Action<int, T> OnSet;
/// <summary>This is called after the item is removed with index and OLD Value</summary>
public Action<int, T> OnRemove;
/// <summary>This is called before the list is cleared so the list can be iterated</summary>
public Action OnClear;
// Deprecated 2024-03-23
[Obsolete("Use individual Actions, which pass OLD values where appropriate, instead.")]
public Action<Operation, int, T, T> Callback; public Action<Operation, int, T, T> Callback;
readonly IList<T> objects; readonly IList<T> objects;
@ -85,7 +102,28 @@ void AddOperation(Operation op, int itemIndex, T oldItem, T newItem, bool checkA
OnDirty?.Invoke(); OnDirty?.Invoke();
} }
switch (op)
{
case Operation.OP_ADD:
OnAdd?.Invoke(itemIndex);
break;
case Operation.OP_INSERT:
OnInsert?.Invoke(itemIndex);
break;
case Operation.OP_SET:
OnSet?.Invoke(itemIndex, oldItem);
break;
case Operation.OP_REMOVEAT:
OnRemove?.Invoke(itemIndex, oldItem);
break;
case Operation.OP_CLEAR:
OnClear?.Invoke();
break;
}
#pragma warning disable CS0618 // Type or member is obsolete
Callback?.Invoke(op, itemIndex, oldItem, newItem); Callback?.Invoke(op, itemIndex, oldItem, newItem);
#pragma warning restore CS0618 // Type or member is obsolete
} }
public override void OnSerializeAll(NetworkWriter writer) public override void OnSerializeAll(NetworkWriter writer)

View File

@ -47,6 +47,7 @@ public void OldValueShouldNotBeNewValue()
player.item.price = 15; player.item.price = 15;
serverList[0] = player; serverList[0] = player;
#pragma warning disable 618 // Type or member is obsolete
bool callbackCalled = false; bool callbackCalled = false;
clientList.Callback = (SyncList<TestPlayer>.Operation op, int itemIndex, TestPlayer oldItem, TestPlayer newItem) => clientList.Callback = (SyncList<TestPlayer>.Operation op, int itemIndex, TestPlayer oldItem, TestPlayer newItem) =>
{ {
@ -56,6 +57,7 @@ public void OldValueShouldNotBeNewValue()
Assert.That(newItem.item.price, Is.EqualTo(15)); Assert.That(newItem.item.price, Is.EqualTo(15));
callbackCalled = true; callbackCalled = true;
}; };
#pragma warning restore 618 // Type or member is obsolete
SyncListTest.SerializeDeltaTo(serverList, clientList); SyncListTest.SerializeDeltaTo(serverList, clientList);
Assert.IsTrue(callbackCalled); Assert.IsTrue(callbackCalled);

View File

@ -97,6 +97,7 @@ public void TestAddRange()
[Test] [Test]
public void TestClear() public void TestClear()
{ {
#pragma warning disable 618 // Type or member is obsolete
bool called = false; bool called = false;
clientSyncList.Callback = (op, index, oldItem, newItem) => clientSyncList.Callback = (op, index, oldItem, newItem) =>
{ {
@ -105,16 +106,26 @@ public void TestClear()
Assert.That(op, Is.EqualTo(SyncList<string>.Operation.OP_CLEAR)); Assert.That(op, Is.EqualTo(SyncList<string>.Operation.OP_CLEAR));
Assert.That(clientSyncList.Count, Is.EqualTo(3)); Assert.That(clientSyncList.Count, Is.EqualTo(3));
}; };
#pragma warning restore 618 // Type or member is obsolete
bool actionCalled = false;
clientSyncList.OnClear = () =>
{
actionCalled = true;
Assert.That(clientSyncList.Count, Is.EqualTo(3));
};
serverSyncList.Clear(); serverSyncList.Clear();
SerializeDeltaTo(serverSyncList, clientSyncList); SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList, Is.EquivalentTo(new string[] { })); Assert.That(clientSyncList, Is.EquivalentTo(new string[] { }));
Assert.That(called, Is.True); Assert.That(called, Is.True);
Assert.That(actionCalled, Is.True);
} }
[Test] [Test]
public void TestInsert() public void TestInsert()
{ {
#pragma warning disable 618 // Type or member is obsolete
bool called = false; bool called = false;
clientSyncList.Callback = (op, index, oldItem, newItem) => clientSyncList.Callback = (op, index, oldItem, newItem) =>
{ {
@ -124,11 +135,20 @@ public void TestInsert()
Assert.That(index, Is.EqualTo(0)); Assert.That(index, Is.EqualTo(0));
Assert.That(newItem, Is.EqualTo("yay")); Assert.That(newItem, Is.EqualTo("yay"));
}; };
#pragma warning restore 618 // Type or member is obsolete
bool actionCalled = false;
clientSyncList.OnInsert = (index) =>
{
actionCalled = true;
Assert.That(index, Is.EqualTo(0));
};
serverSyncList.Insert(0, "yay"); serverSyncList.Insert(0, "yay");
SerializeDeltaTo(serverSyncList, clientSyncList); SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList, Is.EquivalentTo(new[] { "yay", "Hello", "World", "!" })); Assert.That(clientSyncList, Is.EquivalentTo(new[] { "yay", "Hello", "World", "!" }));
Assert.That(called, Is.True); Assert.That(called, Is.True);
Assert.That(actionCalled, Is.True);
} }
[Test] [Test]
@ -142,6 +162,7 @@ public void TestInsertRange()
[Test] [Test]
public void TestSet() public void TestSet()
{ {
#pragma warning disable 618 // Type or member is obsolete
bool called = false; bool called = false;
clientSyncList.Callback = (op, index, oldItem, newItem) => clientSyncList.Callback = (op, index, oldItem, newItem) =>
{ {
@ -152,17 +173,28 @@ public void TestSet()
Assert.That(oldItem, Is.EqualTo("World")); Assert.That(oldItem, Is.EqualTo("World"));
Assert.That(newItem, Is.EqualTo("yay")); Assert.That(newItem, Is.EqualTo("yay"));
}; };
#pragma warning restore 618 // Type or member is obsolete
bool actionCalled = false;
clientSyncList.OnSet = (index, oldItem) =>
{
actionCalled = true;
Assert.That(index, Is.EqualTo(1));
Assert.That(oldItem, Is.EqualTo("World"));
};
serverSyncList[1] = "yay"; serverSyncList[1] = "yay";
SerializeDeltaTo(serverSyncList, clientSyncList); SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList[1], Is.EqualTo("yay")); Assert.That(clientSyncList[1], Is.EqualTo("yay"));
Assert.That(clientSyncList, Is.EquivalentTo(new[] { "Hello", "yay", "!" })); Assert.That(clientSyncList, Is.EquivalentTo(new[] { "Hello", "yay", "!" }));
Assert.That(called, Is.True); Assert.That(called, Is.True);
Assert.That(actionCalled, Is.True);
} }
[Test] [Test]
public void TestSetNull() public void TestSetNull()
{ {
#pragma warning disable 618 // Type or member is obsolete
bool called = false; bool called = false;
clientSyncList.Callback = (op, index, oldItem, newItem) => clientSyncList.Callback = (op, index, oldItem, newItem) =>
{ {
@ -173,15 +205,30 @@ public void TestSetNull()
Assert.That(oldItem, Is.EqualTo("World")); Assert.That(oldItem, Is.EqualTo("World"));
Assert.That(newItem, Is.EqualTo(null)); Assert.That(newItem, Is.EqualTo(null));
}; };
#pragma warning restore 618 // Type or member is obsolete
bool actionCalled = false;
clientSyncList.OnSet = (index, oldItem) =>
{
actionCalled = true;
Assert.That(index, Is.EqualTo(1));
Assert.That(oldItem, Is.EqualTo("World"));
};
serverSyncList[1] = null; serverSyncList[1] = null;
SerializeDeltaTo(serverSyncList, clientSyncList); SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList[1], Is.EqualTo(null)); Assert.That(clientSyncList[1], Is.EqualTo(null));
Assert.That(clientSyncList, Is.EquivalentTo(new[] { "Hello", null, "!" })); Assert.That(clientSyncList, Is.EquivalentTo(new[] { "Hello", null, "!" }));
Assert.That(called, Is.True); Assert.That(called, Is.True);
Assert.That(actionCalled, Is.True);
#pragma warning disable 618 // Type or member is obsolete
// clear callback so we don't get called again // clear callback so we don't get called again
clientSyncList.Callback = null; clientSyncList.Callback = null;
#pragma warning restore 618 // Type or member is obsolete
// clear handlers so we don't get called again
clientSyncList.OnSet = null;
serverSyncList[1] = "yay"; serverSyncList[1] = "yay";
SerializeDeltaTo(serverSyncList, clientSyncList); SerializeDeltaTo(serverSyncList, clientSyncList);
@ -191,6 +238,7 @@ public void TestSetNull()
[Test] [Test]
public void TestRemoveAll() public void TestRemoveAll()
{ {
#pragma warning disable 618 // Type or member is obsolete
bool called = false; bool called = false;
clientSyncList.Callback = (op, index, oldItem, newItem) => clientSyncList.Callback = (op, index, oldItem, newItem) =>
{ {
@ -201,12 +249,22 @@ public void TestRemoveAll()
Assert.That(oldItem, Is.Not.EqualTo("!")); Assert.That(oldItem, Is.Not.EqualTo("!"));
Assert.That(newItem, Is.EqualTo(default(string))); Assert.That(newItem, Is.EqualTo(default(string)));
}; };
#pragma warning restore 618 // Type or member is obsolete
bool actionCalled = false;
clientSyncList.OnRemove = (index, item) =>
{
actionCalled = true;
Assert.That(index, Is.EqualTo(0));
Assert.That(item, Is.Not.EqualTo("!"));
};
// This will remove "Hello" and "World" // This will remove "Hello" and "World"
serverSyncList.RemoveAll(entry => entry.Contains("l")); serverSyncList.RemoveAll(entry => entry.Contains("l"));
SerializeDeltaTo(serverSyncList, clientSyncList); SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList, Is.EquivalentTo(new[] { "!" })); Assert.That(clientSyncList, Is.EquivalentTo(new[] { "!" }));
Assert.That(called, Is.True); Assert.That(called, Is.True);
Assert.That(actionCalled, Is.True);
} }
[Test] [Test]
@ -220,6 +278,7 @@ public void TestRemoveAllNone()
[Test] [Test]
public void TestRemoveAt() public void TestRemoveAt()
{ {
#pragma warning disable 618 // Type or member is obsolete
bool called = false; bool called = false;
clientSyncList.Callback = (op, index, oldItem, newItem) => clientSyncList.Callback = (op, index, oldItem, newItem) =>
{ {
@ -230,16 +289,27 @@ public void TestRemoveAt()
Assert.That(oldItem, Is.EqualTo("World")); Assert.That(oldItem, Is.EqualTo("World"));
Assert.That(newItem, Is.EqualTo(default(string))); Assert.That(newItem, Is.EqualTo(default(string)));
}; };
#pragma warning restore 618 // Type or member is obsolete
bool actionCalled = false;
clientSyncList.OnRemove = (index, oldItem) =>
{
actionCalled = true;
Assert.That(index, Is.EqualTo(1));
Assert.That(oldItem, Is.EqualTo("World"));
};
serverSyncList.RemoveAt(1); serverSyncList.RemoveAt(1);
SerializeDeltaTo(serverSyncList, clientSyncList); SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList, Is.EquivalentTo(new[] { "Hello", "!" })); Assert.That(clientSyncList, Is.EquivalentTo(new[] { "Hello", "!" }));
Assert.That(called, Is.True); Assert.That(called, Is.True);
Assert.That(actionCalled, Is.True);
} }
[Test] [Test]
public void TestRemove() public void TestRemove()
{ {
#pragma warning disable 618 // Type or member is obsolete
bool called = false; bool called = false;
clientSyncList.Callback = (op, index, oldItem, newItem) => clientSyncList.Callback = (op, index, oldItem, newItem) =>
{ {
@ -250,11 +320,21 @@ public void TestRemove()
Assert.That(oldItem, Is.EqualTo("World")); Assert.That(oldItem, Is.EqualTo("World"));
Assert.That(newItem, Is.EqualTo(default(string))); Assert.That(newItem, Is.EqualTo(default(string)));
}; };
#pragma warning restore 618 // Type or member is obsolete
bool actionCalled = false;
clientSyncList.OnRemove = (index, oldItem) =>
{
actionCalled = true;
Assert.That(index, Is.EqualTo(1));
Assert.That(oldItem, Is.EqualTo("World"));
};
serverSyncList.Remove("World"); serverSyncList.Remove("World");
SerializeDeltaTo(serverSyncList, clientSyncList); SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList, Is.EquivalentTo(new[] { "Hello", "!" })); Assert.That(clientSyncList, Is.EquivalentTo(new[] { "Hello", "!" }));
Assert.That(called, Is.True); Assert.That(called, Is.True);
Assert.That(actionCalled, Is.True);
} }
[Test] [Test]
@ -362,8 +442,8 @@ public void SyncListFloatTest()
[Test] [Test]
public void CallbackTest() public void CallbackTest()
{ {
#pragma warning disable 618 // Type or member is obsolete
bool called = false; bool called = false;
clientSyncList.Callback = (op, index, oldItem, newItem) => clientSyncList.Callback = (op, index, oldItem, newItem) =>
{ {
called = true; called = true;
@ -373,18 +453,27 @@ public void CallbackTest()
Assert.That(oldItem, Is.EqualTo(default(string))); Assert.That(oldItem, Is.EqualTo(default(string)));
Assert.That(newItem, Is.EqualTo("yay")); Assert.That(newItem, Is.EqualTo("yay"));
}; };
#pragma warning restore 618 // Type or member is obsolete
bool actionCalled = false;
clientSyncList.OnAdd = (index) =>
{
actionCalled = true;
Assert.That(index, Is.EqualTo(3));
Assert.That(clientSyncList[index], Is.EqualTo("yay"));
};
serverSyncList.Add("yay"); serverSyncList.Add("yay");
SerializeDeltaTo(serverSyncList, clientSyncList); SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(called, Is.True); Assert.That(called, Is.True);
Assert.That(actionCalled, Is.True);
} }
[Test] [Test]
public void CallbackRemoveTest() public void CallbackRemoveTest()
{ {
#pragma warning disable 618 // Type or member is obsolete
bool called = false; bool called = false;
clientSyncList.Callback = (op, index, oldItem, newItem) => clientSyncList.Callback = (op, index, oldItem, newItem) =>
{ {
called = true; called = true;
@ -393,17 +482,27 @@ public void CallbackRemoveTest()
Assert.That(oldItem, Is.EqualTo("World")); Assert.That(oldItem, Is.EqualTo("World"));
Assert.That(newItem, Is.EqualTo(default(string))); Assert.That(newItem, Is.EqualTo(default(string)));
}; };
#pragma warning restore 618 // Type or member is obsolete
bool actionCalled = false;
clientSyncList.OnRemove = (index, oldItem) =>
{
actionCalled = true;
Assert.That(index, Is.EqualTo(1));
Assert.That(oldItem, Is.EqualTo("World"));
};
serverSyncList.Remove("World"); serverSyncList.Remove("World");
SerializeDeltaTo(serverSyncList, clientSyncList); SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(called, Is.True); Assert.That(called, Is.True);
Assert.That(actionCalled, Is.True);
} }
[Test] [Test]
public void CallbackRemoveAtTest() public void CallbackRemoveAtTest()
{ {
#pragma warning disable 618 // Type or member is obsolete
bool called = false; bool called = false;
clientSyncList.Callback = (op, index, oldItem, newItem) => clientSyncList.Callback = (op, index, oldItem, newItem) =>
{ {
called = true; called = true;
@ -413,11 +512,20 @@ public void CallbackRemoveAtTest()
Assert.That(oldItem, Is.EqualTo("World")); Assert.That(oldItem, Is.EqualTo("World"));
Assert.That(newItem, Is.EqualTo(default(string))); Assert.That(newItem, Is.EqualTo(default(string)));
}; };
#pragma warning restore 618 // Type or member is obsolete
bool actionCalled = false;
clientSyncList.OnRemove = (index, oldItem) =>
{
actionCalled = true;
Assert.That(index, Is.EqualTo(1));
Assert.That(oldItem, Is.EqualTo("World"));
};
serverSyncList.RemoveAt(1); serverSyncList.RemoveAt(1);
SerializeDeltaTo(serverSyncList, clientSyncList); SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(called, Is.True); Assert.That(called, Is.True);
Assert.That(actionCalled, Is.True);
} }
[Test] [Test]