diff --git a/Assets/Mirror/Core/SyncDictionary.cs b/Assets/Mirror/Core/SyncDictionary.cs index 37bec21cb..d22d39531 100644 --- a/Assets/Mirror/Core/SyncDictionary.cs +++ b/Assets/Mirror/Core/SyncDictionary.cs @@ -24,6 +24,11 @@ public class SyncIDictionary : SyncObject, IDictionary objects; + public SyncIDictionary(IDictionary objects) + { + this.objects = objects; + } + public int Count => objects.Count; public bool IsReadOnly => !IsWritable(); @@ -55,13 +60,6 @@ struct Change // so we need to skip them int changesAhead; - public override void Reset() - { - changes.Clear(); - changesAhead = 0; - objects.Clear(); - } - public ICollection Keys => objects.Keys; public ICollection Values => objects.Values; @@ -70,54 +68,6 @@ public override void Reset() IEnumerable IReadOnlyDictionary.Values => objects.Values; - // throw away all the changes - // this should be called after a successful sync - public override void ClearChanges() => changes.Clear(); - - public SyncIDictionary(IDictionary objects) - { - this.objects = objects; - } - - void AddOperation(Operation op, TKey key, TValue item, TValue oldItem, bool checkAccess) - { - if (checkAccess && IsReadOnly) - throw new InvalidOperationException("SyncDictionaries can only be modified by the owner."); - - Change change = new Change - { - operation = op, - key = key, - item = item - }; - - if (IsRecording()) - { - changes.Add(change); - 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); -#pragma warning restore CS0618 // Type or member is obsolete - } - public override void OnSerializeAll(NetworkWriter writer) { // if init, write the full list content @@ -261,26 +211,17 @@ public override void OnDeserializeDelta(NetworkReader reader) } } - public void Clear() + // throw away all the changes + // this should be called after a successful sync + public override void ClearChanges() => changes.Clear(); + + public override void Reset() { - AddOperation(Operation.OP_CLEAR, default, default, default, true); - // clear after invoking the callback so users can iterate the dictionary - // and take appropriate action on the items before they are wiped. + changes.Clear(); + changesAhead = 0; objects.Clear(); } - public bool ContainsKey(TKey key) => objects.ContainsKey(key); - - public bool Remove(TKey key) - { - if (objects.TryGetValue(key, out TValue oldItem) && objects.Remove(key)) - { - AddOperation(Operation.OP_REMOVE, key, oldItem, oldItem, true); - return true; - } - return false; - } - public TValue this[TKey i] { get => objects[i]; @@ -302,13 +243,7 @@ public TValue this[TKey i] public bool TryGetValue(TKey key, out TValue value) => objects.TryGetValue(key, out value); - public void Add(TKey key, TValue value) - { - objects.Add(key, value); - AddOperation(Operation.OP_ADD, key, value, default, true); - } - - public void Add(KeyValuePair item) => Add(item.Key, item.Value); + public bool ContainsKey(TKey key) => objects.ContainsKey(key); public bool Contains(KeyValuePair item) => TryGetValue(item.Key, out TValue val) && EqualityComparer.Default.Equals(val, item.Value); @@ -328,6 +263,24 @@ public void CopyTo(KeyValuePair[] array, int arrayIndex) } } + public void Add(KeyValuePair item) => Add(item.Key, item.Value); + + public void Add(TKey key, TValue value) + { + objects.Add(key, value); + AddOperation(Operation.OP_ADD, key, value, default, true); + } + + public bool Remove(TKey key) + { + if (objects.TryGetValue(key, out TValue oldItem) && objects.Remove(key)) + { + AddOperation(Operation.OP_REMOVE, key, oldItem, oldItem, true); + return true; + } + return false; + } + public bool Remove(KeyValuePair item) { bool result = objects.Remove(item.Key); @@ -337,6 +290,53 @@ public bool Remove(KeyValuePair item) return result; } + public void Clear() + { + AddOperation(Operation.OP_CLEAR, default, default, default, true); + // clear after invoking the callback so users can iterate the dictionary + // and take appropriate action on the items before they are wiped. + objects.Clear(); + } + + void AddOperation(Operation op, TKey key, TValue item, TValue oldItem, bool checkAccess) + { + if (checkAccess && IsReadOnly) + throw new InvalidOperationException("SyncDictionaries can only be modified by the owner."); + + Change change = new Change + { + operation = op, + key = key, + item = item + }; + + if (IsRecording()) + { + changes.Add(change); + 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); +#pragma warning restore CS0618 // Type or member is obsolete + } + public IEnumerator> GetEnumerator() => objects.GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => objects.GetEnumerator();