chore: Break up the NetworkVariableSerialization file (#2950)
* reafactor: Break up the NetworkVariableSerialization file * Move related files into the new Serialization folder * Remove unrelated changes
This commit is contained in:
Родитель
d9e1a5c898
Коммит
60d321d5c0
|
@ -721,7 +721,7 @@ namespace Unity.Netcode.Editor.CodeGen
|
|||
continue;
|
||||
}
|
||||
|
||||
if (networkVariableSerializationTypesTypeDef == null && netcodeTypeDef.Name == nameof(NetworkVariableSerializationTypes))
|
||||
if (networkVariableSerializationTypesTypeDef == null && netcodeTypeDef.Name == nameof(NetworkVariableSerializationTypedInitializers))
|
||||
{
|
||||
networkVariableSerializationTypesTypeDef = netcodeTypeDef;
|
||||
continue;
|
||||
|
@ -1007,103 +1007,103 @@ namespace Unity.Netcode.Editor.CodeGen
|
|||
|
||||
switch (method.Name)
|
||||
{
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeSerializer_UnmanagedByMemcpy):
|
||||
m_NetworkVariableSerializationTypes_InitializeSerializer_UnmanagedByMemcpy_MethodRef = method;
|
||||
break;
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpyArray):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeSerializer_UnmanagedByMemcpyArray):
|
||||
m_NetworkVariableSerializationTypes_InitializeSerializer_UnmanagedByMemcpyArray_MethodRef = method;
|
||||
break;
|
||||
|
||||
#if UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpyList):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeSerializer_UnmanagedByMemcpyList):
|
||||
m_NetworkVariableSerializationTypes_InitializeSerializer_UnmanagedByMemcpyList_MethodRef = method;
|
||||
break;
|
||||
#endif
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedINetworkSerializable):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeSerializer_UnmanagedINetworkSerializable):
|
||||
m_NetworkVariableSerializationTypes_InitializeSerializer_UnmanagedINetworkSerializable_MethodRef = method;
|
||||
break;
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedINetworkSerializableArray):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeSerializer_UnmanagedINetworkSerializableArray):
|
||||
m_NetworkVariableSerializationTypes_InitializeSerializer_UnmanagedINetworkSerializableArray_MethodRef = method;
|
||||
break;
|
||||
|
||||
#if UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedINetworkSerializableList):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeSerializer_UnmanagedINetworkSerializableList):
|
||||
m_NetworkVariableSerializationTypes_InitializeSerializer_UnmanagedINetworkSerializableList_MethodRef = method;
|
||||
break;
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeSerializer_NativeHashSet):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeSerializer_NativeHashSet):
|
||||
m_NetworkVariableSerializationTypes_InitializeSerializer_NativeHashSet_MethodRef = method;
|
||||
break;
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeSerializer_NativeHashMap):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeSerializer_NativeHashMap):
|
||||
m_NetworkVariableSerializationTypes_InitializeSerializer_NativeHashMap_MethodRef = method;
|
||||
break;
|
||||
#endif
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeSerializer_List):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeSerializer_List):
|
||||
m_NetworkVariableSerializationTypes_InitializeSerializer_List_MethodRef = method;
|
||||
break;
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeSerializer_HashSet):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeSerializer_HashSet):
|
||||
m_NetworkVariableSerializationTypes_InitializeSerializer_HashSet_MethodRef = method;
|
||||
break;
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeSerializer_Dictionary):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeSerializer_Dictionary):
|
||||
m_NetworkVariableSerializationTypes_InitializeSerializer_Dictionary_MethodRef = method;
|
||||
break;
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeSerializer_ManagedINetworkSerializable):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeSerializer_ManagedINetworkSerializable):
|
||||
m_NetworkVariableSerializationTypes_InitializeSerializer_ManagedINetworkSerializable_MethodRef = method;
|
||||
break;
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeSerializer_FixedString):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeSerializer_FixedString):
|
||||
m_NetworkVariableSerializationTypes_InitializeSerializer_FixedString_MethodRef = method;
|
||||
break;
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeSerializer_FixedStringArray):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeSerializer_FixedStringArray):
|
||||
m_NetworkVariableSerializationTypes_InitializeSerializer_FixedStringArray_MethodRef = method;
|
||||
break;
|
||||
|
||||
#if UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeSerializer_FixedStringList):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeSerializer_FixedStringList):
|
||||
m_NetworkVariableSerializationTypes_InitializeSerializer_FixedStringList_MethodRef = method;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeEqualityChecker_ManagedIEquatable):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeEqualityChecker_ManagedIEquatable):
|
||||
m_NetworkVariableSerializationTypes_InitializeEqualityChecker_ManagedIEquatable_MethodRef = method;
|
||||
break;
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeEqualityChecker_UnmanagedIEquatable):
|
||||
m_NetworkVariableSerializationTypes_InitializeEqualityChecker_UnmanagedIEquatable_MethodRef = method;
|
||||
break;
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatableArray):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeEqualityChecker_UnmanagedIEquatableArray):
|
||||
m_NetworkVariableSerializationTypes_InitializeEqualityChecker_UnmanagedIEquatableArray_MethodRef = method;
|
||||
break;
|
||||
|
||||
#if UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatableList):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeEqualityChecker_UnmanagedIEquatableList):
|
||||
m_NetworkVariableSerializationTypes_InitializeEqualityChecker_UnmanagedIEquatableList_MethodRef = method;
|
||||
break;
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeEqualityChecker_NativeHashSet):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeEqualityChecker_NativeHashSet):
|
||||
m_NetworkVariableSerializationTypes_InitializeEqualityChecker_NativeHashSet_MethodRef = method;
|
||||
break;
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeEqualityChecker_NativeHashMap):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeEqualityChecker_NativeHashMap):
|
||||
m_NetworkVariableSerializationTypes_InitializeEqualityChecker_NativeHashMap_MethodRef = method;
|
||||
break;
|
||||
#endif
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeEqualityChecker_List):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeEqualityChecker_List):
|
||||
m_NetworkVariableSerializationTypes_InitializeEqualityChecker_List_MethodRef = method;
|
||||
break;
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeEqualityChecker_HashSet):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeEqualityChecker_HashSet):
|
||||
m_NetworkVariableSerializationTypes_InitializeEqualityChecker_HashSet_MethodRef = method;
|
||||
break;
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeEqualityChecker_Dictionary):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeEqualityChecker_Dictionary):
|
||||
m_NetworkVariableSerializationTypes_InitializeEqualityChecker_Dictionary_MethodRef = method;
|
||||
break;
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedValueEquals):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeEqualityChecker_UnmanagedValueEquals):
|
||||
m_NetworkVariableSerializationTypes_InitializeEqualityChecker_UnmanagedValueEquals_MethodRef = method;
|
||||
break;
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedValueEqualsArray):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeEqualityChecker_UnmanagedValueEqualsArray):
|
||||
m_NetworkVariableSerializationTypes_InitializeEqualityChecker_UnmanagedValueEqualsArray_MethodRef = method;
|
||||
break;
|
||||
#if UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedValueEqualsList):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeEqualityChecker_UnmanagedValueEqualsList):
|
||||
m_NetworkVariableSerializationTypes_InitializeEqualityChecker_UnmanagedValueEqualsList_MethodRef = method;
|
||||
break;
|
||||
#endif
|
||||
case nameof(NetworkVariableSerializationTypes.InitializeEqualityChecker_ManagedClassEquals):
|
||||
case nameof(NetworkVariableSerializationTypedInitializers.InitializeEqualityChecker_ManagedClassEquals):
|
||||
m_NetworkVariableSerializationTypes_InitializeEqualityChecker_ManagedClassEquals_MethodRef = method;
|
||||
break;
|
||||
}
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,3 +0,0 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2c6ef5fdf2e94ec3b4ce8086d52700b3
|
||||
timeCreated: 1650985453
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d960ae6c5b8241aa9e2906b709095ea1
|
||||
timeCreated: 1718215841
|
|
@ -0,0 +1,99 @@
|
|||
using System;
|
||||
using Unity.Collections;
|
||||
|
||||
namespace Unity.Netcode
|
||||
{
|
||||
/// <summary>
|
||||
/// This class is instantiated for types that we can't determine ahead of time are serializable - types
|
||||
/// that don't meet any of the constraints for methods that are available on FastBufferReader and
|
||||
/// FastBufferWriter. These types may or may not be serializable through extension methods. To ensure
|
||||
/// the user has time to pass in the delegates to UserNetworkVariableSerialization, the existence
|
||||
/// of user serialization isn't checked until it's used, so if no serialization is provided, this
|
||||
/// will throw an exception when an object containing the relevant NetworkVariable is spawned.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
internal class FallbackSerializer<T> : INetworkVariableSerializer<T>
|
||||
{
|
||||
private void ThrowArgumentError()
|
||||
{
|
||||
throw new ArgumentException($"Serialization has not been generated for type {typeof(T).FullName}. This can be addressed by adding a [{nameof(GenerateSerializationForGenericParameterAttribute)}] to your generic class that serializes this value (if you are using one), adding [{nameof(GenerateSerializationForTypeAttribute)}(typeof({typeof(T).FullName})] to the class or method that is attempting to serialize it, or creating a field on a {nameof(NetworkBehaviour)} of type {nameof(NetworkVariable<T>)}. If this error continues to appear after doing one of those things and this is a type you can change, then either implement {nameof(INetworkSerializable)} or mark it as serializable by memcpy by adding {nameof(INetworkSerializeByMemcpy)} to its interface list to enable automatic serialization generation. If not, assign serialization code to {nameof(UserNetworkVariableSerialization<T>)}.{nameof(UserNetworkVariableSerialization<T>.WriteValue)}, {nameof(UserNetworkVariableSerialization<T>)}.{nameof(UserNetworkVariableSerialization<T>.ReadValue)}, and {nameof(UserNetworkVariableSerialization<T>)}.{nameof(UserNetworkVariableSerialization<T>.DuplicateValue)}, or if it's serializable by memcpy (contains no pointers), wrap it in {typeof(ForceNetworkSerializeByMemcpy<>).Name}.");
|
||||
}
|
||||
|
||||
public void Write(FastBufferWriter writer, ref T value)
|
||||
{
|
||||
if (UserNetworkVariableSerialization<T>.ReadValue == null || UserNetworkVariableSerialization<T>.WriteValue == null || UserNetworkVariableSerialization<T>.DuplicateValue == null)
|
||||
{
|
||||
ThrowArgumentError();
|
||||
}
|
||||
UserNetworkVariableSerialization<T>.WriteValue(writer, value);
|
||||
}
|
||||
public void Read(FastBufferReader reader, ref T value)
|
||||
{
|
||||
if (UserNetworkVariableSerialization<T>.ReadValue == null || UserNetworkVariableSerialization<T>.WriteValue == null || UserNetworkVariableSerialization<T>.DuplicateValue == null)
|
||||
{
|
||||
ThrowArgumentError();
|
||||
}
|
||||
UserNetworkVariableSerialization<T>.ReadValue(reader, out value);
|
||||
}
|
||||
|
||||
public void WriteDelta(FastBufferWriter writer, ref T value, ref T previousValue)
|
||||
{
|
||||
if (UserNetworkVariableSerialization<T>.ReadValue == null || UserNetworkVariableSerialization<T>.WriteValue == null || UserNetworkVariableSerialization<T>.DuplicateValue == null)
|
||||
{
|
||||
ThrowArgumentError();
|
||||
}
|
||||
|
||||
if (UserNetworkVariableSerialization<T>.WriteDelta == null || UserNetworkVariableSerialization<T>.ReadDelta == null)
|
||||
{
|
||||
UserNetworkVariableSerialization<T>.WriteValue(writer, value);
|
||||
return;
|
||||
}
|
||||
UserNetworkVariableSerialization<T>.WriteDelta(writer, value, previousValue);
|
||||
}
|
||||
|
||||
public void ReadDelta(FastBufferReader reader, ref T value)
|
||||
{
|
||||
if (UserNetworkVariableSerialization<T>.ReadValue == null || UserNetworkVariableSerialization<T>.WriteValue == null || UserNetworkVariableSerialization<T>.DuplicateValue == null)
|
||||
{
|
||||
ThrowArgumentError();
|
||||
}
|
||||
|
||||
if (UserNetworkVariableSerialization<T>.WriteDelta == null || UserNetworkVariableSerialization<T>.ReadDelta == null)
|
||||
{
|
||||
UserNetworkVariableSerialization<T>.ReadValue(reader, out value);
|
||||
return;
|
||||
}
|
||||
UserNetworkVariableSerialization<T>.ReadDelta(reader, ref value);
|
||||
}
|
||||
|
||||
void INetworkVariableSerializer<T>.ReadWithAllocator(FastBufferReader reader, out T value, Allocator allocator)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Duplicate(in T value, ref T duplicatedValue)
|
||||
{
|
||||
if (UserNetworkVariableSerialization<T>.ReadValue == null || UserNetworkVariableSerialization<T>.WriteValue == null || UserNetworkVariableSerialization<T>.DuplicateValue == null)
|
||||
{
|
||||
ThrowArgumentError();
|
||||
}
|
||||
UserNetworkVariableSerialization<T>.DuplicateValue(value, ref duplicatedValue);
|
||||
}
|
||||
}
|
||||
|
||||
// RuntimeAccessModifiersILPP will make this `public`
|
||||
// This is just pass-through to NetworkVariableSerialization<T> but is here because I could not get ILPP
|
||||
// to generate code that would successfully call Type<T>.Method(T), but it has no problem calling Type.Method<T>(T)
|
||||
internal class RpcFallbackSerialization
|
||||
{
|
||||
public static void Write<T>(FastBufferWriter writer, ref T value)
|
||||
{
|
||||
NetworkVariableSerialization<T>.Write(writer, ref value);
|
||||
}
|
||||
|
||||
public static void Read<T>(FastBufferReader reader, ref T value)
|
||||
{
|
||||
NetworkVariableSerialization<T>.Read(reader, ref value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 288dbe7d1ff74860ae3552c034485538
|
||||
timeCreated: 1718219109
|
|
@ -0,0 +1,26 @@
|
|||
using Unity.Collections;
|
||||
|
||||
namespace Unity.Netcode
|
||||
{
|
||||
/// <summary>
|
||||
/// Interface used by NetworkVariables to serialize them
|
||||
/// </summary>
|
||||
///
|
||||
/// <typeparam name="T"></typeparam>
|
||||
internal interface INetworkVariableSerializer<T>
|
||||
{
|
||||
// Write has to be taken by ref here because of INetworkSerializable
|
||||
// Open Instance Delegates (pointers to methods without an instance attached to them)
|
||||
// require the first parameter passed to them (the instance) to be passed by ref.
|
||||
// So foo.Bar() becomes BarDelegate(ref foo);
|
||||
// Taking T as an in parameter like we do in other places would require making a copy
|
||||
// of it to pass it as a ref parameter.,
|
||||
|
||||
public void Write(FastBufferWriter writer, ref T value);
|
||||
public void Read(FastBufferReader reader, ref T value);
|
||||
public void WriteDelta(FastBufferWriter writer, ref T value, ref T previousValue);
|
||||
public void ReadDelta(FastBufferReader reader, ref T value);
|
||||
internal void ReadWithAllocator(FastBufferReader reader, out T value, Allocator allocator);
|
||||
public void Duplicate(in T value, ref T duplicatedValue);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f78e258ef55f4ee89bc3f24d67b8d242
|
||||
timeCreated: 1718218205
|
|
@ -0,0 +1,357 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Collections;
|
||||
using Unity.Collections.LowLevel.Unsafe;
|
||||
using Unity.Netcode;
|
||||
|
||||
namespace Unity.Netcode
|
||||
{
|
||||
internal static class NetworkVariableEquality<T>
|
||||
{
|
||||
// Compares two values of the same unmanaged type by underlying memory
|
||||
// Ignoring any overridden value checks
|
||||
// Size is fixed
|
||||
internal static unsafe bool ValueEquals<TValueType>(ref TValueType a, ref TValueType b) where TValueType : unmanaged
|
||||
{
|
||||
// get unmanaged pointers
|
||||
var aptr = UnsafeUtility.AddressOf(ref a);
|
||||
var bptr = UnsafeUtility.AddressOf(ref b);
|
||||
|
||||
// compare addresses
|
||||
return UnsafeUtility.MemCmp(aptr, bptr, sizeof(TValueType)) == 0;
|
||||
}
|
||||
|
||||
#if UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
|
||||
// Compares two values of the same unmanaged type by underlying memory
|
||||
// Ignoring any overridden value checks
|
||||
// Size is fixed
|
||||
internal static unsafe bool ValueEqualsList<TValueType>(ref NativeList<TValueType> a, ref NativeList<TValueType> b) where TValueType : unmanaged
|
||||
{
|
||||
if (a.IsCreated != b.IsCreated)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!a.IsCreated)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a.Length != b.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#if UTP_TRANSPORT_2_0_ABOVE
|
||||
var aptr = a.GetUnsafePtr();
|
||||
var bptr = b.GetUnsafePtr();
|
||||
#else
|
||||
var aptr = (TValueType*)a.GetUnsafePtr();
|
||||
var bptr = (TValueType*)b.GetUnsafePtr();
|
||||
#endif
|
||||
|
||||
return UnsafeUtility.MemCmp(aptr, bptr, sizeof(TValueType) * a.Length) == 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Compares two values of the same unmanaged type by underlying memory
|
||||
// Ignoring any overridden value checks
|
||||
// Size is fixed
|
||||
internal static unsafe bool ValueEqualsArray<TValueType>(ref NativeArray<TValueType> a, ref NativeArray<TValueType> b) where TValueType : unmanaged
|
||||
{
|
||||
if (a.IsCreated != b.IsCreated)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!a.IsCreated)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a.Length != b.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var aptr = (TValueType*)a.GetUnsafePtr();
|
||||
var bptr = (TValueType*)b.GetUnsafePtr();
|
||||
return UnsafeUtility.MemCmp(aptr, bptr, sizeof(TValueType) * a.Length) == 0;
|
||||
}
|
||||
|
||||
internal static bool EqualityEqualsObject<TValueType>(ref TValueType a, ref TValueType b) where TValueType : class, IEquatable<TValueType>
|
||||
{
|
||||
if (a == null)
|
||||
{
|
||||
return b == null;
|
||||
}
|
||||
|
||||
if (b == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return a.Equals(b);
|
||||
}
|
||||
|
||||
internal static bool EqualityEquals<TValueType>(ref TValueType a, ref TValueType b) where TValueType : unmanaged, IEquatable<TValueType>
|
||||
{
|
||||
return a.Equals(b);
|
||||
}
|
||||
|
||||
internal static bool EqualityEqualsList<TValueType>(ref List<TValueType> a, ref List<TValueType> b)
|
||||
{
|
||||
if (a == null != (b == null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a.Count != b.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; i < a.Count; ++i)
|
||||
{
|
||||
var aItem = a[i];
|
||||
var bItem = b[i];
|
||||
if (!NetworkVariableSerialization<TValueType>.AreEqual(ref aItem, ref bItem))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static bool EqualityEqualsHashSet<TValueType>(ref HashSet<TValueType> a, ref HashSet<TValueType> b) where TValueType : IEquatable<TValueType>
|
||||
{
|
||||
if (a == null != (b == null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a.Count != b.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var item in a)
|
||||
{
|
||||
if (!b.Contains(item))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Compares two values of the same unmanaged type by underlying memory
|
||||
// Ignoring any overridden value checks
|
||||
// Size is fixed
|
||||
internal static unsafe bool EqualityEqualsArray<TValueType>(ref NativeArray<TValueType> a, ref NativeArray<TValueType> b) where TValueType : unmanaged, IEquatable<TValueType>
|
||||
{
|
||||
if (a.IsCreated != b.IsCreated)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!a.IsCreated)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a.Length != b.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var aptr = (TValueType*)a.GetUnsafePtr();
|
||||
var bptr = (TValueType*)b.GetUnsafePtr();
|
||||
for (var i = 0; i < a.Length; ++i)
|
||||
{
|
||||
if (!EqualityEquals(ref aptr[i], ref bptr[i]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static bool ClassEquals<TValueType>(ref TValueType a, ref TValueType b) where TValueType : class
|
||||
{
|
||||
return a == b;
|
||||
}
|
||||
|
||||
#if UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
|
||||
// Compares two values of the same unmanaged type by underlying memory
|
||||
// Ignoring any overridden value checks
|
||||
// Size is fixed
|
||||
internal static unsafe bool EqualityEqualsNativeList<TValueType>(ref NativeList<TValueType> a, ref NativeList<TValueType> b) where TValueType : unmanaged, IEquatable<TValueType>
|
||||
{
|
||||
if (a.IsCreated != b.IsCreated)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!a.IsCreated)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a.Length != b.Length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#if UTP_TRANSPORT_2_0_ABOVE
|
||||
var aptr = a.GetUnsafePtr();
|
||||
var bptr = b.GetUnsafePtr();
|
||||
#else
|
||||
var aptr = (TValueType*)a.GetUnsafePtr();
|
||||
var bptr = (TValueType*)b.GetUnsafePtr();
|
||||
#endif
|
||||
for (var i = 0; i < a.Length; ++i)
|
||||
{
|
||||
if (!EqualityEquals(ref aptr[i], ref bptr[i]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
internal static bool EqualityEqualsNativeHashSet<TValueType>(ref NativeHashSet<TValueType> a, ref NativeHashSet<TValueType> b) where TValueType : unmanaged, IEquatable<TValueType>
|
||||
{
|
||||
if (a.IsCreated != b.IsCreated)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!a.IsCreated)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#if UTP_TRANSPORT_2_0_ABOVE
|
||||
if (a.Count != b.Count)
|
||||
#else
|
||||
if (a.Count() != b.Count())
|
||||
#endif
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var item in a)
|
||||
{
|
||||
if (!b.Contains(item))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Support methods for equality of NetworkVariable collection types.
|
||||
/// Because there are multiple overloads of WriteValue/ReadValue based on different generic constraints,
|
||||
/// but there's no way to achieve the same thing with a class, this sets up various read/write schemes
|
||||
/// based on which constraints are met by `T` using reflection, which is done at module load time.
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey">The type the associated NetworkVariable dictionary collection key templated on</typeparam>
|
||||
/// <typeparam name="TVal">The type the associated NetworkVariable dictionary collection value templated on</typeparam>
|
||||
internal class NetworkVariableDictionarySerialization<TKey, TVal>
|
||||
where TKey : IEquatable<TKey>
|
||||
{
|
||||
internal static bool GenericEqualsDictionary(ref Dictionary<TKey, TVal> a, ref Dictionary<TKey, TVal> b)
|
||||
{
|
||||
if (a == null != (b == null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (a.Count != b.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var item in a)
|
||||
{
|
||||
var hasKey = b.TryGetValue(item.Key, out var val);
|
||||
if (!hasKey)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var bVal = item.Value;
|
||||
if (!NetworkVariableSerialization<TVal>.AreEqual(ref bVal, ref val))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#if UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
|
||||
internal class NetworkVariableMapSerialization<TKey, TVal>
|
||||
where TKey : unmanaged, IEquatable<TKey>
|
||||
where TVal : unmanaged
|
||||
{
|
||||
internal static bool GenericEqualsNativeHashMap(ref NativeHashMap<TKey, TVal> a, ref NativeHashMap<TKey, TVal> b)
|
||||
{
|
||||
if (a.IsCreated != b.IsCreated)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!a.IsCreated)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
#if UTP_TRANSPORT_2_0_ABOVE
|
||||
if (a.Count != b.Count)
|
||||
#else
|
||||
if (a.Count() != b.Count())
|
||||
#endif
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var item in a)
|
||||
{
|
||||
var hasKey = b.TryGetValue(item.Key, out var val);
|
||||
if (!hasKey || !NetworkVariableSerialization<TVal>.AreEqual(ref item.Value, ref val))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 24b8352a975044509931bf684ccfdb82
|
||||
timeCreated: 1718219366
|
|
@ -0,0 +1,159 @@
|
|||
using System;
|
||||
|
||||
namespace Unity.Netcode
|
||||
{
|
||||
/// <summary>
|
||||
/// Support methods for reading/writing NetworkVariables
|
||||
/// Because there are multiple overloads of WriteValue/ReadValue based on different generic constraints,
|
||||
/// but there's no way to achieve the same thing with a class, this sets up various read/write schemes
|
||||
/// based on which constraints are met by `T` using reflection, which is done at module load time.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type the associated NetworkVariable is templated on</typeparam>
|
||||
[Serializable]
|
||||
public static class NetworkVariableSerialization<T>
|
||||
{
|
||||
internal static INetworkVariableSerializer<T> Serializer = new FallbackSerializer<T>();
|
||||
|
||||
/// <summary>
|
||||
/// The collection item type tells the CMB server how to read the bytes of each item in the collection
|
||||
/// </summary>
|
||||
/// DANGO-EXP TODO: Determine if this is distributed authority only and impacts of this in client-server
|
||||
internal static CollectionItemType Type = CollectionItemType.Unknown;
|
||||
|
||||
/// <summary>
|
||||
/// A callback to check if two values are equal.
|
||||
/// </summary>
|
||||
public delegate bool EqualsDelegate(ref T a, ref T b);
|
||||
|
||||
/// <summary>
|
||||
/// Uses the most efficient mechanism for a given type to determine if two values are equal.
|
||||
/// For types that implement <see cref="IEquatable{T}"/>, it will call the Equals() method.
|
||||
/// For unmanaged types, it will do a bytewise memory comparison.
|
||||
/// For other types, it will call the == operator.
|
||||
/// <br/>
|
||||
/// <br/>
|
||||
/// Note: If you are using this in a custom generic class, please make sure your class is
|
||||
/// decorated with <see cref="GenerateSerializationForGenericParameterAttribute"/> so that codegen can
|
||||
/// initialize the serialization mechanisms correctly. If your class is NOT
|
||||
/// generic, it is better to check their equality yourself.
|
||||
/// </summary>
|
||||
public static EqualsDelegate AreEqual { get; internal set; }
|
||||
/// <summary>
|
||||
/// Serialize a value using the best-known serialization method for a generic value.
|
||||
/// Will reliably serialize any value that is passed to it correctly with no boxing.
|
||||
/// <br />
|
||||
/// <br />
|
||||
/// Note: If you are using this in a custom generic class, please make sure your class is
|
||||
/// decorated with <see cref="GenerateSerializationForGenericParameterAttribute" /> so that codegen can
|
||||
/// initialize the serialization mechanisms correctly. If your class is NOT
|
||||
/// generic, it is better to use FastBufferWriter directly.
|
||||
/// <br />
|
||||
/// <br />
|
||||
/// If the codegen is unable to determine a serializer for a type,
|
||||
/// <see cref="UserNetworkVariableSerialization{T}" />.<see cref="UserNetworkVariableSerialization{T}.WriteValue" /> is called, which, by default,
|
||||
/// will throw an exception, unless you have assigned a user serialization callback to it at runtime.
|
||||
/// </summary>
|
||||
/// <param name="writer"></param>
|
||||
/// <param name="value"></param>
|
||||
public static void Write(FastBufferWriter writer, ref T value)
|
||||
{
|
||||
Serializer.Write(writer, ref value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserialize a value using the best-known serialization method for a generic value.
|
||||
/// Will reliably deserialize any value that is passed to it correctly with no boxing.
|
||||
/// For types whose deserialization can be determined by codegen (which is most types),
|
||||
/// GC will only be incurred if the type is a managed type and the ref value passed in is `null`,
|
||||
/// in which case a new value is created; otherwise, it will be deserialized in-place.
|
||||
/// <br />
|
||||
/// <br />
|
||||
/// Note: If you are using this in a custom generic class, please make sure your class is
|
||||
/// decorated with <see cref="GenerateSerializationForGenericParameterAttribute" /> so that codegen can
|
||||
/// initialize the serialization mechanisms correctly. If your class is NOT
|
||||
/// generic, it is better to use FastBufferReader directly.
|
||||
/// <br />
|
||||
/// <br />
|
||||
/// If the codegen is unable to determine a serializer for a type,
|
||||
/// <see cref="UserNetworkVariableSerialization{T}" />.<see cref="UserNetworkVariableSerialization{T}.ReadValue" /> is called, which, by default,
|
||||
/// will throw an exception, unless you have assigned a user deserialization callback to it at runtime.
|
||||
/// </summary>
|
||||
/// <param name="reader"></param>
|
||||
/// <param name="value"></param>
|
||||
public static void Read(FastBufferReader reader, ref T value)
|
||||
{
|
||||
Serializer.Read(reader, ref value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serialize a value using the best-known serialization method for a generic value.
|
||||
/// Will reliably serialize any value that is passed to it correctly with no boxing.
|
||||
/// <br />
|
||||
/// <br />
|
||||
/// Note: If you are using this in a custom generic class, please make sure your class is
|
||||
/// decorated with <see cref="GenerateSerializationForGenericParameterAttribute" /> so that codegen can
|
||||
/// initialize the serialization mechanisms correctly. If your class is NOT
|
||||
/// generic, it is better to use FastBufferWriter directly.
|
||||
/// <br />
|
||||
/// <br />
|
||||
/// If the codegen is unable to determine a serializer for a type,
|
||||
/// <see cref="UserNetworkVariableSerialization{T}" />.<see cref="UserNetworkVariableSerialization{T}.WriteValue" /> is called, which, by default,
|
||||
/// will throw an exception, unless you have assigned a user serialization callback to it at runtime.
|
||||
/// </summary>
|
||||
/// <param name="writer"></param>
|
||||
/// <param name="value"></param>
|
||||
public static void WriteDelta(FastBufferWriter writer, ref T value, ref T previousValue)
|
||||
{
|
||||
Serializer.WriteDelta(writer, ref value, ref previousValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserialize a value using the best-known serialization method for a generic value.
|
||||
/// Will reliably deserialize any value that is passed to it correctly with no boxing.
|
||||
/// For types whose deserialization can be determined by codegen (which is most types),
|
||||
/// GC will only be incurred if the type is a managed type and the ref value passed in is `null`,
|
||||
/// in which case a new value is created; otherwise, it will be deserialized in-place.
|
||||
/// <br />
|
||||
/// <br />
|
||||
/// Note: If you are using this in a custom generic class, please make sure your class is
|
||||
/// decorated with <see cref="GenerateSerializationForGenericParameterAttribute" /> so that codegen can
|
||||
/// initialize the serialization mechanisms correctly. If your class is NOT
|
||||
/// generic, it is better to use FastBufferReader directly.
|
||||
/// <br />
|
||||
/// <br />
|
||||
/// If the codegen is unable to determine a serializer for a type,
|
||||
/// <see cref="UserNetworkVariableSerialization{T}" />.<see cref="UserNetworkVariableSerialization{T}.ReadValue" /> is called, which, by default,
|
||||
/// will throw an exception, unless you have assigned a user deserialization callback to it at runtime.
|
||||
/// </summary>
|
||||
/// <param name="reader"></param>
|
||||
/// <param name="value"></param>
|
||||
public static void ReadDelta(FastBufferReader reader, ref T value)
|
||||
{
|
||||
Serializer.ReadDelta(reader, ref value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Duplicates a value using the most efficient means of creating a complete copy.
|
||||
/// For most types this is a simple assignment or memcpy.
|
||||
/// For managed types, this is will serialize and then deserialize the value to ensure
|
||||
/// a correct copy.
|
||||
/// <br />
|
||||
/// <br />
|
||||
/// Note: If you are using this in a custom generic class, please make sure your class is
|
||||
/// decorated with <see cref="GenerateSerializationForGenericParameterAttribute" /> so that codegen can
|
||||
/// initialize the serialization mechanisms correctly. If your class is NOT
|
||||
/// generic, it is better to duplicate it directly.
|
||||
/// <br />
|
||||
/// <br />
|
||||
/// If the codegen is unable to determine a serializer for a type,
|
||||
/// <see cref="UserNetworkVariableSerialization{T}" />.<see cref="UserNetworkVariableSerialization{T}.DuplicateValue" /> is called, which, by default,
|
||||
/// will throw an exception, unless you have assigned a user duplication callback to it at runtime.
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="duplicatedValue"></param>
|
||||
public static void Duplicate(in T value, ref T duplicatedValue)
|
||||
{
|
||||
Serializer.Duplicate(value, ref duplicatedValue);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7a943170e35746e8913dd494d79bb63d
|
||||
timeCreated: 1718215899
|
|
@ -0,0 +1,325 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Collections;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Unity.Netcode
|
||||
{
|
||||
/// <summary>
|
||||
/// This class contains initialization functions for various different types used in NetworkVariables.
|
||||
/// Generally speaking, these methods are called by a module initializer created by codegen (NetworkBehaviourILPP)
|
||||
/// and do not need to be called manually.
|
||||
///
|
||||
/// There are two types of initializers: Serializers and EqualityCheckers. Every type must have an EqualityChecker
|
||||
/// registered to it in order to be used in NetworkVariable; however, not all types need a Serializer. Types without
|
||||
/// a serializer registered will fall back to using the delegates in <see cref="UserNetworkVariableSerialization{T}"/>.
|
||||
/// If no such delegate has been registered, a type without a serializer will throw an exception on the first attempt
|
||||
/// to serialize or deserialize it. (Again, however, codegen handles this automatically and this registration doesn't
|
||||
/// typically need to be performed manually.)
|
||||
/// </summary>
|
||||
public static class NetworkVariableSerializationTypedInitializers
|
||||
{
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterAssembliesLoaded)]
|
||||
#if UNITY_EDITOR
|
||||
[InitializeOnLoadMethod]
|
||||
#endif
|
||||
internal static void InitializeIntegerSerialization()
|
||||
{
|
||||
NetworkVariableSerialization<short>.Serializer = new ShortSerializer();
|
||||
NetworkVariableSerialization<short>.AreEqual = NetworkVariableEquality<short>.ValueEquals;
|
||||
NetworkVariableSerialization<ushort>.Serializer = new UshortSerializer();
|
||||
NetworkVariableSerialization<ushort>.AreEqual = NetworkVariableEquality<ushort>.ValueEquals;
|
||||
NetworkVariableSerialization<int>.Serializer = new IntSerializer();
|
||||
NetworkVariableSerialization<int>.AreEqual = NetworkVariableEquality<int>.ValueEquals;
|
||||
NetworkVariableSerialization<uint>.Serializer = new UintSerializer();
|
||||
NetworkVariableSerialization<uint>.AreEqual = NetworkVariableEquality<uint>.ValueEquals;
|
||||
NetworkVariableSerialization<long>.Serializer = new LongSerializer();
|
||||
NetworkVariableSerialization<long>.AreEqual = NetworkVariableEquality<long>.ValueEquals;
|
||||
NetworkVariableSerialization<ulong>.Serializer = new UlongSerializer();
|
||||
NetworkVariableSerialization<ulong>.AreEqual = NetworkVariableEquality<ulong>.ValueEquals;
|
||||
|
||||
// DANGO-EXP TODO: Determine if this is distributed authority only and impacts of this in client-server
|
||||
NetworkVariableSerialization<short>.Type = CollectionItemType.Short;
|
||||
NetworkVariableSerialization<ushort>.Type = CollectionItemType.UShort;
|
||||
NetworkVariableSerialization<int>.Type = CollectionItemType.Int;
|
||||
NetworkVariableSerialization<uint>.Type = CollectionItemType.UInt;
|
||||
NetworkVariableSerialization<long>.Type = CollectionItemType.Long;
|
||||
NetworkVariableSerialization<ulong>.Type = CollectionItemType.ULong;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registeres an unmanaged type that will be serialized by a direct memcpy into a buffer
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeSerializer_UnmanagedByMemcpy<T>() where T : unmanaged
|
||||
{
|
||||
NetworkVariableSerialization<T>.Serializer = new UnmanagedTypeSerializer<T>();
|
||||
// DANGO-EXP TODO: Determine if this is distributed authority only and impacts of this in client-server
|
||||
NetworkVariableSerialization<T>.Type = CollectionItemType.Unmanaged;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registeres an unmanaged type that will be serialized by a direct memcpy into a buffer
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeSerializer_UnmanagedByMemcpyArray<T>() where T : unmanaged
|
||||
{
|
||||
NetworkVariableSerialization<NativeArray<T>>.Serializer = new UnmanagedArraySerializer<T>();
|
||||
}
|
||||
|
||||
#if UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
|
||||
/// <summary>
|
||||
/// Registeres an unmanaged type that will be serialized by a direct memcpy into a buffer
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeSerializer_UnmanagedByMemcpyList<T>() where T : unmanaged
|
||||
{
|
||||
NetworkVariableSerialization<NativeList<T>>.Serializer = new UnmanagedListSerializer<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registeres a native hash set (this generic implementation works with all types)
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeSerializer_NativeHashSet<T>() where T : unmanaged, IEquatable<T>
|
||||
{
|
||||
NetworkVariableSerialization<NativeHashSet<T>>.Serializer = new NativeHashSetSerializer<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registeres a native hash set (this generic implementation works with all types)
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeSerializer_NativeHashMap<TKey, TVal>()
|
||||
where TKey : unmanaged, IEquatable<TKey>
|
||||
where TVal : unmanaged
|
||||
{
|
||||
NetworkVariableSerialization<NativeHashMap<TKey, TVal>>.Serializer = new NativeHashMapSerializer<TKey, TVal>();
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Registeres a native hash set (this generic implementation works with all types)
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeSerializer_List<T>()
|
||||
{
|
||||
NetworkVariableSerialization<List<T>>.Serializer = new ListSerializer<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registeres a native hash set (this generic implementation works with all types)
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeSerializer_HashSet<T>() where T : IEquatable<T>
|
||||
{
|
||||
NetworkVariableSerialization<HashSet<T>>.Serializer = new HashSetSerializer<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registeres a native hash set (this generic implementation works with all types)
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeSerializer_Dictionary<TKey, TVal>() where TKey : IEquatable<TKey>
|
||||
{
|
||||
NetworkVariableSerialization<Dictionary<TKey, TVal>>.Serializer = new DictionarySerializer<TKey, TVal>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers an unmanaged type that implements INetworkSerializable and will be serialized through a call to
|
||||
/// NetworkSerialize
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeSerializer_UnmanagedINetworkSerializable<T>() where T : unmanaged, INetworkSerializable
|
||||
{
|
||||
NetworkVariableSerialization<T>.Serializer = new UnmanagedNetworkSerializableSerializer<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers an unmanaged type that implements INetworkSerializable and will be serialized through a call to
|
||||
/// NetworkSerialize
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeSerializer_UnmanagedINetworkSerializableArray<T>() where T : unmanaged, INetworkSerializable
|
||||
{
|
||||
NetworkVariableSerialization<NativeArray<T>>.Serializer = new UnmanagedNetworkSerializableArraySerializer<T>();
|
||||
}
|
||||
|
||||
#if UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
|
||||
/// <summary>
|
||||
/// Registers an unmanaged type that implements INetworkSerializable and will be serialized through a call to
|
||||
/// NetworkSerialize
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeSerializer_UnmanagedINetworkSerializableList<T>() where T : unmanaged, INetworkSerializable
|
||||
{
|
||||
NetworkVariableSerialization<NativeList<T>>.Serializer = new UnmanagedNetworkSerializableListSerializer<T>();
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Registers a managed type that implements INetworkSerializable and will be serialized through a call to
|
||||
/// NetworkSerialize
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeSerializer_ManagedINetworkSerializable<T>() where T : class, INetworkSerializable, new()
|
||||
{
|
||||
NetworkVariableSerialization<T>.Serializer = new ManagedNetworkSerializableSerializer<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a FixedString type that will be serialized through FastBufferReader/FastBufferWriter's FixedString
|
||||
/// serializers
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeSerializer_FixedString<T>() where T : unmanaged, INativeList<byte>, IUTF8Bytes
|
||||
{
|
||||
NetworkVariableSerialization<T>.Serializer = new FixedStringSerializer<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a FixedString type that will be serialized through FastBufferReader/FastBufferWriter's FixedString
|
||||
/// serializers
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeSerializer_FixedStringArray<T>() where T : unmanaged, INativeList<byte>, IUTF8Bytes
|
||||
{
|
||||
NetworkVariableSerialization<NativeArray<T>>.Serializer = new FixedStringArraySerializer<T>();
|
||||
}
|
||||
|
||||
#if UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
|
||||
/// <summary>
|
||||
/// Registers a FixedString type that will be serialized through FastBufferReader/FastBufferWriter's FixedString
|
||||
/// serializers
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeSerializer_FixedStringList<T>() where T : unmanaged, INativeList<byte>, IUTF8Bytes
|
||||
{
|
||||
NetworkVariableSerialization<NativeList<T>>.Serializer = new FixedStringListSerializer<T>();
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Registers a managed type that will be checked for equality using T.Equals()
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeEqualityChecker_ManagedIEquatable<T>() where T : class, IEquatable<T>
|
||||
{
|
||||
NetworkVariableSerialization<T>.AreEqual = NetworkVariableEquality<T>.EqualityEqualsObject;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers an unmanaged type that will be checked for equality using T.Equals()
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeEqualityChecker_UnmanagedIEquatable<T>() where T : unmanaged, IEquatable<T>
|
||||
{
|
||||
NetworkVariableSerialization<T>.AreEqual = NetworkVariableEquality<T>.EqualityEquals;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers an unmanaged type that will be checked for equality using T.Equals()
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeEqualityChecker_UnmanagedIEquatableArray<T>() where T : unmanaged, IEquatable<T>
|
||||
{
|
||||
NetworkVariableSerialization<NativeArray<T>>.AreEqual = NetworkVariableEquality<T>.EqualityEqualsArray;
|
||||
}
|
||||
/// <summary>
|
||||
/// Registers an unmanaged type that will be checked for equality using T.Equals()
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeEqualityChecker_List<T>()
|
||||
{
|
||||
NetworkVariableSerialization<List<T>>.AreEqual = NetworkVariableEquality<T>.EqualityEqualsList;
|
||||
}
|
||||
/// <summary>
|
||||
/// Registers an unmanaged type that will be checked for equality using T.Equals()
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeEqualityChecker_HashSet<T>() where T : IEquatable<T>
|
||||
{
|
||||
NetworkVariableSerialization<HashSet<T>>.AreEqual = NetworkVariableEquality<T>.EqualityEqualsHashSet;
|
||||
}
|
||||
/// <summary>
|
||||
/// Registers an unmanaged type that will be checked for equality using T.Equals()
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeEqualityChecker_Dictionary<TKey, TVal>()
|
||||
where TKey : IEquatable<TKey>
|
||||
{
|
||||
NetworkVariableSerialization<Dictionary<TKey, TVal>>.AreEqual = NetworkVariableDictionarySerialization<TKey, TVal>.GenericEqualsDictionary;
|
||||
}
|
||||
|
||||
#if UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
|
||||
/// <summary>
|
||||
/// Registers an unmanaged type that will be checked for equality using T.Equals()
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeEqualityChecker_UnmanagedIEquatableList<T>() where T : unmanaged, IEquatable<T>
|
||||
{
|
||||
NetworkVariableSerialization<NativeList<T>>.AreEqual = NetworkVariableEquality<T>.EqualityEqualsNativeList;
|
||||
}
|
||||
/// <summary>
|
||||
/// Registers an unmanaged type that will be checked for equality using T.Equals()
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeEqualityChecker_NativeHashSet<T>() where T : unmanaged, IEquatable<T>
|
||||
{
|
||||
NetworkVariableSerialization<NativeHashSet<T>>.AreEqual = NetworkVariableEquality<T>.EqualityEqualsNativeHashSet;
|
||||
}
|
||||
/// <summary>
|
||||
/// Registers an unmanaged type that will be checked for equality using T.Equals()
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeEqualityChecker_NativeHashMap<TKey, TVal>()
|
||||
where TKey : unmanaged, IEquatable<TKey>
|
||||
where TVal : unmanaged
|
||||
{
|
||||
NetworkVariableSerialization<NativeHashMap<TKey, TVal>>.AreEqual = NetworkVariableMapSerialization<TKey, TVal>.GenericEqualsNativeHashMap;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Registers an unmanaged type that will be checked for equality using memcmp and only considered
|
||||
/// equal if they are bitwise equivalent in memory
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeEqualityChecker_UnmanagedValueEquals<T>() where T : unmanaged
|
||||
{
|
||||
NetworkVariableSerialization<T>.AreEqual = NetworkVariableEquality<T>.ValueEquals;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers an unmanaged type that will be checked for equality using memcmp and only considered
|
||||
/// equal if they are bitwise equivalent in memory
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeEqualityChecker_UnmanagedValueEqualsArray<T>() where T : unmanaged
|
||||
{
|
||||
NetworkVariableSerialization<NativeArray<T>>.AreEqual = NetworkVariableEquality<T>.ValueEqualsArray;
|
||||
}
|
||||
|
||||
#if UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
|
||||
/// <summary>
|
||||
/// Registers an unmanaged type that will be checked for equality using memcmp and only considered
|
||||
/// equal if they are bitwise equivalent in memory
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeEqualityChecker_UnmanagedValueEqualsList<T>() where T : unmanaged
|
||||
{
|
||||
NetworkVariableSerialization<NativeList<T>>.AreEqual = NetworkVariableEquality<T>.ValueEqualsList;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Registers a managed type that will be checked for equality using the == operator
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void InitializeEqualityChecker_ManagedClassEquals<T>() where T : class
|
||||
{
|
||||
NetworkVariableSerialization<T>.AreEqual = NetworkVariableEquality<T>.ClassEquals;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 65bdb3e11a9a412ab5e936a9c96a3da0
|
||||
timeCreated: 1718216842
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: bbfa170e9dd448bbbe381ce38d5c139d
|
||||
timeCreated: 1718216671
|
|
@ -0,0 +1,73 @@
|
|||
namespace Unity.Netcode
|
||||
{
|
||||
/// <summary>
|
||||
/// This class is used to register user serialization with NetworkVariables for types
|
||||
/// that are serialized via user serialization, such as with FastBufferReader and FastBufferWriter
|
||||
/// extension methods. Finding those methods isn't achievable efficiently at runtime, so this allows
|
||||
/// users to tell NetworkVariable about those extension methods (or simply pass in a lambda)
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class UserNetworkVariableSerialization<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// The write value delegate handler definition
|
||||
/// </summary>
|
||||
/// <param name="writer">The <see cref="FastBufferWriter"/> to write the value of type `T`</param>
|
||||
/// <param name="value">The value of type `T` to be written</param>
|
||||
public delegate void WriteValueDelegate(FastBufferWriter writer, in T value);
|
||||
|
||||
/// <summary>
|
||||
/// The write value delegate handler definition
|
||||
/// </summary>
|
||||
/// <param name="writer">The <see cref="FastBufferWriter"/> to write the value of type `T`</param>
|
||||
/// <param name="value">The value of type `T` to be written</param>
|
||||
public delegate void WriteDeltaDelegate(FastBufferWriter writer, in T value, in T previousValue);
|
||||
|
||||
/// <summary>
|
||||
/// The read value delegate handler definition
|
||||
/// </summary>
|
||||
/// <param name="reader">The <see cref="FastBufferReader"/> to read the value of type `T`</param>
|
||||
/// <param name="value">The value of type `T` to be read</param>
|
||||
public delegate void ReadValueDelegate(FastBufferReader reader, out T value);
|
||||
|
||||
/// <summary>
|
||||
/// The read value delegate handler definition
|
||||
/// </summary>
|
||||
/// <param name="reader">The <see cref="FastBufferReader"/> to read the value of type `T`</param>
|
||||
/// <param name="value">The value of type `T` to be read</param>
|
||||
public delegate void ReadDeltaDelegate(FastBufferReader reader, ref T value);
|
||||
|
||||
/// <summary>
|
||||
/// The read value delegate handler definition
|
||||
/// </summary>
|
||||
/// <param name="reader">The <see cref="FastBufferReader"/> to read the value of type `T`</param>
|
||||
/// <param name="value">The value of type `T` to be read</param>
|
||||
public delegate void DuplicateValueDelegate(in T value, ref T duplicatedValue);
|
||||
|
||||
/// <summary>
|
||||
/// Callback to write a value
|
||||
/// </summary>
|
||||
public static WriteValueDelegate WriteValue;
|
||||
|
||||
/// <summary>
|
||||
/// Callback to read a value
|
||||
/// </summary>
|
||||
public static ReadValueDelegate ReadValue;
|
||||
|
||||
/// <summary>
|
||||
/// Callback to write a delta between two values, based on computing the difference between the previous and
|
||||
/// current values.
|
||||
/// </summary>
|
||||
public static WriteDeltaDelegate WriteDelta;
|
||||
|
||||
/// <summary>
|
||||
/// Callback to read a delta, applying only select changes to the current value.
|
||||
/// </summary>
|
||||
public static ReadDeltaDelegate ReadDelta;
|
||||
|
||||
/// <summary>
|
||||
/// Callback to create a duplicate of a value, used to check for dirty status.
|
||||
/// </summary>
|
||||
public static DuplicateValueDelegate DuplicateValue;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b295a6756640488b9824d2ec6e26ddae
|
||||
timeCreated: 1718218272
|
Загрузка…
Ссылка в новой задаче