mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 11:00:32 +00:00
perf: SyncVar<T> some more inlining
This commit is contained in:
parent
0d55ed8448
commit
ff1199607e
@ -16,6 +16,7 @@
|
|||||||
//
|
//
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace Mirror
|
namespace Mirror
|
||||||
@ -33,6 +34,7 @@ public class SyncVar<T> : SyncObject, IEquatable<T>
|
|||||||
// virtual for SyncFieldNetworkIdentity netId trick etc.
|
// virtual for SyncFieldNetworkIdentity netId trick etc.
|
||||||
public virtual T Value
|
public virtual T Value
|
||||||
{
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get => _Value;
|
get => _Value;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
@ -74,6 +76,7 @@ public virtual T Value
|
|||||||
// OnCallback is responsible for calling the callback.
|
// OnCallback is responsible for calling the callback.
|
||||||
// this is necessary for inheriting classes like SyncVarGameObject,
|
// this is necessary for inheriting classes like SyncVarGameObject,
|
||||||
// where the netIds should be converted to GOs and call the GO hook.
|
// where the netIds should be converted to GOs and call the GO hook.
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
protected virtual void InvokeCallback(T oldValue, T newValue) =>
|
protected virtual void InvokeCallback(T oldValue, T newValue) =>
|
||||||
Callback?.Invoke(oldValue, newValue);
|
Callback?.Invoke(oldValue, newValue);
|
||||||
|
|
||||||
@ -107,21 +110,31 @@ public SyncVar(T value)
|
|||||||
// SyncVar<T>s are readonly and only initialized by 'Value' once.
|
// SyncVar<T>s are readonly and only initialized by 'Value' once.
|
||||||
|
|
||||||
// implicit conversion: int value = SyncVar<T>
|
// implicit conversion: int value = SyncVar<T>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static implicit operator T(SyncVar<T> field) => field.Value;
|
public static implicit operator T(SyncVar<T> field) => field.Value;
|
||||||
|
|
||||||
// implicit conversion: SyncVar<T> = value
|
// implicit conversion: SyncVar<T> = value
|
||||||
// even if SyncVar<T> is readonly, it's still useful: SyncVar<int> = 1;
|
// even if SyncVar<T> is readonly, it's still useful: SyncVar<int> = 1;
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static implicit operator SyncVar<T>(T value) => new SyncVar<T>(value);
|
public static implicit operator SyncVar<T>(T value) => new SyncVar<T>(value);
|
||||||
|
|
||||||
// serialization (use .Value instead of _Value so hook is called!)
|
// serialization (use .Value instead of _Value so hook is called!)
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public override void OnSerializeAll(NetworkWriter writer) => writer.Write(Value);
|
public override void OnSerializeAll(NetworkWriter writer) => writer.Write(Value);
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public override void OnSerializeDelta(NetworkWriter writer) => writer.Write(Value);
|
public override void OnSerializeDelta(NetworkWriter writer) => writer.Write(Value);
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public override void OnDeserializeAll(NetworkReader reader) => Value = reader.Read<T>();
|
public override void OnDeserializeAll(NetworkReader reader) => Value = reader.Read<T>();
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public override void OnDeserializeDelta(NetworkReader reader) => Value = reader.Read<T>();
|
public override void OnDeserializeDelta(NetworkReader reader) => Value = reader.Read<T>();
|
||||||
|
|
||||||
// IEquatable should compare Value.
|
// IEquatable should compare Value.
|
||||||
// SyncVar<T> should act invisibly like [SyncVar] before.
|
// SyncVar<T> should act invisibly like [SyncVar] before.
|
||||||
// this way we can do SyncVar<int> health == 0 etc.
|
// this way we can do SyncVar<int> health == 0 etc.
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool Equals(T other) =>
|
public bool Equals(T other) =>
|
||||||
// from NetworkBehaviour.SyncVarEquals:
|
// from NetworkBehaviour.SyncVarEquals:
|
||||||
// EqualityComparer method avoids allocations.
|
// EqualityComparer method avoids allocations.
|
||||||
|
@ -55,7 +55,9 @@ public class SyncVarGameObject : SyncVar<uint>
|
|||||||
// .spawned lookup from netId overwrites base uint .Value
|
// .spawned lookup from netId overwrites base uint .Value
|
||||||
public new GameObject Value
|
public new GameObject Value
|
||||||
{
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get => GetGameObject(base.Value);
|
get => GetGameObject(base.Value);
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
set => base.Value = GetNetId(value);
|
set => base.Value = GetNetId(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,6 +66,7 @@ public class SyncVarGameObject : SyncVar<uint>
|
|||||||
public new event Action<GameObject, GameObject> Callback;
|
public new event Action<GameObject, GameObject> Callback;
|
||||||
|
|
||||||
// overwrite CallCallback to use the GameObject version instead
|
// overwrite CallCallback to use the GameObject version instead
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
protected override void InvokeCallback(uint oldValue, uint newValue) =>
|
protected override void InvokeCallback(uint oldValue, uint newValue) =>
|
||||||
Callback?.Invoke(GetGameObject(oldValue), GetGameObject(newValue));
|
Callback?.Invoke(GetGameObject(oldValue), GetGameObject(newValue));
|
||||||
|
|
||||||
@ -76,6 +79,7 @@ public SyncVarGameObject(GameObject value = null)
|
|||||||
: base(GetNetId(value)) {}
|
: base(GetNetId(value)) {}
|
||||||
|
|
||||||
// helper function to get netId from GameObject (if any)
|
// helper function to get netId from GameObject (if any)
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
static uint GetNetId(GameObject go)
|
static uint GetNetId(GameObject go)
|
||||||
{
|
{
|
||||||
if (go != null)
|
if (go != null)
|
||||||
@ -87,6 +91,7 @@ static uint GetNetId(GameObject go)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// helper function to get GameObject from netId (if spawned)
|
// helper function to get GameObject from netId (if spawned)
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
static GameObject GetGameObject(uint netId)
|
static GameObject GetGameObject(uint netId)
|
||||||
{
|
{
|
||||||
NetworkIdentity spawned = Utils.GetSpawnedInServerOrClient(netId);
|
NetworkIdentity spawned = Utils.GetSpawnedInServerOrClient(netId);
|
||||||
@ -94,10 +99,12 @@ static GameObject GetGameObject(uint netId)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// implicit conversion: GameObject value = SyncFieldGameObject
|
// implicit conversion: GameObject value = SyncFieldGameObject
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static implicit operator GameObject(SyncVarGameObject field) => field.Value;
|
public static implicit operator GameObject(SyncVarGameObject field) => field.Value;
|
||||||
|
|
||||||
// implicit conversion: SyncFieldGameObject = value
|
// implicit conversion: SyncFieldGameObject = value
|
||||||
// even if SyncField is readonly, it's still useful: SyncFieldGameObject = target;
|
// even if SyncField is readonly, it's still useful: SyncFieldGameObject = target;
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static implicit operator SyncVarGameObject(GameObject value) => new SyncVarGameObject(value);
|
public static implicit operator SyncVarGameObject(GameObject value) => new SyncVarGameObject(value);
|
||||||
|
|
||||||
// == operator for comparisons like Player.target==monster
|
// == operator for comparisons like Player.target==monster
|
||||||
@ -129,7 +136,10 @@ static GameObject GetGameObject(uint netId)
|
|||||||
public static bool operator !=(GameObject a, SyncVarGameObject b) => !(a == b);
|
public static bool operator !=(GameObject a, SyncVarGameObject b) => !(a == b);
|
||||||
|
|
||||||
// if we overwrite == operators, we also need to overwrite .Equals.
|
// if we overwrite == operators, we also need to overwrite .Equals.
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public override bool Equals(object obj) => obj is SyncVarGameObject value && this == value;
|
public override bool Equals(object obj) => obj is SyncVarGameObject value && this == value;
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public override int GetHashCode() => Value.GetHashCode();
|
public override int GetHashCode() => Value.GetHashCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,9 @@ public class SyncVarNetworkBehaviour<T> : SyncVar<ulong>
|
|||||||
// .spawned lookup from netId overwrites base uint .Value
|
// .spawned lookup from netId overwrites base uint .Value
|
||||||
public new T Value
|
public new T Value
|
||||||
{
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get => ULongToNetworkBehaviour(base.Value);
|
get => ULongToNetworkBehaviour(base.Value);
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
set => base.Value = NetworkBehaviourToULong(value);
|
set => base.Value = NetworkBehaviourToULong(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,6 +36,7 @@ public class SyncVarNetworkBehaviour<T> : SyncVar<ulong>
|
|||||||
public new event Action<T, T> Callback;
|
public new event Action<T, T> Callback;
|
||||||
|
|
||||||
// overwrite CallCallback to use the NetworkIdentity version instead
|
// overwrite CallCallback to use the NetworkIdentity version instead
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
protected override void InvokeCallback(ulong oldValue, ulong newValue) =>
|
protected override void InvokeCallback(ulong oldValue, ulong newValue) =>
|
||||||
Callback?.Invoke(ULongToNetworkBehaviour(oldValue), ULongToNetworkBehaviour(newValue));
|
Callback?.Invoke(ULongToNetworkBehaviour(oldValue), ULongToNetworkBehaviour(newValue));
|
||||||
|
|
||||||
@ -46,10 +49,12 @@ public SyncVarNetworkBehaviour(T value = null)
|
|||||||
: base(NetworkBehaviourToULong(value)) {}
|
: base(NetworkBehaviourToULong(value)) {}
|
||||||
|
|
||||||
// implicit conversion: NetworkBehaviour value = SyncFieldNetworkBehaviour
|
// implicit conversion: NetworkBehaviour value = SyncFieldNetworkBehaviour
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static implicit operator T(SyncVarNetworkBehaviour<T> field) => field.Value;
|
public static implicit operator T(SyncVarNetworkBehaviour<T> field) => field.Value;
|
||||||
|
|
||||||
// implicit conversion: SyncFieldNetworkBehaviour = value
|
// implicit conversion: SyncFieldNetworkBehaviour = value
|
||||||
// even if SyncField is readonly, it's still useful: SyncFieldNetworkBehaviour = target;
|
// even if SyncField is readonly, it's still useful: SyncFieldNetworkBehaviour = target;
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static implicit operator SyncVarNetworkBehaviour<T>(T value) => new SyncVarNetworkBehaviour<T>(value);
|
public static implicit operator SyncVarNetworkBehaviour<T>(T value) => new SyncVarNetworkBehaviour<T>(value);
|
||||||
|
|
||||||
// NOTE: overloading all == operators blocks '== null' checks with an
|
// NOTE: overloading all == operators blocks '== null' checks with an
|
||||||
@ -97,16 +102,18 @@ public SyncVarNetworkBehaviour(T value = null)
|
|||||||
public static bool operator !=(T a, SyncVarNetworkBehaviour<T> b) => !(a == b);
|
public static bool operator !=(T a, SyncVarNetworkBehaviour<T> b) => !(a == b);
|
||||||
|
|
||||||
// if we overwrite == operators, we also need to overwrite .Equals.
|
// if we overwrite == operators, we also need to overwrite .Equals.
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public override bool Equals(object obj) => obj is SyncVarNetworkBehaviour<T> value && this == value;
|
public override bool Equals(object obj) => obj is SyncVarNetworkBehaviour<T> value && this == value;
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public override int GetHashCode() => Value.GetHashCode();
|
public override int GetHashCode() => Value.GetHashCode();
|
||||||
|
|
||||||
// helper functions to get/set netId, componentIndex from ulong
|
// helper functions to get/set netId, componentIndex from ulong
|
||||||
internal static ulong Pack(uint netId, byte componentIndex)
|
// netId on the 4 left bytes. compIndex on the right most byte.
|
||||||
{
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
// netId on the 4 left bytes. compIndex on the right most byte.
|
internal static ulong Pack(uint netId, byte componentIndex) =>
|
||||||
return (ulong)netId << 32 | componentIndex;
|
(ulong)netId << 32 | componentIndex;
|
||||||
}
|
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal static void Unpack(ulong value, out uint netId, out byte componentIndex)
|
internal static void Unpack(ulong value, out uint netId, out byte componentIndex)
|
||||||
{
|
{
|
||||||
netId = (uint)(value >> 32);
|
netId = (uint)(value >> 32);
|
||||||
@ -133,6 +140,7 @@ static ulong NetworkBehaviourToULong(T value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Serialize should only write 4+1 bytes, not 8 bytes ulong
|
// Serialize should only write 4+1 bytes, not 8 bytes ulong
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public override void OnSerializeAll(NetworkWriter writer)
|
public override void OnSerializeAll(NetworkWriter writer)
|
||||||
{
|
{
|
||||||
Unpack(base.Value, out uint netId, out byte componentIndex);
|
Unpack(base.Value, out uint netId, out byte componentIndex);
|
||||||
@ -140,10 +148,12 @@ public override void OnSerializeAll(NetworkWriter writer)
|
|||||||
writer.WriteByte(componentIndex);
|
writer.WriteByte(componentIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public override void OnSerializeDelta(NetworkWriter writer) =>
|
public override void OnSerializeDelta(NetworkWriter writer) =>
|
||||||
OnSerializeAll(writer);
|
OnSerializeAll(writer);
|
||||||
|
|
||||||
// Deserialize should only write 4+1 bytes, not 8 bytes ulong
|
// Deserialize should only write 4+1 bytes, not 8 bytes ulong
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public override void OnDeserializeAll(NetworkReader reader)
|
public override void OnDeserializeAll(NetworkReader reader)
|
||||||
{
|
{
|
||||||
uint netId = reader.ReadUInt();
|
uint netId = reader.ReadUInt();
|
||||||
@ -151,6 +161,7 @@ public override void OnDeserializeAll(NetworkReader reader)
|
|||||||
base.Value = Pack(netId, componentIndex);
|
base.Value = Pack(netId, componentIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public override void OnDeserializeDelta(NetworkReader reader) =>
|
public override void OnDeserializeDelta(NetworkReader reader) =>
|
||||||
OnDeserializeAll(reader);
|
OnDeserializeAll(reader);
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,9 @@ public class SyncVarNetworkIdentity : SyncVar<uint>
|
|||||||
// .spawned lookup from netId overwrites base uint .Value
|
// .spawned lookup from netId overwrites base uint .Value
|
||||||
public new NetworkIdentity Value
|
public new NetworkIdentity Value
|
||||||
{
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get => Utils.GetSpawnedInServerOrClient(base.Value);
|
get => Utils.GetSpawnedInServerOrClient(base.Value);
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
set => base.Value = value != null ? value.netId : 0;
|
set => base.Value = value != null ? value.netId : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,6 +59,7 @@ public class SyncVarNetworkIdentity : SyncVar<uint>
|
|||||||
public new event Action<NetworkIdentity, NetworkIdentity> Callback;
|
public new event Action<NetworkIdentity, NetworkIdentity> Callback;
|
||||||
|
|
||||||
// overwrite CallCallback to use the NetworkIdentity version instead
|
// overwrite CallCallback to use the NetworkIdentity version instead
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
protected override void InvokeCallback(uint oldValue, uint newValue) =>
|
protected override void InvokeCallback(uint oldValue, uint newValue) =>
|
||||||
Callback?.Invoke(Utils.GetSpawnedInServerOrClient(oldValue), Utils.GetSpawnedInServerOrClient(newValue));
|
Callback?.Invoke(Utils.GetSpawnedInServerOrClient(oldValue), Utils.GetSpawnedInServerOrClient(newValue));
|
||||||
|
|
||||||
@ -69,10 +72,12 @@ public SyncVarNetworkIdentity(NetworkIdentity value = null)
|
|||||||
: base(value != null ? value.netId : 0) {}
|
: base(value != null ? value.netId : 0) {}
|
||||||
|
|
||||||
// implicit conversion: NetworkIdentity value = SyncFieldNetworkIdentity
|
// implicit conversion: NetworkIdentity value = SyncFieldNetworkIdentity
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static implicit operator NetworkIdentity(SyncVarNetworkIdentity field) => field.Value;
|
public static implicit operator NetworkIdentity(SyncVarNetworkIdentity field) => field.Value;
|
||||||
|
|
||||||
// implicit conversion: SyncFieldNetworkIdentity = value
|
// implicit conversion: SyncFieldNetworkIdentity = value
|
||||||
// even if SyncField is readonly, it's still useful: SyncFieldNetworkIdentity = target;
|
// even if SyncField is readonly, it's still useful: SyncFieldNetworkIdentity = target;
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static implicit operator SyncVarNetworkIdentity(NetworkIdentity value) => new SyncVarNetworkIdentity(value);
|
public static implicit operator SyncVarNetworkIdentity(NetworkIdentity value) => new SyncVarNetworkIdentity(value);
|
||||||
|
|
||||||
// NOTE: overloading all == operators blocks '== null' checks with an
|
// NOTE: overloading all == operators blocks '== null' checks with an
|
||||||
@ -104,7 +109,10 @@ public SyncVarNetworkIdentity(NetworkIdentity value = null)
|
|||||||
public static bool operator !=(NetworkIdentity a, SyncVarNetworkIdentity b) => !(a == b);
|
public static bool operator !=(NetworkIdentity a, SyncVarNetworkIdentity b) => !(a == b);
|
||||||
|
|
||||||
// if we overwrite == operators, we also need to overwrite .Equals.
|
// if we overwrite == operators, we also need to overwrite .Equals.
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public override bool Equals(object obj) => obj is SyncVarNetworkIdentity value && this == value;
|
public override bool Equals(object obj) => obj is SyncVarNetworkIdentity value && this == value;
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public override int GetHashCode() => Value.GetHashCode();
|
public override int GetHashCode() => Value.GetHashCode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user