Skip to content

Commit

Permalink
feat(SyncList): Add individual Actions for operations (#3794)
Browse files Browse the repository at this point in the history
  • Loading branch information
MrGadget1024 committed Mar 23, 2024
1 parent c69e13d commit 5e1c802
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 6 deletions.
38 changes: 38 additions & 0 deletions Assets/Mirror/Core/SyncList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,23 @@ public enum Operation : byte
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;

readonly IList<T> objects;
Expand Down Expand Up @@ -85,7 +102,28 @@ void AddOperation(Operation op, int itemIndex, T oldItem, T newItem, bool checkA
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);
#pragma warning restore CS0618 // Type or member is obsolete
}

public override void OnSerializeAll(NetworkWriter writer)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public void OldValueShouldNotBeNewValue()
player.item.price = 15;
serverList[0] = player;

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

SyncListTest.SerializeDeltaTo(serverList, clientList);
Assert.IsTrue(callbackCalled);
Expand Down
120 changes: 114 additions & 6 deletions Assets/Mirror/Tests/Editor/SyncCollections/SyncListTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ public void TestAddRange()
[Test]
public void TestClear()
{
#pragma warning disable 618 // Type or member is obsolete
bool called = false;
clientSyncList.Callback = (op, index, oldItem, newItem) =>
{
Expand All @@ -105,16 +106,26 @@ public void TestClear()
Assert.That(op, Is.EqualTo(SyncList<string>.Operation.OP_CLEAR));
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();
SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList, Is.EquivalentTo(new string[] { }));
Assert.That(called, Is.True);
Assert.That(actionCalled, Is.True);
}

[Test]
public void TestInsert()
{
#pragma warning disable 618 // Type or member is obsolete
bool called = false;
clientSyncList.Callback = (op, index, oldItem, newItem) =>
{
Expand All @@ -124,11 +135,20 @@ public void TestInsert()
Assert.That(index, Is.EqualTo(0));
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");
SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList, Is.EquivalentTo(new[] { "yay", "Hello", "World", "!" }));
Assert.That(called, Is.True);
Assert.That(actionCalled, Is.True);
}

[Test]
Expand All @@ -142,6 +162,7 @@ public void TestInsertRange()
[Test]
public void TestSet()
{
#pragma warning disable 618 // Type or member is obsolete
bool called = false;
clientSyncList.Callback = (op, index, oldItem, newItem) =>
{
Expand All @@ -152,17 +173,28 @@ public void TestSet()
Assert.That(oldItem, Is.EqualTo("World"));
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";
SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList[1], Is.EqualTo("yay"));
Assert.That(clientSyncList, Is.EquivalentTo(new[] { "Hello", "yay", "!" }));
Assert.That(called, Is.True);
Assert.That(actionCalled, Is.True);
}

[Test]
public void TestSetNull()
{
#pragma warning disable 618 // Type or member is obsolete
bool called = false;
clientSyncList.Callback = (op, index, oldItem, newItem) =>
{
Expand All @@ -173,15 +205,30 @@ public void TestSetNull()
Assert.That(oldItem, Is.EqualTo("World"));
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;
SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList[1], Is.EqualTo(null));
Assert.That(clientSyncList, Is.EquivalentTo(new[] { "Hello", null, "!" }));
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
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";
SerializeDeltaTo(serverSyncList, clientSyncList);
Expand All @@ -191,6 +238,7 @@ public void TestSetNull()
[Test]
public void TestRemoveAll()
{
#pragma warning disable 618 // Type or member is obsolete
bool called = false;
clientSyncList.Callback = (op, index, oldItem, newItem) =>
{
Expand All @@ -201,12 +249,22 @@ public void TestRemoveAll()
Assert.That(oldItem, Is.Not.EqualTo("!"));
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"
serverSyncList.RemoveAll(entry => entry.Contains("l"));
SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList, Is.EquivalentTo(new[] { "!" }));
Assert.That(called, Is.True);
Assert.That(actionCalled, Is.True);
}

[Test]
Expand All @@ -220,6 +278,7 @@ public void TestRemoveAllNone()
[Test]
public void TestRemoveAt()
{
#pragma warning disable 618 // Type or member is obsolete
bool called = false;
clientSyncList.Callback = (op, index, oldItem, newItem) =>
{
Expand All @@ -230,16 +289,27 @@ public void TestRemoveAt()
Assert.That(oldItem, Is.EqualTo("World"));
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);
SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList, Is.EquivalentTo(new[] { "Hello", "!" }));
Assert.That(called, Is.True);
Assert.That(actionCalled, Is.True);
}

[Test]
public void TestRemove()
{
#pragma warning disable 618 // Type or member is obsolete
bool called = false;
clientSyncList.Callback = (op, index, oldItem, newItem) =>
{
Expand All @@ -250,11 +320,21 @@ public void TestRemove()
Assert.That(oldItem, Is.EqualTo("World"));
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");
SerializeDeltaTo(serverSyncList, clientSyncList);
Assert.That(clientSyncList, Is.EquivalentTo(new[] { "Hello", "!" }));
Assert.That(called, Is.True);
Assert.That(actionCalled, Is.True);
}

[Test]
Expand Down Expand Up @@ -362,8 +442,8 @@ public void SyncListFloatTest()
[Test]
public void CallbackTest()
{
#pragma warning disable 618 // Type or member is obsolete
bool called = false;

clientSyncList.Callback = (op, index, oldItem, newItem) =>
{
called = true;
Expand All @@ -373,18 +453,27 @@ public void CallbackTest()
Assert.That(oldItem, Is.EqualTo(default(string)));
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");
SerializeDeltaTo(serverSyncList, clientSyncList);

Assert.That(called, Is.True);
Assert.That(actionCalled, Is.True);
}

[Test]
public void CallbackRemoveTest()
{
#pragma warning disable 618 // Type or member is obsolete
bool called = false;

clientSyncList.Callback = (op, index, oldItem, newItem) =>
{
called = true;
Expand All @@ -393,17 +482,27 @@ public void CallbackRemoveTest()
Assert.That(oldItem, Is.EqualTo("World"));
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");
SerializeDeltaTo(serverSyncList, clientSyncList);

Assert.That(called, Is.True);
Assert.That(actionCalled, Is.True);
}

[Test]
public void CallbackRemoveAtTest()
{
#pragma warning disable 618 // Type or member is obsolete
bool called = false;

clientSyncList.Callback = (op, index, oldItem, newItem) =>
{
called = true;
Expand All @@ -413,11 +512,20 @@ public void CallbackRemoveAtTest()
Assert.That(oldItem, Is.EqualTo("World"));
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);
SerializeDeltaTo(serverSyncList, clientSyncList);

Assert.That(called, Is.True);
Assert.That(actionCalled, Is.True);
}

[Test]
Expand Down

0 comments on commit 5e1c802

Please sign in to comment.