From 2e1551adb1a53adec7a56ed24e7f0b1b5816f4a7 Mon Sep 17 00:00:00 2001 From: Matt Walsh Date: Tue, 7 Sep 2021 17:28:58 -0700 Subject: [PATCH 01/17] refactor!: clean up network dictionary, use native containers --- .../Collections/NetworkDictionary.cs | 149 ++++-------------- .../Runtime/com.unity.netcode.runtime.asmdef | 3 +- .../Tests/Runtime/NetworkVariableTests.cs | 57 ++++++- 3 files changed, 85 insertions(+), 124 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkDictionary.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkDictionary.cs index 18b2360436..c56741e9d1 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkDictionary.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkDictionary.cs @@ -1,6 +1,7 @@ -using System.Collections; +using System; using System.Collections.Generic; using System.IO; +using Unity.Collections; namespace Unity.Netcode { @@ -9,9 +10,9 @@ namespace Unity.Netcode /// /// The type for the dictionary keys /// The type for the dictionary values - public class NetworkDictionary : NetworkVariableBase, IDictionary where TKey : unmanaged where TValue : unmanaged + public class NetworkDictionary : NetworkVariableBase where TKey : unmanaged, IEquatable where TValue : unmanaged { - private readonly IDictionary m_Dictionary = new Dictionary(); + private NativeHashMap m_Dictionary = new NativeHashMap(64, Allocator.Persistent); private readonly List> m_DirtyEvents = new List>(); /// @@ -36,25 +37,6 @@ public NetworkDictionary() { } /// The read permission to use for this NetworkDictionary public NetworkDictionary(NetworkVariableReadPermission readPerm) : base(readPerm) { } - /// - /// Creates a NetworkDictionary with a custom value and custom settings - /// - /// The read permission to use for this NetworkDictionary - /// The initial value to use for the NetworkDictionary - public NetworkDictionary(NetworkVariableReadPermission readPerm, IDictionary value) : base(readPerm) - { - m_Dictionary = value; - } - - /// - /// Creates a NetworkDictionary with a custom value and the default settings - /// - /// The initial value to use for the NetworkDictionary - public NetworkDictionary(IDictionary value) - { - m_Dictionary = value; - } - /// public override void ResetDirty() { @@ -127,33 +109,6 @@ public override void ReadDelta(Stream stream, bool keepDirtyDelta) } } break; - case NetworkDictionaryEvent.EventType.RemovePair: - { - var key = (TKey)reader.ReadObjectPacked(typeof(TKey)); - var value = (TValue)reader.ReadObjectPacked(typeof(TValue)); - m_Dictionary.Remove(new KeyValuePair(key, value)); - - if (OnDictionaryChanged != null) - { - OnDictionaryChanged(new NetworkDictionaryEvent - { - Type = eventType, - Key = key, - Value = value - }); - } - - if (keepDirtyDelta) - { - m_DirtyEvents.Add(new NetworkDictionaryEvent() - { - Type = eventType, - Key = key, - Value = value - }); - } - } - break; case NetworkDictionaryEvent.EventType.Clear: { //read nothing @@ -222,12 +177,6 @@ public override void ReadField(Stream stream) } } - /// - public bool TryGetValue(TKey key, out TValue value) - { - return m_Dictionary.TryGetValue(key, out value); - } - /// public override void WriteDelta(Stream stream) { @@ -249,12 +198,6 @@ public override void WriteDelta(Stream stream) writer.WriteObjectPacked(m_DirtyEvents[i].Key); } break; - case NetworkDictionaryEvent.EventType.RemovePair: - { - writer.WriteObjectPacked(m_DirtyEvents[i].Key); - writer.WriteObjectPacked(m_DirtyEvents[i].Value); - } - break; case NetworkDictionaryEvent.EventType.Clear: { //write nothing @@ -274,8 +217,8 @@ public override void WriteDelta(Stream stream) public override void WriteField(Stream stream) { using var writer = PooledNetworkWriter.Get(stream); - writer.WriteUInt16Packed((ushort)m_Dictionary.Count); - foreach (KeyValuePair pair in m_Dictionary) + writer.WriteUInt16Packed((ushort)m_Dictionary.Count()); + foreach (var pair in m_Dictionary) { writer.WriteObjectPacked(pair.Key); writer.WriteObjectPacked(pair.Value); @@ -308,17 +251,25 @@ public TValue this[TKey key] } /// - public ICollection Keys => m_Dictionary.Keys; + public bool TryGetValue(TKey key, out TValue value) + { + return m_Dictionary.TryGetValue(key, out value); + } /// - public ICollection Values => m_Dictionary.Values; + public NativeArray Keys(Allocator alloc) + { + return m_Dictionary.GetKeyArray(alloc); + } /// - public int Count => m_Dictionary.Count; + public NativeArray Values(Allocator alloc) + { + return m_Dictionary.GetValueArray(alloc); + } /// - // TODO: remove w/ native containers - public bool IsReadOnly => m_Dictionary.IsReadOnly; + public int Count => m_Dictionary.Count(); /// public void Add(TKey key, TValue value) @@ -338,16 +289,7 @@ public void Add(TKey key, TValue value) /// public void Add(KeyValuePair item) { - m_Dictionary.Add(item); - - var dictionaryEvent = new NetworkDictionaryEvent() - { - Type = NetworkDictionaryEvent.EventType.Add, - Key = item.Key, - Value = item.Value - }; - - HandleAddDictionaryEvent(dictionaryEvent); + Add(item.Key, item.Value); } /// @@ -366,7 +308,8 @@ public void Clear() /// public bool Contains(KeyValuePair item) { - return m_Dictionary.Contains(item); + return m_Dictionary.ContainsKey(item.Key) && + EqualityComparer.Default.Equals(item.Value, m_Dictionary[item.Key]); } /// @@ -376,19 +319,7 @@ public bool ContainsKey(TKey key) } /// - public void CopyTo(KeyValuePair[] array, int arrayIndex) - { - m_Dictionary.CopyTo(array, arrayIndex); - } - - /// - public IEnumerator> GetEnumerator() - { - return m_Dictionary.GetEnumerator(); - } - - /// - public bool Remove(TKey key) + public void Remove(TKey key) { m_Dictionary.Remove(key); @@ -403,31 +334,6 @@ public bool Remove(TKey key) }; HandleAddDictionaryEvent(dictionaryEvent); - - return true; - } - - - /// - public bool Remove(KeyValuePair item) - { - m_Dictionary.Remove(item); - - var dictionaryEvent = new NetworkDictionaryEvent() - { - Type = NetworkDictionaryEvent.EventType.RemovePair, - Key = item.Key, - Value = item.Value - }; - - HandleAddDictionaryEvent(dictionaryEvent); - return true; - } - - /// - IEnumerator IEnumerable.GetEnumerator() - { - return m_Dictionary.GetEnumerator(); } private void HandleAddDictionaryEvent(NetworkDictionaryEvent dictionaryEvent) @@ -444,6 +350,10 @@ public int LastModifiedTick return NetworkTickSystem.NoTick; } } + public void Dispose() + { + m_Dictionary.Dispose(); + } } /// @@ -468,11 +378,6 @@ public enum EventType /// Remove, - /// - /// Remove pair - /// - RemovePair, - /// /// Clear /// diff --git a/com.unity.netcode.gameobjects/Runtime/com.unity.netcode.runtime.asmdef b/com.unity.netcode.gameobjects/Runtime/com.unity.netcode.runtime.asmdef index 3798f71cb3..0efd561be1 100644 --- a/com.unity.netcode.gameobjects/Runtime/com.unity.netcode.runtime.asmdef +++ b/com.unity.netcode.gameobjects/Runtime/com.unity.netcode.runtime.asmdef @@ -5,7 +5,8 @@ "Unity.Multiplayer.MetricTypes", "Unity.Multiplayer.NetStats", "Unity.Multiplayer.NetStatsReporting", - "Unity.Multiplayer.NetworkSolutionInterface" + "Unity.Multiplayer.NetworkSolutionInterface", + "Unity.Collections" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs index 22ef29e77c..a2aef05b98 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs @@ -1,9 +1,11 @@ using System; using System.Collections; +using System.Collections.Generic; using UnityEngine; using UnityEngine.TestTools; using NUnit.Framework; using Unity.Collections; +using Unity.Collections.LowLevel.Unsafe; namespace Unity.Netcode.RuntimeTests { @@ -48,7 +50,7 @@ public class NetworkVariableTest : NetworkBehaviour public readonly NetworkVariable TheScalar = new NetworkVariable(); public readonly NetworkList TheList = new NetworkList(); public readonly NetworkSet TheSet = new NetworkSet(); - public readonly NetworkDictionary TheDictionary = new NetworkDictionary(); + public NetworkDictionary TheDictionary = new NetworkDictionary(); public readonly NetworkVariable FixedStringStruct = new NetworkVariable(); @@ -74,6 +76,12 @@ public void Awake() TheDictionary.OnDictionaryChanged += DictionaryChanged; } + public void OnDestroy() + { + TheDictionary.Dispose(); + } + + public readonly NetworkVariable TheStruct = new NetworkVariable(); public bool ListDelegateTriggered; @@ -389,6 +397,53 @@ public IEnumerator NetworkSetClear([Values(true, false)] bool useHost) ); } + [Test] + public void NetworkDictionaryTryGetValue([Values(true, false)] bool useHost) + { + m_TestWithHost = useHost; + m_Player1OnServer.TheDictionary[k_TestKey1] = k_TestVal1; + int outValue; + var result = m_Player1OnServer.TheDictionary.TryGetValue(k_TestKey1, out outValue); + Assert.IsTrue(result == true); + Assert.IsTrue(outValue == k_TestVal1); + } + + [Test] + public void NetworkDictionaryAddKeyValue([Values(true, false)] bool useHost) + { + m_TestWithHost = useHost; + + m_Player1OnServer.TheDictionary.Add(k_TestKey1, k_TestVal1); + Assert.IsTrue(m_Player1OnServer.TheDictionary[k_TestKey1] == k_TestVal1); + } + + [Test] + public void NetworkDictionaryAddKeyValuePair([Values(true, false)] bool useHost) + { + m_TestWithHost = useHost; + + m_Player1OnServer.TheDictionary.Add(new KeyValuePair(k_TestKey1, k_TestVal1)); + Assert.IsTrue(m_Player1OnServer.TheDictionary[k_TestKey1] == k_TestVal1); + } + + [Test] + public void NetworkDictionaryContainsKey([Values(true, false)] bool useHost) + { + m_TestWithHost = useHost; + + m_Player1OnServer.TheDictionary.Add(k_TestKey1, k_TestVal1); + Assert.IsTrue(m_Player1OnServer.TheDictionary.ContainsKey(k_TestKey1)); + } + + [Test] + public void NetworkDictionaryContains([Values(true, false)] bool useHost) + { + m_TestWithHost = useHost; + + m_Player1OnServer.TheDictionary.Add(k_TestKey1, k_TestVal1); + Assert.IsTrue(m_Player1OnServer.TheDictionary.Contains(new KeyValuePair(k_TestKey1, k_TestVal1))); + } + [UnityTest] public IEnumerator NetworkDictionaryAdd([Values(true, false)] bool useHost) { From 371869d3eb2946ec8065dc079f44c85063a8c1f5 Mon Sep 17 00:00:00 2001 From: Matt Walsh Date: Tue, 7 Sep 2021 17:58:54 -0700 Subject: [PATCH 02/17] readonly missing --- .../Tests/Runtime/NetworkVariableTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs index a2aef05b98..a106c0c090 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs @@ -50,7 +50,7 @@ public class NetworkVariableTest : NetworkBehaviour public readonly NetworkVariable TheScalar = new NetworkVariable(); public readonly NetworkList TheList = new NetworkList(); public readonly NetworkSet TheSet = new NetworkSet(); - public NetworkDictionary TheDictionary = new NetworkDictionary(); + public readonly NetworkDictionary TheDictionary = new NetworkDictionary(); public readonly NetworkVariable FixedStringStruct = new NetworkVariable(); From 6e4ede6b2a352da054b468c8f136d158edbee853 Mon Sep 17 00:00:00 2001 From: Matt Walsh Date: Tue, 7 Sep 2021 18:03:16 -0700 Subject: [PATCH 03/17] added dirty list as native container --- .../NetworkVariable/Collections/NetworkDictionary.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkDictionary.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkDictionary.cs index c56741e9d1..64ab312b80 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkDictionary.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkDictionary.cs @@ -13,7 +13,7 @@ namespace Unity.Netcode public class NetworkDictionary : NetworkVariableBase where TKey : unmanaged, IEquatable where TValue : unmanaged { private NativeHashMap m_Dictionary = new NativeHashMap(64, Allocator.Persistent); - private readonly List> m_DirtyEvents = new List>(); + private readonly NativeList> m_DirtyEvents = new NativeList>(64, Allocator.Persistent); /// /// Delegate type for dictionary changed event @@ -181,8 +181,8 @@ public override void ReadField(Stream stream) public override void WriteDelta(Stream stream) { using var writer = PooledNetworkWriter.Get(stream); - writer.WriteUInt16Packed((ushort)m_DirtyEvents.Count); - for (int i = 0; i < m_DirtyEvents.Count; i++) + writer.WriteUInt16Packed((ushort)m_DirtyEvents.Length); + for (int i = 0; i < m_DirtyEvents.Length; i++) { writer.WriteBits((byte)m_DirtyEvents[i].Type, 3); switch (m_DirtyEvents[i].Type) @@ -228,7 +228,7 @@ public override void WriteField(Stream stream) /// public override bool IsDirty() { - return base.IsDirty() || m_DirtyEvents.Count > 0; + return base.IsDirty() || m_DirtyEvents.Length > 0; } /// @@ -353,6 +353,7 @@ public int LastModifiedTick public void Dispose() { m_Dictionary.Dispose(); + m_DirtyEvents.Dispose(); } } From eb7c24ff26342471c75e57d54f04987842d2733b Mon Sep 17 00:00:00 2001 From: Matt Walsh Date: Tue, 7 Sep 2021 19:36:18 -0700 Subject: [PATCH 04/17] NetworkSet ported to native --- .../NetworkVariable/Collections/NetworkSet.cs | 206 +++--------------- .../Tests/Runtime/NetworkVariableTests.cs | 1 + testproject/Packages/packages-lock.json | 2 +- 3 files changed, 28 insertions(+), 181 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkSet.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkSet.cs index 10645191f5..8bbc8a1367 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkSet.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkSet.cs @@ -1,7 +1,7 @@ #if !NET35 -using System.Collections; -using System.Collections.Generic; +using System; using System.IO; +using Unity.Collections; namespace Unity.Netcode { @@ -9,10 +9,11 @@ namespace Unity.Netcode /// Event based NetworkVariable container for syncing Sets /// /// The type for the set - public class NetworkSet : NetworkVariableBase, ISet where T : unmanaged + public class NetworkSet : NetworkVariableBase where T : unmanaged, IEquatable { - private readonly ISet m_Set = new HashSet(); - private readonly List> m_DirtyEvents = new List>(); + private const int k_Dummy = 1; + private NativeHashMap m_Set = new NativeHashMap(64, Allocator.Persistent); + private NativeList> m_DirtyEvents = new NativeList>(64, Allocator.Persistent); /// /// Delegate type for set changed event @@ -33,28 +34,9 @@ public NetworkSet() { } /// /// Creates a NetworkSet with the default value and custom settings /// - /// The settings to use for the NetworkList + /// The read permissions to use for the NetworkList public NetworkSet(NetworkVariableReadPermission readPerm) : base(readPerm) { } - /// - /// Creates a NetworkSet with a custom value and custom settings - /// - /// The settings to use for the NetworkSet - /// The initial value to use for the NetworkSet - public NetworkSet(NetworkVariableReadPermission readPerm, ISet value) : base(readPerm) - { - m_Set = value; - } - - /// - /// Creates a NetworkSet with a custom value and the default settings - /// - /// The initial value to use for the NetworkList - public NetworkSet(ISet value) - { - m_Set = value; - } - /// public override void ResetDirty() { @@ -65,15 +47,15 @@ public override void ResetDirty() /// public override bool IsDirty() { - return base.IsDirty() || m_DirtyEvents.Count > 0; + return base.IsDirty() || m_DirtyEvents.Length > 0; } /// public override void WriteDelta(Stream stream) { using var writer = PooledNetworkWriter.Get(stream); - writer.WriteUInt16Packed((ushort)m_DirtyEvents.Count); - for (int i = 0; i < m_DirtyEvents.Count; i++) + writer.WriteUInt16Packed((ushort)m_DirtyEvents.Length); + for (int i = 0; i < m_DirtyEvents.Length; i++) { writer.WriteBits((byte)m_DirtyEvents[i].Type, 2); @@ -102,11 +84,11 @@ public override void WriteDelta(Stream stream) public override void WriteField(Stream stream) { using var writer = PooledNetworkWriter.Get(stream); - writer.WriteUInt16Packed((ushort)m_Set.Count); + writer.WriteUInt16Packed((ushort)m_Set.Count()); - foreach (T value in m_Set) + foreach (var pair in m_Set) { - writer.WriteObjectPacked(value); //BOX + writer.WriteObjectPacked(pair.Key); //BOX } } @@ -119,7 +101,7 @@ public override void ReadField(Stream stream) for (int i = 0; i < count; i++) { - m_Set.Add((T)reader.ReadObjectPacked(typeof(T))); //BOX + m_Set.Add((T)reader.ReadObjectPacked(typeof(T)), k_Dummy); //BOX } } @@ -136,7 +118,7 @@ public override void ReadDelta(Stream stream, bool keepDirtyDelta) case NetworkSetEvent.EventType.Add: { var value = (T)reader.ReadObjectPacked(typeof(T)); //BOX - m_Set.Add(value); + m_Set.Add(value, k_Dummy); if (OnSetChanged != null) { @@ -207,135 +189,9 @@ public override void ReadDelta(Stream stream, bool keepDirtyDelta) } } - /// - public IEnumerator GetEnumerator() - { - return m_Set.GetEnumerator(); - } - - /// - IEnumerator IEnumerable.GetEnumerator() - { - return m_Set.GetEnumerator(); - } - - /// - public void ExceptWith(IEnumerable other) - { - foreach (T value in other) - { - if (m_Set.Contains(value)) - { - Remove(value); - } - } - } - - /// - public void IntersectWith(IEnumerable other) - { - var otherSet = new HashSet(other); - - foreach (T value in m_Set) - { - if (!otherSet.Contains(value)) - { - Remove(value); - } - } - } - - /// - public bool IsProperSubsetOf(IEnumerable other) - { - return m_Set.IsProperSubsetOf(other); - } - - /// - public bool IsProperSupersetOf(IEnumerable other) - { - return m_Set.IsProperSupersetOf(other); - } - - /// - public bool IsSubsetOf(IEnumerable other) - { - return m_Set.IsSubsetOf(other); - } - - /// - public bool IsSupersetOf(IEnumerable other) - { - return m_Set.IsSupersetOf(other); - } - - /// - public bool Overlaps(IEnumerable other) - { - return m_Set.Overlaps(other); - } - - /// - public bool SetEquals(IEnumerable other) - { - return m_Set.SetEquals(other); - } - - /// - public void SymmetricExceptWith(IEnumerable other) - { - foreach (T value in other) - { - if (m_Set.Contains(value)) - { - Remove(value); - } - else - { - m_Set.Add(value); - - var setEvent = new NetworkSetEvent() - { - Type = NetworkSetEvent.EventType.Add, - Value = value - }; - m_DirtyEvents.Add(setEvent); - - if (OnSetChanged != null) - { - OnSetChanged(setEvent); - } - } - } - } - - /// - public void UnionWith(IEnumerable other) + public void Add(T item) { - foreach (T value in other) - { - if (!m_Set.Contains(value)) - { - m_Set.Add(value); - - var setEvent = new NetworkSetEvent() - { - Type = NetworkSetEvent.EventType.Add, - Value = value - }; - m_DirtyEvents.Add(setEvent); - - if (OnSetChanged != null) - { - OnSetChanged(setEvent); - } - } - } - } - - public bool Add(T item) - { - m_Set.Add(item); + m_Set.Add(item, k_Dummy); var setEvent = new NetworkSetEvent() { @@ -348,13 +204,8 @@ public bool Add(T item) { OnSetChanged(setEvent); } - - return true; } - /// - void ICollection.Add(T item) => Add(item); - /// public void Clear() { @@ -375,17 +226,11 @@ public void Clear() /// public bool Contains(T item) { - return m_Set.Contains(item); - } - - /// - public void CopyTo(T[] array, int arrayIndex) - { - m_Set.CopyTo(array, arrayIndex); + return m_Set.ContainsKey(item); } /// - public bool Remove(T item) + public void Remove(T item) { m_Set.Remove(item); @@ -400,15 +245,10 @@ public bool Remove(T item) { OnSetChanged(setEvent); } - - return true; } /// - public int Count => m_Set.Count; - - /// - public bool IsReadOnly => m_Set.IsReadOnly; + public int Count => m_Set.Count(); public int LastModifiedTick { @@ -418,6 +258,12 @@ public int LastModifiedTick return NetworkTickSystem.NoTick; } } + + public void Dispose() + { + m_Set.Dispose(); + m_DirtyEvents.Dispose(); + } } /// diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs index a106c0c090..db07aeb500 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs @@ -78,6 +78,7 @@ public void Awake() public void OnDestroy() { + TheSet.Dispose(); TheDictionary.Dispose(); } diff --git a/testproject/Packages/packages-lock.json b/testproject/Packages/packages-lock.json index 9d043edc10..bafeda3eab 100644 --- a/testproject/Packages/packages-lock.json +++ b/testproject/Packages/packages-lock.json @@ -43,7 +43,7 @@ "url": "https://packages.unity.com" }, "com.unity.ide.visualstudio": { - "version": "2.0.9", + "version": "2.0.8", "depth": 0, "source": "registry", "dependencies": { From cf7707c1eabc198bbcf98ed49a6896205e034702 Mon Sep 17 00:00:00 2001 From: Matt Walsh Date: Wed, 8 Sep 2021 17:26:48 -0700 Subject: [PATCH 05/17] improved destroy --- .../Runtime/Core/NetworkBehaviour.cs | 8 ++++++++ .../Collections/NetworkDictionary.cs | 6 +++--- .../NetworkVariable/Collections/NetworkSet.cs | 15 +++++++-------- .../NetworkVariable/NetworkVariableBase.cs | 4 ++++ 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs index 9c25263d21..f99e78d1fc 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs @@ -824,5 +824,13 @@ protected NetworkObject GetNetworkObject(ulong networkId) { return NetworkManager.SpawnManager.SpawnedObjects.TryGetValue(networkId, out NetworkObject networkObject) ? networkObject : null; } + + public void OnDestroy() + { + for (int i = 0; i < NetworkVariableFields.Count; i++) + { + NetworkVariableFields[i].Dispose(); + } + } } } diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkDictionary.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkDictionary.cs index 64ab312b80..63c96c17eb 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkDictionary.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkDictionary.cs @@ -257,13 +257,13 @@ public bool TryGetValue(TKey key, out TValue value) } /// - public NativeArray Keys(Allocator alloc) + public NativeArray Keys(Allocator alloc = Allocator.Temp) { return m_Dictionary.GetKeyArray(alloc); } /// - public NativeArray Values(Allocator alloc) + public NativeArray Values(Allocator alloc = Allocator.Temp) { return m_Dictionary.GetValueArray(alloc); } @@ -350,7 +350,7 @@ public int LastModifiedTick return NetworkTickSystem.NoTick; } } - public void Dispose() + public override void Dispose() { m_Dictionary.Dispose(); m_DirtyEvents.Dispose(); diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkSet.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkSet.cs index 8bbc8a1367..231354a590 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkSet.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkSet.cs @@ -11,8 +11,7 @@ namespace Unity.Netcode /// The type for the set public class NetworkSet : NetworkVariableBase where T : unmanaged, IEquatable { - private const int k_Dummy = 1; - private NativeHashMap m_Set = new NativeHashMap(64, Allocator.Persistent); + private NativeHashSet m_Set = new NativeHashSet(64, Allocator.Persistent); private NativeList> m_DirtyEvents = new NativeList>(64, Allocator.Persistent); /// @@ -88,7 +87,7 @@ public override void WriteField(Stream stream) foreach (var pair in m_Set) { - writer.WriteObjectPacked(pair.Key); //BOX + writer.WriteObjectPacked(pair); //BOX } } @@ -101,7 +100,7 @@ public override void ReadField(Stream stream) for (int i = 0; i < count; i++) { - m_Set.Add((T)reader.ReadObjectPacked(typeof(T)), k_Dummy); //BOX + m_Set.Add((T)reader.ReadObjectPacked(typeof(T))); //BOX } } @@ -118,7 +117,7 @@ public override void ReadDelta(Stream stream, bool keepDirtyDelta) case NetworkSetEvent.EventType.Add: { var value = (T)reader.ReadObjectPacked(typeof(T)); //BOX - m_Set.Add(value, k_Dummy); + m_Set.Add(value); if (OnSetChanged != null) { @@ -191,7 +190,7 @@ public override void ReadDelta(Stream stream, bool keepDirtyDelta) public void Add(T item) { - m_Set.Add(item, k_Dummy); + m_Set.Add(item); var setEvent = new NetworkSetEvent() { @@ -226,7 +225,7 @@ public void Clear() /// public bool Contains(T item) { - return m_Set.ContainsKey(item); + return m_Set.Contains(item); } /// @@ -259,7 +258,7 @@ public int LastModifiedTick } } - public void Dispose() + public override void Dispose() { m_Set.Dispose(); m_DirtyEvents.Dispose(); diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariableBase.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariableBase.cs index bc782a7476..8be3b16a65 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariableBase.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariableBase.cs @@ -118,5 +118,9 @@ public virtual bool CanClientWrite(ulong clientId) /// The stream to read the delta from /// Whether or not the delta should be kept as dirty or consumed public abstract void ReadDelta(Stream stream, bool keepDirtyDelta); + + public virtual void Dispose() + { + } } } From 5b52d113fa3851c73c3114f2701a4dd45a321fc0 Mon Sep 17 00:00:00 2001 From: Matt Walsh Date: Mon, 13 Sep 2021 09:33:47 -0700 Subject: [PATCH 06/17] remove set & dictionary --- .../Collections/NetworkDictionary.cs | 408 ------------------ .../Collections/NetworkDictionary.cs.meta | 11 - .../NetworkVariable/Collections/NetworkSet.cs | 306 ------------- .../Collections/NetworkSet.cs.meta | 11 - .../Tests/Runtime/NetworkVariableTests.cs | 247 +---------- .../Profiling/NetworkVariableNameTests.cs | 8 - 6 files changed, 2 insertions(+), 989 deletions(-) delete mode 100644 com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkDictionary.cs delete mode 100644 com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkDictionary.cs.meta delete mode 100644 com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkSet.cs delete mode 100644 com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkSet.cs.meta diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkDictionary.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkDictionary.cs deleted file mode 100644 index 63c96c17eb..0000000000 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkDictionary.cs +++ /dev/null @@ -1,408 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using Unity.Collections; - -namespace Unity.Netcode -{ - /// - /// Event based NetworkVariable container for syncing Dictionaries - /// - /// The type for the dictionary keys - /// The type for the dictionary values - public class NetworkDictionary : NetworkVariableBase where TKey : unmanaged, IEquatable where TValue : unmanaged - { - private NativeHashMap m_Dictionary = new NativeHashMap(64, Allocator.Persistent); - private readonly NativeList> m_DirtyEvents = new NativeList>(64, Allocator.Persistent); - - /// - /// Delegate type for dictionary changed event - /// - /// Struct containing information about the change event - public delegate void OnDictionaryChangedDelegate(NetworkDictionaryEvent changeEvent); - - /// - /// The callback to be invoked when the dictionary gets changed - /// - public event OnDictionaryChangedDelegate OnDictionaryChanged; - - /// - /// Creates a NetworkDictionary with the default value and settings - /// - public NetworkDictionary() { } - - /// - /// Creates a NetworkDictionary with the default value and custom settings - /// - /// The read permission to use for this NetworkDictionary - public NetworkDictionary(NetworkVariableReadPermission readPerm) : base(readPerm) { } - - /// - public override void ResetDirty() - { - base.ResetDirty(); - m_DirtyEvents.Clear(); - } - - /// - public override void ReadDelta(Stream stream, bool keepDirtyDelta) - { - using var reader = PooledNetworkReader.Get(stream); - ushort deltaCount = reader.ReadUInt16Packed(); - for (int i = 0; i < deltaCount; i++) - { - var eventType = (NetworkDictionaryEvent.EventType)reader.ReadBits(3); - switch (eventType) - { - case NetworkDictionaryEvent.EventType.Add: - { - var key = (TKey)reader.ReadObjectPacked(typeof(TKey)); - var value = (TValue)reader.ReadObjectPacked(typeof(TValue)); - m_Dictionary.Add(key, value); - - if (OnDictionaryChanged != null) - { - OnDictionaryChanged(new NetworkDictionaryEvent - { - Type = eventType, - Key = key, - Value = value - }); - } - - if (keepDirtyDelta) - { - m_DirtyEvents.Add(new NetworkDictionaryEvent() - { - Type = eventType, - Key = key, - Value = value - }); - } - } - break; - case NetworkDictionaryEvent.EventType.Remove: - { - var key = (TKey)reader.ReadObjectPacked(typeof(TKey)); - TValue value; - m_Dictionary.TryGetValue(key, out value); - m_Dictionary.Remove(key); - - if (OnDictionaryChanged != null) - { - OnDictionaryChanged(new NetworkDictionaryEvent - { - Type = eventType, - Key = key, - Value = value - }); - } - - if (keepDirtyDelta) - { - m_DirtyEvents.Add(new NetworkDictionaryEvent() - { - Type = eventType, - Key = key, - Value = value - }); - } - } - break; - case NetworkDictionaryEvent.EventType.Clear: - { - //read nothing - m_Dictionary.Clear(); - - if (OnDictionaryChanged != null) - { - OnDictionaryChanged(new NetworkDictionaryEvent - { - Type = eventType - }); - } - - if (keepDirtyDelta) - { - m_DirtyEvents.Add(new NetworkDictionaryEvent - { - Type = eventType - }); - } - } - break; - case NetworkDictionaryEvent.EventType.Value: - { - var key = (TKey)reader.ReadObjectPacked(typeof(TKey)); - var value = (TValue)reader.ReadObjectPacked(typeof(TValue)); - - m_Dictionary[key] = value; - - if (OnDictionaryChanged != null) - { - OnDictionaryChanged(new NetworkDictionaryEvent - { - Type = eventType, - Key = key, - Value = value - }); - } - - if (keepDirtyDelta) - { - m_DirtyEvents.Add(new NetworkDictionaryEvent() - { - Type = eventType, - Key = key, - Value = value - }); - } - } - break; - } - } - } - - /// - public override void ReadField(Stream stream) - { - using var reader = PooledNetworkReader.Get(stream); - m_Dictionary.Clear(); - ushort entryCount = reader.ReadUInt16Packed(); - for (int i = 0; i < entryCount; i++) - { - var key = (TKey)reader.ReadObjectPacked(typeof(TKey)); - var value = (TValue)reader.ReadObjectPacked(typeof(TValue)); - m_Dictionary.Add(key, value); - } - } - - /// - public override void WriteDelta(Stream stream) - { - using var writer = PooledNetworkWriter.Get(stream); - writer.WriteUInt16Packed((ushort)m_DirtyEvents.Length); - for (int i = 0; i < m_DirtyEvents.Length; i++) - { - writer.WriteBits((byte)m_DirtyEvents[i].Type, 3); - switch (m_DirtyEvents[i].Type) - { - case NetworkDictionaryEvent.EventType.Add: - { - writer.WriteObjectPacked(m_DirtyEvents[i].Key); - writer.WriteObjectPacked(m_DirtyEvents[i].Value); - } - break; - case NetworkDictionaryEvent.EventType.Remove: - { - writer.WriteObjectPacked(m_DirtyEvents[i].Key); - } - break; - case NetworkDictionaryEvent.EventType.Clear: - { - //write nothing - } - break; - case NetworkDictionaryEvent.EventType.Value: - { - writer.WriteObjectPacked(m_DirtyEvents[i].Key); - writer.WriteObjectPacked(m_DirtyEvents[i].Value); - } - break; - } - } - } - - /// - public override void WriteField(Stream stream) - { - using var writer = PooledNetworkWriter.Get(stream); - writer.WriteUInt16Packed((ushort)m_Dictionary.Count()); - foreach (var pair in m_Dictionary) - { - writer.WriteObjectPacked(pair.Key); - writer.WriteObjectPacked(pair.Value); - } - } - - /// - public override bool IsDirty() - { - return base.IsDirty() || m_DirtyEvents.Length > 0; - } - - /// - public TValue this[TKey key] - { - get => m_Dictionary[key]; - set - { - m_Dictionary[key] = value; - - var dictionaryEvent = new NetworkDictionaryEvent() - { - Type = NetworkDictionaryEvent.EventType.Value, - Key = key, - Value = value - }; - - HandleAddDictionaryEvent(dictionaryEvent); - } - } - - /// - public bool TryGetValue(TKey key, out TValue value) - { - return m_Dictionary.TryGetValue(key, out value); - } - - /// - public NativeArray Keys(Allocator alloc = Allocator.Temp) - { - return m_Dictionary.GetKeyArray(alloc); - } - - /// - public NativeArray Values(Allocator alloc = Allocator.Temp) - { - return m_Dictionary.GetValueArray(alloc); - } - - /// - public int Count => m_Dictionary.Count(); - - /// - public void Add(TKey key, TValue value) - { - m_Dictionary.Add(key, value); - - var dictionaryEvent = new NetworkDictionaryEvent() - { - Type = NetworkDictionaryEvent.EventType.Add, - Key = key, - Value = value - }; - - HandleAddDictionaryEvent(dictionaryEvent); - } - - /// - public void Add(KeyValuePair item) - { - Add(item.Key, item.Value); - } - - /// - public void Clear() - { - m_Dictionary.Clear(); - - var dictionaryEvent = new NetworkDictionaryEvent() - { - Type = NetworkDictionaryEvent.EventType.Clear - }; - - HandleAddDictionaryEvent(dictionaryEvent); - } - - /// - public bool Contains(KeyValuePair item) - { - return m_Dictionary.ContainsKey(item.Key) && - EqualityComparer.Default.Equals(item.Value, m_Dictionary[item.Key]); - } - - /// - public bool ContainsKey(TKey key) - { - return m_Dictionary.ContainsKey(key); - } - - /// - public void Remove(TKey key) - { - m_Dictionary.Remove(key); - - TValue value; - m_Dictionary.TryGetValue(key, out value); - - var dictionaryEvent = new NetworkDictionaryEvent() - { - Type = NetworkDictionaryEvent.EventType.Remove, - Key = key, - Value = value - }; - - HandleAddDictionaryEvent(dictionaryEvent); - } - - private void HandleAddDictionaryEvent(NetworkDictionaryEvent dictionaryEvent) - { - m_DirtyEvents.Add(dictionaryEvent); - OnDictionaryChanged?.Invoke(dictionaryEvent); - } - - public int LastModifiedTick - { - get - { - // todo: implement proper network tick for NetworkDictionary - return NetworkTickSystem.NoTick; - } - } - public override void Dispose() - { - m_Dictionary.Dispose(); - m_DirtyEvents.Dispose(); - } - } - - /// - /// Struct containing event information about changes to a NetworkDictionary. - /// - /// The type for the dictionary key that the event is about - /// The type for the dictionary value that the event is about - public struct NetworkDictionaryEvent - { - /// - /// Enum representing the different operations available for triggering an event. - /// - public enum EventType - { - /// - /// Add - /// - Add, - - /// - /// Remove - /// - Remove, - - /// - /// Clear - /// - Clear, - - /// - /// Value changed - /// - Value - } - - /// - /// Enum representing the operation made to the dictionary. - /// - public EventType Type; - - /// - /// the key changed, added or removed if available. - /// - public TKey Key; - - /// - /// The value changed, added or removed if available. - /// - public TValue Value; - } -} diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkDictionary.cs.meta b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkDictionary.cs.meta deleted file mode 100644 index 08f14ca258..0000000000 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkDictionary.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 262db7b2db1128748a2e88dd7e20a764 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkSet.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkSet.cs deleted file mode 100644 index 231354a590..0000000000 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkSet.cs +++ /dev/null @@ -1,306 +0,0 @@ -#if !NET35 -using System; -using System.IO; -using Unity.Collections; - -namespace Unity.Netcode -{ - /// - /// Event based NetworkVariable container for syncing Sets - /// - /// The type for the set - public class NetworkSet : NetworkVariableBase where T : unmanaged, IEquatable - { - private NativeHashSet m_Set = new NativeHashSet(64, Allocator.Persistent); - private NativeList> m_DirtyEvents = new NativeList>(64, Allocator.Persistent); - - /// - /// Delegate type for set changed event - /// - /// Struct containing information about the change event - public delegate void OnSetChangedDelegate(NetworkSetEvent changeEvent); - - /// - /// The callback to be invoked when the set gets changed - /// - public event OnSetChangedDelegate OnSetChanged; - - /// - /// Creates a NetworkSet with the default value and settings - /// - public NetworkSet() { } - - /// - /// Creates a NetworkSet with the default value and custom settings - /// - /// The read permissions to use for the NetworkList - public NetworkSet(NetworkVariableReadPermission readPerm) : base(readPerm) { } - - /// - public override void ResetDirty() - { - base.ResetDirty(); - m_DirtyEvents.Clear(); - } - - /// - public override bool IsDirty() - { - return base.IsDirty() || m_DirtyEvents.Length > 0; - } - - /// - public override void WriteDelta(Stream stream) - { - using var writer = PooledNetworkWriter.Get(stream); - writer.WriteUInt16Packed((ushort)m_DirtyEvents.Length); - for (int i = 0; i < m_DirtyEvents.Length; i++) - { - writer.WriteBits((byte)m_DirtyEvents[i].Type, 2); - - switch (m_DirtyEvents[i].Type) - { - case NetworkSetEvent.EventType.Add: - { - writer.WriteObjectPacked(m_DirtyEvents[i].Value); //BOX - } - break; - case NetworkSetEvent.EventType.Remove: - { - writer.WriteObjectPacked(m_DirtyEvents[i].Value); //BOX - } - break; - case NetworkSetEvent.EventType.Clear: - { - //Nothing has to be written - } - break; - } - } - } - - /// - public override void WriteField(Stream stream) - { - using var writer = PooledNetworkWriter.Get(stream); - writer.WriteUInt16Packed((ushort)m_Set.Count()); - - foreach (var pair in m_Set) - { - writer.WriteObjectPacked(pair); //BOX - } - } - - /// - public override void ReadField(Stream stream) - { - using var reader = PooledNetworkReader.Get(stream); - m_Set.Clear(); - ushort count = reader.ReadUInt16Packed(); - - for (int i = 0; i < count; i++) - { - m_Set.Add((T)reader.ReadObjectPacked(typeof(T))); //BOX - } - } - - /// - public override void ReadDelta(Stream stream, bool keepDirtyDelta) - { - using var reader = PooledNetworkReader.Get(stream); - ushort deltaCount = reader.ReadUInt16Packed(); - for (int i = 0; i < deltaCount; i++) - { - var eventType = (NetworkSetEvent.EventType)reader.ReadBits(2); - switch (eventType) - { - case NetworkSetEvent.EventType.Add: - { - var value = (T)reader.ReadObjectPacked(typeof(T)); //BOX - m_Set.Add(value); - - if (OnSetChanged != null) - { - OnSetChanged(new NetworkSetEvent - { - Type = eventType, - Value = value - }); - } - - if (keepDirtyDelta) - { - m_DirtyEvents.Add(new NetworkSetEvent() - { - Type = eventType, - Value = value - }); - } - } - break; - case NetworkSetEvent.EventType.Remove: - { - var value = (T)reader.ReadObjectPacked(typeof(T)); //BOX - m_Set.Remove(value); - - if (OnSetChanged != null) - { - OnSetChanged(new NetworkSetEvent - { - Type = eventType, - Value = value - }); - } - - if (keepDirtyDelta) - { - m_DirtyEvents.Add(new NetworkSetEvent() - { - Type = eventType, - Value = value - }); - } - } - break; - case NetworkSetEvent.EventType.Clear: - { - //Read nothing - m_Set.Clear(); - - if (OnSetChanged != null) - { - OnSetChanged(new NetworkSetEvent - { - Type = eventType, - }); - } - - if (keepDirtyDelta) - { - m_DirtyEvents.Add(new NetworkSetEvent() - { - Type = eventType - }); - } - } - break; - } - } - } - - public void Add(T item) - { - m_Set.Add(item); - - var setEvent = new NetworkSetEvent() - { - Type = NetworkSetEvent.EventType.Add, - Value = item - }; - m_DirtyEvents.Add(setEvent); - - if (OnSetChanged != null) - { - OnSetChanged(setEvent); - } - } - - /// - public void Clear() - { - m_Set.Clear(); - - var setEvent = new NetworkSetEvent() - { - Type = NetworkSetEvent.EventType.Clear - }; - m_DirtyEvents.Add(setEvent); - - if (OnSetChanged != null) - { - OnSetChanged(setEvent); - } - } - - /// - public bool Contains(T item) - { - return m_Set.Contains(item); - } - - /// - public void Remove(T item) - { - m_Set.Remove(item); - - var setEvent = new NetworkSetEvent() - { - Type = NetworkSetEvent.EventType.Remove, - Value = item - }; - m_DirtyEvents.Add(setEvent); - - if (OnSetChanged != null) - { - OnSetChanged(setEvent); - } - } - - /// - public int Count => m_Set.Count(); - - public int LastModifiedTick - { - get - { - // todo: implement proper network tick for NetworkSet - return NetworkTickSystem.NoTick; - } - } - - public override void Dispose() - { - m_Set.Dispose(); - m_DirtyEvents.Dispose(); - } - } - - /// - /// Struct containing event information about changes to a NetworkSet. - /// - /// The type for the set that the event is about - public struct NetworkSetEvent - { - /// - /// Enum representing the different operations available for triggering an event. - /// - public enum EventType - { - /// - /// Add - /// - Add, - - /// - /// Remove - /// - Remove, - - /// - /// Clear - /// - Clear - } - - /// - /// Enum representing the operation made to the set. - /// - public EventType Type; - - /// - /// The value changed, added or removed if available. - /// - public T Value; - } -} -#endif diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkSet.cs.meta b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkSet.cs.meta deleted file mode 100644 index 60c0a546d2..0000000000 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkSet.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 245b489a4e4f2174fbdeb27b9cdee07b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs index db07aeb500..5f67b4ab04 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs @@ -49,8 +49,6 @@ public class NetworkVariableTest : NetworkBehaviour { public readonly NetworkVariable TheScalar = new NetworkVariable(); public readonly NetworkList TheList = new NetworkList(); - public readonly NetworkSet TheSet = new NetworkSet(); - public readonly NetworkDictionary TheDictionary = new NetworkDictionary(); public readonly NetworkVariable FixedStringStruct = new NetworkVariable(); @@ -59,35 +57,15 @@ private void ListChanged(NetworkListEvent e) ListDelegateTriggered = true; } - private void SetChanged(NetworkSetEvent e) - { - SetDelegateTriggered = true; - } - - private void DictionaryChanged(NetworkDictionaryEvent e) - { - DictionaryDelegateTriggered = true; - } public void Awake() { TheList.OnListChanged += ListChanged; - TheSet.OnSetChanged += SetChanged; - TheDictionary.OnDictionaryChanged += DictionaryChanged; } - public void OnDestroy() - { - TheSet.Dispose(); - TheDictionary.Dispose(); - } - - public readonly NetworkVariable TheStruct = new NetworkVariable(); public bool ListDelegateTriggered; - public bool SetDelegateTriggered; - public bool DictionaryDelegateTriggered; } public class NetworkVariableTests : BaseMultiInstanceTest @@ -166,14 +144,12 @@ public override IEnumerator Setup() m_Player1OnClient2 = result.Result.GetComponent(); m_Player1OnServer.TheList.Clear(); - m_Player1OnServer.TheSet.Clear(); - m_Player1OnServer.TheDictionary.Clear(); - if (m_Player1OnServer.TheList.Count > 0 || m_Player1OnServer.TheSet.Count > 0 || m_Player1OnServer.TheDictionary.Count > 0) + if (m_Player1OnServer.TheList.Count > 0) { throw new Exception("at least one server network container not empty at start"); } - if (m_Player1OnClient1.TheList.Count > 0 || m_Player1OnClient1.TheSet.Count > 0 || m_Player1OnClient1.TheDictionary.Count > 0) + if (m_Player1OnClient1.TheList.Count > 0) { throw new Exception("at least one client network container not empty at start"); } @@ -327,225 +303,6 @@ public IEnumerator NetworkListClear([Values(true, false)] bool useHost) ); } - [UnityTest] - public IEnumerator NetworkSetAdd([Values(true, false)] bool useHost) - { - m_TestWithHost = useHost; - - yield return MultiInstanceHelpers.RunAndWaitForCondition( - () => - { - m_Player1OnServer.TheSet.Add(k_TestVal1); - m_Player1OnServer.TheSet.Add(k_TestVal2); - }, - () => - { - return m_Player1OnServer.TheSet.Count == 2 && - m_Player1OnClient1.TheSet.Count == 2 && - m_Player1OnServer.SetDelegateTriggered && - m_Player1OnClient1.SetDelegateTriggered && - m_Player1OnServer.TheSet.Contains(k_TestVal1) && - m_Player1OnClient1.TheSet.Contains(k_TestVal1) && - m_Player1OnServer.TheSet.Contains(k_TestVal2) && - m_Player1OnClient1.TheSet.Contains(k_TestVal2); - } - ); - } - - [UnityTest] - public IEnumerator NetworkSetRemove([Values(true, false)] bool useHost) - { - m_TestWithHost = useHost; - - // first put some stuff in; re-use the add test - yield return NetworkSetAdd(useHost); - - yield return MultiInstanceHelpers.RunAndWaitForCondition( - () => - { - m_Player1OnServer.TheSet.Remove(k_TestVal1); - }, - () => - { - return m_Player1OnServer.TheSet.Count == 1 && - m_Player1OnClient1.TheSet.Count == 1 && - m_Player1OnServer.SetDelegateTriggered && - m_Player1OnClient1.SetDelegateTriggered && - m_Player1OnServer.TheSet.Contains(k_TestVal2) && - m_Player1OnClient1.TheSet.Contains(k_TestVal2); - } - ); - } - - [UnityTest] - public IEnumerator NetworkSetClear([Values(true, false)] bool useHost) - { - // first put some stuff in; re-use the add test - yield return NetworkSetAdd(useHost); - - yield return MultiInstanceHelpers.RunAndWaitForCondition( - () => - { - m_Player1OnServer.TheSet.Clear(); - }, - () => - { - return m_Player1OnServer.TheSet.Count == 0 && - m_Player1OnClient1.TheSet.Count == 0 && - m_Player1OnServer.SetDelegateTriggered && - m_Player1OnClient1.SetDelegateTriggered; - } - ); - } - - [Test] - public void NetworkDictionaryTryGetValue([Values(true, false)] bool useHost) - { - m_TestWithHost = useHost; - m_Player1OnServer.TheDictionary[k_TestKey1] = k_TestVal1; - int outValue; - var result = m_Player1OnServer.TheDictionary.TryGetValue(k_TestKey1, out outValue); - Assert.IsTrue(result == true); - Assert.IsTrue(outValue == k_TestVal1); - } - - [Test] - public void NetworkDictionaryAddKeyValue([Values(true, false)] bool useHost) - { - m_TestWithHost = useHost; - - m_Player1OnServer.TheDictionary.Add(k_TestKey1, k_TestVal1); - Assert.IsTrue(m_Player1OnServer.TheDictionary[k_TestKey1] == k_TestVal1); - } - - [Test] - public void NetworkDictionaryAddKeyValuePair([Values(true, false)] bool useHost) - { - m_TestWithHost = useHost; - - m_Player1OnServer.TheDictionary.Add(new KeyValuePair(k_TestKey1, k_TestVal1)); - Assert.IsTrue(m_Player1OnServer.TheDictionary[k_TestKey1] == k_TestVal1); - } - - [Test] - public void NetworkDictionaryContainsKey([Values(true, false)] bool useHost) - { - m_TestWithHost = useHost; - - m_Player1OnServer.TheDictionary.Add(k_TestKey1, k_TestVal1); - Assert.IsTrue(m_Player1OnServer.TheDictionary.ContainsKey(k_TestKey1)); - } - - [Test] - public void NetworkDictionaryContains([Values(true, false)] bool useHost) - { - m_TestWithHost = useHost; - - m_Player1OnServer.TheDictionary.Add(k_TestKey1, k_TestVal1); - Assert.IsTrue(m_Player1OnServer.TheDictionary.Contains(new KeyValuePair(k_TestKey1, k_TestVal1))); - } - - [UnityTest] - public IEnumerator NetworkDictionaryAdd([Values(true, false)] bool useHost) - { - m_TestWithHost = useHost; - - yield return MultiInstanceHelpers.RunAndWaitForCondition( - () => - { - m_Player1OnServer.TheDictionary.Add(k_TestKey1, k_TestVal1); - m_Player1OnServer.TheDictionary.Add(k_TestKey2, k_TestVal2); - }, - () => - { - return m_Player1OnServer.TheDictionary.Count == 2 && - m_Player1OnClient1.TheDictionary.Count == 2 && - m_Player1OnServer.DictionaryDelegateTriggered && - m_Player1OnClient1.DictionaryDelegateTriggered && - m_Player1OnServer.TheDictionary[k_TestKey1] == k_TestVal1 && - m_Player1OnClient1.TheDictionary[k_TestKey1] == k_TestVal1 && - m_Player1OnServer.TheDictionary[k_TestKey2] == k_TestVal2 && - m_Player1OnClient1.TheDictionary[k_TestKey2] == k_TestVal2; - } - ); - } - - /* Note, not adding coverage for RemovePair, because we plan to remove - * this in the next PR - */ - [UnityTest] - public IEnumerator NetworkDictionaryRemoveByKey([Values(true, false)] bool useHost) - { - m_TestWithHost = useHost; - - // first put some stuff in; re-use the add test - yield return NetworkDictionaryAdd(useHost); - - yield return MultiInstanceHelpers.RunAndWaitForCondition( - () => - { - m_Player1OnServer.TheDictionary.Remove(k_TestKey2); - }, - () => - { - return m_Player1OnServer.TheDictionary.Count == 1 && - m_Player1OnClient1.TheDictionary.Count == 1 && - m_Player1OnServer.DictionaryDelegateTriggered && - m_Player1OnClient1.DictionaryDelegateTriggered && - m_Player1OnServer.TheDictionary[k_TestKey1] == k_TestVal1 && - m_Player1OnClient1.TheDictionary[k_TestKey1] == k_TestVal1; - } - ); - } - - [UnityTest] - public IEnumerator NetworkDictionaryChangeValue([Values(true, false)] bool useHost) - { - m_TestWithHost = useHost; - - // first put some stuff in; re-use the add test - yield return NetworkDictionaryAdd(useHost); - - yield return MultiInstanceHelpers.RunAndWaitForCondition( - () => - { - m_Player1OnServer.TheDictionary[k_TestKey1] = k_TestVal3; - }, - () => - { - return m_Player1OnServer.TheDictionary.Count == 2 && - m_Player1OnClient1.TheDictionary.Count == 2 && - m_Player1OnServer.DictionaryDelegateTriggered && - m_Player1OnClient1.DictionaryDelegateTriggered && - m_Player1OnServer.TheDictionary[k_TestKey1] == k_TestVal3 && - m_Player1OnClient1.TheDictionary[k_TestKey1] == k_TestVal3; - } - ); - } - - [UnityTest] - public IEnumerator NetworkDictionaryClear([Values(true, false)] bool useHost) - { - m_TestWithHost = useHost; - - // first put some stuff in; re-use the add test - yield return NetworkDictionaryAdd(useHost); - - yield return MultiInstanceHelpers.RunAndWaitForCondition( - () => - { - m_Player1OnServer.TheDictionary.Clear(); - }, - () => - { - return m_Player1OnServer.TheDictionary.Count == 0 && - m_Player1OnClient1.TheDictionary.Count == 0 && - m_Player1OnServer.DictionaryDelegateTriggered && - m_Player1OnClient1.DictionaryDelegateTriggered; - } - ); - } - [UnityTest] public IEnumerator TestNetworkVariableStruct([Values(true, false)] bool useHost) { diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/Profiling/NetworkVariableNameTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/Profiling/NetworkVariableNameTests.cs index 4161372187..e9d005a3b7 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/Profiling/NetworkVariableNameTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/Profiling/NetworkVariableNameTests.cs @@ -26,21 +26,13 @@ public void TearDown() [Test] public void VerifyNetworkVariableNameInitialization() { - // Properties have the following name format: "k__BackingField" - StringAssert.Contains(nameof(NetworkVariableNameComponent.NetworkVarSet), m_NetworkVariableNameComponent.NetworkVarSet.Name); - // Fields have regular naming Assert.AreEqual(nameof(NetworkVariableNameComponent.NetworkVarList), m_NetworkVariableNameComponent.NetworkVarList.Name); - Assert.AreEqual(nameof(NetworkVariableNameComponent.NetworkVarDictionary), m_NetworkVariableNameComponent.NetworkVarDictionary.Name); } private class NetworkVariableNameComponent : NetworkBehaviour { - public NetworkSet NetworkVarSet { get; } = new NetworkSet(); - public NetworkList NetworkVarList = new NetworkList(); - - public NetworkDictionary NetworkVarDictionary = new NetworkDictionary(); } } } From 9351b6d2b2ad49dc59d12c5c4b731bc21e2a8fc9 Mon Sep 17 00:00:00 2001 From: Matt Walsh Date: Mon, 13 Sep 2021 09:42:28 -0700 Subject: [PATCH 07/17] list cleanup --- .../NetworkVariable/Collections/NetworkList.cs | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs index e95839df17..19b086c3a7 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs @@ -8,9 +8,9 @@ namespace Unity.Netcode /// Event based NetworkVariable container for syncing Lists /// /// The type for the list - public class NetworkList : NetworkVariableBase, IList where T : unmanaged + public class NetworkList : NetworkVariableBase where T : unmanaged { - private readonly IList m_List = new List(); + private readonly List m_List = new List(); private readonly List> m_DirtyEvents = new List>(); /// @@ -40,7 +40,7 @@ public NetworkList(NetworkVariableReadPermission readPerm) : base(readPerm) { } /// /// The read permission to use for the NetworkList /// The initial value to use for the NetworkList - public NetworkList(NetworkVariableReadPermission readPerm, IList value) : base(readPerm) + public NetworkList(NetworkVariableReadPermission readPerm, List value) : base(readPerm) { m_List = value; } @@ -49,7 +49,7 @@ public NetworkList(NetworkVariableReadPermission readPerm, IList value) : bas /// Creates a NetworkList with a custom value and the default settings /// /// The initial value to use for the NetworkList - public NetworkList(IList value) + public NetworkList(List value) { m_List = value; } @@ -315,11 +315,6 @@ public IEnumerator GetEnumerator() return m_List.GetEnumerator(); } - IEnumerator IEnumerable.GetEnumerator() - { - return ((IEnumerable)m_List).GetEnumerator(); - } - /// public void Add(T item) { @@ -378,9 +373,6 @@ public bool Remove(T item) /// public int Count => m_List.Count; - /// - public bool IsReadOnly => m_List.IsReadOnly; - /// public int IndexOf(T item) { From fcfa2178f2686fc1235f310f5c82b5e5e33887ef Mon Sep 17 00:00:00 2001 From: Matt Walsh Date: Mon, 13 Sep 2021 18:48:48 -0700 Subject: [PATCH 08/17] more tests --- .../Runtime/Core/NetworkBehaviour.cs | 14 +- .../Collections/NetworkList.cs | 76 ++++---- .../Tests/Runtime/NetworkVariableTests.cs | 168 +++++++++++++++++- 3 files changed, 211 insertions(+), 47 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs index f99e78d1fc..71fa832ff8 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs @@ -825,12 +825,12 @@ protected NetworkObject GetNetworkObject(ulong networkId) return NetworkManager.SpawnManager.SpawnedObjects.TryGetValue(networkId, out NetworkObject networkObject) ? networkObject : null; } - public void OnDestroy() - { - for (int i = 0; i < NetworkVariableFields.Count; i++) - { - NetworkVariableFields[i].Dispose(); - } - } +// public void OnDestroy() +// { +// for (int i = 0; i < NetworkVariableFields.Count; i++) +// { +// NetworkVariableFields[i].Dispose(); +// } +// } } } diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs index 19b086c3a7..42a6abf643 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs @@ -1,6 +1,7 @@ -using System.Collections; +using System; using System.Collections.Generic; using System.IO; +using Unity.Collections; namespace Unity.Netcode { @@ -8,9 +9,9 @@ namespace Unity.Netcode /// Event based NetworkVariable container for syncing Lists /// /// The type for the list - public class NetworkList : NetworkVariableBase where T : unmanaged + public class NetworkList : NetworkVariableBase where T : unmanaged, IEquatable { - private readonly List m_List = new List(); + private NativeList m_List = new NativeList(64, Allocator.Persistent); private readonly List> m_DirtyEvents = new List>(); /// @@ -39,19 +40,25 @@ public NetworkList(NetworkVariableReadPermission readPerm) : base(readPerm) { } /// Creates a NetworkList with a custom value and custom settings /// /// The read permission to use for the NetworkList - /// The initial value to use for the NetworkList - public NetworkList(NetworkVariableReadPermission readPerm, List value) : base(readPerm) + /// The initial value to use for the NetworkList + public NetworkList(NetworkVariableReadPermission readPerm, NativeList values) : base(readPerm) { - m_List = value; + foreach (var val in values) + { + m_List.Add(val); + } } /// /// Creates a NetworkList with a custom value and the default settings /// - /// The initial value to use for the NetworkList - public NetworkList(List value) + /// The initial value to use for the NetworkList + public NetworkList(List values) { - m_List = value; + foreach (var val in values) + { + m_List.Add(val); + } } /// @@ -118,8 +125,8 @@ public override void WriteDelta(Stream stream) public override void WriteField(Stream stream) { using var writer = PooledNetworkWriter.Get(stream); - writer.WriteUInt16Packed((ushort)m_List.Count); - for (int i = 0; i < m_List.Count; i++) + writer.WriteUInt16Packed((ushort)m_List.Length); + for (int i = 0; i < m_List.Length; i++) { writer.WriteObjectPacked(m_List[i]); //BOX } @@ -156,8 +163,8 @@ public override void ReadDelta(Stream stream, bool keepDirtyDelta) OnListChanged(new NetworkListEvent { Type = eventType, - Index = m_List.Count - 1, - Value = m_List[m_List.Count - 1] + Index = m_List.Length - 1, + Value = m_List[m_List.Length - 1] }); } @@ -166,8 +173,8 @@ public override void ReadDelta(Stream stream, bool keepDirtyDelta) m_DirtyEvents.Add(new NetworkListEvent() { Type = eventType, - Index = m_List.Count - 1, - Value = m_List[m_List.Count - 1] + Index = m_List.Length - 1, + Value = m_List[m_List.Length - 1] }); } } @@ -175,7 +182,8 @@ public override void ReadDelta(Stream stream, bool keepDirtyDelta) case NetworkListEvent.EventType.Insert: { int index = reader.ReadInt32Packed(); - m_List.Insert(index, (T)reader.ReadObjectPacked(typeof(T))); //BOX + m_List.InsertRangeWithBeginEnd(index, index + 1); + m_List[index] = (T)reader.ReadObjectPacked(typeof(T)); //BOX if (OnListChanged != null) { @@ -201,7 +209,9 @@ public override void ReadDelta(Stream stream, bool keepDirtyDelta) case NetworkListEvent.EventType.Remove: { var value = (T)reader.ReadObjectPacked(typeof(T)); //BOX - int index = m_List.IndexOf(value); + int index = NativeArrayExtensions.IndexOf(m_List, value); + if (index == -1) break; + m_List.RemoveAt(index); if (OnListChanged != null) @@ -256,7 +266,7 @@ public override void ReadDelta(Stream stream, bool keepDirtyDelta) { int index = reader.ReadInt32Packed(); var value = (T)reader.ReadObjectPacked(typeof(T)); //BOX - if (index < m_List.Count) + if (index < m_List.Length) { m_List[index] = value; } @@ -308,7 +318,6 @@ public override void ReadDelta(Stream stream, bool keepDirtyDelta) } } - /// public IEnumerator GetEnumerator() { @@ -324,7 +333,7 @@ public void Add(T item) { Type = NetworkListEvent.EventType.Add, Value = item, - Index = m_List.Count - 1 + Index = m_List.Length - 1 }; HandleAddListEvent(listEvent); @@ -346,20 +355,20 @@ public void Clear() /// public bool Contains(T item) { - return m_List.Contains(item); - } - - /// - public void CopyTo(T[] array, int arrayIndex) - { - m_List.CopyTo(array, arrayIndex); + int index = NativeArrayExtensions.IndexOf(m_List, item); + return index == -1; } /// public bool Remove(T item) { - m_List.Remove(item); + int index = NativeArrayExtensions.IndexOf(m_List, item); + if (index == -1) + { + return false; + } + m_List.RemoveAt(index); var listEvent = new NetworkListEvent() { Type = NetworkListEvent.EventType.Remove, @@ -371,7 +380,7 @@ public bool Remove(T item) } /// - public int Count => m_List.Count; + public int Count => m_List.Length; /// public int IndexOf(T item) @@ -382,7 +391,8 @@ public int IndexOf(T item) /// public void Insert(int index, T item) { - m_List.Insert(index, item); + m_List.InsertRangeWithBeginEnd(index, index + 1); + m_List[index] = item; var listEvent = new NetworkListEvent() { @@ -408,7 +418,6 @@ public void RemoveAt(int index) HandleAddListEvent(listEvent); } - /// public T this[int index] { @@ -442,6 +451,11 @@ public int LastModifiedTick return NetworkTickSystem.NoTick; } } + + public override void Dispose() + { + m_List.Dispose(); + } } /// diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs index 5f67b4ab04..c7cb8e6349 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs @@ -1,11 +1,11 @@ using System; using System.Collections; -using System.Collections.Generic; using UnityEngine; using UnityEngine.TestTools; using NUnit.Framework; using Unity.Collections; -using Unity.Collections.LowLevel.Unsafe; + +// TODO: guard write operations namespace Unity.Netcode.RuntimeTests { @@ -57,6 +57,10 @@ private void ListChanged(NetworkListEvent e) ListDelegateTriggered = true; } + public void OnDestroy() + { + TheList.Dispose(); + } public void Awake() { @@ -262,22 +266,168 @@ public IEnumerator NetworkListAdd([Values(true, false)] bool useHost) } [UnityTest] - public IEnumerator NetworkListRemove([Values(true, false)] bool useHost) + public IEnumerator NetworkListContains([Values(true, false)] bool useHost) { m_TestWithHost = useHost; - // first put some stuff in; re-use the add test - yield return NetworkListAdd(useHost); - yield return MultiInstanceHelpers.RunAndWaitForCondition( - () => m_Player1OnServer.TheList.RemoveAt(0), + () => + { + m_Player1OnServer.TheList.Add(k_TestVal1); + }, () => { return m_Player1OnServer.TheList.Count == 1 && m_Player1OnClient1.TheList.Count == 1 && + m_Player1OnServer.TheList.Contains(k_TestKey1) && + m_Player1OnClient1.TheList.Contains(k_TestKey1); + } + ); + } + + [UnityTest] + public IEnumerator NetworkListRemoveValue([Values(true, false)] bool useHost) + { + m_TestWithHost = useHost; + yield return MultiInstanceHelpers.RunAndWaitForCondition( + () => + { + m_Player1OnServer.TheList.Add(k_TestVal1); + m_Player1OnServer.TheList.Add(k_TestVal2); + m_Player1OnServer.TheList.Add(k_TestVal3); + m_Player1OnServer.TheList.Remove(k_TestVal2); + }, + () => + { + return m_Player1OnServer.TheList.Count == 2 && + m_Player1OnClient1.TheList.Count == 2 && + m_Player1OnServer.TheList[0] == k_TestVal1 && + m_Player1OnClient1.TheList[0] == k_TestVal1 && + m_Player1OnServer.TheList[1] == k_TestVal3 && + m_Player1OnClient1.TheList[1] == k_TestVal3; + } + ); + } + + [UnityTest] + public IEnumerator NetworkListInsert([Values(true, false)] bool useHost) + { + m_TestWithHost = useHost; + yield return MultiInstanceHelpers.RunAndWaitForCondition( + () => + { + m_Player1OnServer.TheList.Add(k_TestVal1); + m_Player1OnServer.TheList.Add(k_TestVal2); + m_Player1OnServer.TheList.Insert(1, k_TestVal3); + }, + () => + { + return m_Player1OnServer.TheList.Count == 3 && + m_Player1OnClient1.TheList.Count == 3 && m_Player1OnServer.ListDelegateTriggered && m_Player1OnClient1.ListDelegateTriggered && - m_Player1OnServer.TheList[0] == k_TestVal2 && - m_Player1OnClient1.TheList[0] == k_TestVal2; + m_Player1OnServer.TheList[0] == k_TestVal1 && + m_Player1OnClient1.TheList[0] == k_TestVal1 && + m_Player1OnServer.TheList[1] == k_TestVal3 && + m_Player1OnClient1.TheList[1] == k_TestVal3 && + m_Player1OnServer.TheList[2] == k_TestVal2 && + m_Player1OnClient1.TheList[2] == k_TestVal2; + } + ); + } + + [UnityTest] + public IEnumerator NetworkListIndexOf([Values(true, false)] bool useHost) + { + m_TestWithHost = useHost; + yield return MultiInstanceHelpers.RunAndWaitForCondition( + () => + { + m_Player1OnServer.TheList.Add(k_TestVal1); + m_Player1OnServer.TheList.Add(k_TestVal2); + m_Player1OnServer.TheList.Add(k_TestVal3); + }, + () => + { + return m_Player1OnServer.TheList.IndexOf(k_TestVal1) == 0 && + m_Player1OnClient1.TheList.IndexOf(k_TestVal1) == 0 && + m_Player1OnServer.TheList.IndexOf(k_TestVal2) == 1 && + m_Player1OnClient1.TheList.IndexOf(k_TestVal2) == 1 && + m_Player1OnServer.TheList.IndexOf(k_TestVal3) == 2 && + m_Player1OnClient1.TheList.IndexOf(k_TestVal3) == 2; + } + ); + } + + [UnityTest] + public IEnumerator NetworkListArrayOperator([Values(true, false)] bool useHost) + { + m_TestWithHost = useHost; + yield return MultiInstanceHelpers.RunAndWaitForCondition( + () => + { + m_Player1OnServer.TheList.Add(k_TestVal3); + m_Player1OnServer.TheList.Add(k_TestVal3); + m_Player1OnServer.TheList[0] = k_TestVal1; + m_Player1OnServer.TheList[1] = k_TestVal2; + }, + () => + { + return m_Player1OnServer.TheList.Count == 2 && + m_Player1OnClient1.TheList.Count == 2 && + m_Player1OnServer.TheList[0] == k_TestVal1 && + m_Player1OnClient1.TheList[0] == k_TestVal1 && + m_Player1OnServer.TheList[1] == k_TestVal2 && + m_Player1OnClient1.TheList[1] == k_TestVal2; + } + ); + } + + [Test] + public void NetworkListIEnumerator([Values(true, false)] bool useHost) + { + m_TestWithHost = useHost; + var correctVals = new int[3]; + correctVals[0] = k_TestVal1; + correctVals[1] = k_TestVal2; + correctVals[2] = k_TestVal3; + + m_Player1OnServer.TheList.Add(correctVals[0]); + m_Player1OnServer.TheList.Add(correctVals[1]); + m_Player1OnServer.TheList.Add(correctVals[2]); + + Assert.IsTrue(m_Player1OnServer.TheList.Count == 3); + + int now = 0; + foreach (var val in m_Player1OnServer.TheList) + { + if (val != correctVals[now++]) + { + Assert.Fail(); + } + } + } + + [UnityTest] + public IEnumerator NetworkListRemoveAt([Values(true, false)] bool useHost) + { + m_TestWithHost = useHost; + + yield return MultiInstanceHelpers.RunAndWaitForCondition( + () => + { + m_Player1OnServer.TheList.Add(k_TestVal1); + m_Player1OnServer.TheList.Add(k_TestVal2); + m_Player1OnServer.TheList.Add(k_TestVal3); + m_Player1OnServer.TheList.RemoveAt(1); + }, + () => + { + return m_Player1OnServer.TheList.Count == 2 && + m_Player1OnClient1.TheList.Count == 2 && + m_Player1OnServer.TheList[0] == k_TestVal1 && + m_Player1OnClient1.TheList[0] == k_TestVal1 && + m_Player1OnServer.TheList[1] == k_TestVal3 && + m_Player1OnClient1.TheList[1] == k_TestVal3; } ); } From 4213ae809a20c8d8420c298da20f8ac0e38b3947 Mon Sep 17 00:00:00 2001 From: Matt Walsh Date: Tue, 14 Sep 2021 10:34:35 -0700 Subject: [PATCH 09/17] lint cleanup --- .../Runtime/Core/NetworkBehaviour.cs | 16 +++++++++------- .../NetworkVariable/Collections/NetworkList.cs | 5 ++++- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs index 71fa832ff8..820e56e3c3 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs @@ -825,12 +825,14 @@ protected NetworkObject GetNetworkObject(ulong networkId) return NetworkManager.SpawnManager.SpawnedObjects.TryGetValue(networkId, out NetworkObject networkObject) ? networkObject : null; } -// public void OnDestroy() -// { -// for (int i = 0; i < NetworkVariableFields.Count; i++) -// { -// NetworkVariableFields[i].Dispose(); -// } -// } + /* + public void OnDestroy() + { + for (int i = 0; i < NetworkVariableFields.Count; i++) + { + NetworkVariableFields[i].Dispose(); + } + } + */ } } diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs index 42a6abf643..986c41462d 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs @@ -210,7 +210,10 @@ public override void ReadDelta(Stream stream, bool keepDirtyDelta) { var value = (T)reader.ReadObjectPacked(typeof(T)); //BOX int index = NativeArrayExtensions.IndexOf(m_List, value); - if (index == -1) break; + if (index == -1) + { + break; + } m_List.RemoveAt(index); From 9746836d99cbc262a368d439d02a767be21233f5 Mon Sep 17 00:00:00 2001 From: Andrew Spiering Date: Tue, 14 Sep 2021 20:22:53 +0200 Subject: [PATCH 10/17] Fixing NetworkList tests from throwing --- .../Runtime/Core/NetworkBehaviour.cs | 2 -- .../Tests/Runtime/NetworkVariableTests.cs | 11 +++++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs index 820e56e3c3..f99e78d1fc 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs @@ -825,7 +825,6 @@ protected NetworkObject GetNetworkObject(ulong networkId) return NetworkManager.SpawnManager.SpawnedObjects.TryGetValue(networkId, out NetworkObject networkObject) ? networkObject : null; } - /* public void OnDestroy() { for (int i = 0; i < NetworkVariableFields.Count; i++) @@ -833,6 +832,5 @@ public void OnDestroy() NetworkVariableFields[i].Dispose(); } } - */ } } diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs index c7cb8e6349..5495574f7e 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs @@ -1,5 +1,6 @@ using System; using System.Collections; +using System.Linq; using UnityEngine; using UnityEngine.TestTools; using NUnit.Framework; @@ -57,11 +58,6 @@ private void ListChanged(NetworkListEvent e) ListDelegateTriggered = true; } - public void OnDestroy() - { - TheList.Dispose(); - } - public void Awake() { TheList.OnListChanged += ListChanged; @@ -109,7 +105,10 @@ public override IEnumerator Setup() yield return StartSomeClientsAndServerWithPlayers(useHost: m_TestWithHost, nbClients: NbClients, updatePlayerPrefab: playerPrefab => { - playerPrefab.AddComponent(); + var variable = playerPrefab.AddComponent(); + // This normally gets called when a NetworkBehaviour gets spawned but we are manually setting + // this up here so we need to make sure the internal NetworkVariableFields gets filled in. + variable.InitializeVariables(); }); // These are the *SERVER VERSIONS* of the *CLIENT PLAYER 1 & 2* From 34f4c237acc9b349647d43ca1168c36a3460d40d Mon Sep 17 00:00:00 2001 From: Matt Walsh Date: Tue, 14 Sep 2021 14:13:02 -0700 Subject: [PATCH 11/17] cleanup improvements, nativeList for dirty event list --- .../Runtime/Core/NetworkBehaviour.cs | 11 +++++++++++ .../NetworkVariable/Collections/NetworkList.cs | 9 +++++---- .../Tests/Runtime/HiddenVariableTests.cs | 1 - .../Tests/Runtime/NetworkVariableTests.cs | 5 +---- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs index f99e78d1fc..70f943f700 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs @@ -827,6 +827,17 @@ protected NetworkObject GetNetworkObject(ulong networkId) public void OnDestroy() { + // this seems odd to do here, but in fact especially in tests we can find ourselves + // here without having called InitializedVariables, which causes problems if any + // of those variables use native containers (e.g. NetworkList) as they won't be + // registered here and therefore won't be cleaned up. + // + // we should study to understand the initialization patterns + if (!m_VarInit) + { + InitializeVariables(); + } + for (int i = 0; i < NetworkVariableFields.Count; i++) { NetworkVariableFields[i].Dispose(); diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs index 986c41462d..0a07940a1a 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs @@ -12,7 +12,7 @@ namespace Unity.Netcode public class NetworkList : NetworkVariableBase where T : unmanaged, IEquatable { private NativeList m_List = new NativeList(64, Allocator.Persistent); - private readonly List> m_DirtyEvents = new List>(); + private NativeList> m_DirtyEvents = new NativeList>(64, Allocator.Persistent); /// /// Delegate type for list changed event @@ -72,15 +72,15 @@ public override void ResetDirty() public override bool IsDirty() { // we call the base class to allow the SetDirty() mechanism to work - return base.IsDirty() || m_DirtyEvents.Count > 0; + return base.IsDirty() || m_DirtyEvents.Length > 0; } /// public override void WriteDelta(Stream stream) { using var writer = PooledNetworkWriter.Get(stream); - writer.WriteUInt16Packed((ushort)m_DirtyEvents.Count); - for (int i = 0; i < m_DirtyEvents.Count; i++) + writer.WriteUInt16Packed((ushort)m_DirtyEvents.Length); + for (int i = 0; i < m_DirtyEvents.Length; i++) { writer.WriteBits((byte)m_DirtyEvents[i].Type, 3); switch (m_DirtyEvents[i].Type) @@ -458,6 +458,7 @@ public int LastModifiedTick public override void Dispose() { m_List.Dispose(); + m_DirtyEvents.Dispose(); } } diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/HiddenVariableTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/HiddenVariableTests.cs index 8716d963b5..61db5862fe 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/HiddenVariableTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/HiddenVariableTests.cs @@ -6,7 +6,6 @@ namespace Unity.Netcode.RuntimeTests { public class HiddenVariableTest : NetworkBehaviour { - } public class HiddenVariableObject : NetworkBehaviour diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs index 5495574f7e..226e73765d 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs @@ -105,10 +105,7 @@ public override IEnumerator Setup() yield return StartSomeClientsAndServerWithPlayers(useHost: m_TestWithHost, nbClients: NbClients, updatePlayerPrefab: playerPrefab => { - var variable = playerPrefab.AddComponent(); - // This normally gets called when a NetworkBehaviour gets spawned but we are manually setting - // this up here so we need to make sure the internal NetworkVariableFields gets filled in. - variable.InitializeVariables(); + playerPrefab.AddComponent(); }); // These are the *SERVER VERSIONS* of the *CLIENT PLAYER 1 & 2* From a280d047fc95723977e5b0d8e42799d345c99537 Mon Sep 17 00:00:00 2001 From: Matt Walsh Date: Tue, 14 Sep 2021 14:23:30 -0700 Subject: [PATCH 12/17] test cleanup --- .../Tests/Runtime/NetworkVariableTests.cs | 30 ------------------- 1 file changed, 30 deletions(-) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs index 226e73765d..593bd1be91 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs @@ -80,23 +80,13 @@ public class NetworkVariableTests : BaseMultiInstanceTest private const int k_TestVal3 = 333; private const int k_TestKey1 = 0x0f0f; - private const int k_TestKey2 = 0xf0f0; // Player1 component on the server private NetworkVariableTest m_Player1OnServer; - // Player2 component on the server - private NetworkVariableTest m_Player2OnServer; - // Player1 component on client1 private NetworkVariableTest m_Player1OnClient1; - // Player2 component on client1 - private NetworkVariableTest m_Player2OnClient2; - - // client2's version of client1's player object - private NetworkVariableTest m_Player1OnClient2; - private bool m_TestWithHost; [UnitySetUp] @@ -116,11 +106,6 @@ public override IEnumerator Setup() m_ServerNetworkManager, result)); m_Player1OnServer = result.Result.GetComponent(); - yield return MultiInstanceHelpers.Run(MultiInstanceHelpers.GetNetworkObjectByRepresentation( - x => x.IsPlayerObject && x.OwnerClientId == m_ClientNetworkManagers[1].LocalClientId, - m_ServerNetworkManager, result)); - m_Player2OnServer = result.Result.GetComponent(); - // This is client1's view of itself yield return MultiInstanceHelpers.Run(MultiInstanceHelpers.GetNetworkObjectByRepresentation( x => x.IsPlayerObject && x.OwnerClientId == m_ClientNetworkManagers[0].LocalClientId, @@ -128,21 +113,6 @@ public override IEnumerator Setup() m_Player1OnClient1 = result.Result.GetComponent(); - // This is client2's view of itself - result = new MultiInstanceHelpers.CoroutineResultWrapper(); - yield return MultiInstanceHelpers.Run(MultiInstanceHelpers.GetNetworkObjectByRepresentation( - x => x.IsPlayerObject && x.OwnerClientId == m_ClientNetworkManagers[1].LocalClientId, - m_ClientNetworkManagers[1], result)); - - m_Player2OnClient2 = result.Result.GetComponent(); - - // This is client2's view of client 1's object - yield return MultiInstanceHelpers.Run(MultiInstanceHelpers.GetNetworkObjectByRepresentation( - x => x.IsPlayerObject && x.OwnerClientId == m_ClientNetworkManagers[0].LocalClientId, - m_ClientNetworkManagers[1], result)); - - m_Player1OnClient2 = result.Result.GetComponent(); - m_Player1OnServer.TheList.Clear(); if (m_Player1OnServer.TheList.Count > 0) From 33df729c81cbc6f37790a49d808a027ae3caf63e Mon Sep 17 00:00:00 2001 From: Matt Walsh Date: Tue, 14 Sep 2021 14:35:39 -0700 Subject: [PATCH 13/17] rounded out xtors in NetworkList --- .../NetworkVariable/Collections/NetworkList.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs index 0a07940a1a..d9589286d1 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs @@ -41,7 +41,7 @@ public NetworkList(NetworkVariableReadPermission readPerm) : base(readPerm) { } /// /// The read permission to use for the NetworkList /// The initial value to use for the NetworkList - public NetworkList(NetworkVariableReadPermission readPerm, NativeList values) : base(readPerm) + public NetworkList(NetworkVariableReadPermission readPerm, List values) : base(readPerm) { foreach (var val in values) { @@ -61,6 +61,16 @@ public NetworkList(List values) } } + public NetworkList(NetworkVariableReadPermission readPerm, NativeList values) : base(readPerm) + { + m_List = values; + } + + public NetworkList(NativeList values) + { + m_List = values; + } + /// public override void ResetDirty() { From 161f10e415db174e58a051dddb4980836d66a46c Mon Sep 17 00:00:00 2001 From: Matt Walsh Date: Tue, 14 Sep 2021 15:26:30 -0700 Subject: [PATCH 14/17] improved ienumerable, removed client writability --- .../Runtime/Core/NetworkBehaviour.cs | 2 +- .../Collections/NetworkList.cs | 30 +++++-------------- .../NetworkVariable/NetworkVariableBase.cs | 13 ++------ 3 files changed, 10 insertions(+), 35 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs index 70f943f700..6ca9eb30b5 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs @@ -639,7 +639,7 @@ internal void HandleNetworkVariableDeltas(Stream stream, ulong clientId) } } - if (NetworkManager.IsServer && !NetworkVariableFields[i].CanClientWrite(clientId)) + if (NetworkManager.IsClient) { // we are choosing not to fire an exception here, because otherwise a malicious client could use this to crash the server if (NetworkManager.NetworkConfig.EnsureNetworkVariableLengthSafety) diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs index d9589286d1..6352e2868a 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.IO; using Unity.Collections; @@ -34,18 +35,11 @@ public NetworkList() { } /// Creates a NetworkList with the default value and custom settings /// /// The read permission to use for the NetworkList - public NetworkList(NetworkVariableReadPermission readPerm) : base(readPerm) { } - - /// - /// Creates a NetworkList with a custom value and custom settings - /// - /// The read permission to use for the NetworkList - /// The initial value to use for the NetworkList - public NetworkList(NetworkVariableReadPermission readPerm, List values) : base(readPerm) + public NetworkList(NetworkVariableReadPermission readPerm, IEnumerable values) : base(readPerm) { - foreach (var val in values) + foreach (var value in values) { - m_List.Add(val); + m_List.Add(value); } } @@ -53,24 +47,14 @@ public NetworkList(NetworkVariableReadPermission readPerm, List values) : bas /// Creates a NetworkList with a custom value and the default settings /// /// The initial value to use for the NetworkList - public NetworkList(List values) + public NetworkList(IEnumerable values) { - foreach (var val in values) + foreach (var value in values) { - m_List.Add(val); + m_List.Add(value); } } - public NetworkList(NetworkVariableReadPermission readPerm, NativeList values) : base(readPerm) - { - m_List = values; - } - - public NetworkList(NativeList values) - { - m_List = values; - } - /// public override void ResetDirty() { diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariableBase.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariableBase.cs index 8be3b16a65..84bc6b5bef 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariableBase.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/NetworkVariableBase.cs @@ -1,3 +1,4 @@ +using System; using System.IO; namespace Unity.Netcode @@ -5,7 +6,7 @@ namespace Unity.Netcode /// /// Interface for network value containers /// - public abstract class NetworkVariableBase + public abstract class NetworkVariableBase : IDisposable { /// /// The delivery type (QoS) to send data with @@ -84,16 +85,6 @@ public bool CanClientRead(ulong clientId) return true; } - /// - /// Gets Whether or not a specific client can read to the varaible - /// - /// The clientId of the remote client - /// Whether or not the client can read to the variable - public virtual bool CanClientWrite(ulong clientId) - { - return false; - } - /// /// Writes the dirty changes, that is, the changes since the variable was last dirty, to the writer /// From c7d6301c4c60c0c80bc747130cb8a2f36387a112 Mon Sep 17 00:00:00 2001 From: Matt Walsh Date: Tue, 14 Sep 2021 15:29:19 -0700 Subject: [PATCH 15/17] header cleanup --- .../Runtime/NetworkVariable/Collections/NetworkList.cs | 2 +- .../Tests/Runtime/NetworkVariableTests.cs | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs index 6352e2868a..7099b3c53e 100644 --- a/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs +++ b/com.unity.netcode.gameobjects/Runtime/NetworkVariable/Collections/NetworkList.cs @@ -1,5 +1,4 @@ using System; -using System.Collections; using System.Collections.Generic; using System.IO; using Unity.Collections; @@ -35,6 +34,7 @@ public NetworkList() { } /// Creates a NetworkList with the default value and custom settings /// /// The read permission to use for the NetworkList + /// The initial value to use for the NetworkList public NetworkList(NetworkVariableReadPermission readPerm, IEnumerable values) : base(readPerm) { foreach (var value in values) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs index da73749e3f..aeacbfe9fc 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs @@ -1,13 +1,10 @@ using System; using System.Collections; -using System.Linq; using UnityEngine; using UnityEngine.TestTools; using NUnit.Framework; using Unity.Collections; -// TODO: guard write operations - namespace Unity.Netcode.RuntimeTests { public struct FixedString32Struct : INetworkSerializable From 42566aff7ac203360f336d2983a19e3888d93ff6 Mon Sep 17 00:00:00 2001 From: Matt Walsh Date: Tue, 14 Sep 2021 15:30:44 -0700 Subject: [PATCH 16/17] now -> index --- .../Tests/Runtime/NetworkVariableTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs index aeacbfe9fc..09f15e7d41 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkVariableTests.cs @@ -360,10 +360,10 @@ public void NetworkListIEnumerator([Values(true, false)] bool useHost) Assert.IsTrue(m_Player1OnServer.TheList.Count == 3); - int now = 0; + int index = 0; foreach (var val in m_Player1OnServer.TheList) { - if (val != correctVals[now++]) + if (val != correctVals[index++]) { Assert.Fail(); } From e2b55a7a4b5e6922f09d87d9fa23c4fcd2f54b2f Mon Sep 17 00:00:00 2001 From: Matt Walsh Date: Tue, 14 Sep 2021 15:51:32 -0700 Subject: [PATCH 17/17] server -> client --- com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs b/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs index 6ca9eb30b5..aa1e25338b 100644 --- a/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs +++ b/com.unity.netcode.gameobjects/Runtime/Core/NetworkBehaviour.cs @@ -639,7 +639,7 @@ internal void HandleNetworkVariableDeltas(Stream stream, ulong clientId) } } - if (NetworkManager.IsClient) + if (NetworkManager.IsServer) { // we are choosing not to fire an exception here, because otherwise a malicious client could use this to crash the server if (NetworkManager.NetworkConfig.EnsureNetworkVariableLengthSafety)