com.unity.netcode.gameobjects@1.5.1

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

Additional documentation and release notes are available at [Multiplayer Documentation](https://docs-multiplayer.unity3d.com).

## [1.5.1] - 2023-06-07

### Added

- Added support for serializing `NativeArray<>` and `NativeList<>` in `FastBufferReader`/`FastBufferWriter`, `BufferSerializer`, `NetworkVariable`, and RPCs. (To use `NativeList<>`, add `UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT` to your Scripting Define Symbols in `Project Settings > Player`) (#2375)
- The location of the automatically-created default network prefab list can now be configured (#2544)
- Added: Message size limits (max single message and max fragmented message) can now be set using NetworkManager.MaximumTransmissionUnitSize and NetworkManager.MaximumFragmentedMessageSize for transports that don't work with the default values (#2530)
- Added `NetworkObject.SpawnWithObservers` property (default is true) that when set to false will spawn a `NetworkObject` with no observers and will not be spawned on any client until `NetworkObject.NetworkShow` is invoked. (#2568)

### Fixed

- Fixed: Fixed a null reference in codegen in some projects (#2581)
- Fixed issue where the `OnClientDisconnected` client identifier was incorrect after a pending client connection was denied. (#2569)
- Fixed warning "Runtime Network Prefabs was not empty at initialization time." being erroneously logged when no runtime network prefabs had been added (#2565)
- Fixed issue where some temporary debug console logging was left in a merged PR. (#2562)
- Fixed the "Generate Default Network Prefabs List" setting not loading correctly and always reverting to being checked. (#2545)
- Fixed issue where users could not use NetworkSceneManager.VerifySceneBeforeLoading to exclude runtime generated scenes from client synchronization. (#2550)
- Fixed missing value on `NetworkListEvent` for `EventType.RemoveAt` events.  (#2542,#2543)
- Fixed issue where parenting a NetworkTransform under a transform with a scale other than Vector3.one would result in incorrect values on non-authoritative instances. (#2538)
- Fixed issue where a server would include scene migrated and then despawned NetworkObjects to a client that was being synchronized. (#2532)
- Fixed the inspector throwing exceptions when attempting to render `NetworkVariable`s of enum types. (#2529)
- Making a `NetworkVariable` with an `INetworkSerializable` type that doesn't meet the `new()` constraint will now create a compile-time error instead of an editor crash (#2528)
- Fixed Multiplayer Tools package installation docs page link on the NetworkManager popup. (#2526)
- Fixed an exception and error logging when two different objects are shown and hidden on the same frame (#2524)
- Fixed a memory leak in `UnityTransport` that occurred if `StartClient` failed. (#2518)
- Fixed issue where a client could throw an exception if abruptly disconnected from a network session with one or more spawned `NetworkObject`(s). (#2510)
- Fixed issue where invalid endpoint addresses were not being detected and returning false from NGO UnityTransport. (#2496)
- Fixed some errors that could occur if a connection is lost and the loss is detected when attempting to write to the socket. (#2495)

## Changed

- Adding network prefabs before NetworkManager initialization is now supported. (#2565)
- Connecting clients being synchronized now switch to the server's active scene before spawning and synchronizing NetworkObjects. (#2532)
- Updated `UnityTransport` dependency on `com.unity.transport` to 1.3.4. (#2533)
- Improved performance of NetworkBehaviour initialization by replacing reflection when initializing NetworkVariables with compile-time code generation, which should help reduce hitching during additive scene loads. (#2522)
This commit is contained in:
Unity Technologies
2023-06-07 00:00:00 +00:00
parent b5abc3ff7c
commit 4d70c198bd
119 changed files with 11328 additions and 3164 deletions

View File

@@ -1,5 +1,6 @@
using System;
using NUnit.Framework;
using Unity.Collections;
using UnityEngine;
using Random = System.Random;
@@ -11,50 +12,50 @@ namespace Unity.Netcode.EditorTests
{
A,
B,
C
};
C = byte.MaxValue
}
protected enum SByteEnum : sbyte
{
A,
B,
C
};
C = sbyte.MaxValue
}
protected enum ShortEnum : short
{
A,
B,
C
};
C = short.MaxValue
}
protected enum UShortEnum : ushort
{
A,
B,
C
};
C = ushort.MaxValue
}
protected enum IntEnum : int
{
A,
B,
C
};
C = int.MaxValue
}
protected enum UIntEnum : uint
{
A,
B,
C
};
C = uint.MaxValue
}
protected enum LongEnum : long
{
A,
B,
C
};
C = long.MaxValue
}
protected enum ULongEnum : ulong
{
A,
B,
C
};
C = ulong.MaxValue
}
protected struct TestStruct : INetworkSerializeByMemcpy
{
@@ -85,23 +86,32 @@ namespace Unity.Netcode.EditorTests
protected abstract void RunTypeArrayTestSafe<T>(T[] valueToTest) where T : unmanaged;
protected abstract void RunTypeNativeArrayTest<T>(NativeArray<T> valueToTest) where T : unmanaged;
protected abstract void RunTypeNativeArrayTestSafe<T>(NativeArray<T> valueToTest) where T : unmanaged;
#if UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
protected abstract void RunTypeNativeListTest<T>(NativeList<T> valueToTest) where T : unmanaged;
protected abstract void RunTypeNativeListTestSafe<T>(NativeList<T> valueToTest) where T : unmanaged;
#endif
private Random m_Random = new Random();
protected TestStruct GetTestStruct()
{
var random = new Random();
var testStruct = new TestStruct
{
A = (byte)random.Next(),
B = (short)random.Next(),
C = (ushort)random.Next(),
D = random.Next(),
E = (uint)random.Next(),
F = ((long)random.Next() << 32) + random.Next(),
G = ((ulong)random.Next() << 32) + (ulong)random.Next(),
A = (byte)m_Random.Next(),
B = (short)m_Random.Next(),
C = (ushort)m_Random.Next(),
D = m_Random.Next(),
E = (uint)m_Random.Next(),
F = ((long)m_Random.Next() << 32) + m_Random.Next(),
G = ((ulong)m_Random.Next() << 32) + (ulong)m_Random.Next(),
H = true,
I = '\u263a',
J = (float)random.NextDouble(),
K = random.NextDouble(),
J = (float)m_Random.NextDouble(),
K = m_Random.NextDouble(),
};
return testStruct;
@@ -600,5 +610,695 @@ namespace Unity.Netcode.EditorTests
Assert.Fail("No type handler was provided for this type in the test!");
}
}
public void BaseNativeArrayTypeTest(Type testType, WriteType writeType)
{
var random = new Random();
void RunTypeTestLocal<T>(NativeArray<T> val, WriteType wt) where T : unmanaged
{
switch (wt)
{
case WriteType.WriteDirect:
RunTypeNativeArrayTest(val);
break;
case WriteType.WriteSafe:
RunTypeNativeArrayTestSafe(val);
break;
}
}
if (testType == typeof(byte))
{
RunTypeTestLocal(new NativeArray<byte>(new[]{
(byte) random.Next(),
(byte) random.Next(),
(byte) random.Next(),
(byte) random.Next(),
(byte) random.Next(),
(byte) random.Next(),
(byte) random.Next()
}, Allocator.Temp), writeType);
}
else if (testType == typeof(sbyte))
{
RunTypeTestLocal(new NativeArray<sbyte>(new[]{
(sbyte) random.Next(),
(sbyte) random.Next(),
(sbyte) random.Next(),
(sbyte) random.Next(),
(sbyte) random.Next(),
(sbyte) random.Next(),
(sbyte) random.Next()
}, Allocator.Temp), writeType);
}
else if (testType == typeof(short))
{
RunTypeTestLocal(new NativeArray<short>(new[]{
(short) random.Next(),
(short) random.Next(),
(short) random.Next(),
(short) random.Next(),
(short) random.Next()
}, Allocator.Temp), writeType);
}
else if (testType == typeof(ushort))
{
RunTypeTestLocal(new NativeArray<ushort>(new[]{
(ushort) random.Next(),
(ushort) random.Next(),
(ushort) random.Next(),
(ushort) random.Next(),
(ushort) random.Next(),
(ushort) random.Next()
}, Allocator.Temp), writeType);
}
else if (testType == typeof(int))
{
RunTypeTestLocal(new NativeArray<int>(new[]{
random.Next(),
random.Next(),
random.Next(),
random.Next(),
random.Next(),
random.Next(),
random.Next(),
random.Next()
}, Allocator.Temp), writeType);
}
else if (testType == typeof(uint))
{
RunTypeTestLocal(new NativeArray<uint>(new[]{
(uint) random.Next(),
(uint) random.Next(),
(uint) random.Next(),
(uint) random.Next(),
(uint) random.Next(),
(uint) random.Next()
}, Allocator.Temp), writeType);
}
else if (testType == typeof(long))
{
RunTypeTestLocal(new NativeArray<long>(new[]{
((long)random.Next() << 32) + random.Next(),
((long)random.Next() << 32) + random.Next(),
((long)random.Next() << 32) + random.Next(),
((long)random.Next() << 32) + random.Next()
}, Allocator.Temp), writeType);
}
else if (testType == typeof(ulong))
{
RunTypeTestLocal(new NativeArray<ulong>(new[]{
((ulong)random.Next() << 32) + (ulong)random.Next(),
((ulong)random.Next() << 32) + (ulong)random.Next(),
((ulong)random.Next() << 32) + (ulong)random.Next(),
((ulong)random.Next() << 32) + (ulong)random.Next(),
((ulong)random.Next() << 32) + (ulong)random.Next(),
((ulong)random.Next() << 32) + (ulong)random.Next(),
((ulong)random.Next() << 32) + (ulong)random.Next(),
((ulong)random.Next() << 32) + (ulong)random.Next(),
((ulong)random.Next() << 32) + (ulong)random.Next()
}, Allocator.Temp), writeType);
}
else if (testType == typeof(bool))
{
RunTypeTestLocal(new NativeArray<bool>(new[]{
true,
false,
true,
true,
false,
false,
true,
false,
true
}, Allocator.Temp), writeType);
}
else if (testType == typeof(char))
{
RunTypeTestLocal(new NativeArray<char>(new[]{
'a',
'\u263a'
}, Allocator.Temp), writeType);
}
else if (testType == typeof(float))
{
RunTypeTestLocal(new NativeArray<float>(new[]{
(float)random.NextDouble(),
(float)random.NextDouble(),
(float)random.NextDouble(),
(float)random.NextDouble(),
(float)random.NextDouble(),
(float)random.NextDouble(),
(float)random.NextDouble(),
(float)random.NextDouble(),
(float)random.NextDouble()
}, Allocator.Temp), writeType);
}
else if (testType == typeof(double))
{
RunTypeTestLocal(new NativeArray<double>(new[]{
random.NextDouble(),
random.NextDouble(),
random.NextDouble(),
random.NextDouble(),
random.NextDouble(),
random.NextDouble(),
random.NextDouble(),
random.NextDouble(),
random.NextDouble()
}, Allocator.Temp), writeType);
}
else if (testType == typeof(ByteEnum))
{
RunTypeTestLocal(new NativeArray<ByteEnum>(new[]{
ByteEnum.C,
ByteEnum.A,
ByteEnum.B
}, Allocator.Temp), writeType);
}
else if (testType == typeof(SByteEnum))
{
RunTypeTestLocal(new NativeArray<SByteEnum>(new[]{
SByteEnum.C,
SByteEnum.A,
SByteEnum.B
}, Allocator.Temp), writeType);
}
else if (testType == typeof(ShortEnum))
{
RunTypeTestLocal(new NativeArray<ShortEnum>(new[]{
ShortEnum.C,
ShortEnum.A,
ShortEnum.B
}, Allocator.Temp), writeType);
}
else if (testType == typeof(UShortEnum))
{
RunTypeTestLocal(new NativeArray<UShortEnum>(new[]{
UShortEnum.C,
UShortEnum.A,
UShortEnum.B
}, Allocator.Temp), writeType);
}
else if (testType == typeof(IntEnum))
{
RunTypeTestLocal(new NativeArray<IntEnum>(new[]{
IntEnum.C,
IntEnum.A,
IntEnum.B
}, Allocator.Temp), writeType);
}
else if (testType == typeof(UIntEnum))
{
RunTypeTestLocal(new NativeArray<UIntEnum>(new[]{
UIntEnum.C,
UIntEnum.A,
UIntEnum.B
}, Allocator.Temp), writeType);
}
else if (testType == typeof(LongEnum))
{
RunTypeTestLocal(new NativeArray<LongEnum>(new[]{
LongEnum.C,
LongEnum.A,
LongEnum.B
}, Allocator.Temp), writeType);
}
else if (testType == typeof(ULongEnum))
{
RunTypeTestLocal(new NativeArray<ULongEnum>(new[]{
ULongEnum.C,
ULongEnum.A,
ULongEnum.B
}, Allocator.Temp), writeType);
}
else if (testType == typeof(Vector2))
{
RunTypeTestLocal(new NativeArray<Vector2>(new[]{
new Vector2((float) random.NextDouble(), (float) random.NextDouble()),
new Vector2((float) random.NextDouble(), (float) random.NextDouble()),
new Vector2((float) random.NextDouble(), (float) random.NextDouble()),
}, Allocator.Temp), writeType);
}
else if (testType == typeof(Vector3))
{
RunTypeTestLocal(new NativeArray<Vector3>(new[]{
new Vector3((float) random.NextDouble(), (float) random.NextDouble(), (float) random.NextDouble()),
new Vector3((float) random.NextDouble(), (float) random.NextDouble(), (float) random.NextDouble()),
new Vector3((float) random.NextDouble(), (float) random.NextDouble(), (float) random.NextDouble()),
}, Allocator.Temp), writeType);
}
else if (testType == typeof(Vector2Int))
{
RunTypeTestLocal(new NativeArray<Vector2Int>(new[]{
new Vector2Int((int) random.NextDouble(), (int) random.NextDouble()),
new Vector2Int((int) random.NextDouble(), (int) random.NextDouble()),
new Vector2Int((int) random.NextDouble(), (int) random.NextDouble()),
}, Allocator.Temp), writeType);
}
else if (testType == typeof(Vector3Int))
{
RunTypeTestLocal(new NativeArray<Vector3Int>(new[]{
new Vector3Int((int) random.NextDouble(), (int) random.NextDouble(), (int) random.NextDouble()),
new Vector3Int((int) random.NextDouble(), (int) random.NextDouble(), (int) random.NextDouble()),
new Vector3Int((int) random.NextDouble(), (int) random.NextDouble(), (int) random.NextDouble()),
}, Allocator.Temp), writeType);
}
else if (testType == typeof(Vector4))
{
RunTypeTestLocal(new NativeArray<Vector4>(new[]{
new Vector4((float) random.NextDouble(), (float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble()),
new Vector4((float) random.NextDouble(), (float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble()),
new Vector4((float) random.NextDouble(), (float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble()),
}, Allocator.Temp), writeType);
}
else if (testType == typeof(Quaternion))
{
RunTypeTestLocal(new NativeArray<Quaternion>(new[]{
new Quaternion((float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble(), (float) random.NextDouble()),
new Quaternion((float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble(), (float) random.NextDouble()),
new Quaternion((float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble(), (float) random.NextDouble()),
}, Allocator.Temp), writeType);
}
else if (testType == typeof(Color))
{
RunTypeTestLocal(new NativeArray<Color>(new[]{
new Color((float) random.NextDouble(), (float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble()),
new Color((float) random.NextDouble(), (float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble()),
new Color((float) random.NextDouble(), (float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble()),
}, Allocator.Temp), writeType);
}
else if (testType == typeof(Color32))
{
RunTypeTestLocal(new NativeArray<Color32>(new[]{
new Color32((byte) random.Next(), (byte) random.Next(), (byte) random.Next(), (byte) random.Next()),
new Color32((byte) random.Next(), (byte) random.Next(), (byte) random.Next(), (byte) random.Next()),
new Color32((byte) random.Next(), (byte) random.Next(), (byte) random.Next(), (byte) random.Next()),
}, Allocator.Temp), writeType);
}
else if (testType == typeof(Ray))
{
RunTypeTestLocal(new NativeArray<Ray>(new[]{
new Ray(
new Vector3((float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble()),
new Vector3((float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble())),
new Ray(
new Vector3((float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble()),
new Vector3((float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble())),
new Ray(
new Vector3((float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble()),
new Vector3((float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble())),
}, Allocator.Temp), writeType);
}
else if (testType == typeof(Ray2D))
{
RunTypeTestLocal(new NativeArray<Ray2D>(new[]{
new Ray2D(
new Vector2((float) random.NextDouble(), (float) random.NextDouble()),
new Vector2((float) random.NextDouble(), (float) random.NextDouble())),
new Ray2D(
new Vector2((float) random.NextDouble(), (float) random.NextDouble()),
new Vector2((float) random.NextDouble(), (float) random.NextDouble())),
new Ray2D(
new Vector2((float) random.NextDouble(), (float) random.NextDouble()),
new Vector2((float) random.NextDouble(), (float) random.NextDouble())),
}, Allocator.Temp), writeType);
}
else if (testType == typeof(TestStruct))
{
RunTypeTestLocal(new NativeArray<TestStruct>(new[] {
GetTestStruct(),
GetTestStruct(),
GetTestStruct(),
}, Allocator.Temp), writeType);
}
else
{
Assert.Fail("No type handler was provided for this type in the test!");
}
}
#if UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
public void BaseNativeListTypeTest(Type testType, WriteType writeType)
{
var random = new Random();
void RunTypeTestLocal<T>(NativeArray<T> val, WriteType wt) where T : unmanaged
{
var lst = new NativeList<T>(val.Length, Allocator.Temp);
foreach (var item in val)
{
lst.Add(item);
}
switch (wt)
{
case WriteType.WriteDirect:
RunTypeNativeListTest(lst);
break;
case WriteType.WriteSafe:
RunTypeNativeListTestSafe(lst);
break;
}
}
if (testType == typeof(byte))
{
RunTypeTestLocal(new NativeArray<byte>(new[]{
(byte) random.Next(),
(byte) random.Next(),
(byte) random.Next(),
(byte) random.Next(),
(byte) random.Next(),
(byte) random.Next(),
(byte) random.Next()
}, Allocator.Temp), writeType);
}
else if (testType == typeof(sbyte))
{
RunTypeTestLocal(new NativeArray<sbyte>(new[]{
(sbyte) random.Next(),
(sbyte) random.Next(),
(sbyte) random.Next(),
(sbyte) random.Next(),
(sbyte) random.Next(),
(sbyte) random.Next(),
(sbyte) random.Next()
}, Allocator.Temp), writeType);
}
else if (testType == typeof(short))
{
RunTypeTestLocal(new NativeArray<short>(new[]{
(short) random.Next(),
(short) random.Next(),
(short) random.Next(),
(short) random.Next(),
(short) random.Next()
}, Allocator.Temp), writeType);
}
else if (testType == typeof(ushort))
{
RunTypeTestLocal(new NativeArray<ushort>(new[]{
(ushort) random.Next(),
(ushort) random.Next(),
(ushort) random.Next(),
(ushort) random.Next(),
(ushort) random.Next(),
(ushort) random.Next()
}, Allocator.Temp), writeType);
}
else if (testType == typeof(int))
{
RunTypeTestLocal(new NativeArray<int>(new[]{
random.Next(),
random.Next(),
random.Next(),
random.Next(),
random.Next(),
random.Next(),
random.Next(),
random.Next()
}, Allocator.Temp), writeType);
}
else if (testType == typeof(uint))
{
RunTypeTestLocal(new NativeArray<uint>(new[]{
(uint) random.Next(),
(uint) random.Next(),
(uint) random.Next(),
(uint) random.Next(),
(uint) random.Next(),
(uint) random.Next()
}, Allocator.Temp), writeType);
}
else if (testType == typeof(long))
{
RunTypeTestLocal(new NativeArray<long>(new[]{
((long)random.Next() << 32) + random.Next(),
((long)random.Next() << 32) + random.Next(),
((long)random.Next() << 32) + random.Next(),
((long)random.Next() << 32) + random.Next()
}, Allocator.Temp), writeType);
}
else if (testType == typeof(ulong))
{
RunTypeTestLocal(new NativeArray<ulong>(new[]{
((ulong)random.Next() << 32) + (ulong)random.Next(),
((ulong)random.Next() << 32) + (ulong)random.Next(),
((ulong)random.Next() << 32) + (ulong)random.Next(),
((ulong)random.Next() << 32) + (ulong)random.Next(),
((ulong)random.Next() << 32) + (ulong)random.Next(),
((ulong)random.Next() << 32) + (ulong)random.Next(),
((ulong)random.Next() << 32) + (ulong)random.Next(),
((ulong)random.Next() << 32) + (ulong)random.Next(),
((ulong)random.Next() << 32) + (ulong)random.Next()
}, Allocator.Temp), writeType);
}
else if (testType == typeof(bool))
{
RunTypeTestLocal(new NativeArray<bool>(new[]{
true,
false,
true,
true,
false,
false,
true,
false,
true
}, Allocator.Temp), writeType);
}
else if (testType == typeof(char))
{
RunTypeTestLocal(new NativeArray<char>(new[]{
'a',
'\u263a'
}, Allocator.Temp), writeType);
}
else if (testType == typeof(float))
{
RunTypeTestLocal(new NativeArray<float>(new[]{
(float)random.NextDouble(),
(float)random.NextDouble(),
(float)random.NextDouble(),
(float)random.NextDouble(),
(float)random.NextDouble(),
(float)random.NextDouble(),
(float)random.NextDouble(),
(float)random.NextDouble(),
(float)random.NextDouble()
}, Allocator.Temp), writeType);
}
else if (testType == typeof(double))
{
RunTypeTestLocal(new NativeArray<double>(new[]{
random.NextDouble(),
random.NextDouble(),
random.NextDouble(),
random.NextDouble(),
random.NextDouble(),
random.NextDouble(),
random.NextDouble(),
random.NextDouble(),
random.NextDouble()
}, Allocator.Temp), writeType);
}
else if (testType == typeof(ByteEnum))
{
RunTypeTestLocal(new NativeArray<ByteEnum>(new[]{
ByteEnum.C,
ByteEnum.A,
ByteEnum.B
}, Allocator.Temp), writeType);
}
else if (testType == typeof(SByteEnum))
{
RunTypeTestLocal(new NativeArray<SByteEnum>(new[]{
SByteEnum.C,
SByteEnum.A,
SByteEnum.B
}, Allocator.Temp), writeType);
}
else if (testType == typeof(ShortEnum))
{
RunTypeTestLocal(new NativeArray<ShortEnum>(new[]{
ShortEnum.C,
ShortEnum.A,
ShortEnum.B
}, Allocator.Temp), writeType);
}
else if (testType == typeof(UShortEnum))
{
RunTypeTestLocal(new NativeArray<UShortEnum>(new[]{
UShortEnum.C,
UShortEnum.A,
UShortEnum.B
}, Allocator.Temp), writeType);
}
else if (testType == typeof(IntEnum))
{
RunTypeTestLocal(new NativeArray<IntEnum>(new[]{
IntEnum.C,
IntEnum.A,
IntEnum.B
}, Allocator.Temp), writeType);
}
else if (testType == typeof(UIntEnum))
{
RunTypeTestLocal(new NativeArray<UIntEnum>(new[]{
UIntEnum.C,
UIntEnum.A,
UIntEnum.B
}, Allocator.Temp), writeType);
}
else if (testType == typeof(LongEnum))
{
RunTypeTestLocal(new NativeArray<LongEnum>(new[]{
LongEnum.C,
LongEnum.A,
LongEnum.B
}, Allocator.Temp), writeType);
}
else if (testType == typeof(ULongEnum))
{
RunTypeTestLocal(new NativeArray<ULongEnum>(new[]{
ULongEnum.C,
ULongEnum.A,
ULongEnum.B
}, Allocator.Temp), writeType);
}
else if (testType == typeof(Vector2))
{
RunTypeTestLocal(new NativeArray<Vector2>(new[]{
new Vector2((float) random.NextDouble(), (float) random.NextDouble()),
new Vector2((float) random.NextDouble(), (float) random.NextDouble()),
new Vector2((float) random.NextDouble(), (float) random.NextDouble()),
}, Allocator.Temp), writeType);
}
else if (testType == typeof(Vector3))
{
RunTypeTestLocal(new NativeArray<Vector3>(new[]{
new Vector3((float) random.NextDouble(), (float) random.NextDouble(), (float) random.NextDouble()),
new Vector3((float) random.NextDouble(), (float) random.NextDouble(), (float) random.NextDouble()),
new Vector3((float) random.NextDouble(), (float) random.NextDouble(), (float) random.NextDouble()),
}, Allocator.Temp), writeType);
}
else if (testType == typeof(Vector2Int))
{
RunTypeTestLocal(new NativeArray<Vector2Int>(new[]{
new Vector2Int((int) random.NextDouble(), (int) random.NextDouble()),
new Vector2Int((int) random.NextDouble(), (int) random.NextDouble()),
new Vector2Int((int) random.NextDouble(), (int) random.NextDouble()),
}, Allocator.Temp), writeType);
}
else if (testType == typeof(Vector3Int))
{
RunTypeTestLocal(new NativeArray<Vector3Int>(new[]{
new Vector3Int((int) random.NextDouble(), (int) random.NextDouble(), (int) random.NextDouble()),
new Vector3Int((int) random.NextDouble(), (int) random.NextDouble(), (int) random.NextDouble()),
new Vector3Int((int) random.NextDouble(), (int) random.NextDouble(), (int) random.NextDouble()),
}, Allocator.Temp), writeType);
}
else if (testType == typeof(Vector4))
{
RunTypeTestLocal(new NativeArray<Vector4>(new[]{
new Vector4((float) random.NextDouble(), (float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble()),
new Vector4((float) random.NextDouble(), (float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble()),
new Vector4((float) random.NextDouble(), (float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble()),
}, Allocator.Temp), writeType);
}
else if (testType == typeof(Quaternion))
{
RunTypeTestLocal(new NativeArray<Quaternion>(new[]{
new Quaternion((float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble(), (float) random.NextDouble()),
new Quaternion((float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble(), (float) random.NextDouble()),
new Quaternion((float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble(), (float) random.NextDouble()),
}, Allocator.Temp), writeType);
}
else if (testType == typeof(Color))
{
RunTypeTestLocal(new NativeArray<Color>(new[]{
new Color((float) random.NextDouble(), (float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble()),
new Color((float) random.NextDouble(), (float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble()),
new Color((float) random.NextDouble(), (float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble()),
}, Allocator.Temp), writeType);
}
else if (testType == typeof(Color32))
{
RunTypeTestLocal(new NativeArray<Color32>(new[]{
new Color32((byte) random.Next(), (byte) random.Next(), (byte) random.Next(), (byte) random.Next()),
new Color32((byte) random.Next(), (byte) random.Next(), (byte) random.Next(), (byte) random.Next()),
new Color32((byte) random.Next(), (byte) random.Next(), (byte) random.Next(), (byte) random.Next()),
}, Allocator.Temp), writeType);
}
else if (testType == typeof(Ray))
{
RunTypeTestLocal(new NativeArray<Ray>(new[]{
new Ray(
new Vector3((float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble()),
new Vector3((float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble())),
new Ray(
new Vector3((float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble()),
new Vector3((float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble())),
new Ray(
new Vector3((float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble()),
new Vector3((float) random.NextDouble(), (float) random.NextDouble(),
(float) random.NextDouble())),
}, Allocator.Temp), writeType);
}
else if (testType == typeof(Ray2D))
{
RunTypeTestLocal(new NativeArray<Ray2D>(new[]{
new Ray2D(
new Vector2((float) random.NextDouble(), (float) random.NextDouble()),
new Vector2((float) random.NextDouble(), (float) random.NextDouble())),
new Ray2D(
new Vector2((float) random.NextDouble(), (float) random.NextDouble()),
new Vector2((float) random.NextDouble(), (float) random.NextDouble())),
new Ray2D(
new Vector2((float) random.NextDouble(), (float) random.NextDouble()),
new Vector2((float) random.NextDouble(), (float) random.NextDouble())),
}, Allocator.Temp), writeType);
}
else if (testType == typeof(TestStruct))
{
RunTypeTestLocal(new NativeArray<TestStruct>(new[] {
GetTestStruct(),
GetTestStruct(),
GetTestStruct(),
}, Allocator.Temp), writeType);
}
else
{
Assert.Fail("No type handler was provided for this type in the test!");
}
}
#endif
}
}

View File

@@ -69,6 +69,10 @@ namespace Unity.Netcode.EditorTests
{
continue;
}
if (candidateMethod.GetParameters()[0].ParameterType.IsGenericType)
{
continue;
}
try
{
method = candidateMethod.MakeGenericMethod(typeof(T));
@@ -110,6 +114,10 @@ namespace Unity.Netcode.EditorTests
{
continue;
}
if (candidateMethod.GetParameters()[0].ParameterType.IsGenericType)
{
continue;
}
try
{
method = candidateMethod.MakeGenericMethod(typeof(T));
@@ -134,6 +142,90 @@ namespace Unity.Netcode.EditorTests
method.Invoke(writer, args);
}
private void RunWriteMethod<T>(string methodName, FastBufferWriter writer, in NativeArray<T> value) where T : unmanaged
{
MethodInfo method = typeof(FastBufferWriter).GetMethod(methodName, new[] { typeof(NativeArray<T>) });
if (method == null)
{
foreach (var candidateMethod in typeof(FastBufferWriter).GetMethods())
{
if (candidateMethod.Name == methodName && candidateMethod.IsGenericMethodDefinition)
{
if (candidateMethod.GetParameters().Length == 0 || (candidateMethod.GetParameters().Length > 1 && !candidateMethod.GetParameters()[1].HasDefaultValue))
{
continue;
}
if (!candidateMethod.GetParameters()[0].ParameterType.Name.Contains("NativeArray"))
{
continue;
}
try
{
method = candidateMethod.MakeGenericMethod(typeof(T));
break;
}
catch (ArgumentException)
{
continue;
}
}
}
}
Assert.NotNull(method);
object[] args = new object[method.GetParameters().Length];
args[0] = value;
for (var i = 1; i < args.Length; ++i)
{
args[i] = method.GetParameters()[i].DefaultValue;
}
method.Invoke(writer, args);
}
#if UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
private void RunWriteMethod<T>(string methodName, FastBufferWriter writer, in NativeList<T> value) where T : unmanaged
{
MethodInfo method = typeof(FastBufferWriter).GetMethod(methodName, new[] { typeof(NativeList<T>) });
if (method == null)
{
foreach (var candidateMethod in typeof(FastBufferWriter).GetMethods())
{
if (candidateMethod.Name == methodName && candidateMethod.IsGenericMethodDefinition)
{
if (candidateMethod.GetParameters().Length == 0 || (candidateMethod.GetParameters().Length > 1 && !candidateMethod.GetParameters()[1].HasDefaultValue))
{
continue;
}
if (!candidateMethod.GetParameters()[0].ParameterType.Name.Contains("NativeList"))
{
continue;
}
try
{
method = candidateMethod.MakeGenericMethod(typeof(T));
break;
}
catch (ArgumentException)
{
continue;
}
}
}
}
Assert.NotNull(method);
object[] args = new object[method.GetParameters().Length];
args[0] = value;
for (var i = 1; i < args.Length; ++i)
{
args[i] = method.GetParameters()[i].DefaultValue;
}
method.Invoke(writer, args);
}
#endif
private void RunReadMethod<T>(string methodName, FastBufferReader reader, out T value) where T : unmanaged
{
MethodInfo method = typeof(FastBufferReader).GetMethod(methodName, new[] { typeof(T).MakeByRefType() });
@@ -151,6 +243,10 @@ namespace Unity.Netcode.EditorTests
{
continue;
}
if (candidateMethod.GetParameters()[0].ParameterType.IsGenericType)
{
continue;
}
try
{
method = candidateMethod.MakeGenericMethod(typeof(T));
@@ -203,6 +299,10 @@ namespace Unity.Netcode.EditorTests
{
continue;
}
if (candidateMethod.GetParameters()[0].ParameterType.IsGenericType)
{
continue;
}
try
{
method = candidateMethod.MakeGenericMethod(typeof(T));
@@ -230,6 +330,112 @@ namespace Unity.Netcode.EditorTests
value = (T[])args[0];
}
private void RunReadMethod<T>(string methodName, FastBufferReader reader, out NativeArray<T> value) where T : unmanaged
{
MethodInfo method = null;
try
{
method = typeof(FastBufferReader).GetMethod(methodName, new[] { typeof(NativeArray<T>).MakeByRefType(), typeof(Allocator) });
}
catch (AmbiguousMatchException)
{
// skip.
}
if (method == null)
{
foreach (var candidateMethod in typeof(FastBufferReader).GetMethods())
{
if (candidateMethod.Name == methodName && candidateMethod.IsGenericMethodDefinition)
{
if (candidateMethod.GetParameters().Length < 2 || (candidateMethod.GetParameters().Length > 2 && !candidateMethod.GetParameters()[2].HasDefaultValue))
{
continue;
}
if (!candidateMethod.GetParameters()[0].ParameterType.Name.Contains("NativeArray"))
{
continue;
}
try
{
method = candidateMethod.MakeGenericMethod(typeof(T));
break;
}
catch (ArgumentException)
{
continue;
}
}
}
}
Assert.NotNull(method);
value = new NativeArray<T>();
object[] args = new object[method.GetParameters().Length];
args[0] = value;
args[1] = Allocator.Temp;
for (var i = 2; i < args.Length; ++i)
{
args[i] = method.GetParameters()[i].DefaultValue;
}
method.Invoke(reader, args);
value = (NativeArray<T>)args[0];
}
#if UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
private void RunReadMethod<T>(string methodName, FastBufferReader reader, ref NativeList<T> value) where T : unmanaged
{
MethodInfo method = null;
try
{
method = typeof(FastBufferReader).GetMethod(methodName, new[] { typeof(NativeList<T>).MakeByRefType() });
}
catch (AmbiguousMatchException)
{
// skip.
}
if (method == null)
{
foreach (var candidateMethod in typeof(FastBufferReader).GetMethods())
{
if (candidateMethod.Name == methodName && candidateMethod.IsGenericMethodDefinition)
{
if (candidateMethod.GetParameters().Length == 0 || (candidateMethod.GetParameters().Length > 1 && !candidateMethod.GetParameters()[1].HasDefaultValue))
{
continue;
}
if (!candidateMethod.GetParameters()[0].ParameterType.Name.Contains("NativeList"))
{
continue;
}
try
{
method = candidateMethod.MakeGenericMethod(typeof(T));
break;
}
catch (ArgumentException)
{
continue;
}
}
}
}
Assert.NotNull(method);
object[] args = new object[method.GetParameters().Length];
args[0] = value;
for (var i = 1; i < args.Length; ++i)
{
args[i] = method.GetParameters()[i].DefaultValue;
}
method.Invoke(reader, args);
}
#endif
protected override unsafe void RunTypeTest<T>(T valueToTest)
{
var writeSize = FastBufferWriter.GetWriteSize(valueToTest);
@@ -288,6 +494,28 @@ namespace Unity.Netcode.EditorTests
}
}
private void VerifyArrayEquality<T>(NativeArray<T> value, NativeArray<T> compareValue, int offset) where T : unmanaged
{
Assert.AreEqual(value.Length, compareValue.Length);
for (var i = 0; i < value.Length; ++i)
{
Assert.AreEqual(value[i], compareValue[i]);
}
}
#if UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
private void VerifyArrayEquality<T>(NativeList<T> value, NativeList<T> compareValue, int offset) where T : unmanaged
{
Assert.AreEqual(value.Length, compareValue.Length);
for (var i = 0; i < value.Length; ++i)
{
Assert.AreEqual(value[i], compareValue[i]);
}
}
#endif
protected override unsafe void RunTypeArrayTest<T>(T[] valueToTest)
{
var writeSize = FastBufferWriter.GetWriteSize(valueToTest);
@@ -340,6 +568,114 @@ namespace Unity.Netcode.EditorTests
}
}
protected override unsafe void RunTypeNativeArrayTest<T>(NativeArray<T> valueToTest)
{
var writeSize = FastBufferWriter.GetWriteSize(valueToTest);
var writer = new FastBufferWriter(writeSize + 2, Allocator.Temp);
using (writer)
{
Assert.AreEqual(sizeof(int) + sizeof(T) * valueToTest.Length, writeSize);
Assert.IsTrue(writer.TryBeginWrite(writeSize + 2), "Writer denied write permission");
RunWriteMethod(nameof(FastBufferWriter.WriteValue), writer, valueToTest);
WriteCheckBytes(writer, writeSize);
var reader = new FastBufferReader(writer, Allocator.Temp);
using (reader)
{
VerifyPositionAndLength(reader, writer.Length);
Assert.IsTrue(reader.TryBeginRead(writeSize));
RunReadMethod(nameof(FastBufferReader.ReadValue), reader, out NativeArray<T> result);
VerifyArrayEquality(valueToTest, result, 0);
VerifyCheckBytes(reader, writeSize);
}
}
}
protected override unsafe void RunTypeNativeArrayTestSafe<T>(NativeArray<T> valueToTest)
{
var writeSize = FastBufferWriter.GetWriteSize(valueToTest);
var writer = new FastBufferWriter(writeSize + 2, Allocator.Temp);
using (writer)
{
Assert.AreEqual(sizeof(int) + sizeof(T) * valueToTest.Length, writeSize);
RunWriteMethod(nameof(FastBufferWriter.WriteValueSafe), writer, valueToTest);
WriteCheckBytes(writer, writeSize);
var reader = new FastBufferReader(writer, Allocator.Temp);
using (reader)
{
VerifyPositionAndLength(reader, writer.Length);
RunReadMethod(nameof(FastBufferReader.ReadValueSafe), reader, out NativeArray<T> result);
VerifyArrayEquality(valueToTest, result, 0);
VerifyCheckBytes(reader, writeSize);
}
}
}
#if UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
protected override unsafe void RunTypeNativeListTest<T>(NativeList<T> valueToTest)
{
var writeSize = FastBufferWriter.GetWriteSize(valueToTest);
var writer = new FastBufferWriter(writeSize + 2, Allocator.Temp);
using (writer)
{
Assert.AreEqual(sizeof(int) + sizeof(T) * valueToTest.Length, writeSize);
Assert.IsTrue(writer.TryBeginWrite(writeSize + 2), "Writer denied write permission");
RunWriteMethod(nameof(FastBufferWriter.WriteValue), writer, valueToTest);
WriteCheckBytes(writer, writeSize);
var reader = new FastBufferReader(writer, Allocator.Temp);
using (reader)
{
VerifyPositionAndLength(reader, writer.Length);
Assert.IsTrue(reader.TryBeginRead(writeSize));
var result = new NativeList<T>(Allocator.Temp);
RunReadMethod(nameof(FastBufferReader.ReadValueInPlace), reader, ref result);
VerifyArrayEquality(valueToTest, result, 0);
VerifyCheckBytes(reader, writeSize);
}
}
}
protected override unsafe void RunTypeNativeListTestSafe<T>(NativeList<T> valueToTest)
{
var writeSize = FastBufferWriter.GetWriteSize(valueToTest);
var writer = new FastBufferWriter(writeSize + 2, Allocator.Temp);
using (writer)
{
Assert.AreEqual(sizeof(int) + sizeof(T) * valueToTest.Length, writeSize);
RunWriteMethod(nameof(FastBufferWriter.WriteValueSafe), writer, valueToTest);
WriteCheckBytes(writer, writeSize);
var reader = new FastBufferReader(writer, Allocator.Temp);
using (reader)
{
VerifyPositionAndLength(reader, writer.Length);
var result = new NativeList<T>(Allocator.Temp);
RunReadMethod(nameof(FastBufferReader.ReadValueSafeInPlace), reader, ref result);
VerifyArrayEquality(valueToTest, result, 0);
VerifyCheckBytes(reader, writeSize);
}
}
}
#endif
[Test]
public void GivenFastBufferWriterContainingValue_WhenReadingUnmanagedType_ValueMatchesWhatWasWritten(
[Values(typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(uint),
@@ -368,6 +704,35 @@ namespace Unity.Netcode.EditorTests
BaseArrayTypeTest(testType, writeType);
}
[Test]
public void GivenFastBufferWriterContainingValue_WhenReadingNativeArrayOfUnmanagedElementType_ValueMatchesWhatWasWritten(
[Values(typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(uint),
typeof(long), typeof(ulong), typeof(bool), typeof(char), typeof(float), typeof(double),
typeof(ByteEnum), typeof(SByteEnum), typeof(ShortEnum), typeof(UShortEnum), typeof(IntEnum),
typeof(UIntEnum), typeof(LongEnum), typeof(ULongEnum), typeof(Vector2), typeof(Vector3),
typeof(Vector2Int), typeof(Vector3Int), typeof(Vector4), typeof(Quaternion), typeof(Color),
typeof(Color32), typeof(Ray), typeof(Ray2D), typeof(TestStruct))]
Type testType,
[Values] WriteType writeType)
{
BaseNativeArrayTypeTest(testType, writeType);
}
#if UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
[Test]
public void GivenFastBufferWriterContainingValue_WhenReadingNativeListOfUnmanagedElementType_ValueMatchesWhatWasWritten(
[Values(typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(uint),
typeof(long), typeof(ulong), typeof(bool), typeof(char), typeof(float), typeof(double),
typeof(ByteEnum), typeof(SByteEnum), typeof(ShortEnum), typeof(UShortEnum), typeof(IntEnum),
typeof(UIntEnum), typeof(LongEnum), typeof(ULongEnum), typeof(Vector2), typeof(Vector3),
typeof(Vector2Int), typeof(Vector3Int), typeof(Vector4), typeof(Quaternion), typeof(Color),
typeof(Color32), typeof(Ray), typeof(Ray2D), typeof(TestStruct))]
Type testType,
[Values] WriteType writeType)
{
BaseNativeListTypeTest(testType, writeType);
}
#endif
public unsafe void RunFixedStringTest<T>(T fixedStringValue, int numBytesWritten, WriteType writeType) where T : unmanaged, INativeList<byte>, IUTF8Bytes
{

View File

@@ -2,6 +2,7 @@ using System;
using System.Reflection;
using NUnit.Framework;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using UnityEngine;
using Random = System.Random;
@@ -80,6 +81,11 @@ namespace Unity.Netcode.EditorTests
{
continue;
}
if (candidateMethod.GetParameters()[0].ParameterType.IsGenericType)
{
continue;
}
try
{
method = candidateMethod.MakeGenericMethod(typeof(T));
@@ -121,6 +127,10 @@ namespace Unity.Netcode.EditorTests
{
continue;
}
if (candidateMethod.GetParameters()[0].ParameterType.IsGenericType)
{
continue;
}
try
{
method = candidateMethod.MakeGenericMethod(typeof(T));
@@ -145,6 +155,90 @@ namespace Unity.Netcode.EditorTests
method.Invoke(writer, args);
}
private void RunMethod<T>(string methodName, FastBufferWriter writer, in NativeArray<T> value) where T : unmanaged
{
MethodInfo method = typeof(FastBufferWriter).GetMethod(methodName, new[] { typeof(NativeArray<T>) });
if (method == null)
{
foreach (var candidateMethod in typeof(FastBufferWriter).GetMethods())
{
if (candidateMethod.Name == methodName && candidateMethod.IsGenericMethodDefinition)
{
if (candidateMethod.GetParameters().Length == 0 || (candidateMethod.GetParameters().Length > 1 && !candidateMethod.GetParameters()[1].HasDefaultValue))
{
continue;
}
if (!candidateMethod.GetParameters()[0].ParameterType.Name.Contains("NativeArray"))
{
continue;
}
try
{
method = candidateMethod.MakeGenericMethod(typeof(T));
break;
}
catch (ArgumentException)
{
continue;
}
}
}
}
Assert.NotNull(method);
object[] args = new object[method.GetParameters().Length];
args[0] = value;
for (var i = 1; i < args.Length; ++i)
{
args[i] = method.GetParameters()[i].DefaultValue;
}
method.Invoke(writer, args);
}
#if UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
private void RunMethod<T>(string methodName, FastBufferWriter writer, in NativeList<T> value) where T : unmanaged
{
MethodInfo method = typeof(FastBufferWriter).GetMethod(methodName, new[] { typeof(NativeList<T>) });
if (method == null)
{
foreach (var candidateMethod in typeof(FastBufferWriter).GetMethods())
{
if (candidateMethod.Name == methodName && candidateMethod.IsGenericMethodDefinition)
{
if (candidateMethod.GetParameters().Length == 0 || (candidateMethod.GetParameters().Length > 1 && !candidateMethod.GetParameters()[1].HasDefaultValue))
{
continue;
}
if (!candidateMethod.GetParameters()[0].ParameterType.Name.Contains("NativeList"))
{
continue;
}
try
{
method = candidateMethod.MakeGenericMethod(typeof(T));
break;
}
catch (ArgumentException)
{
continue;
}
}
}
}
Assert.NotNull(method);
object[] args = new object[method.GetParameters().Length];
args[0] = value;
for (var i = 1; i < args.Length; ++i)
{
args[i] = method.GetParameters()[i].DefaultValue;
}
method.Invoke(writer, args);
}
#endif
protected override unsafe void RunTypeTest<T>(T valueToTest)
{
@@ -199,6 +293,34 @@ namespace Unity.Netcode.EditorTests
}
}
private unsafe void VerifyArrayEquality<T>(NativeArray<T> value, byte* unsafePtr, int offset) where T : unmanaged
{
int* sizeValue = (int*)(unsafePtr + offset);
Assert.AreEqual(value.Length, *sizeValue);
var asTPointer = (T*)value.GetUnsafePtr();
var underlyingTArray = (T*)(unsafePtr + sizeof(int) + offset);
for (var i = 0; i < value.Length; ++i)
{
Assert.AreEqual(asTPointer[i], underlyingTArray[i]);
}
}
#if UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
private unsafe void VerifyArrayEquality<T>(NativeList<T> value, byte* unsafePtr, int offset) where T : unmanaged
{
int* sizeValue = (int*)(unsafePtr + offset);
Assert.AreEqual(value.Length, *sizeValue);
var asTPointer = (T*)value.GetUnsafePtr();
var underlyingTArray = (T*)(unsafePtr + sizeof(int) + offset);
for (var i = 0; i < value.Length; ++i)
{
Assert.AreEqual(asTPointer[i], underlyingTArray[i]);
}
}
#endif
protected override unsafe void RunTypeArrayTest<T>(T[] valueToTest)
{
var writeSize = FastBufferWriter.GetWriteSize(valueToTest);
@@ -242,6 +364,96 @@ namespace Unity.Netcode.EditorTests
}
}
protected override unsafe void RunTypeNativeArrayTest<T>(NativeArray<T> valueToTest)
{
var writeSize = FastBufferWriter.GetWriteSize(valueToTest);
var writer = new FastBufferWriter(writeSize + 2, Allocator.Temp);
using (writer)
{
Assert.AreEqual(sizeof(int) + sizeof(T) * valueToTest.Length, writeSize);
Assert.IsTrue(writer.TryBeginWrite(writeSize + 2), "Writer denied write permission");
RunMethod(nameof(FastBufferWriter.WriteValue), writer, valueToTest);
VerifyPositionAndLength(writer, writeSize);
WriteCheckBytes(writer, writeSize);
VerifyArrayEquality(valueToTest, writer.GetUnsafePtr(), 0);
var underlyingArray = writer.ToArray();
VerifyCheckBytes(underlyingArray, writeSize);
}
}
protected override unsafe void RunTypeNativeArrayTestSafe<T>(NativeArray<T> valueToTest)
{
var writeSize = FastBufferWriter.GetWriteSize(valueToTest);
var writer = new FastBufferWriter(writeSize + 2, Allocator.Temp);
using (writer)
{
Assert.AreEqual(sizeof(int) + sizeof(T) * valueToTest.Length, writeSize);
RunMethod(nameof(FastBufferWriter.WriteValueSafe), writer, valueToTest);
VerifyPositionAndLength(writer, writeSize);
WriteCheckBytes(writer, writeSize);
VerifyArrayEquality(valueToTest, writer.GetUnsafePtr(), 0);
var underlyingArray = writer.ToArray();
VerifyCheckBytes(underlyingArray, writeSize);
}
}
#if UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
protected override unsafe void RunTypeNativeListTest<T>(NativeList<T> valueToTest)
{
var writeSize = FastBufferWriter.GetWriteSize(valueToTest);
var writer = new FastBufferWriter(writeSize + 2, Allocator.Temp);
using (writer)
{
Assert.AreEqual(sizeof(int) + sizeof(T) * valueToTest.Length, writeSize);
Assert.IsTrue(writer.TryBeginWrite(writeSize + 2), "Writer denied write permission");
RunMethod(nameof(FastBufferWriter.WriteValue), writer, valueToTest);
VerifyPositionAndLength(writer, writeSize);
WriteCheckBytes(writer, writeSize);
VerifyArrayEquality(valueToTest, writer.GetUnsafePtr(), 0);
var underlyingArray = writer.ToArray();
VerifyCheckBytes(underlyingArray, writeSize);
}
}
protected override unsafe void RunTypeNativeListTestSafe<T>(NativeList<T> valueToTest)
{
var writeSize = FastBufferWriter.GetWriteSize(valueToTest);
var writer = new FastBufferWriter(writeSize + 2, Allocator.Temp);
using (writer)
{
Assert.AreEqual(sizeof(int) + sizeof(T) * valueToTest.Length, writeSize);
RunMethod(nameof(FastBufferWriter.WriteValueSafe), writer, valueToTest);
VerifyPositionAndLength(writer, writeSize);
WriteCheckBytes(writer, writeSize);
VerifyArrayEquality(valueToTest, writer.GetUnsafePtr(), 0);
var underlyingArray = writer.ToArray();
VerifyCheckBytes(underlyingArray, writeSize);
}
}
#endif
[Test, Description("Tests")]
public void WhenWritingUnmanagedType_ValueIsWrittenCorrectly(
[Values(typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(uint),
@@ -270,6 +482,36 @@ namespace Unity.Netcode.EditorTests
BaseArrayTypeTest(testType, writeType);
}
[Test]
public void WhenWritingNativeArrayOfUnmanagedElementType_NativeArrayIsWrittenCorrectly(
[Values(typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(uint),
typeof(long), typeof(ulong), typeof(bool), typeof(char), typeof(float), typeof(double),
typeof(ByteEnum), typeof(SByteEnum), typeof(ShortEnum), typeof(UShortEnum), typeof(IntEnum),
typeof(UIntEnum), typeof(LongEnum), typeof(ULongEnum), typeof(Vector2), typeof(Vector3),
typeof(Vector2Int), typeof(Vector3Int), typeof(Vector4), typeof(Quaternion), typeof(Color),
typeof(Color32), typeof(Ray), typeof(Ray2D), typeof(TestStruct))]
Type testType,
[Values] WriteType writeType)
{
BaseNativeArrayTypeTest(testType, writeType);
}
#if UNITY_NETCODE_NATIVE_COLLECTION_SUPPORT
[Test]
public void WhenWritingNativeListOfUnmanagedElementType_NativeListIsWrittenCorrectly(
[Values(typeof(byte), typeof(sbyte), typeof(short), typeof(ushort), typeof(int), typeof(uint),
typeof(long), typeof(ulong), typeof(bool), typeof(char), typeof(float), typeof(double),
typeof(ByteEnum), typeof(SByteEnum), typeof(ShortEnum), typeof(UShortEnum), typeof(IntEnum),
typeof(UIntEnum), typeof(LongEnum), typeof(ULongEnum), typeof(Vector2), typeof(Vector3),
typeof(Vector2Int), typeof(Vector3Int), typeof(Vector4), typeof(Quaternion), typeof(Color),
typeof(Color32), typeof(Ray), typeof(Ray2D), typeof(TestStruct))]
Type testType,
[Values] WriteType writeType)
{
BaseNativeListTypeTest(testType, writeType);
}
#endif
[TestCase(false, WriteType.WriteDirect)]
[TestCase(false, WriteType.WriteSafe)]
[TestCase(true, WriteType.WriteDirect)]