SyncVarNetworkBehaviour ==, != overloads

This commit is contained in:
vis2k 2022-02-01 12:05:18 +08:00
parent 0e42e5ce48
commit ed7de945d5
3 changed files with 93 additions and 0 deletions

View File

@ -7,6 +7,7 @@
//
// original Weaver code was broken because it didn't store by netId.
using System;
using System.Runtime.CompilerServices;
namespace Mirror
{
@ -44,6 +45,34 @@ public SyncVarNetworkBehaviour(T value = null, Action<T, T> hook = null)
// even if SyncField is readonly, it's still useful: SyncFieldNetworkBehaviour = target;
public static implicit operator SyncVarNetworkBehaviour<T>(T value) => new SyncVarNetworkBehaviour<T>(value);
// NOTE: overloading all == operators blocks '== null' checks with an
// "ambiguous invocation" error. that's good. this way user code like
// "player.target == null" won't compile instead of silently failing!
// == operator for comparisons like Player.target==monster
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(SyncVarNetworkBehaviour<T> a, SyncVarNetworkBehaviour<T> b) =>
a.Value == b.Value;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(SyncVarNetworkBehaviour<T> a, SyncVarNetworkBehaviour<T> b) => !(a == b);
// == operator for comparisons like Player.target==monster
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(SyncVarNetworkBehaviour<T> a, NetworkBehaviour b) =>
a.Value == b;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(SyncVarNetworkBehaviour<T> a, NetworkBehaviour b) => !(a == b);
// == operator for comparisons like Player.target==monster
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(NetworkBehaviour a, SyncVarNetworkBehaviour<T> b) =>
a == b.Value;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(NetworkBehaviour a, SyncVarNetworkBehaviour<T> b) => !(a == b);
// wrap <NetworkIdentity> hook within base <uint> hook
static Action<ulong, ulong> WrapHook(Action<T, T> hook) =>
(oldValue, newValue) => { hook(ULongToNetworkBehaviour(oldValue), ULongToNetworkBehaviour(newValue)); };

View File

@ -1,4 +1,5 @@
using NUnit.Framework;
using UnityEngine;
namespace Mirror.Tests
{
@ -96,6 +97,37 @@ public void ImplicitFrom_SetsValue()
Assert.That(field.Value, Is.EqualTo(component));
}
[Test]
public void OperatorEquals()
{
// != null
SyncVarNetworkBehaviour<NetworkBehaviour> field = new SyncVarNetworkBehaviour<NetworkBehaviour>(component);
// NOTE: this throws a compilation error, which is good!
// we don't want users to do 'player.target == null'.
// better to not compile than to fail silently.
// Assert.That(field != null, Is.True);
// different SyncVar<T>, same .Value
SyncVarNetworkBehaviour<NetworkBehaviour> fieldSame = new SyncVarNetworkBehaviour<NetworkBehaviour>(component);
Assert.That(field == fieldSame, Is.True);
Assert.That(field != fieldSame, Is.False);
// different SyncVar<T>, different .Value
SyncVarNetworkBehaviour<NetworkBehaviour> fieldNull = new SyncVarNetworkBehaviour<NetworkBehaviour>(null);
Assert.That(field == fieldNull, Is.False);
Assert.That(field != fieldNull, Is.True);
// same NetworkBehaviour<NetworkBehaviour>
Assert.That(field == component, Is.True);
Assert.That(field != component, Is.False);
// different NetworkBehaviour<NetworkBehaviour>
EmptyBehaviour other = new GameObject().AddComponent<EmptyBehaviour>();
Assert.That(field == (NetworkBehaviour)other, Is.False); // NRE
Assert.That(field != (NetworkBehaviour)other, Is.True);
}
// make sure the NetworkBehaviour hook works, even though base is uint.
[Test]
public void Hook()

View File

@ -1,4 +1,5 @@
using NUnit.Framework;
using UnityEngine;
namespace Mirror.Tests
{
@ -93,6 +94,37 @@ public void ImplicitFrom_SetsValue()
Assert.That(field.Value, Is.EqualTo(component));
}
[Test]
public void OperatorEquals()
{
// != null
SyncVarNetworkBehaviour<EmptyBehaviour> field = new SyncVarNetworkBehaviour<EmptyBehaviour>(component);
// NOTE: this throws a compilation error, which is good!
// we don't want users to do 'player.target == null'.
// better to not compile than to fail silently.
// Assert.That(field != null, Is.True);
// different SyncVar<T>, same .Value
SyncVarNetworkBehaviour<EmptyBehaviour> fieldSame = new SyncVarNetworkBehaviour<EmptyBehaviour>(component);
Assert.That(field == fieldSame, Is.True);
Assert.That(field != fieldSame, Is.False);
// different SyncVar<T>, different .Value
SyncVarNetworkBehaviour<EmptyBehaviour> fieldNull = new SyncVarNetworkBehaviour<EmptyBehaviour>(null);
Assert.That(field == fieldNull, Is.False);
Assert.That(field != fieldNull, Is.True);
// same NetworkBehaviour<EmptyBehaviour>
Assert.That(field == component, Is.True);
Assert.That(field != component, Is.False);
// different NetworkBehaviour<EmptyBehaviour>
CreateNetworked(out GameObject otherGo, out NetworkIdentity otherIdentity, out EmptyBehaviour otherComp);
Assert.That(field == otherComp, Is.False);
Assert.That(field != otherComp, Is.True);
}
// make sure the NetworkBehaviour hook works, even though base is uint.
[Test]
public void Hook()