This repository has been archived on 2025-04-22. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
com.unity.netcode.gameobjects/Tests/Editor/Serialization/BaseFastBufferReaderWriterTest.cs
Unity Technologies 0f7a30d285 com.unity.netcode.gameobjects@1.0.0-pre.10
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.0.0-pre.10] - 2022-06-21

### Added

- Added a new `OnTransportFailure` callback to `NetworkManager`. This callback is invoked when the manager's `NetworkTransport` encounters an unrecoverable error. Transport failures also cause the `NetworkManager` to shut down. Currently, this is only used by `UnityTransport` to signal a timeout of its connection to the Unity Relay servers. (#1994)
- Added `NetworkEvent.TransportFailure`, which can be used by implementations of `NetworkTransport` to signal to `NetworkManager` that an unrecoverable error was encountered. (#1994)
- Added test to ensure a warning occurs when nesting NetworkObjects in a NetworkPrefab (#1969)
- Added `NetworkManager.RemoveNetworkPrefab(...)` to remove a prefab from the prefabs list (#1950)

### Changed

- Updated `UnityTransport` dependency on `com.unity.transport` to 1.1.0. (#2025)
- (API Breaking) `ConnectionApprovalCallback` is no longer an `event` and will not allow more than 1 handler registered at a time. Also, `ConnectionApprovalCallback` is now a `Func<>` taking `ConnectionApprovalRequest` in and returning `ConnectionApprovalResponse` back out (#1972)

### Removed

### Fixed
- Fixed issue where dynamically spawned `NetworkObject`s could throw an exception if the scene of origin handle was zero (0) and the `NetworkObject` was already spawned. (#2017)
- Fixed issue where `NetworkObject.Observers` was not being cleared when despawned. (#2009)
- Fixed `NetworkAnimator` could not run in the server authoritative mode. (#2003)
- Fixed issue where late joining clients would get a soft synchronization error if any in-scene placed NetworkObjects were parented under another `NetworkObject`. (#1985)
- Fixed issue where `NetworkBehaviourReference` would throw a type cast exception if using `NetworkBehaviourReference.TryGet` and the component type was not found. (#1984)
- Fixed `NetworkSceneManager` was not sending scene event notifications for the currently active scene and any additively loaded scenes when loading a new scene in `LoadSceneMode.Single` mode. (#1975)
- Fixed issue where one or more clients disconnecting during a scene event would cause `LoadEventCompleted` or `UnloadEventCompleted` to wait until the `NetworkConfig.LoadSceneTimeOut` period before being triggered. (#1973)
- Fixed issues when multiple `ConnectionApprovalCallback`s were registered (#1972)
- Fixed a regression in serialization support: `FixedString`, `Vector2Int`, and `Vector3Int` types can now be used in NetworkVariables and RPCs again without requiring a `ForceNetworkSerializeByMemcpy<>` wrapper. (#1961)
- Fixed generic types that inherit from NetworkBehaviour causing crashes at compile time. (#1976)
- Fixed endless dialog boxes when adding a `NetworkBehaviour` to a `NetworkManager` or vice-versa. (#1947)
- Fixed `NetworkAnimator` issue where it was only synchronizing parameters if the layer or state changed or was transitioning between states. (#1946)
- Fixed `NetworkAnimator` issue where when it did detect a parameter had changed it would send all parameters as opposed to only the parameters that changed. (#1946)
- Fixed `NetworkAnimator` issue where it was not always disposing the `NativeArray` that is allocated when spawned. (#1946)
- Fixed `NetworkAnimator` issue where it was not taking the animation speed or state speed multiplier into consideration. (#1946)
- Fixed `NetworkAnimator` issue where it was not properly synchronizing late joining clients if they joined while `Animator` was transitioning between states. (#1946)
- Fixed `NetworkAnimator` issue where the server was not relaying changes to non-owner clients when a client was the owner. (#1946)
- Fixed issue where the `PacketLoss` metric for tools would return the packet loss over a connection lifetime instead of a single frame. (#2004)
2022-06-21 00:00:00 +00:00

612 lines
23 KiB
C#

using System;
using NUnit.Framework;
using UnityEngine;
using Random = System.Random;
namespace Unity.Netcode.EditorTests
{
public abstract class BaseFastBufferReaderWriterTest
{
#region Test Types
protected enum ByteEnum : byte
{
A,
B,
C
};
protected enum SByteEnum : sbyte
{
A,
B,
C
};
protected enum ShortEnum : short
{
A,
B,
C
};
protected enum UShortEnum : ushort
{
A,
B,
C
};
protected enum IntEnum : int
{
A,
B,
C
};
protected enum UIntEnum : uint
{
A,
B,
C
};
protected enum LongEnum : long
{
A,
B,
C
};
protected enum ULongEnum : ulong
{
A,
B,
C
};
protected struct TestStruct : INetworkSerializeByMemcpy
{
public byte A;
public short B;
public ushort C;
public int D;
public uint E;
public long F;
public ulong G;
public bool H;
public char I;
public float J;
public double K;
}
public enum WriteType
{
WriteDirect,
WriteSafe
}
#endregion
protected abstract void RunTypeTest<T>(T valueToTest) where T : unmanaged;
protected abstract void RunTypeTestSafe<T>(T valueToTest) where T : unmanaged;
protected abstract void RunTypeArrayTest<T>(T[] valueToTest) where T : unmanaged;
protected abstract void RunTypeArrayTestSafe<T>(T[] valueToTest) where T : unmanaged;
#region Helpers
protected TestStruct GetTestStruct()
{
var random = new Random();
var testStruct = new TestStruct
{
A = (byte)random.Next(),
B = (short)random.Next(),
C = (ushort)random.Next(),
D = (int)random.Next(),
E = (uint)random.Next(),
F = ((long)random.Next() << 32) + random.Next(),
G = ((ulong)random.Next() << 32) + (ulong)random.Next(),
H = true,
I = '\u263a',
J = (float)random.NextDouble(),
K = random.NextDouble(),
};
return testStruct;
}
#endregion
private void RunTestWithWriteType<T>(T val, WriteType wt, FastBufferWriter.ForPrimitives _ = default) where T : unmanaged
{
switch (wt)
{
case WriteType.WriteDirect:
RunTypeTest(val);
break;
case WriteType.WriteSafe:
RunTypeTestSafe(val);
break;
}
}
public void BaseTypeTest(Type testType, WriteType writeType)
{
var random = new Random();
if (testType == typeof(byte))
{
RunTestWithWriteType((byte)random.Next(), writeType);
}
else if (testType == typeof(sbyte))
{
RunTestWithWriteType((sbyte)random.Next(), writeType);
}
else if (testType == typeof(short))
{
RunTestWithWriteType((short)random.Next(), writeType);
}
else if (testType == typeof(ushort))
{
RunTestWithWriteType((ushort)random.Next(), writeType);
}
else if (testType == typeof(int))
{
RunTestWithWriteType((int)random.Next(), writeType);
}
else if (testType == typeof(uint))
{
RunTestWithWriteType((uint)random.Next(), writeType);
}
else if (testType == typeof(long))
{
RunTestWithWriteType(((long)random.Next() << 32) + random.Next(), writeType);
}
else if (testType == typeof(ulong))
{
RunTestWithWriteType(((ulong)random.Next() << 32) + (ulong)random.Next(), writeType);
}
else if (testType == typeof(bool))
{
RunTestWithWriteType(true, writeType);
}
else if (testType == typeof(char))
{
RunTestWithWriteType('a', writeType);
RunTestWithWriteType('\u263a', writeType);
}
else if (testType == typeof(float))
{
RunTestWithWriteType((float)random.NextDouble(), writeType);
}
else if (testType == typeof(double))
{
RunTestWithWriteType(random.NextDouble(), writeType);
}
else if (testType == typeof(ByteEnum))
{
RunTestWithWriteType(ByteEnum.C, writeType);
}
else if (testType == typeof(SByteEnum))
{
RunTestWithWriteType(SByteEnum.C, writeType);
}
else if (testType == typeof(ShortEnum))
{
RunTestWithWriteType(ShortEnum.C, writeType);
}
else if (testType == typeof(UShortEnum))
{
RunTestWithWriteType(UShortEnum.C, writeType);
}
else if (testType == typeof(IntEnum))
{
RunTestWithWriteType(IntEnum.C, writeType);
}
else if (testType == typeof(UIntEnum))
{
RunTestWithWriteType(UIntEnum.C, writeType);
}
else if (testType == typeof(LongEnum))
{
RunTestWithWriteType(LongEnum.C, writeType);
}
else if (testType == typeof(ULongEnum))
{
RunTestWithWriteType(ULongEnum.C, writeType);
}
else if (testType == typeof(Vector2))
{
RunTestWithWriteType(new Vector2((float)random.NextDouble(), (float)random.NextDouble()), writeType);
}
else if (testType == typeof(Vector3))
{
RunTestWithWriteType(new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()), writeType);
}
else if (testType == typeof(Vector2Int))
{
RunTestWithWriteType(new Vector2Int((int)random.NextDouble(), (int)random.NextDouble()), writeType);
}
else if (testType == typeof(Vector3Int))
{
RunTestWithWriteType(new Vector3Int((int)random.NextDouble(), (int)random.NextDouble(), (int)random.NextDouble()), writeType);
}
else if (testType == typeof(Vector4))
{
RunTestWithWriteType(new Vector4((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()), writeType);
}
else if (testType == typeof(Quaternion))
{
RunTestWithWriteType(new Quaternion((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()), writeType);
}
else if (testType == typeof(Color))
{
RunTestWithWriteType(new Color((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()), writeType);
}
else if (testType == typeof(Color32))
{
RunTestWithWriteType(new Color32((byte)random.Next(), (byte)random.Next(), (byte)random.Next(), (byte)random.Next()), writeType);
}
else if (testType == typeof(Ray))
{
RunTestWithWriteType(new Ray(
new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble()),
new Vector3((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble())), writeType);
}
else if (testType == typeof(Ray2D))
{
RunTestWithWriteType(new Ray2D(
new Vector2((float)random.NextDouble(), (float)random.NextDouble()),
new Vector2((float)random.NextDouble(), (float)random.NextDouble())), writeType);
}
else if (testType == typeof(TestStruct))
{
RunTestWithWriteType(GetTestStruct(), writeType);
}
else
{
Assert.Fail("No type handler was provided for this type in the test!");
}
}
public void BaseArrayTypeTest(Type testType, WriteType writeType)
{
var random = new Random();
void RunTypeTestLocal<T>(T[] val, WriteType wt) where T : unmanaged
{
switch (wt)
{
case WriteType.WriteDirect:
RunTypeArrayTest(val);
break;
case WriteType.WriteSafe:
RunTypeArrayTestSafe(val);
break;
}
}
if (testType == typeof(byte))
{
RunTypeTestLocal(new[]{
(byte) random.Next(),
(byte) random.Next(),
(byte) random.Next(),
(byte) random.Next(),
(byte) random.Next(),
(byte) random.Next(),
(byte) random.Next()
}, writeType);
}
else if (testType == typeof(sbyte))
{
RunTypeTestLocal(new[]{
(sbyte) random.Next(),
(sbyte) random.Next(),
(sbyte) random.Next(),
(sbyte) random.Next(),
(sbyte) random.Next(),
(sbyte) random.Next(),
(sbyte) random.Next()
}, writeType);
}
else if (testType == typeof(short))
{
RunTypeTestLocal(new[]{
(short) random.Next(),
(short) random.Next(),
(short) random.Next(),
(short) random.Next(),
(short) random.Next()
}, writeType);
}
else if (testType == typeof(ushort))
{
RunTypeTestLocal(new[]{
(ushort) random.Next(),
(ushort) random.Next(),
(ushort) random.Next(),
(ushort) random.Next(),
(ushort) random.Next(),
(ushort) random.Next()
}, writeType);
}
else if (testType == typeof(int))
{
RunTypeTestLocal(new[]{
random.Next(),
random.Next(),
random.Next(),
random.Next(),
random.Next(),
random.Next(),
random.Next(),
random.Next()
}, writeType);
}
else if (testType == typeof(uint))
{
RunTypeTestLocal(new[]{
(uint) random.Next(),
(uint) random.Next(),
(uint) random.Next(),
(uint) random.Next(),
(uint) random.Next(),
(uint) random.Next()
}, writeType);
}
else if (testType == typeof(long))
{
RunTypeTestLocal(new[]{
((long)random.Next() << 32) + (long)random.Next(),
((long)random.Next() << 32) + (long)random.Next(),
((long)random.Next() << 32) + (long)random.Next(),
((long)random.Next() << 32) + (long)random.Next()
}, writeType);
}
else if (testType == typeof(ulong))
{
RunTypeTestLocal(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()
}, writeType);
}
else if (testType == typeof(bool))
{
RunTypeTestLocal(new[]{
true,
false,
true,
true,
false,
false,
true,
false,
true
}, writeType);
}
else if (testType == typeof(char))
{
RunTypeTestLocal(new[]{
'a',
'\u263a'
}, writeType);
}
else if (testType == typeof(float))
{
RunTypeTestLocal(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()
}, writeType);
}
else if (testType == typeof(double))
{
RunTypeTestLocal(new[]{
random.NextDouble(),
random.NextDouble(),
random.NextDouble(),
random.NextDouble(),
random.NextDouble(),
random.NextDouble(),
random.NextDouble(),
random.NextDouble(),
random.NextDouble()
}, writeType);
}
else if (testType == typeof(ByteEnum))
{
RunTypeTestLocal(new[]{
ByteEnum.C,
ByteEnum.A,
ByteEnum.B
}, writeType);
}
else if (testType == typeof(SByteEnum))
{
RunTypeTestLocal(new[]{
SByteEnum.C,
SByteEnum.A,
SByteEnum.B
}, writeType);
}
else if (testType == typeof(ShortEnum))
{
RunTypeTestLocal(new[]{
ShortEnum.C,
ShortEnum.A,
ShortEnum.B
}, writeType);
}
else if (testType == typeof(UShortEnum))
{
RunTypeTestLocal(new[]{
UShortEnum.C,
UShortEnum.A,
UShortEnum.B
}, writeType);
}
else if (testType == typeof(IntEnum))
{
RunTypeTestLocal(new[]{
IntEnum.C,
IntEnum.A,
IntEnum.B
}, writeType);
}
else if (testType == typeof(UIntEnum))
{
RunTypeTestLocal(new[]{
UIntEnum.C,
UIntEnum.A,
UIntEnum.B
}, writeType);
}
else if (testType == typeof(LongEnum))
{
RunTypeTestLocal(new[]{
LongEnum.C,
LongEnum.A,
LongEnum.B
}, writeType);
}
else if (testType == typeof(ULongEnum))
{
RunTypeTestLocal(new[]{
ULongEnum.C,
ULongEnum.A,
ULongEnum.B
}, writeType);
}
else if (testType == typeof(Vector2))
{
RunTypeTestLocal(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()),
}, writeType);
}
else if (testType == typeof(Vector3))
{
RunTypeTestLocal(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()),
}, writeType);
}
else if (testType == typeof(Vector2Int))
{
RunTypeTestLocal(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()),
}, writeType);
}
else if (testType == typeof(Vector3Int))
{
RunTypeTestLocal(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()),
}, writeType);
}
else if (testType == typeof(Vector4))
{
RunTypeTestLocal(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()),
}, writeType);
}
else if (testType == typeof(Quaternion))
{
RunTypeTestLocal(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()),
}, writeType);
}
else if (testType == typeof(Color))
{
RunTypeTestLocal(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()),
}, writeType);
}
else if (testType == typeof(Color32))
{
RunTypeTestLocal(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()),
}, writeType);
}
else if (testType == typeof(Ray))
{
RunTypeTestLocal(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())),
}, writeType);
}
else if (testType == typeof(Ray2D))
{
RunTypeTestLocal(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())),
}, writeType);
}
else if (testType == typeof(TestStruct))
{
RunTypeTestLocal(new[] {
GetTestStruct(),
GetTestStruct(),
GetTestStruct(),
}, writeType);
}
else
{
Assert.Fail("No type handler was provided for this type in the test!");
}
}
}
}