using System; using System.Collections.Generic; namespace Unity.Netcode.TestHelpers.Runtime { /// /// Will automatically register for the NetworkVariable OnValueChanged /// delegate handler. It then will expose that single delegate invocation /// to anything that registers for this NetworkVariableHelper's instance's OnValueChanged event. /// This allows us to register any NetworkVariable type as well as there are basically two "types of types": /// IEquatable /// ValueType /// From both we can then at least determine if the value indeed changed /// /// public class NetworkVariableHelper : NetworkVariableBaseHelper { private readonly NetworkVariable m_NetworkVariable; public delegate void OnMyValueChangedDelegateHandler(T previous, T next); public event OnMyValueChangedDelegateHandler OnValueChanged; /// /// IEquatable Equals Check /// private void CheckVariableChanged(IEquatable previous, IEquatable next) { if (!previous.Equals(next)) { ValueChanged(); } } /// /// ValueType Equals Check /// private void CheckVariableChanged(ValueType previous, ValueType next) { if (!previous.Equals(next)) { ValueChanged(); } } /// /// INetworkVariable's OnVariableChanged delegate callback /// /// /// private void OnVariableChanged(T previous, T next) { if (previous is ValueType testValueType) { CheckVariableChanged(previous as ValueType, next as ValueType); } else { CheckVariableChanged(previous as IEquatable, next as IEquatable); } OnValueChanged?.Invoke(previous, next); } public NetworkVariableHelper(NetworkVariableBase networkVariable) : base(networkVariable) { m_NetworkVariable = networkVariable as NetworkVariable; m_NetworkVariable.OnValueChanged = OnVariableChanged; } } /// /// The BaseNetworkVariableHelper keeps track of: /// The number of instances and associates the instance with the NetworkVariable /// The number of times a specific NetworkVariable instance had its value changed (i.e. !Equal) /// Note: This could be expanded for future tests focuses around NetworkVariables /// public class NetworkVariableBaseHelper { private static Dictionary s_Instances; private static Dictionary s_InstanceChangedCount; /// /// Returns the total number of registered INetworkVariables /// public static int InstanceCount { get { if (s_Instances != null) { return s_Instances.Count; } return 0; } } /// /// Returns total number of changes that occurred for all registered INetworkVariables /// public static int VarChangedCount { get { if (s_InstanceChangedCount != null) { var changeCount = 0; foreach (var keyPair in s_InstanceChangedCount) { changeCount += keyPair.Value; } return changeCount; } return 0; } } /// /// Called by the child class NetworkVariableHelper when a value changed /// protected void ValueChanged() { if (s_Instances.ContainsKey(this)) { if (s_InstanceChangedCount.ContainsKey(s_Instances[this])) { s_InstanceChangedCount[s_Instances[this]]++; } } } public NetworkVariableBaseHelper(NetworkVariableBase networkVariable) { if (s_Instances == null) { s_Instances = new Dictionary(); } if (s_InstanceChangedCount == null) { s_InstanceChangedCount = new Dictionary(); } // Register new instance and associated INetworkVariable if (!s_Instances.ContainsKey(this)) { s_Instances.Add(this, networkVariable); if (!s_InstanceChangedCount.ContainsKey(networkVariable)) { s_InstanceChangedCount.Add(networkVariable, 0); } } } } }