mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 02:50:32 +00:00
feat(SyncDictionary): Add individual Actions for operations (#3791)
This commit is contained in:
parent
b59fa3511e
commit
81238b69d1
@ -6,6 +6,20 @@ namespace Mirror
|
|||||||
{
|
{
|
||||||
public class SyncIDictionary<TKey, TValue> : SyncObject, IDictionary<TKey, TValue>, IReadOnlyDictionary<TKey, TValue>
|
public class SyncIDictionary<TKey, TValue> : SyncObject, IDictionary<TKey, TValue>, IReadOnlyDictionary<TKey, TValue>
|
||||||
{
|
{
|
||||||
|
/// <summary>This is called after the item is added with TKey</summary>
|
||||||
|
public Action<TKey> OnAdd;
|
||||||
|
|
||||||
|
/// <summary>This is called after the item is changed with TKey. TValue is the OLD item</summary>
|
||||||
|
public Action<TKey, TValue> OnSet;
|
||||||
|
|
||||||
|
/// <summary>This is called after the item is removed with TKey. TValue is the OLD item</summary>
|
||||||
|
public Action<TKey, TValue> OnRemove;
|
||||||
|
|
||||||
|
/// <summary>This is called before the data is cleared</summary>
|
||||||
|
public Action OnClear;
|
||||||
|
|
||||||
|
// Deprecated 2024-03-22
|
||||||
|
[Obsolete("Use individual Actions, which pass OLD values where appropriate, instead.")]
|
||||||
public Action<Operation, TKey, TValue> Callback;
|
public Action<Operation, TKey, TValue> Callback;
|
||||||
|
|
||||||
protected readonly IDictionary<TKey, TValue> objects;
|
protected readonly IDictionary<TKey, TValue> objects;
|
||||||
@ -83,7 +97,25 @@ void AddOperation(Operation op, TKey key, TValue item, TValue oldItem, bool chec
|
|||||||
OnDirty?.Invoke();
|
OnDirty?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (op)
|
||||||
|
{
|
||||||
|
case Operation.OP_ADD:
|
||||||
|
OnAdd?.Invoke(key);
|
||||||
|
break;
|
||||||
|
case Operation.OP_SET:
|
||||||
|
OnSet?.Invoke(key, oldItem);
|
||||||
|
break;
|
||||||
|
case Operation.OP_REMOVE:
|
||||||
|
OnRemove?.Invoke(key, oldItem);
|
||||||
|
break;
|
||||||
|
case Operation.OP_CLEAR:
|
||||||
|
OnClear?.Invoke();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CS0618 // Type or member is obsolete
|
||||||
Callback?.Invoke(op, key, item);
|
Callback?.Invoke(op, key, item);
|
||||||
|
#pragma warning restore CS0618 // Type or member is obsolete
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnSerializeAll(NetworkWriter writer)
|
public override void OnSerializeAll(NetworkWriter writer)
|
||||||
|
@ -58,7 +58,9 @@ IEnumerator AddPlayersToMatchController()
|
|||||||
|
|
||||||
public override void OnStartClient()
|
public override void OnStartClient()
|
||||||
{
|
{
|
||||||
matchPlayerData.Callback += UpdateWins;
|
#pragma warning disable CS0618 // Type or member is obsolete
|
||||||
|
matchPlayerData.Callback = UpdateWins;
|
||||||
|
#pragma warning restore CS0618 // Type or member is obsolete
|
||||||
|
|
||||||
canvasGroup.alpha = 1f;
|
canvasGroup.alpha = 1f;
|
||||||
canvasGroup.interactable = true;
|
canvasGroup.interactable = true;
|
||||||
|
@ -80,72 +80,131 @@ public void CurlyBracesConstructor()
|
|||||||
public void TestAdd()
|
public void TestAdd()
|
||||||
{
|
{
|
||||||
// Adds a new entry with index of 4 using .Add method
|
// Adds a new entry with index of 4 using .Add method
|
||||||
|
#pragma warning disable 618 // Type or member is obsolete
|
||||||
|
bool called = false;
|
||||||
|
clientSyncDictionary.Callback = (op, key, item) =>
|
||||||
|
{
|
||||||
|
called = true;
|
||||||
|
|
||||||
|
Assert.That(op, Is.EqualTo(SyncDictionary<int, string>.Operation.OP_ADD));
|
||||||
|
Assert.That(key, Is.EqualTo(4));
|
||||||
|
Assert.That(item, Is.EqualTo("yay"));
|
||||||
|
Assert.That(clientSyncDictionary[key], Is.EqualTo("yay"));
|
||||||
|
};
|
||||||
|
#pragma warning restore 618 // Type or member is obsolete
|
||||||
|
|
||||||
|
bool actionCalled = false;
|
||||||
|
clientSyncDictionary.OnAdd = (key) =>
|
||||||
|
{
|
||||||
|
actionCalled = true;
|
||||||
|
Assert.That(key, Is.EqualTo(4));
|
||||||
|
Assert.That(clientSyncDictionary[key], Is.EqualTo("yay"));
|
||||||
|
};
|
||||||
|
|
||||||
serverSyncDictionary.Add(4, "yay");
|
serverSyncDictionary.Add(4, "yay");
|
||||||
SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary);
|
SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary);
|
||||||
Assert.That(clientSyncDictionary.ContainsKey(4));
|
Assert.That(clientSyncDictionary.ContainsKey(4));
|
||||||
Assert.That(clientSyncDictionary[4], Is.EqualTo("yay"));
|
Assert.That(clientSyncDictionary[4], Is.EqualTo("yay"));
|
||||||
|
Assert.That(called, Is.True);
|
||||||
|
Assert.That(actionCalled, Is.True);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestClear()
|
public void TestClear()
|
||||||
{
|
{
|
||||||
// Verifies that the clear method works and that the data is still present for the Callback.
|
// Verifies that the clear method works and that the data is still present for the Callback.
|
||||||
|
#pragma warning disable 618 // Type or member is obsolete
|
||||||
bool called = false;
|
bool called = false;
|
||||||
clientSyncDictionary.Callback = (op, index, item) =>
|
clientSyncDictionary.Callback = (op, key, item) =>
|
||||||
{
|
{
|
||||||
called = true;
|
called = true;
|
||||||
|
|
||||||
Assert.That(op, Is.EqualTo(SyncDictionary<int, string>.Operation.OP_CLEAR));
|
Assert.That(op, Is.EqualTo(SyncDictionary<int, string>.Operation.OP_CLEAR));
|
||||||
Assert.That(clientSyncDictionary.Count, Is.EqualTo(3));
|
Assert.That(clientSyncDictionary.Count, Is.EqualTo(3));
|
||||||
};
|
};
|
||||||
|
#pragma warning restore 618 // Type or member is obsolete
|
||||||
|
|
||||||
|
bool actionCalled = false;
|
||||||
|
clientSyncDictionary.OnClear = () =>
|
||||||
|
{
|
||||||
|
actionCalled = true;
|
||||||
|
Assert.That(clientSyncDictionary.Count, Is.EqualTo(3));
|
||||||
|
};
|
||||||
|
|
||||||
serverSyncDictionary.Clear();
|
serverSyncDictionary.Clear();
|
||||||
SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary);
|
SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary);
|
||||||
Assert.That(serverSyncDictionary, Is.EquivalentTo(new SyncDictionary<int, string>()));
|
Assert.That(serverSyncDictionary, Is.EquivalentTo(new SyncDictionary<int, string>()));
|
||||||
Assert.That(called, Is.True);
|
Assert.That(called, Is.True);
|
||||||
|
Assert.That(actionCalled, Is.True);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestSet()
|
public void TestSet()
|
||||||
{
|
{
|
||||||
// Overwrites an existing entry
|
// Overwrites an existing entry
|
||||||
|
#pragma warning disable 618 // Type or member is obsolete
|
||||||
bool called = false;
|
bool called = false;
|
||||||
clientSyncDictionary.Callback = (op, index, item) =>
|
clientSyncDictionary.Callback = (op, key, item) =>
|
||||||
{
|
{
|
||||||
called = true;
|
called = true;
|
||||||
|
|
||||||
Assert.That(op, Is.EqualTo(SyncDictionary<int, string>.Operation.OP_SET));
|
Assert.That(op, Is.EqualTo(SyncDictionary<int, string>.Operation.OP_SET));
|
||||||
Assert.That(index, Is.EqualTo(1));
|
Assert.That(key, Is.EqualTo(1));
|
||||||
Assert.That(item, Is.EqualTo("yay"));
|
Assert.That(item, Is.EqualTo("yay"));
|
||||||
Assert.That(clientSyncDictionary[index], Is.EqualTo("yay"));
|
Assert.That(clientSyncDictionary[key], Is.EqualTo("yay"));
|
||||||
|
|
||||||
};
|
};
|
||||||
|
#pragma warning restore 618 // Type or member is obsolete
|
||||||
|
|
||||||
|
bool actionCalled = false;
|
||||||
|
clientSyncDictionary.OnSet = (key, oldItem) =>
|
||||||
|
{
|
||||||
|
actionCalled = true;
|
||||||
|
Assert.That(key, Is.EqualTo(1));
|
||||||
|
Assert.That(oldItem, Is.EqualTo("World"));
|
||||||
|
Assert.That(clientSyncDictionary[key], Is.EqualTo("yay"));
|
||||||
|
};
|
||||||
|
|
||||||
serverSyncDictionary[1] = "yay";
|
serverSyncDictionary[1] = "yay";
|
||||||
SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary);
|
SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary);
|
||||||
Assert.That(clientSyncDictionary.ContainsKey(1));
|
Assert.That(clientSyncDictionary.ContainsKey(1));
|
||||||
Assert.That(clientSyncDictionary[1], Is.EqualTo("yay"));
|
Assert.That(clientSyncDictionary[1], Is.EqualTo("yay"));
|
||||||
Assert.That(called, Is.True);
|
Assert.That(called, Is.True);
|
||||||
|
Assert.That(actionCalled, Is.True);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestBareSet()
|
public void TestBareSet()
|
||||||
{
|
{
|
||||||
// Adds a new entry with index of 4 without using .Add method
|
// Adds a new entry with index of 4 without using .Add method
|
||||||
|
#pragma warning disable 618 // Type or member is obsolete
|
||||||
bool called = false;
|
bool called = false;
|
||||||
clientSyncDictionary.Callback = (op, index, item) =>
|
clientSyncDictionary.Callback = (op, key, item) =>
|
||||||
{
|
{
|
||||||
called = true;
|
called = true;
|
||||||
|
|
||||||
Assert.That(op, Is.EqualTo(SyncDictionary<int, string>.Operation.OP_ADD));
|
Assert.That(op, Is.EqualTo(SyncDictionary<int, string>.Operation.OP_ADD));
|
||||||
Assert.That(index, Is.EqualTo(4));
|
Assert.That(key, Is.EqualTo(4));
|
||||||
Assert.That(item, Is.EqualTo("yay"));
|
Assert.That(item, Is.EqualTo("yay"));
|
||||||
Assert.That(clientSyncDictionary[index], Is.EqualTo("yay"));
|
Assert.That(clientSyncDictionary[key], Is.EqualTo("yay"));
|
||||||
|
|
||||||
};
|
};
|
||||||
|
#pragma warning restore 618 // Type or member is obsolete
|
||||||
|
|
||||||
|
bool actionCalled = false;
|
||||||
|
clientSyncDictionary.OnAdd = (key) =>
|
||||||
|
{
|
||||||
|
actionCalled = true;
|
||||||
|
Assert.That(key, Is.EqualTo(4));
|
||||||
|
Assert.That(clientSyncDictionary[key], Is.EqualTo("yay"));
|
||||||
|
};
|
||||||
|
|
||||||
serverSyncDictionary[4] = "yay";
|
serverSyncDictionary[4] = "yay";
|
||||||
SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary);
|
SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary);
|
||||||
Assert.That(clientSyncDictionary.ContainsKey(4));
|
Assert.That(clientSyncDictionary.ContainsKey(4));
|
||||||
Assert.That(clientSyncDictionary[4], Is.EqualTo("yay"));
|
Assert.That(clientSyncDictionary[4], Is.EqualTo("yay"));
|
||||||
Assert.That(called, Is.True);
|
Assert.That(called, Is.True);
|
||||||
|
Assert.That(actionCalled, Is.True);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -209,52 +268,90 @@ public void TestContains()
|
|||||||
[Test]
|
[Test]
|
||||||
public void CallbackTest()
|
public void CallbackTest()
|
||||||
{
|
{
|
||||||
|
#pragma warning disable 618 // Type or member is obsolete
|
||||||
bool called = false;
|
bool called = false;
|
||||||
clientSyncDictionary.Callback = (op, index, item) =>
|
clientSyncDictionary.Callback = (op, key, item) =>
|
||||||
{
|
{
|
||||||
called = true;
|
called = true;
|
||||||
|
|
||||||
Assert.That(op, Is.EqualTo(SyncDictionary<int, string>.Operation.OP_ADD));
|
Assert.That(op, Is.EqualTo(SyncDictionary<int, string>.Operation.OP_ADD));
|
||||||
Assert.That(index, Is.EqualTo(3));
|
Assert.That(key, Is.EqualTo(3));
|
||||||
Assert.That(item, Is.EqualTo("yay"));
|
Assert.That(item, Is.EqualTo("yay"));
|
||||||
Assert.That(clientSyncDictionary[index], Is.EqualTo("yay"));
|
Assert.That(clientSyncDictionary[key], Is.EqualTo("yay"));
|
||||||
|
|
||||||
};
|
};
|
||||||
|
#pragma warning restore 618 // Type or member is obsolete
|
||||||
|
|
||||||
|
bool actionCalled = false;
|
||||||
|
clientSyncDictionary.OnAdd = (key) =>
|
||||||
|
{
|
||||||
|
actionCalled = true;
|
||||||
|
Assert.That(key, Is.EqualTo(3));
|
||||||
|
Assert.That(clientSyncDictionary[key], Is.EqualTo("yay"));
|
||||||
|
};
|
||||||
|
|
||||||
serverSyncDictionary.Add(3, "yay");
|
serverSyncDictionary.Add(3, "yay");
|
||||||
SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary);
|
SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary);
|
||||||
Assert.That(called, Is.True);
|
Assert.That(called, Is.True);
|
||||||
|
Assert.That(actionCalled, Is.True);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void ServerCallbackTest()
|
public void ServerCallbackTest()
|
||||||
{
|
{
|
||||||
|
#pragma warning disable 618 // Type or member is obsolete
|
||||||
bool called = false;
|
bool called = false;
|
||||||
serverSyncDictionary.Callback = (op, index, item) =>
|
serverSyncDictionary.Callback = (op, key, item) =>
|
||||||
{
|
{
|
||||||
called = true;
|
called = true;
|
||||||
|
|
||||||
Assert.That(op, Is.EqualTo(SyncDictionary<int, string>.Operation.OP_ADD));
|
Assert.That(op, Is.EqualTo(SyncDictionary<int, string>.Operation.OP_ADD));
|
||||||
Assert.That(index, Is.EqualTo(3));
|
Assert.That(key, Is.EqualTo(3));
|
||||||
Assert.That(item, Is.EqualTo("yay"));
|
Assert.That(item, Is.EqualTo("yay"));
|
||||||
Assert.That(serverSyncDictionary[index], Is.EqualTo("yay"));
|
Assert.That(serverSyncDictionary[key], Is.EqualTo("yay"));
|
||||||
};
|
};
|
||||||
|
#pragma warning restore 618 // Type or member is obsolete
|
||||||
|
|
||||||
|
bool actionCalled = false;
|
||||||
|
serverSyncDictionary.OnAdd = (key) =>
|
||||||
|
{
|
||||||
|
actionCalled = true;
|
||||||
|
Assert.That(key, Is.EqualTo(3));
|
||||||
|
Assert.That(serverSyncDictionary[key], Is.EqualTo("yay"));
|
||||||
|
};
|
||||||
|
|
||||||
serverSyncDictionary[3] = "yay";
|
serverSyncDictionary[3] = "yay";
|
||||||
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;
|
||||||
clientSyncDictionary.Callback = (op, key, item) =>
|
clientSyncDictionary.Callback = (op, key, item) =>
|
||||||
{
|
{
|
||||||
called = true;
|
called = true;
|
||||||
Assert.That(op, Is.EqualTo(SyncDictionary<int, string>.Operation.OP_REMOVE));
|
Assert.That(op, Is.EqualTo(SyncDictionary<int, string>.Operation.OP_REMOVE));
|
||||||
|
Assert.That(key, Is.EqualTo(1));
|
||||||
Assert.That(item, Is.EqualTo("World"));
|
Assert.That(item, Is.EqualTo("World"));
|
||||||
};
|
};
|
||||||
|
#pragma warning restore 618 // Type or member is obsolete
|
||||||
|
|
||||||
|
bool actionCalled = false;
|
||||||
|
clientSyncDictionary.OnRemove = (key, oldItem) =>
|
||||||
|
{
|
||||||
|
actionCalled = true;
|
||||||
|
Assert.That(key, Is.EqualTo(1));
|
||||||
|
Assert.That(oldItem, Is.EqualTo("World"));
|
||||||
|
Assert.That(!clientSyncDictionary.ContainsKey(1));
|
||||||
|
};
|
||||||
|
|
||||||
serverSyncDictionary.Remove(1);
|
serverSyncDictionary.Remove(1);
|
||||||
SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary);
|
SerializeDeltaTo(serverSyncDictionary, clientSyncDictionary);
|
||||||
Assert.That(called, Is.True);
|
Assert.That(called, Is.True);
|
||||||
|
Assert.That(actionCalled, Is.True);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
Loading…
Reference in New Issue
Block a user