From bcbcd695e1a9ac4ce27926c86ec45abab2527f25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?JasonXuDeveloper=20-=20=E5=82=91?= Date: Wed, 3 Jul 2024 19:07:55 +1000 Subject: [PATCH] nino v2.0.1 unity --- Nino.unitypackage | Bin 0 -> 111733 bytes .../Assets/Nino/Editor/SerializationHelper.cs | 43 - ...ino_Test_BuildTestDataCodeGen_Serialize.cs | 94 -- .../Nino_Test_CollectionTest_Serialize.cs | 65 -- .../Nino_Test_ComplexData_Serialize.cs | 80 -- .../Nino_Test_CustomTypeTest_Serialize.cs | 69 -- .../Generated/Nino_Test_Data_Serialize.cs | 53 - ...o_Test_IncludeAllClassCodeGen_Serialize.cs | 56 - .../Nino_Test_NestedData2_Serialize.cs | 59 -- .../Nino_Test_NestedData_Serialize.cs | 56 - .../Nino_Test_NotIncludeAllClass_Serialize.cs | 56 - .../Attributes/CodeGenIgnoreAttribute.cs | 9 - .../Attributes/NinoIgnoreAttribute.cs | 9 - .../Attributes/NinoMemberAttribute.cs | 20 - .../Attributes/NinoSerializeAttribute.cs | 20 - .../Nino/Serialization/CodeGenerator.cs | 696 ------------- .../Serialization/Deserializer.Generic.cs | 335 ------ .../Assets/Nino/Serialization/Deserializer.cs | 565 ---------- .../Serialization/Enums/CompressOption.cs | 27 - .../Serialization/Interfaces/INinoWrapper.cs | 16 - .../Serialization/Nino.Serialization.asmdef | 16 - .../Nino/Serialization/Reader.Generic.cs | 469 --------- .../Assets/Nino/Serialization/Reader.cs | 443 -------- .../Nino/Serialization/Serializer.Generic.cs | 418 -------- .../Nino/Serialization/Serializer.Helper.cs | 437 -------- .../Assets/Nino/Serialization/Serializer.cs | 196 ---- .../Assets/Nino/Serialization/TypeModel.cs | 348 ------- .../Wrappers/Common/NinoWrapperBase.cs | 32 - .../Wrappers/Primitives/Basics.cs | 395 ------- .../Wrappers/Primitives/Decimals.cs | 289 ------ .../Wrappers/Primitives/Integers.cs | 707 ------------- .../Serialization/Wrappers/WrapperManifest.cs | 68 -- .../Nino/Serialization/Writer.Generic.cs | 537 ---------- .../Assets/Nino/Serialization/Writer.cs | 338 ------ .../MonoPInvokeCallbackAttribute.cs | 11 - .../Shared/Collections/FunctorComparer.cs | 17 - .../Nino/Shared/Collections/UncheckedList.cs | 978 ------------------ .../Nino/Shared/Collections/UncheckedStack.cs | 261 ----- .../Nino/Shared/IO/Buffer/ExtensibleBuffer.cs | 208 ---- .../IO/Buffer/ExtensibleBufferExtensions.cs | 66 -- .../Assets/Nino/Shared/IO/Pool/ArrayPool.cs | 90 -- .../Assets/Nino/Shared/IO/Pool/BufferPool.cs | 83 -- .../Assets/Nino/Shared/IO/Pool/ObjectPool.cs | 73 -- .../Nino/Shared/IO/Stream/DeflateStream.cs | 608 ----------- .../Nino/Shared/IO/Stream/FlexibleStream.cs | 533 ---------- .../Assets/Nino/Shared/Mgr/CompressMgr.cs | 352 ------- Nino_Unity/Assets/Nino/Shared/Mgr/ConstMgr.cs | 85 -- .../Assets/Nino/Shared/Mgr/StringMgr.cs | 72 -- .../Assets/Nino/Shared/Nino.Shared.asmdef | 13 - .../Shared/ThirdParty/System.IO.Pipelines.dll | Bin 83048 -> 0 bytes .../ThirdParty/System.Numerics.Vectors.dll | Bin 115856 -> 0 bytes .../Shared/ThirdParty/System.Numerics.dll | Bin 138656 -> 0 bytes .../System.Threading.Tasks.Extensions.dll | Bin 33048 -> 0 bytes Nino_Unity/Assets/Nino/Shared/Util/Hash.cs | 37 - Nino_Unity/Assets/Nino/Shared/Util/PowOf2.cs | 69 -- .../Nino/Test/Editor/Serialization/Test5.cs | 248 ----- .../Nino/Test/Editor/Serialization/Test9.cs | 59 -- .../Assets/{Nino => }/Test/BuildTest.cs | 236 +---- .../Assets/{Nino => }/Test/BuildTest2.cs | 36 +- Nino_Unity/Assets/{Nino => }/Test/Data.cs | 166 +-- .../Shared/Util => Test/Editor}/Logger.cs | 3 +- .../Test/Editor/Serialization/Test1.cs | 29 +- .../Test/Editor/Serialization/Test10.cs | 7 +- .../Test/Editor/Serialization/Test2.cs | 29 +- .../Test/Editor/Serialization/Test3.cs | 13 +- .../Test/Editor/Serialization/Test4.cs | 9 +- .../Assets/Test/Editor/Serialization/Test5.cs | 171 +++ .../Test/Editor/Serialization/Test6.cs | 73 +- .../Test/Editor/Serialization/Test7.cs | 48 +- .../Test/Editor/Serialization/Test8.cs | 37 +- .../Assets/Test/Editor/Serialization/Test9.cs | 81 ++ .../Assets/Test/Editor/Test.Editor.asmdef | 16 + .../{Nino => }/Test/MessagePackGenerated.cs | 146 +-- Nino_Unity/Assets/Test/Nino/Nino.Core.dll | Bin 0 -> 10752 bytes .../Assets/Test/Nino/Nino.Generator.dll | Bin 0 -> 55808 bytes .../Nino}/ThirdParty/System.Buffers.dll | Bin .../Nino}/ThirdParty/System.Memory.dll | Bin ...System.Runtime.CompilerServices.Unsafe.dll | Bin .../Nino.Editor.asmdef => Test/Test.asmdef} | 13 +- .../BurstAotSettings_Android.json | 17 + .../CommonBurstAotSettings.json | 6 + .../ProjectSettings/MemorySettings.asset | 35 + .../ProjectSettings/ProjectSettings.asset | 193 +++- Nino_Unity/ProjectSettings/ProjectVersion.txt | 4 +- 84 files changed, 631 insertions(+), 11621 deletions(-) create mode 100644 Nino.unitypackage delete mode 100644 Nino_Unity/Assets/Nino/Editor/SerializationHelper.cs delete mode 100644 Nino_Unity/Assets/Nino/Generated/Nino_Test_BuildTestDataCodeGen_Serialize.cs delete mode 100644 Nino_Unity/Assets/Nino/Generated/Nino_Test_CollectionTest_Serialize.cs delete mode 100644 Nino_Unity/Assets/Nino/Generated/Nino_Test_ComplexData_Serialize.cs delete mode 100644 Nino_Unity/Assets/Nino/Generated/Nino_Test_CustomTypeTest_Serialize.cs delete mode 100644 Nino_Unity/Assets/Nino/Generated/Nino_Test_Data_Serialize.cs delete mode 100644 Nino_Unity/Assets/Nino/Generated/Nino_Test_IncludeAllClassCodeGen_Serialize.cs delete mode 100644 Nino_Unity/Assets/Nino/Generated/Nino_Test_NestedData2_Serialize.cs delete mode 100644 Nino_Unity/Assets/Nino/Generated/Nino_Test_NestedData_Serialize.cs delete mode 100644 Nino_Unity/Assets/Nino/Generated/Nino_Test_NotIncludeAllClass_Serialize.cs delete mode 100644 Nino_Unity/Assets/Nino/Serialization/Attributes/CodeGenIgnoreAttribute.cs delete mode 100644 Nino_Unity/Assets/Nino/Serialization/Attributes/NinoIgnoreAttribute.cs delete mode 100644 Nino_Unity/Assets/Nino/Serialization/Attributes/NinoMemberAttribute.cs delete mode 100644 Nino_Unity/Assets/Nino/Serialization/Attributes/NinoSerializeAttribute.cs delete mode 100644 Nino_Unity/Assets/Nino/Serialization/CodeGenerator.cs delete mode 100644 Nino_Unity/Assets/Nino/Serialization/Deserializer.Generic.cs delete mode 100644 Nino_Unity/Assets/Nino/Serialization/Deserializer.cs delete mode 100644 Nino_Unity/Assets/Nino/Serialization/Enums/CompressOption.cs delete mode 100644 Nino_Unity/Assets/Nino/Serialization/Interfaces/INinoWrapper.cs delete mode 100644 Nino_Unity/Assets/Nino/Serialization/Nino.Serialization.asmdef delete mode 100644 Nino_Unity/Assets/Nino/Serialization/Reader.Generic.cs delete mode 100644 Nino_Unity/Assets/Nino/Serialization/Reader.cs delete mode 100644 Nino_Unity/Assets/Nino/Serialization/Serializer.Generic.cs delete mode 100644 Nino_Unity/Assets/Nino/Serialization/Serializer.Helper.cs delete mode 100644 Nino_Unity/Assets/Nino/Serialization/Serializer.cs delete mode 100644 Nino_Unity/Assets/Nino/Serialization/TypeModel.cs delete mode 100644 Nino_Unity/Assets/Nino/Serialization/Wrappers/Common/NinoWrapperBase.cs delete mode 100644 Nino_Unity/Assets/Nino/Serialization/Wrappers/Primitives/Basics.cs delete mode 100644 Nino_Unity/Assets/Nino/Serialization/Wrappers/Primitives/Decimals.cs delete mode 100644 Nino_Unity/Assets/Nino/Serialization/Wrappers/Primitives/Integers.cs delete mode 100644 Nino_Unity/Assets/Nino/Serialization/Wrappers/WrapperManifest.cs delete mode 100644 Nino_Unity/Assets/Nino/Serialization/Writer.Generic.cs delete mode 100644 Nino_Unity/Assets/Nino/Serialization/Writer.cs delete mode 100644 Nino_Unity/Assets/Nino/Shared/Attributes/MonoPInvokeCallbackAttribute.cs delete mode 100644 Nino_Unity/Assets/Nino/Shared/Collections/FunctorComparer.cs delete mode 100644 Nino_Unity/Assets/Nino/Shared/Collections/UncheckedList.cs delete mode 100644 Nino_Unity/Assets/Nino/Shared/Collections/UncheckedStack.cs delete mode 100644 Nino_Unity/Assets/Nino/Shared/IO/Buffer/ExtensibleBuffer.cs delete mode 100644 Nino_Unity/Assets/Nino/Shared/IO/Buffer/ExtensibleBufferExtensions.cs delete mode 100644 Nino_Unity/Assets/Nino/Shared/IO/Pool/ArrayPool.cs delete mode 100644 Nino_Unity/Assets/Nino/Shared/IO/Pool/BufferPool.cs delete mode 100644 Nino_Unity/Assets/Nino/Shared/IO/Pool/ObjectPool.cs delete mode 100644 Nino_Unity/Assets/Nino/Shared/IO/Stream/DeflateStream.cs delete mode 100644 Nino_Unity/Assets/Nino/Shared/IO/Stream/FlexibleStream.cs delete mode 100644 Nino_Unity/Assets/Nino/Shared/Mgr/CompressMgr.cs delete mode 100644 Nino_Unity/Assets/Nino/Shared/Mgr/ConstMgr.cs delete mode 100644 Nino_Unity/Assets/Nino/Shared/Mgr/StringMgr.cs delete mode 100644 Nino_Unity/Assets/Nino/Shared/Nino.Shared.asmdef delete mode 100755 Nino_Unity/Assets/Nino/Shared/ThirdParty/System.IO.Pipelines.dll delete mode 100755 Nino_Unity/Assets/Nino/Shared/ThirdParty/System.Numerics.Vectors.dll delete mode 100644 Nino_Unity/Assets/Nino/Shared/ThirdParty/System.Numerics.dll delete mode 100755 Nino_Unity/Assets/Nino/Shared/ThirdParty/System.Threading.Tasks.Extensions.dll delete mode 100644 Nino_Unity/Assets/Nino/Shared/Util/Hash.cs delete mode 100644 Nino_Unity/Assets/Nino/Shared/Util/PowOf2.cs delete mode 100644 Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test5.cs delete mode 100644 Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test9.cs rename Nino_Unity/Assets/{Nino => }/Test/BuildTest.cs (56%) rename Nino_Unity/Assets/{Nino => }/Test/BuildTest2.cs (92%) rename Nino_Unity/Assets/{Nino => }/Test/Data.cs (66%) rename Nino_Unity/Assets/{Nino/Shared/Util => Test/Editor}/Logger.cs (98%) rename Nino_Unity/Assets/{Nino => }/Test/Editor/Serialization/Test1.cs (81%) rename Nino_Unity/Assets/{Nino => }/Test/Editor/Serialization/Test10.cs (98%) rename Nino_Unity/Assets/{Nino => }/Test/Editor/Serialization/Test2.cs (82%) rename Nino_Unity/Assets/{Nino => }/Test/Editor/Serialization/Test3.cs (91%) rename Nino_Unity/Assets/{Nino => }/Test/Editor/Serialization/Test4.cs (95%) create mode 100644 Nino_Unity/Assets/Test/Editor/Serialization/Test5.cs rename Nino_Unity/Assets/{Nino => }/Test/Editor/Serialization/Test6.cs (64%) rename Nino_Unity/Assets/{Nino => }/Test/Editor/Serialization/Test7.cs (50%) rename Nino_Unity/Assets/{Nino => }/Test/Editor/Serialization/Test8.cs (63%) create mode 100644 Nino_Unity/Assets/Test/Editor/Serialization/Test9.cs create mode 100644 Nino_Unity/Assets/Test/Editor/Test.Editor.asmdef rename Nino_Unity/Assets/{Nino => }/Test/MessagePackGenerated.cs (74%) create mode 100644 Nino_Unity/Assets/Test/Nino/Nino.Core.dll create mode 100644 Nino_Unity/Assets/Test/Nino/Nino.Generator.dll rename Nino_Unity/Assets/{Nino/Shared => Test/Nino}/ThirdParty/System.Buffers.dll (100%) rename Nino_Unity/Assets/{Nino/Shared => Test/Nino}/ThirdParty/System.Memory.dll (100%) rename Nino_Unity/Assets/{Nino/Shared => Test/Nino}/ThirdParty/System.Runtime.CompilerServices.Unsafe.dll (100%) rename Nino_Unity/Assets/{Nino/Editor/Nino.Editor.asmdef => Test/Test.asmdef} (59%) create mode 100644 Nino_Unity/ProjectSettings/BurstAotSettings_Android.json create mode 100644 Nino_Unity/ProjectSettings/CommonBurstAotSettings.json create mode 100644 Nino_Unity/ProjectSettings/MemorySettings.asset diff --git a/Nino.unitypackage b/Nino.unitypackage new file mode 100644 index 0000000000000000000000000000000000000000..9875b7fe69c31d42f79ef521e72bc03e11f09a55 GIT binary patch literal 111733 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

Nnxw-cCw@F88zmA{R=hn8h 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%0AO_Tw%0a=jC54RN1Teg-Ta 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 literal 0 HcmV?d00001 diff --git a/Nino_Unity/Assets/Nino/Editor/SerializationHelper.cs b/Nino_Unity/Assets/Nino/Editor/SerializationHelper.cs deleted file mode 100644 index 84d97e5..0000000 --- a/Nino_Unity/Assets/Nino/Editor/SerializationHelper.cs +++ /dev/null @@ -1,43 +0,0 @@ -#if UNITY_2017_1_OR_NEWER -using System.IO; -using System.Linq; -using UnityEditor; -using System.Reflection; -using Nino.Serialization; - -namespace Nino.Editor -{ - public static class SerializationHelper - { - ///

- /// External DLL, such as ILRuntime/huatuo hot update dll - /// 外部dll,例如ILRuntime和huatuo的热更dll - /// - private static readonly string[] ExternalDLLPath = new string[] - { -#if ILRuntime - "Assets/Nino/Test/Editor/Serialization/Test11.bytes" -#endif - }; - - /// - /// Export path, you can change this to export it anywhere under Assets directory - /// If you want to export outside of Assets, you can use ../ - /// 导出目录,你可以修改这个路径,代码会生成到Assets目录下你指定的这个路径内 - /// 如果需要导出到Assets外部,可以在路径内写入../ - /// - private const string ExportPath = "Nino/Generated"; - - [MenuItem("Nino/Generator/Serialization Code")] - public static void GenerateSerializationCode() - { - var assemblies = System.AppDomain.CurrentDomain.GetAssemblies().ToList(); - assemblies.AddRange(ExternalDLLPath.Select(s => Assembly.Load(File.ReadAllBytes(s)))); - // ReSharper disable RedundantArgumentDefaultValue - CodeGenerator.GenerateSerializationCodeForAllTypePossible(ExportPath, assemblies.ToArray()); - AssetDatabase.Refresh(); - // ReSharper restore RedundantArgumentDefaultValue - } - } -} -#endif \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Generated/Nino_Test_BuildTestDataCodeGen_Serialize.cs b/Nino_Unity/Assets/Nino/Generated/Nino_Test_BuildTestDataCodeGen_Serialize.cs deleted file mode 100644 index e7acec1..0000000 --- a/Nino_Unity/Assets/Nino/Generated/Nino_Test_BuildTestDataCodeGen_Serialize.cs +++ /dev/null @@ -1,94 +0,0 @@ -/* this is generated by nino */ -using System.Runtime.CompilerServices; - -namespace Nino.Test -{ - public partial class BuildTestDataCodeGen - { - public static BuildTestDataCodeGen.SerializationHelper NinoSerializationHelper = new BuildTestDataCodeGen.SerializationHelper(); - public unsafe class SerializationHelper: Nino.Serialization.NinoWrapperBase - { - #region NINO_CODEGEN - public SerializationHelper() - { - - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override void Serialize(BuildTestDataCodeGen value, ref Nino.Serialization.Writer writer) - { - if(value == null) - { - writer.Write(false); - return; - } - writer.Write(true); - writer.Write(ref value.a, sizeof(System.Byte),ref value.b, sizeof(System.SByte),ref value.c, sizeof(System.Int16),ref value.d, sizeof(System.UInt16),ref value.e, sizeof(System.Int32),ref value.f, sizeof(System.UInt32),ref value.g, sizeof(System.Int64),ref value.h, sizeof(System.UInt64)); - writer.Write(ref value.i, sizeof(System.Single),ref value.j, sizeof(System.Double),ref value.k, sizeof(System.Decimal),ref value.l, sizeof(System.Boolean),ref value.m, sizeof(System.Char)); - writer.Write(value.n); - writer.Write(value.o); - writer.Write(value.p); - writer.Write(value.q); - writer.Write(value.r); - writer.Write(value.s); - writer.Write(value.t); - writer.Write(value.u); - writer.Write(value.v); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override BuildTestDataCodeGen Deserialize(Nino.Serialization.Reader reader) - { - if(!reader.ReadBool()) - return null; - BuildTestDataCodeGen value = new BuildTestDataCodeGen(); - reader.Read(ref value.a, sizeof(System.Byte),ref value.b, sizeof(System.SByte),ref value.c, sizeof(System.Int16),ref value.d, sizeof(System.UInt16),ref value.e, sizeof(System.Int32),ref value.f, sizeof(System.UInt32),ref value.g, sizeof(System.Int64),ref value.h, sizeof(System.UInt64)); - reader.Read(ref value.i, sizeof(System.Single),ref value.j, sizeof(System.Double),ref value.k, sizeof(System.Decimal),ref value.l, sizeof(System.Boolean),ref value.m, sizeof(System.Char)); - value.n = reader.ReadString(); - value.o = reader.ReadList(); - value.p = reader.ReadList(); - value.q = reader.ReadArray(); - value.r = reader.ReadArray(); - value.s = reader.ReadDictionary(); - value.t = reader.ReadDictionary(); - value.u = reader.ReadDictionary(); - value.v = reader.ReadDictionary(); - return value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetSize(BuildTestDataCodeGen value) - { - if(value == null) - { - return 1; - } - int ret = 1; - ret += Nino.Serialization.Serializer.GetSize(value.a); - ret += Nino.Serialization.Serializer.GetSize(value.b); - ret += Nino.Serialization.Serializer.GetSize(value.c); - ret += Nino.Serialization.Serializer.GetSize(value.d); - ret += Nino.Serialization.Serializer.GetSize(value.e); - ret += Nino.Serialization.Serializer.GetSize(value.f); - ret += Nino.Serialization.Serializer.GetSize(value.g); - ret += Nino.Serialization.Serializer.GetSize(value.h); - ret += Nino.Serialization.Serializer.GetSize(value.i); - ret += Nino.Serialization.Serializer.GetSize(value.j); - ret += Nino.Serialization.Serializer.GetSize(value.k); - ret += Nino.Serialization.Serializer.GetSize(value.l); - ret += Nino.Serialization.Serializer.GetSize(value.m); - ret += Nino.Serialization.Serializer.GetSize(value.n); - ret += Nino.Serialization.Serializer.GetSize(value.o); - ret += Nino.Serialization.Serializer.GetSize(value.p); - ret += Nino.Serialization.Serializer.GetSize(value.q); - ret += Nino.Serialization.Serializer.GetSize(value.r); - ret += Nino.Serialization.Serializer.GetSize(value.s); - ret += Nino.Serialization.Serializer.GetSize(value.t); - ret += Nino.Serialization.Serializer.GetSize(value.u); - ret += Nino.Serialization.Serializer.GetSize(value.v); - return ret; - } - #endregion - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Generated/Nino_Test_CollectionTest_Serialize.cs b/Nino_Unity/Assets/Nino/Generated/Nino_Test_CollectionTest_Serialize.cs deleted file mode 100644 index 960f649..0000000 --- a/Nino_Unity/Assets/Nino/Generated/Nino_Test_CollectionTest_Serialize.cs +++ /dev/null @@ -1,65 +0,0 @@ -/* this is generated by nino */ -using System.Runtime.CompilerServices; - -namespace Nino.Test -{ - public partial class CollectionTest - { - public static CollectionTest.SerializationHelper NinoSerializationHelper = new CollectionTest.SerializationHelper(); - public unsafe class SerializationHelper: Nino.Serialization.NinoWrapperBase - { - #region NINO_CODEGEN - public SerializationHelper() - { - - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override void Serialize(CollectionTest value, ref Nino.Serialization.Writer writer) - { - if(value == null) - { - writer.Write(false); - return; - } - writer.Write(true); - writer.Write(value.a); - writer.Write(value.b); - writer.Write(value.c); - writer.Write(value.d); - writer.Write(value.e); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override CollectionTest Deserialize(Nino.Serialization.Reader reader) - { - if(!reader.ReadBool()) - return null; - CollectionTest value = new CollectionTest(); - value.a = reader.ReadList(); - value.b = reader.ReadList(); - value.c = reader.ReadDictionary(); - value.d = reader.ReadDictionary(); - value.e = reader.ReadDictionary(); - return value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetSize(CollectionTest value) - { - if(value == null) - { - return 1; - } - int ret = 1; - ret += Nino.Serialization.Serializer.GetSize(value.a); - ret += Nino.Serialization.Serializer.GetSize(value.b); - ret += Nino.Serialization.Serializer.GetSize(value.c); - ret += Nino.Serialization.Serializer.GetSize(value.d); - ret += Nino.Serialization.Serializer.GetSize(value.e); - return ret; - } - #endregion - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Generated/Nino_Test_ComplexData_Serialize.cs b/Nino_Unity/Assets/Nino/Generated/Nino_Test_ComplexData_Serialize.cs deleted file mode 100644 index 83ed16f..0000000 --- a/Nino_Unity/Assets/Nino/Generated/Nino_Test_ComplexData_Serialize.cs +++ /dev/null @@ -1,80 +0,0 @@ -/* this is generated by nino */ -using System.Runtime.CompilerServices; - -namespace Nino.Test -{ - public partial class ComplexData - { - public static ComplexData.SerializationHelper NinoSerializationHelper = new ComplexData.SerializationHelper(); - public unsafe class SerializationHelper: Nino.Serialization.NinoWrapperBase - { - #region NINO_CODEGEN - public SerializationHelper() - { - - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override void Serialize(ComplexData value, ref Nino.Serialization.Writer writer) - { - if(value == null) - { - writer.Write(false); - return; - } - writer.Write(true); - writer.Write(value.a); - writer.Write(value.b); - writer.Write(value.c); - writer.Write(value.d); - writer.Write(value.e); - writer.Write(value.f); - writer.Write(value.g); - writer.Write(value.h); - writer.Write(value.i); - writer.Write(value.j); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override ComplexData Deserialize(Nino.Serialization.Reader reader) - { - if(!reader.ReadBool()) - return null; - ComplexData value = new ComplexData(); - value.a = reader.ReadArray(); - value.b = reader.ReadList(); - value.c = reader.ReadArray>(); - value.d = reader.ReadDictionary>(); - value.e = reader.ReadArray>>(); - value.f = reader.ReadArray(); - value.g = reader.ReadList(); - value.h = reader.ReadArray(); - value.i = reader.ReadArray>(); - value.j = reader.ReadArray>(); - return value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetSize(ComplexData value) - { - if(value == null) - { - return 1; - } - int ret = 1; - ret += Nino.Serialization.Serializer.GetSize(value.a); - ret += Nino.Serialization.Serializer.GetSize(value.b); - ret += Nino.Serialization.Serializer.GetSize(value.c); - ret += Nino.Serialization.Serializer.GetSize(value.d); - ret += Nino.Serialization.Serializer.GetSize(value.e); - ret += Nino.Serialization.Serializer.GetSize(value.f); - ret += Nino.Serialization.Serializer.GetSize(value.g); - ret += Nino.Serialization.Serializer.GetSize(value.h); - ret += Nino.Serialization.Serializer.GetSize(value.i); - ret += Nino.Serialization.Serializer.GetSize(value.j); - return ret; - } - #endregion - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Generated/Nino_Test_CustomTypeTest_Serialize.cs b/Nino_Unity/Assets/Nino/Generated/Nino_Test_CustomTypeTest_Serialize.cs deleted file mode 100644 index 861a096..0000000 --- a/Nino_Unity/Assets/Nino/Generated/Nino_Test_CustomTypeTest_Serialize.cs +++ /dev/null @@ -1,69 +0,0 @@ -/* this is generated by nino */ -using System.Runtime.CompilerServices; - -namespace Nino.Test -{ - public partial class CustomTypeTest - { - public static CustomTypeTest.SerializationHelper NinoSerializationHelper = new CustomTypeTest.SerializationHelper(); - public unsafe class SerializationHelper: Nino.Serialization.NinoWrapperBase - { - #region NINO_CODEGEN - public SerializationHelper() - { - - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override void Serialize(CustomTypeTest value, ref Nino.Serialization.Writer writer) - { - if(value == null) - { - writer.Write(false); - return; - } - writer.Write(true); - writer.Write(ref value.v3, sizeof(UnityEngine.Vector3),ref value.dt, sizeof(System.DateTime)); - writer.Write(value.ni); - writer.Write(value.qs); - writer.Write(ref value.m, sizeof(UnityEngine.Matrix4x4)); - writer.Write(value.dict); - writer.Write(value.dict2); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override CustomTypeTest Deserialize(Nino.Serialization.Reader reader) - { - if(!reader.ReadBool()) - return null; - CustomTypeTest value = new CustomTypeTest(); - reader.Read(ref value.v3, sizeof(UnityEngine.Vector3),ref value.dt, sizeof(System.DateTime)); - value.ni = reader.ReadNullable(); - value.qs = reader.ReadList(); - reader.Read(ref value.m, sizeof(UnityEngine.Matrix4x4)); - value.dict = reader.ReadDictionary(); - value.dict2 = reader.ReadDictionary(); - return value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetSize(CustomTypeTest value) - { - if(value == null) - { - return 1; - } - int ret = 1; - ret += Nino.Serialization.Serializer.GetSize(value.v3); - ret += Nino.Serialization.Serializer.GetSize(value.dt); - ret += Nino.Serialization.Serializer.GetSize(value.ni); - ret += Nino.Serialization.Serializer.GetSize(value.qs); - ret += Nino.Serialization.Serializer.GetSize(value.m); - ret += Nino.Serialization.Serializer.GetSize(value.dict); - ret += Nino.Serialization.Serializer.GetSize(value.dict2); - return ret; - } - #endregion - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Generated/Nino_Test_Data_Serialize.cs b/Nino_Unity/Assets/Nino/Generated/Nino_Test_Data_Serialize.cs deleted file mode 100644 index 082a81a..0000000 --- a/Nino_Unity/Assets/Nino/Generated/Nino_Test_Data_Serialize.cs +++ /dev/null @@ -1,53 +0,0 @@ -/* this is generated by nino */ -using System.Runtime.CompilerServices; - -namespace Nino.Test -{ - public partial struct Data - { - public static Data.SerializationHelper NinoSerializationHelper = new Data.SerializationHelper(); - public unsafe class SerializationHelper: Nino.Serialization.NinoWrapperBase - { - #region NINO_CODEGEN - public SerializationHelper() - { - int ret = 1; - ret += sizeof(System.Int32); - ret += sizeof(System.Int16); - ret += sizeof(System.Int64); - ret += sizeof(System.Single); - ret += sizeof(System.Decimal); - ret += sizeof(System.Double); - ret += sizeof(System.Boolean); - ret += sizeof(Nino.Test.TestEnum); - Nino.Serialization.Serializer.SetFixedSize(ret); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override void Serialize(Data value, ref Nino.Serialization.Writer writer) - { - - writer.Write(true); - writer.Write(ref value.x, sizeof(System.Int32),ref value.y, sizeof(System.Int16),ref value.z, sizeof(System.Int64),ref value.f, sizeof(System.Single),ref value.d, sizeof(System.Decimal),ref value.db, sizeof(System.Double),ref value.bo, sizeof(System.Boolean),ref value.en, sizeof(Nino.Test.TestEnum)); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override Data Deserialize(Nino.Serialization.Reader reader) - { - if(!reader.ReadBool()) - return default; - Data value = new Data(); - reader.Read(ref value.x, sizeof(System.Int32),ref value.y, sizeof(System.Int16),ref value.z, sizeof(System.Int64),ref value.f, sizeof(System.Single),ref value.d, sizeof(System.Decimal),ref value.db, sizeof(System.Double),ref value.bo, sizeof(System.Boolean),ref value.en, sizeof(Nino.Test.TestEnum)); - return value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetSize(Data value) - { - - return Nino.Serialization.Serializer.GetFixedSize(); - } - #endregion - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Generated/Nino_Test_IncludeAllClassCodeGen_Serialize.cs b/Nino_Unity/Assets/Nino/Generated/Nino_Test_IncludeAllClassCodeGen_Serialize.cs deleted file mode 100644 index a35fa86..0000000 --- a/Nino_Unity/Assets/Nino/Generated/Nino_Test_IncludeAllClassCodeGen_Serialize.cs +++ /dev/null @@ -1,56 +0,0 @@ -/* this is generated by nino */ -using System.Runtime.CompilerServices; - -namespace Nino.Test -{ - public partial class IncludeAllClassCodeGen - { - public static IncludeAllClassCodeGen.SerializationHelper NinoSerializationHelper = new IncludeAllClassCodeGen.SerializationHelper(); - public unsafe class SerializationHelper: Nino.Serialization.NinoWrapperBase - { - #region NINO_CODEGEN - public SerializationHelper() - { - int ret = 1; - ret += sizeof(System.Int32); - ret += sizeof(System.Int64); - ret += sizeof(System.Single); - ret += sizeof(System.Double); - Nino.Serialization.Serializer.SetFixedSize(ret); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override void Serialize(IncludeAllClassCodeGen value, ref Nino.Serialization.Writer writer) - { - if(value == null) - { - writer.Write(false); - return; - } - writer.Write(true); - writer.Write(ref value.a, sizeof(System.Int32),ref value.b, sizeof(System.Int64),ref value.c, sizeof(System.Single),ref value.d, sizeof(System.Double)); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override IncludeAllClassCodeGen Deserialize(Nino.Serialization.Reader reader) - { - if(!reader.ReadBool()) - return null; - IncludeAllClassCodeGen value = new IncludeAllClassCodeGen(); - reader.Read(ref value.a, sizeof(System.Int32),ref value.b, sizeof(System.Int64),ref value.c, sizeof(System.Single),ref value.d, sizeof(System.Double)); - return value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetSize(IncludeAllClassCodeGen value) - { - if(value == null) - { - return 1; - } - return Nino.Serialization.Serializer.GetFixedSize(); - } - #endregion - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Generated/Nino_Test_NestedData2_Serialize.cs b/Nino_Unity/Assets/Nino/Generated/Nino_Test_NestedData2_Serialize.cs deleted file mode 100644 index 1f48182..0000000 --- a/Nino_Unity/Assets/Nino/Generated/Nino_Test_NestedData2_Serialize.cs +++ /dev/null @@ -1,59 +0,0 @@ -/* this is generated by nino */ -using System.Runtime.CompilerServices; - -namespace Nino.Test -{ - public partial class NestedData2 - { - public static NestedData2.SerializationHelper NinoSerializationHelper = new NestedData2.SerializationHelper(); - public unsafe class SerializationHelper: Nino.Serialization.NinoWrapperBase - { - #region NINO_CODEGEN - public SerializationHelper() - { - - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override void Serialize(NestedData2 value, ref Nino.Serialization.Writer writer) - { - if(value == null) - { - writer.Write(false); - return; - } - writer.Write(true); - writer.Write(value.name); - writer.Write(value.ps); - writer.Write(value.vs); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override NestedData2 Deserialize(Nino.Serialization.Reader reader) - { - if(!reader.ReadBool()) - return null; - NestedData2 value = new NestedData2(); - value.name = reader.ReadString(); - value.ps = reader.ReadArray(); - value.vs = reader.ReadList(); - return value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetSize(NestedData2 value) - { - if(value == null) - { - return 1; - } - int ret = 1; - ret += Nino.Serialization.Serializer.GetSize(value.name); - ret += Nino.Serialization.Serializer.GetSize(value.ps); - ret += Nino.Serialization.Serializer.GetSize(value.vs); - return ret; - } - #endregion - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Generated/Nino_Test_NestedData_Serialize.cs b/Nino_Unity/Assets/Nino/Generated/Nino_Test_NestedData_Serialize.cs deleted file mode 100644 index e6688da..0000000 --- a/Nino_Unity/Assets/Nino/Generated/Nino_Test_NestedData_Serialize.cs +++ /dev/null @@ -1,56 +0,0 @@ -/* this is generated by nino */ -using System.Runtime.CompilerServices; - -namespace Nino.Test -{ - public partial class NestedData - { - public static NestedData.SerializationHelper NinoSerializationHelper = new NestedData.SerializationHelper(); - public unsafe class SerializationHelper: Nino.Serialization.NinoWrapperBase - { - #region NINO_CODEGEN - public SerializationHelper() - { - - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override void Serialize(NestedData value, ref Nino.Serialization.Writer writer) - { - if(value == null) - { - writer.Write(false); - return; - } - writer.Write(true); - writer.Write(value.name); - writer.Write(value.ps); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override NestedData Deserialize(Nino.Serialization.Reader reader) - { - if(!reader.ReadBool()) - return null; - NestedData value = new NestedData(); - value.name = reader.ReadString(); - value.ps = reader.ReadArray(); - return value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetSize(NestedData value) - { - if(value == null) - { - return 1; - } - int ret = 1; - ret += Nino.Serialization.Serializer.GetSize(value.name); - ret += Nino.Serialization.Serializer.GetSize(value.ps); - return ret; - } - #endregion - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Generated/Nino_Test_NotIncludeAllClass_Serialize.cs b/Nino_Unity/Assets/Nino/Generated/Nino_Test_NotIncludeAllClass_Serialize.cs deleted file mode 100644 index 94dff11..0000000 --- a/Nino_Unity/Assets/Nino/Generated/Nino_Test_NotIncludeAllClass_Serialize.cs +++ /dev/null @@ -1,56 +0,0 @@ -/* this is generated by nino */ -using System.Runtime.CompilerServices; - -namespace Nino.Test -{ - public partial class NotIncludeAllClass - { - public static NotIncludeAllClass.SerializationHelper NinoSerializationHelper = new NotIncludeAllClass.SerializationHelper(); - public unsafe class SerializationHelper: Nino.Serialization.NinoWrapperBase - { - #region NINO_CODEGEN - public SerializationHelper() - { - int ret = 1; - ret += sizeof(System.Int32); - ret += sizeof(System.Int64); - ret += sizeof(System.Single); - ret += sizeof(System.Double); - Nino.Serialization.Serializer.SetFixedSize(ret); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override void Serialize(NotIncludeAllClass value, ref Nino.Serialization.Writer writer) - { - if(value == null) - { - writer.Write(false); - return; - } - writer.Write(true); - writer.Write(ref value.a, sizeof(System.Int32),ref value.b, sizeof(System.Int64),ref value.c, sizeof(System.Single),ref value.d, sizeof(System.Double)); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override NotIncludeAllClass Deserialize(Nino.Serialization.Reader reader) - { - if(!reader.ReadBool()) - return null; - NotIncludeAllClass value = new NotIncludeAllClass(); - reader.Read(ref value.a, sizeof(System.Int32),ref value.b, sizeof(System.Int64),ref value.c, sizeof(System.Single),ref value.d, sizeof(System.Double)); - return value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetSize(NotIncludeAllClass value) - { - if(value == null) - { - return 1; - } - return Nino.Serialization.Serializer.GetFixedSize(); - } - #endregion - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Serialization/Attributes/CodeGenIgnoreAttribute.cs b/Nino_Unity/Assets/Nino/Serialization/Attributes/CodeGenIgnoreAttribute.cs deleted file mode 100644 index ce79d46..0000000 --- a/Nino_Unity/Assets/Nino/Serialization/Attributes/CodeGenIgnoreAttribute.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace Nino.Serialization -{ - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false)] - public class CodeGenIgnoreAttribute : Attribute - { - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Serialization/Attributes/NinoIgnoreAttribute.cs b/Nino_Unity/Assets/Nino/Serialization/Attributes/NinoIgnoreAttribute.cs deleted file mode 100644 index e59454b..0000000 --- a/Nino_Unity/Assets/Nino/Serialization/Attributes/NinoIgnoreAttribute.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace Nino.Serialization -{ - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)] - public class NinoIgnoreAttribute : Attribute - { - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Serialization/Attributes/NinoMemberAttribute.cs b/Nino_Unity/Assets/Nino/Serialization/Attributes/NinoMemberAttribute.cs deleted file mode 100644 index c756f58..0000000 --- a/Nino_Unity/Assets/Nino/Serialization/Attributes/NinoMemberAttribute.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; - -namespace Nino.Serialization -{ - [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)] - public class NinoMemberAttribute : Attribute - { - public readonly ushort Index; - - /// - /// Indicate a member that can be serialized and deserialized - /// 标明该成员可以被序列化或反序列化 - /// - /// index while serializing or deserializing | 序列化或反序列化时的顺序 - public NinoMemberAttribute(ushort index) - { - this.Index = index; - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Serialization/Attributes/NinoSerializeAttribute.cs b/Nino_Unity/Assets/Nino/Serialization/Attributes/NinoSerializeAttribute.cs deleted file mode 100644 index 609cd02..0000000 --- a/Nino_Unity/Assets/Nino/Serialization/Attributes/NinoSerializeAttribute.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; - -namespace Nino.Serialization -{ - [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false)] - public class NinoSerializeAttribute : Attribute - { - public readonly bool IncludeAll; - - /// - /// A struct or class to be serialized and deserialized - /// 一个结构体或一个类型的会被序列化以及反序列化 - /// include all fields and properties - /// - public NinoSerializeAttribute(bool includeAll = true) - { - IncludeAll = includeAll; - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Serialization/CodeGenerator.cs b/Nino_Unity/Assets/Nino/Serialization/CodeGenerator.cs deleted file mode 100644 index 0e1102f..0000000 --- a/Nino_Unity/Assets/Nino/Serialization/CodeGenerator.cs +++ /dev/null @@ -1,696 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using Nino.Shared.Mgr; -using Nino.Shared.Util; -using System.Reflection; - -namespace Nino.Serialization -{ - /// - /// Nino code generator - /// TODO support nullable, hashset, queue, stack - /// - public static class CodeGenerator - { - /// - /// Generate serialization code file at Assets/ouputPath - /// editor only method - /// - /// - /// - public static void GenerateSerializationCodeForAllTypePossible(string outputPath = "Nino/Generated", - Assembly[] assemblies = null) - { - //find all types - var types = (assemblies ?? AppDomain.CurrentDomain.GetAssemblies()).SelectMany(a => a.GetTypes()).ToList() - .FindAll(t => - { - //find NinoSerializeAttribute - NinoSerializeAttribute[] ns = - (NinoSerializeAttribute[])t.GetCustomAttributes(typeof(NinoSerializeAttribute), true); - if (ns.Length == 0) return false; - return true; - }).ToList(); - //iterate - foreach (var type in types) - { - //gen - GenerateSerializationCode(type, outputPath); - } - } - - /// - /// Get a valid nino serialize class - /// - /// - /// - /// - private static bool GetValidNinoClass(Type type, bool log = true) - { - //nested - if (type.IsNested) - { - if (log) - Logger.E("Code Gen", $"Can not generate code for type: {type} due to it is a nested class"); - return false; - } - - //generic - if (type.IsGenericType) - { - if (log) - Logger.E("Code Gen", $"Can not generate code for type: {type} due to it is a generic class"); - return false; - } - - //find NinoSerializeAttribute - NinoSerializeAttribute[] ns = - (NinoSerializeAttribute[])type.GetCustomAttributes(typeof(NinoSerializeAttribute), true); - if (ns.Length == 0) return false; - - CodeGenIgnoreAttribute[] ci = - (CodeGenIgnoreAttribute[])type.GetCustomAttributes(typeof(CodeGenIgnoreAttribute), true); - if (ci.Length != 0) return false; - return true; - } - - /// - /// Generate serialization code file at Assets/ouputPath - /// editor only method - /// - /// - /// - // ReSharper disable CognitiveComplexity - public static void GenerateSerializationCode(Type type, string outputPath = "Nino/Generated") - // ReSharper restore CognitiveComplexity - { - //nino class only - if (!GetValidNinoClass(type)) return; - - //code template - string template = - @"/* this is generated by nino */ -using System.Runtime.CompilerServices; - -{namespace} -{start} - public partial struct {type} - { - public static {type}.SerializationHelper NinoSerializationHelper = new {type}.SerializationHelper(); - public unsafe class SerializationHelper: Nino.Serialization.NinoWrapperBase<{type}> - { - #region NINO_CODEGEN - public SerializationHelper() - { -{ctor} - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override void Serialize({type} value, ref Nino.Serialization.Writer writer) - { - {nullCheck} - writer.Write(true); -{members} - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override {type} Deserialize(Nino.Serialization.Reader reader) - { - if(!reader.ReadBool()) - {returnNull} - {createObj} -{fields} - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public override int GetSize({type} value) - { - {sizeNull} -{size} - } - #endregion - } - } -{end}"; - if (type.IsClass) - { - template = template.Replace("struct", "class"); - template = template.Replace("{nullCheck}", @"if(value == null) - { - writer.Write(false); - return; - }"); - template = template.Replace("{returnNull}", "return null;"); - template = template.Replace("{sizeNull}", @"if(value == null) - { - return 1; - }"); - -#if UNITY_2017_1_OR_NEWER - //see if type inherits MonoBehaviour - if (type.IsSubclassOf(typeof(UnityEngine.MonoBehaviour))) - { - template = template.Replace("{createObj}", "{type} value = new UnityEngine.GameObject(\"{type}\").AddComponent<{type}>();"); - } - else -#endif - { - template = template.Replace("{createObj}", "{type} value = new {type}();"); - } - } - else - { - template = template.Replace("{nullCheck}", @""); - template = template.Replace("{returnNull}", "return default;"); - template = template.Replace("{sizeNull}", @""); - } - - //replace namespace - if (!string.IsNullOrEmpty(type.Namespace)) - { - template = template.Replace("{namespace}", $"namespace {type.Namespace}"); - template = template.Replace("{start}", "{"); - template = template.Replace("{end}", "}"); - } - else - { - template = template.Replace("{namespace}", string.Empty); - template = template.Replace("{start}", string.Empty); - template = template.Replace("{end}", string.Empty); - } - - //class full name - var classFullName = - $"{type.GetFriendlyName()}"; - //replace full name - template = template.Replace("{type}", classFullName); - - //find members - TypeModel.TryGetModel(type, out var model); - //invalid model - if (model != null) - { - if (!model.Valid) - { - throw new InvalidOperationException("invalid model"); - } - } - - //generate model - if (model == null) - { - model = TypeModel.CreateModel(type); - } - - var members = model.Members; - - #region serialize - - //build params - StringBuilder sb = new StringBuilder(); - List unmanagedMembers = new List(); - for (int i = 0; i < members.Count; i++) - { - var info = members[i]; - var member = info.Member; - var mt = info.Type; - - //try optimize - if (TypeModel.IsUnmanaged(mt) && member is FieldInfo) - { - unmanagedMembers.Clear(); - unmanagedMembers.Add(info); - for (int j = i + 1; j < members.Count; j++) - { - var info2 = members[j]; - var member2 = info2.Member; - var mt2 = info2.Type; - if (TypeModel.IsUnmanaged(mt2) && member2 is FieldInfo) - { - unmanagedMembers.Add(info2); - } - else - { - break; - } - } - - i += unmanagedMembers.Count - 1; - //batch write with batch size 8 - while (unmanagedMembers.Count > 0) - { - if (unmanagedMembers.Count <= 8) - { - sb.Append( - $" writer.Write({string.Join(",", unmanagedMembers.Select(x => $"ref value.{x.Member.Name}, sizeof({BeautifulLongTypeName(x.Type)})"))});\n"); - unmanagedMembers.Clear(); - } - else - { - sb.Append( - $" writer.Write({string.Join(",", unmanagedMembers.Take(8).Select(x => $"ref value.{x.Member.Name}, sizeof({BeautifulLongTypeName(x.Type)})"))});\n"); - unmanagedMembers.RemoveRange(0, 8); - } - } - - continue; - } - - //enum - if (mt.IsEnum) - { - sb.Append( - $" writer.WriteEnum<{BeautifulLongTypeName(mt)}>(value.{member.Name});\n"); - } - //array/list - else if (mt.IsArray || (mt.IsGenericType && mt.GetGenericTypeDefinition() == ConstMgr.ListDefType)) - { - sb.Append($" writer.Write(value.{member.Name});\n"); - } - //dict - else if (mt.IsGenericType && mt.GetGenericTypeDefinition() == ConstMgr.DictDefType) - { - sb.Append($" writer.Write(value.{member.Name});\n"); - } - //nullable - else if (mt.IsGenericType && mt.GetGenericTypeDefinition() == ConstMgr.NullableDefType) - { - sb.Append($" writer.Write(value.{member.Name});\n"); - } - //basic type - else - { - sb.Append( - $" {GetSerializeBasicTypeStatement(mt, $"value.{member.Name}", member is PropertyInfo)};\n"); - } - } - - if (members.Count > 0) - { - //remove \n at the end - sb.Remove(sb.Length - 1, 1); - } - - //replace template members - template = template.Replace("{members}", sb.ToString()); - - #endregion - - #region deserialize - - sb.Clear(); - for (int i = 0; i < members.Count; i++) - { - var info = members[i]; - var member = info.Member; - var mt = info.Type; - - //try optimize - if (TypeModel.IsUnmanaged(mt) && member is FieldInfo) - { - unmanagedMembers.Clear(); - unmanagedMembers.Add(info); - for (int j = i + 1; j < members.Count; j++) - { - var info2 = members[j]; - var member2 = info2.Member; - var mt2 = info2.Type; - if (TypeModel.IsUnmanaged(mt2) && member2 is FieldInfo) - { - unmanagedMembers.Add(info2); - } - else - { - break; - } - } - - i += unmanagedMembers.Count - 1; - //batch write with batch size 8 - while (unmanagedMembers.Count > 0) - { - if (unmanagedMembers.Count <= 8) - { - sb.Append( - $" reader.Read({string.Join(",", unmanagedMembers.Select(x => $"ref value.{x.Member.Name}, sizeof({BeautifulLongTypeName(x.Type)})"))});\n"); - unmanagedMembers.Clear(); - } - else - { - sb.Append( - $" reader.Read({string.Join(",", unmanagedMembers.Take(8).Select(x => $"ref value.{x.Member.Name}, sizeof({BeautifulLongTypeName(x.Type)})"))});\n"); - unmanagedMembers.RemoveRange(0, 8); - } - } - - continue; - } - - //enum - if (mt.IsEnum) - { - if (member is PropertyInfo) - { - sb.Append( - $" value.{member.Name} = reader.ReadEnum<{BeautifulLongTypeName(mt)}>();\n"); - } - else - { - sb.Append( - $" reader.ReadEnum<{BeautifulLongTypeName(mt)}>(ref value.{member.Name});\n"); - } - } - //array/list - else if (mt.IsArray || (mt.IsGenericType && mt.GetGenericTypeDefinition() == ConstMgr.ListDefType)) - { - Type elemType = mt.IsGenericType ? mt.GenericTypeArguments[0] : mt.GetElementType(); - - //create field - if (mt.IsArray) - { - //multidimensional array - if (mt.GetArrayRank() > 1) - { - throw new NotSupportedException( - "can not serialize multidimensional array, use jagged array instead"); - } - - sb.Append( - $" value.{member.Name} = reader.ReadArray<{BeautifulLongTypeName(elemType)}>();\n"); - } - else - { - sb.Append( - $" value.{member.Name} = reader.ReadList<{BeautifulLongTypeName(elemType)}>();\n"); - } - } - //dict - else if (mt.IsGenericType && mt.GetGenericTypeDefinition() == ConstMgr.DictDefType) - { - var args = mt.GetGenericArguments(); - Type keyType = args[0]; - Type valueType = args[1]; - - sb.Append( - $" value.{member.Name} = reader.ReadDictionary<{BeautifulLongTypeName(keyType)},{BeautifulLongTypeName(valueType)}>();\n"); - } - //nullable - else if (mt.IsGenericType && mt.GetGenericTypeDefinition() == ConstMgr.NullableDefType) - { - var args = mt.GetGenericArguments(); - Type keyType = args[0]; - - sb.Append( - $" value.{member.Name} = reader.ReadNullable<{BeautifulLongTypeName(keyType)}>();\n"); - } - //not enum -> basic type - else - { - string val = GetDeserializeBasicTypeStatement(mt, member is PropertyInfo, - $"value.{member.Name}"); - sb.Append($" {val}\n"); - } - } - - sb.Append(" return value;\n"); - //remove comma at the end - sb.Remove(sb.Length - 1, 1); - - //replace template fields - template = template.Replace("{fields}", sb.ToString()); - - #endregion - - #region getsize - - sb.Clear(); - if (TypeModel.IsFixedSizeType(type)) - { - sb.Append( - $" return Nino.Serialization.Serializer.GetFixedSize<{BeautifulLongTypeName(type)}>();"); - } - else - { - sb.Append(" int ret = 1;\n"); - foreach (var info in members) - { - var member = info.Member; - var size = Serializer.GetFixedSize(info.Type); - sb.Append( - size != -1 - ? $" ret += {size}; // size for {member.Name}\n" - : $" ret += Nino.Serialization.Serializer.GetSize(value.{member.Name});\n"); - } - - sb.Append(" return ret;"); - } - - //replace template fields - template = template.Replace("{size}", sb.ToString()); - - #endregion - - #region ctor - - sb.Clear(); - if (TypeModel.IsFixedSizeType(type)) - { - sb.Append(" int ret = 1;\n"); - foreach (var info in members) - { - var mt = info.Type; - sb.Append( - $" ret += sizeof({BeautifulLongTypeName(mt)});\n"); - } - - sb.Append( - $" Nino.Serialization.Serializer.SetFixedSize<{BeautifulLongTypeName(type)}>(ret);"); - } - - //replace template fields - template = template.Replace("{ctor}", sb.ToString()); - - #endregion - - //save path - var output = Path.Combine(ConstMgr.AssetPath, outputPath); - if (!Directory.Exists(output)) - { - Directory.CreateDirectory(output); - } - - //save file path - output = Path.Combine(output, - $"{type.Namespace}{(!string.IsNullOrEmpty(type.Namespace) ? "." : "")}{type.GetFriendlyName()}" - .Replace(".", "_").Replace(",", "_") - .Replace("<", "_").Replace(">", "_") + - "_Serialize.cs"); - if (File.Exists(output)) - { - File.Delete(output); - } - - //save - File.WriteAllText(output, template); - -#if UNITY_2017_1_OR_NEWER - Logger.D("Code Gen", $"saved {output}"); -#else - Logger.D("Code Gen", $"saved {output}, please move this file to your project"); -#endif - } - - // ReSharper disable CognitiveComplexity - private static string GetDeserializeBasicTypeStatement(Type mt, bool isProperty, string val = "", - string space = " ") - // ReSharper restore CognitiveComplexity - { - switch (Type.GetTypeCode(mt)) - { - case TypeCode.Int32: - case TypeCode.UInt32: - case TypeCode.Int64: - case TypeCode.UInt64: - case TypeCode.Byte: - case TypeCode.SByte: - case TypeCode.Int16: - case TypeCode.UInt16: - case TypeCode.Boolean: - case TypeCode.Double: - case TypeCode.Single: - case TypeCode.Decimal: - case TypeCode.Char: - case TypeCode.DateTime: - return isProperty - ? $"{val} = reader.Read<{BeautifulLongTypeName(mt)}>(sizeof({BeautifulLongTypeName(mt)}));" - : $"reader.Read<{BeautifulLongTypeName(mt)}>(ref {val}, sizeof({BeautifulLongTypeName(mt)}));"; - case TypeCode.String: - return $"{val} = reader.ReadString();"; - default: - if (GetValidNinoClass(mt, false)) - { - return $"{val} = {BeautifulLongTypeName(mt)}.NinoSerializationHelper.Deserialize(reader);"; - } - - //enum - if (mt.IsEnum) - { - return isProperty - ? $"{val} = reader.ReadEnum<{BeautifulLongTypeName(mt)}>();" - : $"reader.ReadEnum<{BeautifulLongTypeName(mt)}>(ref {val});"; - } - - if (mt.IsArray || - (mt.IsGenericType && mt.GetGenericTypeDefinition() == ConstMgr.ListDefType)) - { - Type elemType = mt.IsGenericType ? mt.GenericTypeArguments[0] : mt.GetElementType(); - StringBuilder builder = new StringBuilder(); - if (mt.IsArray) - { - //multidimensional array - if (mt.GetArrayRank() > 1) - { - throw new NotSupportedException( - "can not serialize multidimensional array, use jagged array instead"); - } - - builder.Append( - $"{val} = reader.ReadArray<{BeautifulLongTypeName(elemType)}>();\n"); - } - else - { - builder.Append( - $"{val} = reader.ReadList<{BeautifulLongTypeName(elemType)}>();\n"); - } - - return builder.ToString(); - } - - if (mt.IsGenericType && mt.GetGenericTypeDefinition() == ConstMgr.DictDefType) - { - StringBuilder builder = new StringBuilder(); - var args = mt.GetGenericArguments(); - Type keyType = args[0]; - Type valueType = args[1]; - //create field - builder.Append(space).Append( - $"{BeautifulLongTypeName(mt)} {val} = reader.ReadDictionary<{BeautifulLongTypeName(keyType)},{BeautifulLongTypeName(valueType)}>();\n"); - return builder.ToString(); - } - - return $"{val} = reader.ReadCommonVal<{BeautifulLongTypeName(mt)}>();"; - } - } - - // ReSharper disable CognitiveComplexity - private static string GetSerializeBasicTypeStatement(Type mt, string val, bool isProperty, int indent = 0, - string space = " ") - // ReSharper restore CognitiveComplexity - { - switch (Type.GetTypeCode(mt)) - { - case TypeCode.Int32: - case TypeCode.UInt32: - case TypeCode.Int64: - case TypeCode.UInt64: - case TypeCode.Byte: - case TypeCode.SByte: - case TypeCode.Int16: - case TypeCode.UInt16: - case TypeCode.Boolean: - case TypeCode.Double: - case TypeCode.Single: - case TypeCode.Decimal: - case TypeCode.Char: - case TypeCode.DateTime: - return isProperty - ? $"writer.Write({val})" - : $"writer.Write(ref {val}, sizeof({BeautifulLongTypeName(mt)}))"; - case TypeCode.String: - return $"writer.Write({val})"; - default: - if (GetValidNinoClass(mt, false)) - { - return $"{BeautifulLongTypeName(mt)}.NinoSerializationHelper.Serialize({val}, ref writer)"; - } - - if (mt.IsArray || (mt.IsGenericType && mt.GetGenericTypeDefinition() == ConstMgr.ListDefType)) - { - StringBuilder builder = new StringBuilder(); - Type elemType = mt.IsGenericType ? mt.GenericTypeArguments[0] : mt.GetElementType(); - if (elemType == null) - { - throw new InvalidOperationException("Invalid array type"); - } - - builder.Append(space).Append(Repeat(" ", indent)) - .Append($"writer.Write({val});\n"); - return builder.ToString(); - } - - if (mt.IsGenericType && mt.GetGenericTypeDefinition() == ConstMgr.DictDefType) - { - StringBuilder builder = new StringBuilder(); - builder.Append(space).Append(Repeat(" ", indent)) - .Append($"writer.Write({val});\n"); - return builder.ToString(); - } - - if (mt.IsGenericType && mt.GetGenericTypeDefinition() == ConstMgr.NullableDefType) - { - StringBuilder builder = new StringBuilder(); - builder.Append(space).Append(Repeat(" ", indent)) - .Append($"writer.Write({val});\n"); - return builder.ToString(); - } - - return $"writer.WriteCommonVal<{BeautifulLongTypeName(mt)}>({val})"; - } - } - - private static string Repeat(string value, int count) - { - if (count < 1) return string.Empty; - return new StringBuilder(value.Length * count).Insert(0, value, count).ToString(); - } - - private static string BeautifulLongTypeName(this Type mt) - { - return $"{mt.Namespace}{(!string.IsNullOrEmpty(mt.Namespace) ? "." : "")}{mt.GetFriendlyName()}"; - } - - /// - /// 获取类型名字 - /// - /// - /// - private static string GetFriendlyName(this Type type) - { - string friendlyName = type.Name; - if (type.IsGenericType) - { - int iBacktick = friendlyName.IndexOf('`'); - if (iBacktick > 0) - { - friendlyName = friendlyName.Remove(iBacktick); - } - - friendlyName += "<"; - Type[] typeParameters = type.GetGenericArguments(); - for (int i = 0; i < typeParameters.Length; ++i) - { - string typeParamName = - $"{typeParameters[i].Namespace}{(!string.IsNullOrEmpty(typeParameters[i].Namespace) ? "." : "")}{GetFriendlyName(typeParameters[i])}"; - friendlyName += (i == 0 ? typeParamName : "," + typeParamName); - } - - friendlyName += ">"; - } - - return friendlyName; - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Serialization/Deserializer.Generic.cs b/Nino_Unity/Assets/Nino/Serialization/Deserializer.Generic.cs deleted file mode 100644 index 7de3e7e..0000000 --- a/Nino_Unity/Assets/Nino/Serialization/Deserializer.Generic.cs +++ /dev/null @@ -1,335 +0,0 @@ -using System; -using System.Collections.Generic; -using Nino.Shared.IO; - -namespace Nino.Serialization -{ - public static partial class Deserializer - { - #region Array - - /// - /// Deserialize an array NinoSerialize object - /// - /// - /// - /// - public static T[] DeserializeArray(byte[] data) - => DeserializeArray(new Span(data)); - - /// - /// Deserialize an array NinoSerialize object - /// - /// - /// - /// - public static T[] DeserializeArray(ArraySegment data) - => DeserializeArray(new Span(data.Array, data.Offset, data.Count)); - - /// - /// Deserialize an array of NinoSerialize object - /// - /// - /// - /// - public static T[] DeserializeArray(Span data) - { - var type = typeof(T[]); - var reader = ObjectPool.Request(); - reader.Init(data, data.Length); - - /* - * NO GC DESERIALIZATION ATTEMPT - */ - //basic type - if (TryDeserializeWrapperType(type, reader, false, true, out T[] ret)) - { - return ret; - } - - //attempt to deserialize using generic method - return reader.ReadArray(); - } - - #endregion - - #region Nullable - - /// - /// Deserialize a nullable of NinoSerialize struct - /// - /// - /// - /// - public static T? DeserializeNullable(byte[] data) - where T : struct - => DeserializeNullable(new Span(data)); - - /// - /// Deserialize a nullable of NinoSerialize struct - /// - /// - /// - /// - public static T? DeserializeNullable(ArraySegment data) - where T : struct - => DeserializeNullable(new Span(data.Array, data.Offset, data.Count)); - - /// - /// Deserialize a nullable of NinoSerialize struct - /// - /// - /// - /// - public static T? DeserializeNullable(Span data) - where T : struct - { - var reader = ObjectPool.Request(); - reader.Init(data, data.Length); - - //attempt to deserialize using generic method - return reader.ReadNullable(); - } - - #endregion - - #region List - - /// - /// Deserialize a list of NinoSerialize object - /// - /// - /// - /// - public static List DeserializeList(byte[] data) - => DeserializeList(new Span(data)); - - /// - /// Deserialize a list of NinoSerialize object - /// - /// - /// - /// - public static List DeserializeList(ArraySegment data) - => DeserializeList(new Span(data.Array, data.Offset, data.Count)); - - /// - /// Deserialize a list of NinoSerialize object - /// - /// - /// - /// - public static List DeserializeList(Span data) - { - var type = typeof(List); - var reader = ObjectPool.Request(); - reader.Init(data, data.Length); - - /* - * NO GC DESERIALIZATION ATTEMPT - */ - //basic type - if (TryDeserializeWrapperType(type, reader, false, true, out List ret)) - { - return ret; - } - - //attempt to deserialize using generic method - return reader.ReadList(); - } - - #endregion - - #region HashSet - - /// - /// Deserialize a HashSet of NinoSerialize object - /// - /// - /// - /// - public static HashSet DeserializeHashSet(byte[] data) - => DeserializeHashSet(new Span(data)); - - /// - /// Deserialize a HashSet of NinoSerialize object - /// - /// - /// - /// - public static HashSet DeserializeHashSet(ArraySegment data) - => DeserializeHashSet(new Span(data.Array, data.Offset, data.Count)); - - /// - /// Deserialize a HashSet of NinoSerialize object - /// - /// - /// - /// - public static HashSet DeserializeHashSet(Span data) - { - var type = typeof(HashSet); - var reader = ObjectPool.Request(); - reader.Init(data, data.Length); - - /* - * NO GC DESERIALIZATION ATTEMPT - */ - //basic type - if (TryDeserializeWrapperType(type, reader, false, true, out HashSet ret)) - { - return ret; - } - - //attempt to deserialize using generic method - return reader.ReadHashSet(); - } - - #endregion - - #region Queue - - /// - /// Deserialize a Queue of NinoSerialize object - /// - /// - /// - /// - public static Queue DeserializeQueue(byte[] data) - => DeserializeQueue(new Span(data)); - - /// - /// Deserialize a Queue of NinoSerialize object - /// - /// - /// - /// - public static Queue DeserializeQueue(ArraySegment data) - => DeserializeQueue(new Span(data.Array, data.Offset, data.Count)); - - /// - /// Deserialize a Queue of NinoSerialize object - /// - /// - /// - /// - public static Queue DeserializeQueue(Span data) - { - var type = typeof(Queue); - var reader = ObjectPool.Request(); - reader.Init(data, data.Length); - - /* - * NO GC DESERIALIZATION ATTEMPT - */ - //basic type - if (TryDeserializeWrapperType(type, reader, false, true, out Queue ret)) - { - return ret; - } - - //attempt to deserialize using generic method - return reader.ReadQueue(); - } - - #endregion - - #region Stack - - /// - /// Deserialize a Stack of NinoSerialize object - /// - /// - /// - /// - public static Stack DeserializeStack(byte[] data) - => DeserializeStack(new Span(data)); - - /// - /// Deserialize a Stack of NinoSerialize object - /// - /// - /// - /// - public static Stack DeserializeStack(ArraySegment data) - => DeserializeStack(new Span(data.Array, data.Offset, data.Count)); - - /// - /// Deserialize a Stack of NinoSerialize object - /// - /// - /// - /// - public static Stack DeserializeStack(Span data) - { - var type = typeof(Stack); - var reader = ObjectPool.Request(); - reader.Init(data, data.Length); - - /* - * NO GC DESERIALIZATION ATTEMPT - */ - //basic type - if (TryDeserializeWrapperType(type, reader, false, true, out Stack ret)) - { - return ret; - } - - //attempt to deserialize using generic method - return reader.ReadStack(); - } - - #endregion - - #region Dictionary - - /// - /// Deserialize a Dictionary of NinoSerialize object - /// - /// - /// - /// - /// - public static Dictionary DeserializeDictionary(byte[] data) - => DeserializeDictionary(new Span(data)); - - /// - /// Deserialize a Dictionary of NinoSerialize object - /// - /// - /// - /// - /// - public static Dictionary DeserializeDictionary(ArraySegment data) - => DeserializeDictionary(new Span(data.Array, data.Offset, data.Count)); - - /// - /// Deserialize a Dictionary of NinoSerialize object - /// - /// - /// - /// - /// - public static Dictionary DeserializeDictionary(Span data) - { - var type = typeof(Dictionary); - var reader = ObjectPool.Request(); - reader.Init(data, data.Length); - - /* - * NO GC DESERIALIZATION ATTEMPT - */ - //basic type - if (TryDeserializeWrapperType(type, reader, false, true, - out Dictionary ret)) - { - return ret; - } - - //attempt to deserialize using generic method - return reader.ReadDictionary(); - } - - #endregion - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Serialization/Deserializer.cs b/Nino_Unity/Assets/Nino/Serialization/Deserializer.cs deleted file mode 100644 index 2881141..0000000 --- a/Nino_Unity/Assets/Nino/Serialization/Deserializer.cs +++ /dev/null @@ -1,565 +0,0 @@ -using System; -using Nino.Shared.IO; -using Nino.Shared.Mgr; -using System.Reflection; -using System.Collections; -using System.Runtime.InteropServices; -using System.Runtime.CompilerServices; - -namespace Nino.Serialization -{ - public static partial class Deserializer - { - /// - /// Deserialize a NinoSerialize object - /// - /// - /// - /// - public static T Deserialize(byte[] data) - => Deserialize(new Span(data), null); - - /// - /// Deserialize a NinoSerialize object - /// - /// - /// - /// - public static T Deserialize(ArraySegment data) - => Deserialize(new Span(data.Array, data.Offset, data.Count), null); - - /// - /// Deserialize a NinoSerialize object - /// - /// - /// - /// - public static T Deserialize(Span data) - => Deserialize(data, null); - - /// - /// Deserialize a NinoSerialize object - /// - /// - /// - /// - public static object Deserialize(Type type, byte[] data) - => Deserialize(type, null, new Span(data), null); - - /// - /// Deserialize a NinoSerialize object - /// - /// - /// - /// - public static object Deserialize(Type type, ArraySegment data) - => Deserialize(type, null, new Span(data.Array, data.Offset, data.Count), null); - - /// - /// Deserialize a NinoSerialize object - /// - /// - /// - /// - public static object Deserialize(Type type, Span data) - => Deserialize(type, null, data, null); - - /// - /// Deserialize a NinoSerialize object - /// - /// - /// - /// - /// - /// - internal static T Deserialize(Span data, Reader reader, - [MarshalAs(UnmanagedType.U1)] bool returnDispose = true) - { - Type type = typeof(T); - - if (reader == null) - { - reader = ObjectPool.Request(); - reader.Init(data, data.Length); - } - - /* - * NO GC DESERIALIZATION ATTEMPT - */ - //basic type - if (TryDeserializeWrapperType(type, reader, false, returnDispose, out T ret)) - { - return ret; - } - - //enum - if (TryDeserializeEnum(type, reader, returnDispose, out var e)) - { - return e; - } - - //code generated type - if (TryDeserializeCodeGenType(type, reader, false, returnDispose, out ret)) - { - return ret; - } - - //unmanaged type - if (TryDeserializeUnmanagedType(type, reader, returnDispose, out var un)) - { - return un; - } - - /* - * GC DESERIALIZATION WHILE T IS STRUCT - */ - var result = Deserialize(type, null, data, reader, returnDispose); - if (result != null) return (T)result; - ObjectPool.Return(reader); - return default; - } - - /// - /// Deserialize a NinoSerialize object - /// - /// - /// - /// - /// - /// - /// - /// - /// - internal static object Deserialize(Type type, object val, Span data, Reader reader, - [MarshalAs(UnmanagedType.U1)] bool returnDispose = true) - { - if (reader == null) - { - reader = ObjectPool.Request(); - reader.Init(data, data.Length); - } - - //array - if (TryDeserializeArray(type, reader, returnDispose, out var arr)) - { - return arr; - } - - //list, dict - if (type.IsGenericType) - { - var genericDefType = type.GetGenericTypeDefinition(); - if (TryDeserializeList(type, genericDefType, reader, returnDispose, out var lst)) - { - return lst; - } - - if (TryDeserializeDict(type, genericDefType, reader, returnDispose, out var dict)) - { - return dict; - } - } - - //basic type - if (TryDeserializeWrapperType(type, reader, true, returnDispose, out object basicObj)) - { - return basicObj; - } - - //enum - if (TryDeserializeEnum(type, reader, returnDispose, out var e)) - { - return e; - } - - //code generated type - if (TryDeserializeCodeGenType(type, reader, true, returnDispose, out object codeGenRet)) - { - return codeGenRet; - } - - //unmanaged type - if (TryDeserializeUnmanagedType(type, reader, returnDispose, out var un)) - { - return un; - } - - /* - * CUSTOM STRUCT/CLASS SERIALIZATION - */ - if (ReadNullCheck(reader, returnDispose, out var nullCheck)) - { - return nullCheck; - } - - //create type - if (val == null || val == ConstMgr.Null) - { -#if UNITY_2017_1_OR_NEWER - //see if type inherits MonoBehaviour - if (type.IsSubclassOf(typeof(UnityEngine.MonoBehaviour))) - { - val = new UnityEngine.GameObject(type.AssemblyQualifiedName).AddComponent(type); - } - else -#endif - { - val = Activator.CreateInstance(type); - } - } - - //Get Attribute that indicates a class/struct to be serialized - TypeModel.TryGetModel(type, out var model); - - //invalid model - if (model != null && !model.Valid) - { - return val; - } - - //generate model - if (model == null) - { - model = TypeModel.CreateModel(type); - } - - //start Deserialize - foreach (var info in model.Members) - { - //if end, skip - if (reader.EndOfReader) - { - break; - } - - type = info.Type; - - //read basic values - SetMember(info.Member, val, Deserialize(type, ConstMgr.Null, Span.Empty, reader, false)); - } - - if (returnDispose) - { - ObjectPool.Return(reader); - } - - return val; - } - - /// - /// Try deserialize wrapper type - /// - /// - /// - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool TryDeserializeWrapperType(Type type, Reader reader, - [MarshalAs(UnmanagedType.U1)] bool boxed, [MarshalAs(UnmanagedType.U1)] bool returnDispose, - out T ret) - { - if (WrapperManifest.TryGetWrapper(type, out var wrapper)) - { - if (boxed) - { - var obj = wrapper.Deserialize(reader); - ret = obj != null ? (T)obj : default; - } - else - { - ret = ((NinoWrapperBase)wrapper).Deserialize(reader); - } - - if (returnDispose) - ObjectPool.Return(reader); - return true; - } - - ret = default; - return false; - } - - /// - /// Try deserialize code generated type (first time only) - /// - /// - /// - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool TryDeserializeCodeGenType(Type type, Reader reader, - [MarshalAs(UnmanagedType.U1)] bool boxed, [MarshalAs(UnmanagedType.U1)] bool returnDispose, - out T ret) - { - if (TypeModel.TryGetWrapper(type, out var wrapper)) - { - //add wrapper - WrapperManifest.AddWrapper(type, wrapper); - //start Deserialize - if (boxed) - { - var obj = wrapper.Deserialize(reader); - ret = obj != null ? (T)obj : default; - } - else - { - ret = ((NinoWrapperBase)wrapper).Deserialize(reader); - } - - if (returnDispose) - ObjectPool.Return(reader); - return true; - } - - ret = default; - return false; - } - - /// - /// Try deserialize array - /// - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool TryDeserializeArray(Type type, Reader reader, - [MarshalAs(UnmanagedType.U1)] bool returnDispose, out Array ret) - { - if (type.IsArray) - { - ret = reader.ReadArray(type); - if (returnDispose) - { - ObjectPool.Return(reader); - } - - return true; - } - - ret = null; - return false; - } - - /// - /// Try deserialize list - /// - /// - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool TryDeserializeList(Type type, Type genericDefType, Reader reader, - [MarshalAs(UnmanagedType.U1)] bool returnDispose, out IList ret) - { - if (genericDefType == ConstMgr.ListDefType) - { - ret = reader.ReadList(type); - if (returnDispose) - { - ObjectPool.Return(reader); - } - - return true; - } - - ret = null; - return false; - } - - /// - /// Try deserialize dictionary - /// - /// - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool TryDeserializeDict(Type type, Type genericDefType, Reader reader, - [MarshalAs(UnmanagedType.U1)] bool returnDispose, out IDictionary ret) - { - if (genericDefType == ConstMgr.DictDefType) - { - ret = reader.ReadDictionary(type); - if (returnDispose) - { - ObjectPool.Return(reader); - } - - return true; - } - - ret = null; - return false; - } - - /// - /// Try deserialize enum - /// - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool TryDeserializeEnum(Type type, Reader reader, - [MarshalAs(UnmanagedType.U1)] bool returnDispose, out T obj) - { - obj = default; - if (TypeModel.IsEnum(type)) - { - reader.ReadEnum(ref obj); - if (returnDispose) - { - ObjectPool.Return(reader); - } - - return true; - } - - return false; - } - - /// - /// Try deserialize enum - /// - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool TryDeserializeEnum(Type type, Reader reader, - [MarshalAs(UnmanagedType.U1)] bool returnDispose, out object obj) - { - if (TypeModel.IsEnum(type)) - { - var underlyingType = Enum.GetUnderlyingType(type); - var ret = reader.ReadEnum(underlyingType); - obj = Enum.ToObject(type, ret); - if (returnDispose) - { - ObjectPool.Return(reader); - } - - return true; - } - - obj = null; - return false; - } - - /// - /// Try deserialize enum - /// - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool TryDeserializeUnmanagedType(Type type, Reader reader, - [MarshalAs(UnmanagedType.U1)] bool returnDispose, out T obj) - { - obj = default; - if (TypeModel.IsUnmanaged(type)) - { - reader.ReadAsUnmanaged(ref obj, Marshal.SizeOf(type)); - if (returnDispose) - { - ObjectPool.Return(reader); - } - - return true; - } - - return false; - } - - /// - /// Try deserialize enum - /// - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool TryDeserializeUnmanagedType(Type type, Reader reader, - [MarshalAs(UnmanagedType.U1)] bool returnDispose, out object obj) - { - obj = default; - if (TypeModel.IsUnmanaged(type)) - { - reader.ReadAsUnmanaged(ref obj, Marshal.SizeOf(type)); - if (returnDispose) - { - ObjectPool.Return(reader); - } - - return true; - } - - return false; - } - - /// - /// Check for null - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool ReadNullCheck(Reader reader, [MarshalAs(UnmanagedType.U1)] bool returnDispose, - out object obj) - { - obj = null; - if (!reader.ReadBool()) // if null -> readBool will give false - { - if (returnDispose) - { - ObjectPool.Return(reader); - } - - return true; - } - - return false; - } - - /// - /// Set value from MemberInfo - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static void SetMember(MemberInfo info, object instance, object val) - { - switch (info) - { - case FieldInfo fo: - fo.SetValue(instance, val); - break; - case PropertyInfo po: - po.SetValue(instance, val); - break; - default: - return; - } - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Serialization/Enums/CompressOption.cs b/Nino_Unity/Assets/Nino/Serialization/Enums/CompressOption.cs deleted file mode 100644 index 61ec116..0000000 --- a/Nino_Unity/Assets/Nino/Serialization/Enums/CompressOption.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace Nino.Serialization -{ - /// - /// Compress option - /// 压缩类型 - /// - public enum CompressOption : byte - { - /// - /// zlib (gzip/deflate) compression (high compression ratio but low performance) - /// zlib (gzip/deflate) 压缩模式 (高压缩率低性能) - /// - Zlib = 0, - - /// - /// lz4 compression (average compression ration but high performance) - /// lz4 压缩模式 (平均压缩率高性能) - /// - Lz4 = 1, - - /// - /// no compression (very high performance but huge size) - /// 无压缩 (高性能但体积很大) - /// - NoCompression = 2 - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Serialization/Interfaces/INinoWrapper.cs b/Nino_Unity/Assets/Nino/Serialization/Interfaces/INinoWrapper.cs deleted file mode 100644 index e88bc93..0000000 --- a/Nino_Unity/Assets/Nino/Serialization/Interfaces/INinoWrapper.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Nino.Serialization -{ - public interface INinoWrapper - { - void Serialize(T val, ref Writer writer); - T Deserialize(Reader reader); - int GetSize(T val); - } - - public interface INinoWrapper - { - void Serialize(object val, ref Writer writer); - object Deserialize(Reader reader); - int GetSize(object val); - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Serialization/Nino.Serialization.asmdef b/Nino_Unity/Assets/Nino/Serialization/Nino.Serialization.asmdef deleted file mode 100644 index 492dba4..0000000 --- a/Nino_Unity/Assets/Nino/Serialization/Nino.Serialization.asmdef +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "Nino.Serialization", - "references": [ - "Nino.Shared", - "ILRuntime" - ], - "includePlatforms": [], - "excludePlatforms": [], - "allowUnsafeCode": true, - "overrideReferences": false, - "precompiledReferences": [], - "autoReferenced": true, - "defineConstraints": [], - "versionDefines": [], - "noEngineReferences": true -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Serialization/Reader.Generic.cs b/Nino_Unity/Assets/Nino/Serialization/Reader.Generic.cs deleted file mode 100644 index 03f8fac..0000000 --- a/Nino_Unity/Assets/Nino/Serialization/Reader.Generic.cs +++ /dev/null @@ -1,469 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace Nino.Serialization -{ - /// - /// Generic methods for reader (ILRuntime hotupdate requests wont access here) - /// - public unsafe partial class Reader - { - /// - /// Read primitive value from binary writer, DO NOT USE THIS FOR CUSTOM EXPORTER - /// Compress and write enum - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public T ReadCommonVal() => - Deserializer.Deserialize(buffer.AsSpan(position, _length - position), this, false); - - /// - /// Compress and write enum - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public T ReadEnum() - { - T val = default; - ReadEnum(ref val); - return val; - } - - /// - /// Compress and write enum - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ReadEnum(ref T val) - { - if (EndOfReader) return; - - switch (TypeModel.GetTypeCode(typeof(T))) - { - case TypeCode.Byte: - Unsafe.As(ref val) = ReadByte(); - return; - case TypeCode.SByte: - Unsafe.As(ref val) = ReadSByte(); - return; - case TypeCode.Int16: - Unsafe.As(ref val) = ReadInt16(); - return; - case TypeCode.UInt16: - Unsafe.As(ref val) = ReadUInt16(); - return; - case TypeCode.Int32: - Unsafe.As(ref val) = ReadInt32(); - return; - case TypeCode.UInt32: - Unsafe.As(ref val) = ReadUInt32(); - return; - case TypeCode.Int64: - Unsafe.As(ref val) = ReadInt64(); - return; - case TypeCode.UInt64: - Unsafe.As(ref val) = ReadUInt64(); - return; - } - } - - /// - /// Read unmanaged type - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public T Read(int len) where T : unmanaged - { - if (EndOfReader) - { - return default; - } - - var ret = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T))); - position += len; - return ret; - } - - /// - /// Read unmanaged type - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - // ReSharper disable UnusedMember.Local - internal void ReadAsUnmanaged(ref T val, int len) - // ReSharper restore UnusedMember.Local - { - if (EndOfReader) - { - return; - } - - Span span = buffer.AsSpan(position, len); - var first = span[0]; - val = Unsafe.ReadUnaligned(ref first); - position += len; - } - - /// - /// Read unmanaged type - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - // ReSharper disable UnusedMember.Local - public void Read(ref T val, int len) where T : unmanaged - // ReSharper restore UnusedMember.Local - { - if (EndOfReader) - { - return; - } - - val = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T))); - position += len; - } - - /// - /// Read unmanaged type - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Read(ref T1 val1, int len1, ref T2 val2, int len2) where T1 : unmanaged where T2 : unmanaged - { - if (EndOfReader) - { - return; - } - - val1 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T1))); - position += len1; - val2 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T2))); - position += len2; - } - - /// - /// Read unmanaged type - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Read(ref T1 val1, int len1, ref T2 val2, int len2, ref T3 val3, int len3) - where T1 : unmanaged where T2 : unmanaged where T3 : unmanaged - { - if (EndOfReader) - { - return; - } - - val1 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T1))); - position += len1; - val2 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T2))); - position += len2; - val3 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T3))); - position += len3; - } - - /// - /// Read unmanaged type - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Read(ref T1 val1, int len1, ref T2 val2, int len2, ref T3 val3, int len3, - ref T4 val4, int len4) where T1 : unmanaged where T2 : unmanaged where T3 : unmanaged where T4 : unmanaged - { - if (EndOfReader) - { - return; - } - - val1 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T1))); - position += len1; - val2 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T2))); - position += len2; - val3 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T3))); - position += len3; - val4 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T4))); - position += len4; - } - - /// - /// Read unmanaged type - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Read(ref T1 val1, int len1, ref T2 val2, int len2, ref T3 val3, int len3, - ref T4 val4, int len4, ref T5 val5, int len5) where T1 : unmanaged - where T2 : unmanaged - where T3 : unmanaged - where T4 : unmanaged - where T5 : unmanaged - { - if (EndOfReader) - { - return; - } - - val1 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T1))); - position += len1; - val2 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T2))); - position += len2; - val3 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T3))); - position += len3; - val4 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T4))); - position += len4; - val5 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T5))); - position += len5; - } - - /// - /// Read unmanaged type - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Read(ref T1 val1, int len1, ref T2 val2, int len2, ref T3 val3, int len3, - ref T4 val4, int len4, ref T5 val5, int len5, ref T6 val6, int len6) where T1 : unmanaged - where T2 : unmanaged - where T3 : unmanaged - where T4 : unmanaged - where T5 : unmanaged - where T6 : unmanaged - { - if (EndOfReader) - { - return; - } - - val1 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T1))); - position += len1; - val2 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T2))); - position += len2; - val3 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T3))); - position += len3; - val4 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T4))); - position += len4; - val5 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T5))); - position += len5; - val6 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T6))); - position += len6; - } - - /// - /// Read unmanaged type - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Read(ref T1 val1, int len1, ref T2 val2, int len2, ref T3 val3, - int len3, ref T4 val4, int len4, ref T5 val5, int len5, ref T6 val6, int len6, ref T7 val7, int len7) - where T1 : unmanaged - where T2 : unmanaged - where T3 : unmanaged - where T4 : unmanaged - where T5 : unmanaged - where T6 : unmanaged - where T7 : unmanaged - { - if (EndOfReader) - { - return; - } - - val1 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T1))); - position += len1; - val2 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T2))); - position += len2; - val3 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T3))); - position += len3; - val4 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T4))); - position += len4; - val5 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T5))); - position += len5; - val6 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T6))); - position += len6; - val7 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T7))); - position += len7; - } - - /// - /// Read unmanaged type - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Read(ref T1 val1, int len1, ref T2 val2, int len2, ref T3 val3, - int len3, ref T4 val4, int len4, ref T5 val5, int len5, ref T6 val6, int len6, ref T7 val7, int len7, - ref T8 val8, int len8) where T1 : unmanaged - where T2 : unmanaged - where T3 : unmanaged - where T4 : unmanaged - where T5 : unmanaged - where T6 : unmanaged - where T7 : unmanaged - where T8 : unmanaged - { - if (EndOfReader) - { - return; - } - - val1 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T1))); - position += len1; - val2 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T2))); - position += len2; - val3 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T3))); - position += len3; - val4 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T4))); - position += len4; - val5 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T5))); - position += len5; - val6 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T6))); - position += len6; - val7 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T7))); - position += len7; - val8 = MemoryMarshal.Read(buffer.AsSpan(position, sizeof(T8))); - position += len8; - } - - /// - /// Read nullable - /// - /// - /// - public T? ReadNullable() where T : struct - { - if (!ReadBool()) - { - return null; - } - - return ReadCommonVal(); - } - - - /// - /// Read Array - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public T[] ReadArray() - { - if (EndOfReader) return default; - //check null - if (!ReadBool()) return null; - - //read len - int len = ReadLength(); - - T[] arr = new T[len]; - //read item - int i = 0; - while (i < len) - { - arr[i++] = ReadCommonVal(); - } - - return arr; - } - - /// - /// Read list - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public List ReadList() - { - if (EndOfReader) return default; - //check null - if (!ReadBool()) return null; - //read len - int len = ReadLength(); - List lst = new List(); - //read item - while (len-- > 0) - { - lst.Add(ReadCommonVal()); - } - - return lst; - } - - /// - /// Read hashset - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public HashSet ReadHashSet() - { - if (EndOfReader) return default; - //check null - if (!ReadBool()) return null; - //read len - int len = ReadLength(); - HashSet lst = new HashSet(); - //read item - while (len-- > 0) - { - lst.Add(ReadCommonVal()); - } - - return lst; - } - - /// - /// Read Queue - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Queue ReadQueue() - { - if (EndOfReader) return default; - //check null - if (!ReadBool()) return null; - //read len - int len = ReadLength(); - Queue lst = new Queue(); - //read item - while (len-- > 0) - { - lst.Enqueue(ReadCommonVal()); - } - - return lst; - } - - /// - /// Read Stack - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Stack ReadStack() - { - if (EndOfReader) return default; - //reverse stack - var arr = ReadArray(); - if (arr == null) - { - return null; - } - - Array.Reverse(arr); - var lst = new Stack(arr); - - return lst; - } - - /// - /// Read Dictionary - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Dictionary ReadDictionary() - { - if (EndOfReader) return default; - if (!ReadBool()) return null; - //read len - int len = ReadLength(); - Dictionary dic = new Dictionary(); - //read item - while (len-- > 0) - { - var key = ReadCommonVal(); - var val = ReadCommonVal(); - dic.Add(key, val); - } - - return dic; - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Serialization/Reader.cs b/Nino_Unity/Assets/Nino/Serialization/Reader.cs deleted file mode 100644 index a22f87f..0000000 --- a/Nino_Unity/Assets/Nino/Serialization/Reader.cs +++ /dev/null @@ -1,443 +0,0 @@ -using System; -using Nino.Shared.IO; -using Nino.Shared.Mgr; -using System.Collections; -using System.Runtime.CompilerServices; - -namespace Nino.Serialization -{ - /// - /// A read that Reads serialization Data - /// - public unsafe partial class Reader - { - /// - /// block size when creating buffer - /// - private const ushort BufferBlockSize = ushort.MaxValue; - - /// - /// Buffer that stores data - /// - private ExtensibleBuffer buffer; - - /// - /// Position of the current buffer - /// - private int position; - - /// - /// Length of the current reader - /// - private int _length; - - /// - /// End of Reader - /// - public bool EndOfReader => position >= _length; - - /// - /// Create an empty reader, need to set up values - /// - public Reader() - { - } - - /// - /// Create a nino read - /// - /// - /// - public Reader(byte[] data, int outputLength) - { - Init(data, outputLength); - } - - /// - /// Create a nino read - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void Init(IntPtr data, int outputLength) - { - if (buffer == null) - { - var peak = ObjectPool>.Peak(); - if (peak != null && peak.ExpandSize == BufferBlockSize) - { - buffer = ObjectPool>.Request(); - } - else - { - buffer = new ExtensibleBuffer(BufferBlockSize); - } - } - - buffer.CopyFrom((byte*)data, 0, 0, outputLength); - position = 0; - _length = outputLength; - } - - /// - /// Create a nino reader - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Init(Span data, int outputLength) - { - fixed (byte* ptr = &data.GetPinnableReference()) - { - Init((IntPtr)ptr, outputLength); - } - } - - /// - /// Create a nino reader - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Init(byte[] data, int outputLength) - { - fixed (byte* ptr = data) - { - Init((IntPtr)ptr, outputLength); - } - } - - /// - /// Get Length - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int ReadLength() => ReadInt32(); - - /// - /// Read primitive value from binary writer, DO NOT USE THIS FOR CUSTOM EXPORTER - /// Compress and write enum - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public object ReadCommonVal(Type type) => - Deserializer.Deserialize(type, ConstMgr.Null, ConstMgr.Null, this, false); - - /// - /// Read a byte - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public byte ReadByte() - { - if (EndOfReader) return default; - - return buffer[position++]; - } - - /// - /// Read byte[] - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public byte[] ReadBytes(int len) - { - if (EndOfReader) return default; - - byte[] ret = new byte[len]; - fixed (byte* ptr = ret) - { - buffer.CopyTo(ptr, position, len); - position += len; - } - - return ret; - } - - /// - /// Copy buffer to a buffer, usually buffer allocated with stackalloc - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void ReadToBuffer(byte* ptr, int len) - { - buffer.CopyTo(ptr, position, len); - position += len; - } - - /// - /// Read sbyte - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public sbyte ReadSByte() => Unsafe.As(ref buffer.Data[position++]); - - /// - /// Read char - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public char ReadChar() => Read(ConstMgr.SizeOfUShort); - - /// - /// Read DateTime - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public DateTime ReadDateTime() - { - if (EndOfReader) return default; - - return Read(ConstMgr.SizeOfLong); - } - - /// - /// Read short - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public short ReadInt16() => Read(ConstMgr.SizeOfShort); - - /// - /// Read ushort - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ushort ReadUInt16() => Read(ConstMgr.SizeOfUShort); - - /// - /// Read int - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int ReadInt32() => Read(ConstMgr.SizeOfInt); - - /// - /// Read uint - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public uint ReadUInt32() => Read(ConstMgr.SizeOfUInt); - - /// - /// Read long - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public long ReadInt64() => Read(ConstMgr.SizeOfLong); - - /// - /// Read ulong - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ulong ReadUInt64() => Read(ConstMgr.SizeOfULong); - - /// - /// Read float - /// - /// - [System.Security.SecuritySafeCritical] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float ReadSingle() => Read(ConstMgr.SizeOfUInt); - - /// - /// Read float - /// - /// - [System.Security.SecuritySafeCritical] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public float ReadFloat() => ReadSingle(); - - /// - /// Read double - /// - /// - [System.Security.SecuritySafeCritical] - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public double ReadDouble() => Read(ConstMgr.SizeOfULong); - - /// - /// Read decimal - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public decimal ReadDecimal() => Read(ConstMgr.SizeOfDecimal); - - /// - /// Read bool - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool ReadBool() - { - if (EndOfReader) return default; - - return buffer[position++] == 1; - } - - /// - /// Read string - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public string ReadString() - { - if (EndOfReader) return default; - if (!ReadBool()) return null; - - int len = ReadInt32(); - //empty string -> no gc - if (len == 0) - { - return String.Empty; - } - - byte* ptr = buffer.Data + position; - position += len; - char* chars = (char*)ptr; - return new string(chars, 0, len / ConstMgr.SizeOfUShort); - } - - /// - /// Compress and write enum - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ulong ReadEnum(Type enumType) - { - if (EndOfReader) return default; - - switch (TypeModel.GetTypeCode(enumType)) - { - case TypeCode.Byte: - return ReadByte(); - case TypeCode.SByte: - return (ulong)ReadSByte(); - case TypeCode.Int16: - return (ulong)ReadInt16(); - case TypeCode.UInt16: - return ReadUInt16(); - case TypeCode.Int32: - return (ulong)ReadInt32(); - case TypeCode.UInt32: - return ReadUInt32(); - case TypeCode.Int64: - return (ulong)ReadInt64(); - case TypeCode.UInt64: - return ReadUInt64(); - } - - return 0; - } - - /// - /// Read Array - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public Array ReadArray(Type type) - { - if (EndOfReader) return default; - - //basic type - if (WrapperManifest.TryGetWrapper(type, out var wrapper)) - { - var ret = wrapper.Deserialize(this); - return (Array)ret; - } - - //other type - //check null - if (!ReadBool()) return null; - var elemType = type.GetElementType(); - if (elemType == null) - { - throw new NullReferenceException("element type is null, can not make array"); - } - - //read len - int len = ReadLength(); - - Array arr = Array.CreateInstance(elemType, len); - //read item - int i = 0; - while (i < len) - { - var obj = ReadCommonVal(elemType); - arr.SetValue(obj, i++); - } - - return arr; - } - - /// - /// Read list - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public IList ReadList(Type type) - { - if (EndOfReader) return default; - - //basic type - if (WrapperManifest.TryGetWrapper(type, out var wrapper)) - { - var ret = wrapper.Deserialize(this); - return (IList)ret; - } - - //other - //check null - if (!ReadBool()) return null; - var elemType = type.GenericTypeArguments[0]; - - //read len - int len = ReadLength(); - - IList arr = Activator.CreateInstance(type, ConstMgr.EmptyParam) as IList; - //read item - int i = 0; - while (i++ < len) - { - var obj = ReadCommonVal(elemType); - arr?.Add(obj); - } - - return arr; - } - - /// - /// Read Dictionary - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public IDictionary ReadDictionary(Type type) - { - if (EndOfReader) return default; - if (!ReadBool()) return null; - - //parse dict type - var args = type.GetGenericArguments(); - Type keyType = args[0]; - Type valueType = args[1]; - - var dict = Activator.CreateInstance(type) as IDictionary; - - //read len - int len = ReadLength(); - - //read item - int i = 0; - while (i++ < len) - { - //read key - var key = ReadCommonVal(keyType); - //read value - var val = ReadCommonVal(valueType); - - //add - dict?.Add(key, val); - } - - return dict; - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Serialization/Serializer.Generic.cs b/Nino_Unity/Assets/Nino/Serialization/Serializer.Generic.cs deleted file mode 100644 index 65dad70..0000000 --- a/Nino_Unity/Assets/Nino/Serialization/Serializer.Generic.cs +++ /dev/null @@ -1,418 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace Nino.Serialization -{ - public static partial class Serializer - { - /// - /// Attempt to serialize hard-coded types + code gen types + custom delegate types - /// - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool TrySerializeWrapperType(Type type, ref T value, ref Writer writer) - { - //basic type - if (!WrapperManifest.TryGetWrapper(type, out var wrapper)) - { - return false; - } - - if (wrapper is NinoWrapperBase @base) - { - @base.Serialize(value, ref writer); - } - else - { - wrapper.Serialize(value, ref writer); - } - - return true; - } - - /// - /// Attempt to serialize enum - /// - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool TrySerializeEnumType(Type type, ref T value, ref Writer writer) - { - //enum - if (!TypeModel.IsEnum(type)) - { - return false; - } - - writer.WriteEnum(value); - return true; - } - - /// - /// Attempt to serialize unmanaged type - /// - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool TrySerializeUnmanagedType(Type type, ref T value, ref Writer writer) - { - //enum - if (!TypeModel.IsUnmanaged(type)) - { - return false; - } - - writer.WriteAsUnmanaged(ref value, Marshal.SizeOf()); - return true; - } - - /// - /// Attempt to serialize code gen type (first time only) - /// - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool TrySerializeCodeGenType(Type type, ref T value, ref Writer writer) - { - //code generated type - if (!TypeModel.TryGetWrapper(type, out var wrapper)) - { - return false; - } - - //add wrapper - WrapperManifest.AddWrapper(type, wrapper); - - //start serialize - if (wrapper is NinoWrapperBase @base) - { - @base.Serialize(value, ref writer); - } - else - { - wrapper.Serialize(value, ref writer); - } - - return true; - } - - /// - /// Attempt to serialize array - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool TrySerializeArray(ref T value, ref Writer writer) - { - //array - if (!(value is Array arr)) - { - return false; - } - - writer.Write(arr); - return true; - } - - /// - /// Attempt to serialize list (boxed) - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool TrySerializeList(ref T value, ref Writer writer) - { - if (!(value is IList lst)) - { - return false; - } - - writer.Write(lst); - return true; - } - - /// - /// Attempt to serialize dict - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool TrySerializeDict(ref T value, ref Writer writer) - { - if (!(value is IDictionary dict)) - { - return false; - } - - writer.Write(dict); - return true; - } - - /// - /// Serialize an array of NinoSerialize object - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte[] Serialize(T[] val) - { - int length = GetSize(in val); - if (length == 0) - { - return Array.Empty(); - } - - byte[] ret = new byte[length]; - if (val == null) - { - return ret; - } - - Writer writer = new Writer(ret.AsSpan(), 0); - - /* - * HARD-CODED SERIALIZATION - */ - if (TrySerializeWrapperType(typeof(T[]), ref val, ref writer)) - { - return ret; - } - - //attempt to serialize using generic method - writer.Write(val); - return ret; - } - - /// - /// Serialize a nullable of NinoSerialize struct - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte[] Serialize(T? val) where T : struct - { - int length = GetSize(in val); - if (length == 0) - { - return Array.Empty(); - } - - byte[] ret = new byte[length]; - if (val == null) - { - return ret; - } - - Writer writer = new Writer(ret.AsSpan(), 0); - - //attempt to serialize using generic method - writer.Write(val); - return ret; - } - - /// - /// Serialize a list of NinoSerialize object - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte[] Serialize(List val) - { - int length = GetSize(in val); - if (length == 0) - { - return Array.Empty(); - } - - byte[] ret = new byte[length]; - if (val == null) - { - return ret; - } - - Writer writer = new Writer(ret.AsSpan(), 0); - - /* - * HARD-CODED SERIALIZATION - */ - if (TrySerializeWrapperType(typeof(List), ref val, ref writer)) - { - return ret; - } - - //attempt to serialize using generic method - writer.Write(val); - return ret; - } - - /// - /// Serialize a hashset of NinoSerialize object - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte[] Serialize(HashSet val) - { - int length = GetSize(in val); - if (length == 0) - { - return Array.Empty(); - } - - byte[] ret = new byte[length]; - if (val == null) - { - return ret; - } - - Writer writer = new Writer(ret.AsSpan(), 0); - - /* - * HARD-CODED SERIALIZATION - */ - if (TrySerializeWrapperType(typeof(HashSet), ref val, ref writer)) - { - return ret; - } - - //attempt to serialize using generic method - writer.Write(val); - return ret; - } - - /// - /// Serialize a hashset of NinoSerialize object - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte[] Serialize(Queue val) - { - int length = GetSize(in val); - if (length == 0) - { - return Array.Empty(); - } - - byte[] ret = new byte[length]; - if (val == null) - { - return ret; - } - - Writer writer = new Writer(ret.AsSpan(), 0); - - /* - * HARD-CODED SERIALIZATION - */ - if (TrySerializeWrapperType(typeof(Queue), ref val, ref writer)) - { - return ret; - } - - //attempt to serialize using generic method - writer.Write(val); - return ret; - } - - /// - /// Serialize a hashset of NinoSerialize object - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte[] Serialize(Stack val) - { - int length = GetSize(in val); - if (length == 0) - { - return Array.Empty(); - } - - byte[] ret = new byte[length]; - if (val == null) - { - return ret; - } - - Writer writer = new Writer(ret.AsSpan(), 0); - - /* - * HARD-CODED SERIALIZATION - */ - if (TrySerializeWrapperType(typeof(Stack), ref val, ref writer)) - { - return ret; - } - - //attempt to serialize using generic method - writer.Write(val); - return ret; - } - - /// - /// Serialize a dictionary of NinoSerialize object - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte[] Serialize(Dictionary val) - { - int length = GetSize(in val); - if (length == 0) - { - return Array.Empty(); - } - - byte[] ret = new byte[length]; - if (val == null) - { - return ret; - } - - Writer writer = new Writer(ret.AsSpan(), 0); - - /* - * HARD-CODED SERIALIZATION - */ - if (TrySerializeWrapperType(typeof(Dictionary), ref val, ref writer)) - { - return ret; - } - - //attempt to serialize using generic method - writer.Write(val); - return ret; - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Serialization/Serializer.Helper.cs b/Nino_Unity/Assets/Nino/Serialization/Serializer.Helper.cs deleted file mode 100644 index bc20e19..0000000 --- a/Nino_Unity/Assets/Nino/Serialization/Serializer.Helper.cs +++ /dev/null @@ -1,437 +0,0 @@ -// Serializer.Helper.cs -// -// Author: -// JasonXuDeveloper(傑) -// -// Copyright (c) 2023 Nino - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using Nino.Shared.Mgr; - -namespace Nino.Serialization -{ - public static partial class Serializer - { - private static readonly Dictionary FixedSizeCache = new Dictionary() - { - { typeof(bool), 1 }, - { typeof(byte), 1 }, - { typeof(sbyte), 1 }, - { typeof(char), 2 }, - { typeof(short), 2 }, - { typeof(ushort), 2 }, - { typeof(int), 4 }, - { typeof(uint), 4 }, - { typeof(long), 8 }, - { typeof(ulong), 8 }, - { typeof(float), 4 }, - { typeof(double), 8 }, - { typeof(decimal), 16 }, - { typeof(DateTime), 8 }, - { typeof(TimeSpan), 8 }, - { typeof(Guid), 16 }, - { typeof(IntPtr), 8 }, - { typeof(UIntPtr), 8 }, - }; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int GetFixedSize() - { - if (FixedSizeCache.TryGetValue(typeof(T), out var size)) - { - return size; - } - - return -1; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int GetFixedSize(Type type) - { - if (FixedSizeCache.TryGetValue(type, out var size)) - { - return size; - } - - return -1; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void SetFixedSize(int size) - { - FixedSizeCache[typeof(T)] = size; - } - - public static int GetSize(in T[] val = default, Dictionary members = null) - { - if (val == null) return 1; - var type = typeof(T); - int length = val.Length; - - if (!WrapperManifest.TryGetWrapper(type, out var wrapper)) - { - if (TypeModel.TryGetWrapper(type, out wrapper)) - { - WrapperManifest.AddWrapper(type, wrapper); - } - } - - if (TypeModel.IsUnmanaged(type)) - { - return Unsafe.SizeOf() * length + 1 + 4; - } - - if (FixedSizeCache.TryGetValue(type, out var size)) - { - return 1 + 4 + length * size; - } - - return GetSize(typeof(T[]), val, members); - } - - public static int GetSize(in List val = default, Dictionary members = null) - { - if (val == null) return 1; - var type = typeof(T); - int length = val.Count; - - if (!WrapperManifest.TryGetWrapper(type, out var wrapper)) - { - if (TypeModel.TryGetWrapper(type, out wrapper)) - { - WrapperManifest.AddWrapper(type, wrapper); - } - } - - if (TypeModel.IsUnmanaged(type)) - { - return Unsafe.SizeOf() * length + 1 + 4; - } - - if (FixedSizeCache.TryGetValue(type, out var size)) - { - return 1 + 4 + length * size; - } - - return GetSize(typeof(List), val, members); - } - - public static int GetSize(in T? val = default, Dictionary members = null) - where T : struct - { - if (val == null) return 1; - var type = typeof(T); - - if (!WrapperManifest.TryGetWrapper(type, out var wrapper)) - { - if (TypeModel.TryGetWrapper(type, out wrapper)) - { - WrapperManifest.AddWrapper(type, wrapper); - } - } - - if (TypeModel.IsUnmanaged(type)) - { - return Unsafe.SizeOf() + 1; - } - - if (FixedSizeCache.TryGetValue(type, out var size)) - { - return 1 + size; - } - - return GetSize(typeof(T?), val, members); - } - - public static int GetSize(in T val = default, Dictionary members = null) - { - var type = typeof(T); - int size = 0; - if (TypeModel.IsEnum(type)) type = type.GetEnumUnderlyingType(); - - //nullable - if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) - { - type = type.GetGenericArguments()[0]; - size += 1; - } - - if (val == null) return 1; - - if (FixedSizeCache.TryGetValue(type, out var size2)) - { - return size + size2; - } - - if (!WrapperManifest.TryGetWrapper(type, out var wrapper)) - { - //code generated type - if (TypeModel.TryGetWrapper(type, out wrapper)) - { - //add wrapper - WrapperManifest.AddWrapper(type, wrapper); - } - } - - if (wrapper != null) - { - if (wrapper is NinoWrapperBase @base) - { - return size + @base.GetSize(val); - } - - return size + wrapper.GetSize(val); - } - - if (TypeModel.IsUnmanaged(type)) - { - return Unsafe.SizeOf(); - } - - return GetSize(type, val, members); - } - - public static int GetSize(Type type, object obj, Dictionary members = null) - { - if (TypeModel.IsEnum(type)) type = type.GetEnumUnderlyingType(); - - int size = 0; - bool isGeneric = type.IsGenericType; - Type genericTypeDef = null; - Type[] genericArgs = null; - if (isGeneric) - { - genericTypeDef = type.GetGenericTypeDefinition(); - genericArgs = type.GetGenericArguments(); - } - - //nullable - if (genericTypeDef != null && genericTypeDef == typeof(Nullable<>)) - { - type = genericArgs[0]; - size += 1; - } - - if (obj == null) return 1; - - if (FixedSizeCache.TryGetValue(type, out var size2)) - { - return size + size2; - } - - if (!WrapperManifest.TryGetWrapper(type, out var wrapper)) - { - //code generated type - if (TypeModel.TryGetWrapper(type, out wrapper)) - { - //add wrapper - WrapperManifest.AddWrapper(type, wrapper); - } - } - - if (wrapper != null) - { - return size + wrapper.GetSize(obj); - } - - if (TypeModel.IsUnmanaged(type)) - { - return Marshal.SizeOf(type); - } - - size = 1; //null indicator - - if (type == ConstMgr.ObjectType) - { - type = obj.GetType(); - } - - if (type.IsArray) - { - var elementType = type.GetElementType(); - var array = obj as Array; - if (array == null) - { - return size; - } - - size += 4; //length - if (array.Length == 0) return size; - - if (elementType != null && FixedSizeCache.TryGetValue(elementType, out var eleSize)) - { - size += eleSize * array.Length; - return size; - } - - foreach (var item in array) - { - size += GetSize(elementType, item); - } - - return size; - } - - if (isGeneric && genericTypeDef != null) - { - switch (genericTypeDef) - { - case var _ when genericTypeDef.GetInterface(nameof(IList)) != null: - var lstElemType = genericArgs[0]; - var lst = obj as ICollection; - if (lst == null) - { - return size; - } - - size += 4; //length - if (lst.Count == 0) return size; - - if (FixedSizeCache.TryGetValue(lstElemType, out var lstEleSize)) - { - size += lstEleSize * lst.Count; - return size; - } - - foreach (var item in lst) - { - size += GetSize(lstElemType, item); - } - - return size; - case var _ when genericTypeDef.GetInterface(nameof(IDictionary)) != null: - var keyType = genericArgs[0]; - var valueType = genericArgs[1]; - var dict = obj as IDictionary; - if (dict == null) - { - return size; - } - - size += 4; //length - if (dict.Count == 0) return size; - - bool hasKeySize = FixedSizeCache.TryGetValue(keyType, out var keySize); - bool hasValueSize = FixedSizeCache.TryGetValue(valueType, out var valueSize); - - if (hasKeySize && hasValueSize) - { - size += (keySize + valueSize) * dict.Count; - return size; - } - - if (hasKeySize) - { - size += keySize * dict.Count; - foreach (var item in dict.Values) - { - size += GetSize(valueType, item); - } - - return size; - } - - if (hasValueSize) - { - size += valueSize * dict.Count; - foreach (var item in dict.Keys) - { - size += GetSize(keyType, item); - } - - return size; - } - - foreach (DictionaryEntry item in dict) - { - size += GetSize(keyType, item.Key); - size += GetSize(valueType, item.Value); - } - - return size; - case var _ when genericTypeDef.GetInterface(nameof(ICollection)) != null: - var elementType2 = genericArgs[0]; - var collection = obj as ICollection; - if (collection == null) - { - return size; - } - - size += 4; //length - if (collection.Count == 0) return size; - - if (FixedSizeCache.TryGetValue(elementType2, out var eleSize)) - { - size += eleSize * collection.Count; - return size; - } - - foreach (var item in collection) - { - size += GetSize(elementType2, item); - } - - return size; - case var _ when genericTypeDef.GetInterface(nameof(IEnumerable)) != null: - var elementType = genericArgs[0]; - var enumerable = obj as IEnumerable; - if (enumerable == null) - { - return size; - } - - size += 4; //length - - var enumerator = enumerable.GetEnumerator(); - if (!enumerator.MoveNext()) return size; - do - { - size += GetSize(elementType, enumerator.Current); - } while (enumerator.MoveNext()); - - return size; - } - } - - //Nino serializable type - TypeModel.TryGetModel(type, out var model); - - //invalid model - if (model != null && !model.Valid) - { - throw new InvalidOperationException($"Invalid model for type {type}"); - } - - //generate model - if (model == null) - { - model = TypeModel.CreateModel(type); - } - - var isFixed = true; - foreach (var info in model.Members) - { - object memberObj = info.GetValue(obj); - if (members != null) - { - members[info.Member] = memberObj; - } - - size += GetSize(info.Type, memberObj); - if (!FixedSizeCache.ContainsKey(info.Type)) - { - isFixed = false; - } - } - - if (isFixed) - FixedSizeCache[type] = size; - return size; - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Serialization/Serializer.cs b/Nino_Unity/Assets/Nino/Serialization/Serializer.cs deleted file mode 100644 index 5b2f0b7..0000000 --- a/Nino_Unity/Assets/Nino/Serialization/Serializer.cs +++ /dev/null @@ -1,196 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Runtime.CompilerServices; -using Nino.Shared.IO; - -namespace Nino.Serialization -{ - public static partial class Serializer - { - /// - /// Serialize a NinoSerialize object - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte[] Serialize(in T val) - { - Dictionary fields = ObjectPool>.Request(); - fields.Clear(); - int length = GetSize(in val, fields); - if (length == 0) - { - return Array.Empty(); - } - - byte[] ret = new byte[length]; - if (val == null) - { - ObjectPool>.Return(fields); - return ret; - } - - Serialize(typeof(T), val, fields, ret.AsSpan(), 0); - ObjectPool>.Return(fields); - return ret; - } - - /// - /// Serialize a NinoSerialize object - /// - /// - /// - /// - /// - /// actual written size - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int Serialize(Span buffer, in T val, Dictionary fields = null) - { - if (val == null) - { - buffer[0] = 0; - return 1; - } - - return Serialize(typeof(T), val, fields, buffer, 0); - } - - /// - /// Serialize a NinoSerialize object - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte[] Serialize(object val) - { - Dictionary fields = ObjectPool>.Request(); - fields.Clear(); - int length = GetSize(in val, fields); - if (length == 0) - { - return Array.Empty(); - } - - byte[] ret = new byte[length]; - if (val == null) - { - ObjectPool>.Return(fields); - return ret; - } - - Serialize(val.GetType(), val, fields, ret.AsSpan(), 0); - ObjectPool>.Return(fields); - return ret; - } - - /// - /// Serialize a NinoSerialize object - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int Serialize(Span buffer, object val) - { - if (val == null) - { - buffer[0] = 0; - return 1; - } - - return Serialize(val.GetType(), val, null, buffer, 0); - } - - internal static int Serialize(Type type, T value, Dictionary fields, Span buffer, - int pos) - { - Writer writer = new Writer(buffer, pos); - - //null check - if (value == null) - { - writer.Write(false); // false -> is null - return writer.Position; - } - - /* - * HARD-CODED SERIALIZATION - */ - - if (TrySerializeWrapperType(type, ref value, ref writer)) - { - return writer.Position; - } - - if (TrySerializeEnumType(type, ref value, ref writer)) - { - return writer.Position; - } - - if (TrySerializeCodeGenType(type, ref value, ref writer)) - { - return writer.Position; - } - - if (TrySerializeUnmanagedType(type, ref value, ref writer)) - { - return writer.Position; - } - - if (TrySerializeArray(ref value, ref writer)) - { - return writer.Position; - } - - //generic - if (type.IsGenericType) - { - if (TrySerializeList(ref value, ref writer)) - { - return writer.Position; - } - - if (TrySerializeDict(ref value, ref writer)) - { - return writer.Position; - } - } - - /* - * CUSTOM STRUCT/CLASS SERIALIZATION - */ - writer.Write(true); //true -> not null - - //Get Attribute that indicates a class/struct to be serialized - TypeModel.TryGetModel(type, out var model); - - //invalid model - if (model != null && !model.Valid) - { - return 0; - } - - //generate model - if (model == null) - { - model = TypeModel.CreateModel(type); - } - - //serialize all recorded members - foreach (var info in model.Members) - { - type = info.Type; - if (fields == null || !fields.TryGetValue(info.Member, out var obj)) - { - obj = info.GetValue(value); - } - - writer.Position = Serialize(type, obj, null, buffer, writer.Position); - } - - return writer.Position; - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Serialization/TypeModel.cs b/Nino_Unity/Assets/Nino/Serialization/TypeModel.cs deleted file mode 100644 index 164af57..0000000 --- a/Nino_Unity/Assets/Nino/Serialization/TypeModel.cs +++ /dev/null @@ -1,348 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Concurrent; -using Nino.Shared.Util; -using System.Reflection; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using System.Threading; -using Nino.Shared.IO; - -// ReSharper disable CognitiveComplexity - -namespace Nino.Serialization -{ - /// - /// A model of a serialized type - /// - internal class TypeModel - { - private const string HelperName = "NinoSerializationHelper"; - - private const BindingFlags ReflectionFlags = - BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Default; - - private const BindingFlags StaticReflectionFlags = ReflectionFlags | BindingFlags.Static; - private const BindingFlags FlattenHierarchyReflectionFlags = ReflectionFlags | BindingFlags.FlattenHierarchy; - private static readonly Type NinoSerializeType = typeof(NinoSerializeAttribute); - private static readonly Type NinoMemberType = typeof(NinoMemberAttribute); - private static readonly Type NinoIgnoreType = typeof(NinoIgnoreAttribute); - private static readonly Type CompilerGeneratedType = typeof(CompilerGeneratedAttribute); - - public List Members; - - public struct NinoMember - { - public MemberInfo Member; - public Type Type; - public Func GetValue; - - public NinoMember(MemberInfo member, Type type, Func getValue) - { - Member = member; - Type = type; - GetValue = getValue; - } - } - - public bool Valid; - public bool IncludeAll; - - /// - /// Cached Models - /// - private static readonly Dictionary TypeModels = new Dictionary(10); - - /// - /// Cached Models - /// - private static readonly Dictionary TypeCodes = new Dictionary(30) - { - { typeof(byte).GetTypeHashCode(), TypeCode.Byte }, - { typeof(sbyte).GetTypeHashCode(), TypeCode.SByte }, - { typeof(short).GetTypeHashCode(), TypeCode.Int16 }, - { typeof(ushort).GetTypeHashCode(), TypeCode.UInt16 }, - { typeof(int).GetTypeHashCode(), TypeCode.Int32 }, - { typeof(uint).GetTypeHashCode(), TypeCode.UInt32 }, - { typeof(long).GetTypeHashCode(), TypeCode.Int64 }, - { typeof(ulong).GetTypeHashCode(), TypeCode.UInt64 }, - { typeof(float).GetTypeHashCode(), TypeCode.Single }, - { typeof(double).GetTypeHashCode(), TypeCode.Double }, - { typeof(decimal).GetTypeHashCode(), TypeCode.Decimal }, - { typeof(char).GetTypeHashCode(), TypeCode.Char }, - { typeof(bool).GetTypeHashCode(), TypeCode.Boolean }, - { typeof(string).GetTypeHashCode(), TypeCode.String }, - { typeof(object).GetTypeHashCode(), TypeCode.Object }, - { typeof(DateTime).GetTypeHashCode(), TypeCode.DateTime }, - }; - - /// - /// Generated helpers - /// - private static readonly Dictionary GeneratedWrapper = new Dictionary(50) - { - { typeof(byte).GetTypeHashCode(), null }, - { typeof(sbyte).GetTypeHashCode(), null }, - { typeof(short).GetTypeHashCode(), null }, - { typeof(ushort).GetTypeHashCode(), null }, - { typeof(int).GetTypeHashCode(), null }, - { typeof(uint).GetTypeHashCode(), null }, - { typeof(long).GetTypeHashCode(), null }, - { typeof(ulong).GetTypeHashCode(), null }, - { typeof(bool).GetTypeHashCode(), null }, - { typeof(float).GetTypeHashCode(), null }, - { typeof(double).GetTypeHashCode(), null }, - { typeof(decimal).GetTypeHashCode(), null }, - { typeof(char).GetTypeHashCode(), null }, - { typeof(string).GetTypeHashCode(), null }, - { typeof(DateTime).GetTypeHashCode(), null }, - }; - - /// - /// Cached Models - /// - private static readonly ConcurrentDictionary IsEnumTypeCache = - new ConcurrentDictionary(3, 30); - - /// - /// Get a type code - /// - /// - /// - internal static TypeCode GetTypeCode(Type type) - { - var hash = type.GetTypeHashCode(); - if (TypeCodes.TryGetValue(hash, out var ret)) - { - return ret; - } - - TypeCodes[hash] = ret = Type.GetTypeCode(type); - return ret; - } - - public static bool IsFixedSizeType(Type type) - { - if (type.IsClass) return false; - return IsUnmanaged(type); - } - - private static readonly ConcurrentDictionary IsManagedTypeCache = - new ConcurrentDictionary(); - - public static bool IsUnmanaged(Type type) - { - if (type.IsPrimitive || IsEnum(type)) return true; - if (!type.IsValueType) return false; - // check if we already know the answer - if (!IsManagedTypeCache.TryGetValue(type, out var ret)) - { - ret = true; - // otherwise check recursively - var fields = type - .GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); - foreach (var field in fields) - { - if (field.GetCustomAttributes(CompilerGeneratedType, true).Length > 0 || - !IsUnmanaged(field.FieldType)) - { - ret = false; - break; - } - } - - IsManagedTypeCache[type] = ret; - } - - return ret; - } - - /// - /// Get whether or not a type is enum - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static bool IsEnum(Type type) - { - if (IsEnumTypeCache.TryGetValue(type, out var ret)) return ret; - IsEnumTypeCache[type] = ret = type.IsEnum; - return ret; - } - - /// - /// Get whether or not a type is a code gen type - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static bool TryGetWrapper(Type type, out INinoWrapper helper) - { - var hash = type.GetTypeHashCode(); - if (GeneratedWrapper.TryGetValue(hash, out helper)) return helper != null; - - var field = type.GetField(HelperName, StaticReflectionFlags); - helper = (INinoWrapper)field?.GetValue(null); - GeneratedWrapper[hash] = helper; - return helper != null; - } - - /// - /// Try get cached model - /// - /// - /// - /// - internal static void TryGetModel(Type type, out TypeModel model) - { - var hash = type.GetTypeHashCode(); - if (TypeModels.TryGetValue(hash, out model)) return; - object[] ns = type.GetCustomAttributes(NinoSerializeType, false); - if (ns.Length != 0) return; - model = new TypeModel() - { - Valid = false - }; - TypeModels.Add(hash, model); - throw new InvalidOperationException( - $"The type {type.FullName} does not have NinoSerialize attribute or custom importer/exporter"); - } - - /// - /// Thread safe lock - /// - private static SpinLock _createLock; - - /// - /// Create a typeModel using given type - /// - /// - /// - // ReSharper disable CognitiveComplexity - internal static TypeModel CreateModel(Type type) - // ReSharper restore CognitiveComplexity - { - TypeModel model; - //thread safe - bool lockTaken = false; - try - { - _createLock.Enter(ref lockTaken); - TryGetModel(type, out model); - if (model != null) return model; - model = new TypeModel - { - Valid = true, - //fetch members - Members = new List(), - }; - - //include all or not - object[] ns = type.GetCustomAttributes(NinoSerializeType, true); - model.IncludeAll = ((NinoSerializeAttribute)ns[0]).IncludeAll; - - //flag - ushort index = 0; - //dict - SortedDictionary dict = ObjectPool>.Request(); - dict.Clear(); - - //fetch fields (only public and private fields that declared in the type) - FieldInfo[] fs = type.GetFields(FlattenHierarchyReflectionFlags); - //iterate fields - foreach (var f in fs) - { - if (f.GetCustomAttributes(CompilerGeneratedType, true).Length > 0) - { - continue; - } - - if (model.IncludeAll) - { - //skip nino ignore - var ig = f.GetCustomAttributes(NinoIgnoreType, true); - if (ig.Length > 0) continue; - index++; - } - else - { - ns = f.GetCustomAttributes(NinoMemberType, true); - //not fetch all and no attribute => skip this member - if (ns.Length != 1) continue; - index = ((NinoMemberAttribute)ns[0]).Index; - } - - //record field - dict.Add(index, f); - } - - //fetch properties (only public and private properties that declared in the type) - PropertyInfo[] ps = type.GetProperties(FlattenHierarchyReflectionFlags); - //iterate properties - foreach (var p in ps) - { - if (model.IncludeAll) - { - //skip nino ignore - var ig = p.GetCustomAttributes(NinoIgnoreType, true); - if (ig.Length > 0) continue; - } - - if (model.IncludeAll) - { - index++; - } - else - { - ns = p.GetCustomAttributes(NinoMemberType, true); - //not fetch all and no attribute => skip this member - if (ns.Length != 1) continue; - - //has to have getter and setter - if (!(p.CanRead && p.CanWrite)) - { - if (model.IncludeAll) continue; - throw new InvalidOperationException( - $"Cannot read or write property {p.Name} in {type.FullName}, cannot Serialize or Deserialize this property"); - } - index = ((NinoMemberAttribute)ns[0]).Index; - } - - //record property - dict.Add(index, p); - } - - //add members to model - foreach (var pair in dict) - { - if (pair.Value is FieldInfo fi) - { - model.Members.Add(new NinoMember(fi, fi.FieldType, fi.GetValue)); - } - else if (pair.Value is PropertyInfo pi) - { - model.Members.Add(new NinoMember(pi, pi.PropertyType, pi.GetValue)); - } - } - - //release dict - dict.Clear(); - ObjectPool>.Return(dict); - - if (model.Members.Count == 0) - { - model.Valid = false; - } - - TypeModels[type.GetTypeHashCode()] = model; - } - finally - { - if (lockTaken) _createLock.Exit(false); - } - - return model; - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Serialization/Wrappers/Common/NinoWrapperBase.cs b/Nino_Unity/Assets/Nino/Serialization/Wrappers/Common/NinoWrapperBase.cs deleted file mode 100644 index 897f114..0000000 --- a/Nino_Unity/Assets/Nino/Serialization/Wrappers/Common/NinoWrapperBase.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Runtime.CompilerServices; - -namespace Nino.Serialization -{ - public abstract class NinoWrapperBase : INinoWrapper, INinoWrapper - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public abstract void Serialize(T val, ref Writer writer); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public abstract T Deserialize(Reader reader); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public abstract int GetSize(T val); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Serialize(object val, ref Writer writer) - { - Serialize((T)val, ref writer); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - object INinoWrapper.Deserialize(Reader reader) - { - return Deserialize(reader); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int GetSize(object val) - { - return GetSize((T)val); - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Serialization/Wrappers/Primitives/Basics.cs b/Nino_Unity/Assets/Nino/Serialization/Wrappers/Primitives/Basics.cs deleted file mode 100644 index 66c58ed..0000000 --- a/Nino_Unity/Assets/Nino/Serialization/Wrappers/Primitives/Basics.cs +++ /dev/null @@ -1,395 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Nino.Serialization -{ - internal class BoolWrapper : NinoWrapperBase - { - public override void Serialize(bool val, ref Writer writer) - { - writer.Write(val); - } - - public override bool Deserialize(Reader reader) - { - return reader.ReadBool(); - } - - public override int GetSize(bool val) - { - return 1; - } - } - - internal class BoolArrWrapper : NinoWrapperBase - { - public override void Serialize(bool[] val, ref Writer writer) - { - writer.Write(val.AsSpan()); - } - - public override unsafe bool[] Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - bool[] arr; - if (len == 0) - { - arr = Array.Empty(); - } - else - { - arr = new bool[len]; - fixed (bool* arrPtr = arr) - { - reader.ReadToBuffer((byte*)arrPtr, len); - } - } - - return arr; - } - - public override int GetSize(bool[] val) - { - if (val is null) return 1; - return 1 + 4 + val.Length; - } - } - - internal class BoolListWrapper : NinoWrapperBase> - { - public override void Serialize(List val, ref Writer writer) - { - if (val is null) - { - writer.Write(false); - return; - } - - writer.Write(true); - writer.Write(val.Count); - foreach (var v in val) - { - writer.Write(v); - } - } - - public override List Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - var arr = new List(len); - //read item - int i = 0; - while (i++ < len) - { - arr.Add(reader.ReadBool()); - } - - return arr; - } - - public override int GetSize(List val) - { - if (val is null) return 1; - return 1 + 4 + val.Count; - } - } - - internal class CharWrapper : NinoWrapperBase - { - public override void Serialize(char val, ref Writer writer) - { - writer.Write(val); - } - - public override char Deserialize(Reader reader) - { - return reader.ReadChar(); - } - - public override int GetSize(char val) - { - return 2; - } - } - - internal class CharArrWrapper : NinoWrapperBase - { - public override void Serialize(char[] val, ref Writer writer) - { - writer.Write(val.AsSpan()); - } - - public override unsafe char[] Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - char[] arr; - if (len == 0) - { - arr = Array.Empty(); - } - else - { - arr = new char[len]; - fixed (char* arrPtr = arr) - { - reader.ReadToBuffer((byte*)arrPtr, len * 2); - } - } - - return arr; - } - - public override int GetSize(char[] val) - { - if (val is null) return 1; - return 1 + 4 + val.Length * 2; - } - } - - internal class CharListWrapper : NinoWrapperBase> - { - public override void Serialize(List val, ref Writer writer) - { - if (val is null) - { - writer.Write(false); - return; - } - - writer.Write(true); - writer.Write(val.Count); - foreach (var v in val) - { - writer.Write(v); - } - } - - public override List Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - var arr = new List(len); - //read item - int i = 0; - while (i++ < len) - { - arr.Add(reader.ReadChar()); - } - - return arr; - } - - public override int GetSize(List val) - { - if (val is null) return 1; - return 1 + 4 + val.Count * 2; - } - } - - internal class StringWrapper : NinoWrapperBase - { - public override void Serialize(string val, ref Writer writer) - { - writer.Write(val); - } - - public override string Deserialize(Reader reader) - { - return reader.ReadString(); - } - - public override int GetSize(string val) - { - if (val is null) return 1; - return 1 + 4 + val.Length * 2; - } - } - - internal class StringArrWrapper : NinoWrapperBase - { - public override void Serialize(string[] val, ref Writer writer) - { - if (val is null) - { - writer.Write(false); - return; - } - - writer.Write(true); - writer.Write(val.Length); - foreach (var v in val) - { - writer.Write(v); - } - } - - public override string[] Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - var arr = new string[len]; - int i = 0; - while (i < len) - { - arr[i++] = reader.ReadString(); - } - - return arr; - } - - public override int GetSize(string[] val) - { - if (val is null) return 1; - int size = 1 + 4; - foreach (var v in val) - { - size += 1 + 4 + v.Length * 2; - } - - return size; - } - } - - internal class StringListWrapper : NinoWrapperBase> - { - public override void Serialize(List val, ref Writer writer) - { - if (val is null) - { - writer.Write(false); - return; - } - - writer.Write(true); - writer.Write(val.Count); - foreach (var v in val) - { - writer.Write(v); - } - } - - public override List Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - var arr = new List(len); - //read item - int i = 0; - while (i++ < len) - { - arr.Add(reader.ReadString()); - } - - return arr; - } - - public override int GetSize(List val) - { - if (val is null) return 1; - int size = 1 + 4; - foreach (var v in val) - { - size += 1 + 4 + v.Length * 2; - } - - return size; - } - } - - internal class DateTimeWrapper : NinoWrapperBase - { - public override void Serialize(DateTime val, ref Writer writer) - { - writer.Write(val); - } - - public override DateTime Deserialize(Reader reader) - { - return reader.ReadDateTime(); - } - - public override int GetSize(DateTime val) - { - return 8; - } - } - - internal class DateTimeArrWrapper : NinoWrapperBase - { - public override void Serialize(DateTime[] val, ref Writer writer) - { - writer.Write(val.AsSpan()); - } - - public override unsafe DateTime[] Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - DateTime[] arr; - if (len == 0) - { - arr = Array.Empty(); - } - else - { - arr = new DateTime[len]; - fixed (DateTime* arrPtr = arr) - { - reader.ReadToBuffer((byte*)arrPtr, len * 8); - } - } - - return arr; - } - - public override int GetSize(DateTime[] val) - { - if (val is null) return 1; - return 1 + 4 + val.Length * 8; - } - } - - internal class DateTimeListWrapper : NinoWrapperBase> - { - public override void Serialize(List val, ref Writer writer) - { - if (val is null) - { - writer.Write(false); - return; - } - - writer.Write(true); - writer.Write(val.Count); - foreach (var v in val) - { - writer.Write(v); - } - } - - public override List Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - var arr = new List(len); - int i = 0; - while (i++ < len) - { - arr.Add(reader.ReadDateTime()); - } - - return arr; - } - - public override int GetSize(List val) - { - if (val is null) return 1; - int size = 1 + 4 + val.Count * 8; - - return size; - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Serialization/Wrappers/Primitives/Decimals.cs b/Nino_Unity/Assets/Nino/Serialization/Wrappers/Primitives/Decimals.cs deleted file mode 100644 index 6a376bc..0000000 --- a/Nino_Unity/Assets/Nino/Serialization/Wrappers/Primitives/Decimals.cs +++ /dev/null @@ -1,289 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace Nino.Serialization -{ - internal class FloatWrapper : NinoWrapperBase - { - public override void Serialize(float val, ref Writer writer) - { - writer.Write(val); - } - - public override float Deserialize(Reader reader) - { - return reader.ReadSingle(); - } - - public override int GetSize(float val) - { - return 4; - } - } - - internal class FloatArrWrapper : NinoWrapperBase - { - public override void Serialize(float[] val, ref Writer writer) - { - writer.Write(val.AsSpan()); - } - - public override unsafe float[] Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - float[] arr; - if (len == 0) - { - arr = Array.Empty(); - } - else - { - arr = new float[len]; - fixed (float* arrPtr = arr) - { - reader.ReadToBuffer((byte*)arrPtr, len * 4); - } - } - - return arr; - } - - public override int GetSize(float[] val) - { - if (val is null) return 1; - return 1 + 4 + val.Length * 4; - } - } - - internal class FloatListWrapper : NinoWrapperBase> - { - public override void Serialize(List val, ref Writer writer) - { - if (val is null) - { - writer.Write(false); - return; - } - - writer.Write(true); - writer.Write(val.Count); - foreach (var v in val) - { - writer.Write(v); - } - } - - public override List Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - var arr = new List(len); - //read item - for (int i = 0; i < len; i++) - { - arr.Add(reader.ReadSingle()); - } - - return arr; - } - - public override int GetSize(List val) - { - if (val is null) return 1; - int size = 1 + 4 + val.Count * 4; - - return size; - } - } - - internal class DoubleWrapper : NinoWrapperBase - { - public override void Serialize(double val, ref Writer writer) - { - writer.Write(val); - } - - public override double Deserialize(Reader reader) - { - return reader.ReadDouble(); - } - - public override int GetSize(double val) - { - return 8; - } - } - - internal class DoubleArrWrapper : NinoWrapperBase - { - public override void Serialize(double[] val, ref Writer writer) - { - writer.Write(val.AsSpan()); - } - - public override unsafe double[] Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - double[] arr; - if (len == 0) - { - arr = Array.Empty(); - } - else - { - arr = new double[len]; - fixed (double* arrPtr = arr) - { - reader.ReadToBuffer((byte*)arrPtr, len * 8); - } - } - - return arr; - } - - public override int GetSize(double[] val) - { - if (val is null) return 1; - return 1 + 4 + val.Length * 8; - } - } - - internal class DoubleListWrapper : NinoWrapperBase> - { - public override void Serialize(List val, ref Writer writer) - { - if (val is null) - { - writer.Write(false); - return; - } - - writer.Write(true); - writer.Write(val.Count); - foreach (var v in val) - { - writer.Write(v); - } - } - - public override List Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - var arr = new List(len); - //read item - for (int i = 0; i < len; i++) - { - arr.Add(reader.ReadDouble()); - } - - return arr; - } - - public override int GetSize(List val) - { - if (val is null) return 1; - int size = 1 + 4 + val.Count * 8; - - return size; - } - } - - internal class DecimalWrapper : NinoWrapperBase - { - public override void Serialize(decimal val, ref Writer writer) - { - writer.Write(val); - } - - public override decimal Deserialize(Reader reader) - { - return reader.ReadDecimal(); - } - - public override int GetSize(decimal val) - { - return 16; - } - } - - internal class DecimalArrWrapper : NinoWrapperBase - { - public override void Serialize(decimal[] val, ref Writer writer) - { - writer.Write(val.AsSpan()); - } - - public override unsafe decimal[] Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - decimal[] arr; - if (len == 0) - { - arr = Array.Empty(); - } - else - { - arr = new decimal[len]; - fixed (decimal* arrPtr = arr) - { - reader.ReadToBuffer((byte*)arrPtr, len * 16); - } - } - - return arr; - } - - public override int GetSize(decimal[] val) - { - if (val is null) return 1; - return 1 + 4 + val.Length * 16; - } - } - - internal class DecimalListWrapper : NinoWrapperBase> - { - public override void Serialize(List val, ref Writer writer) - { - if (val is null) - { - writer.Write(false); - return; - } - - writer.Write(true); - writer.Write(val.Count); - foreach (var v in val) - { - writer.Write(v); - } - } - - public override List Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - var arr = new List(len); - //read item - for (int i = 0; i < len; i++) - { - arr.Add(reader.ReadDecimal()); - } - - return arr; - } - - public override int GetSize(List val) - { - if (val is null) return 1; - int size = 1 + 4 + val.Count * 16; - - return size; - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Serialization/Wrappers/Primitives/Integers.cs b/Nino_Unity/Assets/Nino/Serialization/Wrappers/Primitives/Integers.cs deleted file mode 100644 index be67ac2..0000000 --- a/Nino_Unity/Assets/Nino/Serialization/Wrappers/Primitives/Integers.cs +++ /dev/null @@ -1,707 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Nino.Serialization -{ - internal class ByteWrapper : NinoWrapperBase - { - public override void Serialize(byte val, ref Writer writer) - { - writer.Write(val); - } - - public override byte Deserialize(Reader reader) - { - return reader.ReadByte(); - } - - public override int GetSize(byte val) - { - return 1; - } - } - - internal class ByteArrWrapper : NinoWrapperBase - { - public override void Serialize(byte[] val, ref Writer writer) - { - writer.Write(val.AsSpan()); - } - - public override byte[] Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - return len != 0 ? reader.ReadBytes(len) : Array.Empty(); - } - - public override int GetSize(byte[] val) - { - if (val is null) return 1; - return 1 + 4 + val.Length; - } - } - - internal class ByteListWrapper : NinoWrapperBase> - { - public override void Serialize(List val, ref Writer writer) - { - if (val is null) - { - writer.Write(false); - return; - } - - writer.Write(true); - writer.Write(val.Count); - foreach (var v in val) - { - writer.Write(v); - } - } - - public override List Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - var arr = new List(len); - //read item - int i = 0; - while (i++ < len) - { - arr.Add(reader.ReadByte()); - } - - return arr; - } - - public override int GetSize(List val) - { - if (val is null) return 1; - return 1 + 4 + val.Count; - } - } - - internal class SByteWrapper : NinoWrapperBase - { - public override void Serialize(sbyte val, ref Writer writer) - { - writer.Write(val); - } - - public override sbyte Deserialize(Reader reader) - { - return reader.ReadSByte(); - } - - public override int GetSize(sbyte val) - { - return 1; - } - } - - internal class SByteArrWrapper : NinoWrapperBase - { - public override void Serialize(sbyte[] val, ref Writer writer) - { - writer.Write(val.AsSpan()); - } - - public override unsafe sbyte[] Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - sbyte[] arr; - if (len == 0) - { - arr = Array.Empty(); - } - else - { - arr = new sbyte[len]; - fixed (sbyte* arrPtr = arr) - { - reader.ReadToBuffer((byte*)arrPtr, len); - } - } - - return arr; - } - - public override int GetSize(sbyte[] val) - { - if (val is null) return 1; - return 1 + 4 + val.Length; - } - } - - internal class SByteListWrapper : NinoWrapperBase> - { - public override void Serialize(List val, ref Writer writer) - { - if (val is null) - { - writer.Write(false); - return; - } - - writer.Write(true); - writer.Write(val.Count); - foreach (var v in val) - { - writer.Write(v); - } - } - - public override List Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - var arr = new List(len); - //read item - int i = 0; - while (i++ < len) - { - arr.Add(reader.ReadSByte()); - } - - return arr; - } - - public override int GetSize(List val) - { - if (val is null) return 1; - return 1 + 4 + val.Count; - } - } - - internal class ShortWrapper : NinoWrapperBase - { - public override void Serialize(short val, ref Writer writer) - { - writer.Write(val); - } - - public override short Deserialize(Reader reader) - { - return reader.ReadInt16(); - } - - public override int GetSize(short val) - { - return 2; - } - } - - internal class ShortArrWrapper : NinoWrapperBase - { - public override void Serialize(short[] val, ref Writer writer) - { - writer.Write(val.AsSpan()); - } - - public override unsafe short[] Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - short[] arr; - if (len == 0) - { - arr = Array.Empty(); - } - else - { - arr = new short[len]; - fixed (short* arrPtr = arr) - { - reader.ReadToBuffer((byte*)arrPtr, len * 2); - } - } - - return arr; - } - - public override int GetSize(short[] val) - { - if (val is null) return 1; - return 1 + 4 + val.Length * 2; - } - } - - internal class ShortListWrapper : NinoWrapperBase> - { - public override void Serialize(List val, ref Writer writer) - { - if (val is null) - { - writer.Write(false); - return; - } - - writer.Write(true); - writer.Write(val.Count); - foreach (var v in val) - { - writer.Write(v); - } - } - - public override List Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - var arr = new List(len); - //read item - int i = 0; - while (i++ < len) - { - arr.Add(reader.ReadInt16()); - } - - return arr; - } - - public override int GetSize(List val) - { - if (val is null) return 1; - return 1 + 4 + val.Count * 2; - } - } - - internal class UShortWrapper : NinoWrapperBase - { - public override void Serialize(ushort val, ref Writer writer) - { - writer.Write(val); - } - - public override ushort Deserialize(Reader reader) - { - return reader.ReadUInt16(); - } - - public override int GetSize(ushort val) - { - return 2; - } - } - - internal class UShortArrWrapper : NinoWrapperBase - { - public override void Serialize(ushort[] val, ref Writer writer) - { - writer.Write(val.AsSpan()); - } - - public override unsafe ushort[] Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - ushort[] arr; - if (len == 0) - { - arr = Array.Empty(); - } - else - { - arr = new ushort[len]; - fixed (ushort* arrPtr = arr) - { - reader.ReadToBuffer((byte*)arrPtr, len * 2); - } - } - - return arr; - } - - public override int GetSize(ushort[] val) - { - if (val is null) return 1; - return 1 + 4 + val.Length * 2; - } - } - - internal class UShortListWrapper : NinoWrapperBase> - { - public override void Serialize(List val, ref Writer writer) - { - if (val is null) - { - writer.Write(false); - return; - } - - writer.Write(true); - writer.Write(val.Count); - foreach (var v in val) - { - writer.Write(v); - } - } - - public override List Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - var arr = new List(len); - //read item - int i = 0; - while (i++ < len) - { - arr.Add(reader.ReadUInt16()); - } - - return arr; - } - - public override int GetSize(List val) - { - if (val is null) return 1; - return 1 + 4 + val.Count * 2; - } - } - - internal class IntWrapper : NinoWrapperBase - { - public override void Serialize(int val, ref Writer writer) - { - writer.Write(val); - } - - public override int Deserialize(Reader reader) - { - return reader.ReadInt32(); - } - - public override int GetSize(int val) - { - return 4; - } - } - - internal class IntArrWrapper : NinoWrapperBase - { - public override void Serialize(int[] val, ref Writer writer) - { - writer.Write(val.AsSpan()); - } - - public override unsafe int[] Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - var arr = new int[len]; - //read item - fixed (int* arrPtr = arr) - { - reader.ReadToBuffer((byte*)arrPtr, len * 4); - } - - return arr; - } - - public override int GetSize(int[] val) - { - if (val is null) return 1; - return 1 + 4 + val.Length * 4; - } - } - - internal class IntListWrapper : NinoWrapperBase> - { - public override void Serialize(List val, ref Writer writer) - { - if (val is null) - { - writer.Write(false); - return; - } - - writer.Write(true); - writer.Write(val.Count); - foreach (var v in val) - { - writer.Write(v); - } - } - - public override List Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - var arr = new List(len); - //read item - int i = 0; - while (i++ < len) - { - arr.Add(reader.ReadInt32()); - } - - return arr; - } - - public override int GetSize(List val) - { - if (val is null) return 1; - return 1 + 4 + val.Count * 4; - } - } - - internal class UIntWrapper : NinoWrapperBase - { - public override void Serialize(uint val, ref Writer writer) - { - writer.Write(val); - } - - public override uint Deserialize(Reader reader) - { - return reader.ReadUInt32(); - } - - public override int GetSize(uint val) - { - return 4; - } - } - - internal class UIntArrWrapper : NinoWrapperBase - { - public override void Serialize(uint[] val, ref Writer writer) - { - writer.Write(val.AsSpan()); - } - - public override unsafe uint[] Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - var arr = new uint[len]; - //read item - fixed (uint* arrPtr = arr) - { - reader.ReadToBuffer((byte*)arrPtr, len * 4); - } - - return arr; - } - - public override int GetSize(uint[] val) - { - if (val is null) return 1; - return 1 + 4 + val.Length * 4; - } - } - - internal class UIntListWrapper : NinoWrapperBase> - { - public override void Serialize(List val, ref Writer writer) - { - if (val is null) - { - writer.Write(false); - return; - } - - writer.Write(true); - writer.Write(val.Count); - foreach (var v in val) - { - writer.Write(v); - } - } - - public override List Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - var arr = new List(len); - //read item - int i = 0; - while (i++ < len) - { - arr.Add(reader.ReadUInt32()); - } - - return arr; - } - - public override int GetSize(List val) - { - if (val is null) return 1; - return 1 + 4 + val.Count * 4; - } - } - - internal class LongWrapper : NinoWrapperBase - { - public override void Serialize(long val, ref Writer writer) - { - writer.Write(val); - } - - public override long Deserialize(Reader reader) - { - return reader.ReadInt64(); - } - - public override int GetSize(long val) - { - return 8; - } - } - - internal class LongArrWrapper : NinoWrapperBase - { - public override void Serialize(long[] val, ref Writer writer) - { - writer.Write(val.AsSpan()); - } - - public override unsafe long[] Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - var arr = new long[len]; - //read item - fixed (long* arrPtr = arr) - { - reader.ReadToBuffer((byte*)arrPtr, len * 8); - } - - return arr; - } - - public override int GetSize(long[] val) - { - if (val is null) return 1; - return 1 + 4 + val.Length * 8; - } - } - - internal class LongListWrapper : NinoWrapperBase> - { - public override void Serialize(List val, ref Writer writer) - { - if (val is null) - { - writer.Write(false); - return; - } - - writer.Write(true); - writer.Write(val.Count); - foreach (var v in val) - { - writer.Write(v); - } - } - - public override List Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - var arr = new List(len); - //read item - int i = 0; - while (i++ < len) - { - arr.Add(reader.ReadInt64()); - } - - return arr; - } - - public override int GetSize(List val) - { - if (val is null) return 1; - return 1 + 4 + val.Count * 8; - } - } - - internal class ULongWrapper : NinoWrapperBase - { - public override void Serialize(ulong val, ref Writer writer) - { - writer.Write(val); - } - - public override ulong Deserialize(Reader reader) - { - return reader.ReadUInt64(); - } - - public override int GetSize(ulong val) - { - return 8; - } - } - - internal class ULongArrWrapper : NinoWrapperBase - { - public override void Serialize(ulong[] val, ref Writer writer) - { - writer.Write(val.AsSpan()); - } - - public override unsafe ulong[] Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - var arr = new ulong[len]; - //read item - fixed (ulong* arrPtr = arr) - { - reader.ReadToBuffer((byte*)arrPtr, len * 8); - } - - return arr; - } - - public override int GetSize(ulong[] val) - { - if (val is null) return 1; - return 1 + 4 + val.Length * 8; - } - } - - internal class ULongListWrapper : NinoWrapperBase> - { - public override void Serialize(List val, ref Writer writer) - { - if (val is null) - { - writer.Write(false); - return; - } - - writer.Write(true); - writer.Write(val.Count); - foreach (var v in val) - { - writer.Write(v); - } - } - - public override List Deserialize(Reader reader) - { - if (!reader.ReadBool()) return null; - int len = reader.ReadLength(); - var arr = new List(len); - //read item - int i = 0; - while (i++ < len) - { - arr.Add(reader.ReadUInt64()); - } - - return arr; - } - - public override int GetSize(List val) - { - if (val is null) return 1; - return 1 + 4 + val.Count * 8; - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Serialization/Wrappers/WrapperManifest.cs b/Nino_Unity/Assets/Nino/Serialization/Wrappers/WrapperManifest.cs deleted file mode 100644 index 20003a2..0000000 --- a/Nino_Unity/Assets/Nino/Serialization/Wrappers/WrapperManifest.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using Nino.Shared.Util; -using System.Collections.Generic; - -namespace Nino.Serialization -{ - public static class WrapperManifest - { - private static readonly Dictionary Wrappers = new Dictionary(300) - { - { typeof(byte).GetTypeHashCode(), new ByteWrapper() }, - { typeof(byte[]).GetTypeHashCode(), new ByteArrWrapper() }, - { typeof(List).GetTypeHashCode(), new ByteListWrapper() }, - { typeof(sbyte).GetTypeHashCode(), new SByteWrapper() }, - { typeof(sbyte[]).GetTypeHashCode(), new SByteArrWrapper() }, - { typeof(List).GetTypeHashCode(), new SByteListWrapper() }, - { typeof(short).GetTypeHashCode(), new ShortWrapper() }, - { typeof(short[]).GetTypeHashCode(), new ShortArrWrapper() }, - { typeof(List).GetTypeHashCode(), new ShortListWrapper() }, - { typeof(ushort).GetTypeHashCode(), new UShortWrapper() }, - { typeof(ushort[]).GetTypeHashCode(), new UShortArrWrapper() }, - { typeof(List).GetTypeHashCode(), new UShortListWrapper() }, - { typeof(int).GetTypeHashCode(), new IntWrapper() }, - { typeof(int[]).GetTypeHashCode(), new IntArrWrapper() }, - { typeof(List).GetTypeHashCode(), new IntListWrapper() }, - { typeof(uint).GetTypeHashCode(), new UIntWrapper() }, - { typeof(uint[]).GetTypeHashCode(), new UIntArrWrapper() }, - { typeof(List).GetTypeHashCode(), new UIntListWrapper() }, - { typeof(long).GetTypeHashCode(), new LongWrapper() }, - { typeof(long[]).GetTypeHashCode(), new LongArrWrapper() }, - { typeof(List).GetTypeHashCode(), new LongListWrapper() }, - { typeof(ulong).GetTypeHashCode(), new ULongWrapper() }, - { typeof(ulong[]).GetTypeHashCode(), new ULongArrWrapper() }, - { typeof(List).GetTypeHashCode(), new ULongListWrapper() }, - { typeof(float).GetTypeHashCode(), new FloatWrapper() }, - { typeof(float[]).GetTypeHashCode(), new FloatArrWrapper() }, - { typeof(List).GetTypeHashCode(), new FloatListWrapper() }, - { typeof(double).GetTypeHashCode(), new DoubleWrapper() }, - { typeof(double[]).GetTypeHashCode(), new DoubleArrWrapper() }, - { typeof(List).GetTypeHashCode(), new DoubleListWrapper() }, - { typeof(decimal).GetTypeHashCode(), new DecimalWrapper() }, - { typeof(decimal[]).GetTypeHashCode(), new DecimalArrWrapper() }, - { typeof(List).GetTypeHashCode(), new DecimalListWrapper() }, - { typeof(string).GetTypeHashCode(), new StringWrapper() }, - { typeof(string[]).GetTypeHashCode(), new StringArrWrapper() }, - { typeof(List).GetTypeHashCode(), new StringListWrapper() }, - { typeof(char).GetTypeHashCode(), new CharWrapper() }, - { typeof(char[]).GetTypeHashCode(), new CharArrWrapper() }, - { typeof(List).GetTypeHashCode(), new CharListWrapper() }, - { typeof(bool).GetTypeHashCode(), new BoolWrapper() }, - { typeof(bool[]).GetTypeHashCode(), new BoolArrWrapper() }, - { typeof(List).GetTypeHashCode(), new BoolListWrapper() }, - { typeof(DateTime).GetTypeHashCode(), new DateTimeWrapper() }, - { typeof(DateTime[]).GetTypeHashCode(), new DateTimeArrWrapper() }, - { typeof(List).GetTypeHashCode(), new DateTimeListWrapper() }, - }; - - public static bool TryGetWrapper(Type type, out INinoWrapper wrapper) - { - return Wrappers.TryGetValue(type.GetTypeHashCode(), out wrapper); - } - - public static void AddWrapper(Type type, INinoWrapper wrapper) - { - Wrappers[type.GetTypeHashCode()] = wrapper; - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Serialization/Writer.Generic.cs b/Nino_Unity/Assets/Nino/Serialization/Writer.Generic.cs deleted file mode 100644 index 5adbdcd..0000000 --- a/Nino_Unity/Assets/Nino/Serialization/Writer.Generic.cs +++ /dev/null @@ -1,537 +0,0 @@ -using System; -using System.IO; -using System.Collections.Generic; -using System.Runtime.InteropServices; -using System.Runtime.CompilerServices; -using Nino.Shared.Mgr; - -namespace Nino.Serialization -{ - public ref partial struct Writer - { - /// - /// Write primitive values, DO NOT USE THIS FOR CUSTOM IMPORTER - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteCommonVal(T val) => Position = Serializer.Serialize(typeof(T), val, null, buffer, Position); - - /// - /// Write primitive values, DO NOT USE THIS FOR CUSTOM IMPORTER - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteCommonVal(Type type, T val) => - Position = Serializer.Serialize(type, val, null, buffer, Position); - - /// - /// Write unmanaged type - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal void WriteAsUnmanaged(ref T val, int len) - { - Unsafe.WriteUnaligned(ref buffer[Position], val); - Position += len; - } - - /// - /// Write unmanaged type - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(ref T val, int len) where T : unmanaged - { - Unsafe.WriteUnaligned(ref buffer[Position], val); - Position += len; - } - - /// - /// Write unmanaged type - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(ref T1 val1, int len1, ref T2 val2, int len2) - where T1 : unmanaged where T2 : unmanaged - { - Unsafe.WriteUnaligned(ref buffer[Position], val1); - Position += len1; - Unsafe.WriteUnaligned(ref buffer[Position], val2); - Position += len2; - } - - /// - /// Write unmanaged type - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(ref T1 val1, int len1, ref T2 val2, int len2, ref T3 val3, int len3) - where T1 : unmanaged where T2 : unmanaged where T3 : unmanaged - { - Unsafe.WriteUnaligned(ref buffer[Position], val1); - Position += len1; - Unsafe.WriteUnaligned(ref buffer[Position], val2); - Position += len2; - Unsafe.WriteUnaligned(ref buffer[Position], val3); - Position += len3; - } - - /// - /// Write unmanaged type - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(ref T1 val1, int len1, ref T2 val2, int len2, ref T3 val3, int len3, - ref T4 val4, int len4) where T1 : unmanaged where T2 : unmanaged where T3 : unmanaged where T4 : unmanaged - { - Unsafe.WriteUnaligned(ref buffer[Position], val1); - Position += len1; - Unsafe.WriteUnaligned(ref buffer[Position], val2); - Position += len2; - Unsafe.WriteUnaligned(ref buffer[Position], val3); - Position += len3; - Unsafe.WriteUnaligned(ref buffer[Position], val4); - Position += len4; - } - - /// - /// Write unmanaged type - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(ref T1 val1, int len1, ref T2 val2, int len2, ref T3 val3, int len3, - ref T4 val4, int len4, ref T5 val5, int len5) where T1 : unmanaged - where T2 : unmanaged - where T3 : unmanaged - where T4 : unmanaged - where T5 : unmanaged - { - Unsafe.WriteUnaligned(ref buffer[Position], val1); - Position += len1; - Unsafe.WriteUnaligned(ref buffer[Position], val2); - Position += len2; - Unsafe.WriteUnaligned(ref buffer[Position], val3); - Position += len3; - Unsafe.WriteUnaligned(ref buffer[Position], val4); - Position += len4; - Unsafe.WriteUnaligned(ref buffer[Position], val5); - Position += len5; - } - - /// - /// Write unmanaged type - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(ref T1 val1, int len1, ref T2 val2, int len2, ref T3 val3, int len3, - ref T4 val4, int len4, ref T5 val5, int len5, ref T6 val6, int len6) where T1 : unmanaged - where T2 : unmanaged - where T3 : unmanaged - where T4 : unmanaged - where T5 : unmanaged - where T6 : unmanaged - { - Unsafe.WriteUnaligned(ref buffer[Position], val1); - Position += len1; - Unsafe.WriteUnaligned(ref buffer[Position], val2); - Position += len2; - Unsafe.WriteUnaligned(ref buffer[Position], val3); - Position += len3; - Unsafe.WriteUnaligned(ref buffer[Position], val4); - Position += len4; - Unsafe.WriteUnaligned(ref buffer[Position], val5); - Position += len5; - Unsafe.WriteUnaligned(ref buffer[Position], val6); - Position += len6; - } - - /// - /// Write unmanaged type - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(ref T1 val1, int len1, ref T2 val2, int len2, ref T3 val3, - int len3, ref T4 val4, int len4, ref T5 val5, int len5, ref T6 val6, int len6, ref T7 val7, int len7) - where T1 : unmanaged - where T2 : unmanaged - where T3 : unmanaged - where T4 : unmanaged - where T5 : unmanaged - where T6 : unmanaged - where T7 : unmanaged - { - Unsafe.WriteUnaligned(ref buffer[Position], val1); - Position += len1; - Unsafe.WriteUnaligned(ref buffer[Position], val2); - Position += len2; - Unsafe.WriteUnaligned(ref buffer[Position], val3); - Position += len3; - Unsafe.WriteUnaligned(ref buffer[Position], val4); - Position += len4; - Unsafe.WriteUnaligned(ref buffer[Position], val5); - Position += len5; - Unsafe.WriteUnaligned(ref buffer[Position], val6); - Position += len6; - Unsafe.WriteUnaligned(ref buffer[Position], val7); - Position += len7; - } - - /// - /// Write unmanaged type - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(ref T1 val1, int len1, ref T2 val2, int len2, ref T3 val3, - int len3, ref T4 val4, int len4, ref T5 val5, int len5, ref T6 val6, int len6, ref T7 val7, int len7, - ref T8 val8, int len8) where T1 : unmanaged - where T2 : unmanaged - where T3 : unmanaged - where T4 : unmanaged - where T5 : unmanaged - where T6 : unmanaged - where T7 : unmanaged - where T8 : unmanaged - { - Unsafe.WriteUnaligned(ref buffer[Position], val1); - Position += len1; - Unsafe.WriteUnaligned(ref buffer[Position], val2); - Position += len2; - Unsafe.WriteUnaligned(ref buffer[Position], val3); - Position += len3; - Unsafe.WriteUnaligned(ref buffer[Position], val4); - Position += len4; - Unsafe.WriteUnaligned(ref buffer[Position], val5); - Position += len5; - Unsafe.WriteUnaligned(ref buffer[Position], val6); - Position += len6; - Unsafe.WriteUnaligned(ref buffer[Position], val7); - Position += len7; - Unsafe.WriteUnaligned(ref buffer[Position], val8); - Position += len8; - } - - /// - /// Write byte[] - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe void Write(Span data) where T : unmanaged - { - if (data == null) - { - Write(false); - return; - } - - Write(true); - var len = data.Length; - Write(len); - len *= sizeof(T); - MemoryMarshal.AsBytes(data).CopyTo(buffer.Slice(Position, len)); - Position += len; - } - - /// - /// write enum - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteEnum(T val) - { - //boxed - if (typeof(T) == ConstMgr.ObjectType) - { - WriteEnum((object)val); - return; - } - - ref byte p = ref MemoryMarshal.GetReference(buffer); - switch (TypeModel.GetTypeCode(typeof(T))) - { - case TypeCode.Byte: - case TypeCode.SByte: - case TypeCode.Int16: - case TypeCode.UInt16: - case TypeCode.Int32: - case TypeCode.UInt32: - byte len = (byte)Unsafe.SizeOf(); - Unsafe.WriteUnaligned(ref Unsafe.Add(ref p, Position), val); - Position += len; - return; - case TypeCode.Int64: - case TypeCode.UInt64: - Unsafe.WriteUnaligned(ref Unsafe.Add(ref p, Position), val); - Position += 8; - return; - } - } - - /// - /// write enum - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe void WriteEnum(object val) - { - var type = val.GetType(); - ref byte p = ref MemoryMarshal.GetReference(buffer); - switch (TypeModel.GetTypeCode(type)) - { - case TypeCode.Byte: - buffer[Position++] = Unsafe.Unbox(val); - return; - case TypeCode.SByte: - buffer[Position++] = *(byte*)Unsafe.Unbox(val); - return; - case TypeCode.Int16: - Unsafe.WriteUnaligned(ref Unsafe.Add(ref p, Position), Unsafe.Unbox(val)); - Position += 2; - return; - case TypeCode.UInt16: - Unsafe.WriteUnaligned(ref Unsafe.Add(ref p, Position), Unsafe.Unbox(val)); - Position += 2; - return; - case TypeCode.Int32: - Unsafe.WriteUnaligned(ref Unsafe.Add(ref p, Position), Unsafe.Unbox(val)); - Position += 4; - return; - case TypeCode.UInt32: - Unsafe.WriteUnaligned(ref Unsafe.Add(ref p, Position), Unsafe.Unbox(val)); - Position += 4; - return; - case TypeCode.Int64: - Unsafe.WriteUnaligned(ref Unsafe.Add(ref p, Position), Unsafe.Unbox(val)); - Position += 8; - return; - case TypeCode.UInt64: - Unsafe.WriteUnaligned(ref Unsafe.Add(ref p, Position), Unsafe.Unbox(val)); - Position += 8; - return; - } - } - - /// - /// Write array - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(T[] arr) - { - //null - if (arr == null) - { - Write(false); - return; - } - - Write(true); - //write len - int len = arr.Length; - - //empty - if (len == 0) - { - //write len - Write(0); - return; - } - - Write(len); - //write item - int i = 0; - while (i < len) - { - var obj = arr[i++]; - var eType = obj.GetType(); - WriteCommonVal(eType, obj); - } - } - - /// - /// Write nullable - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(T? val) where T : struct - { - //null - if (val == null) - { - Write(false); - return; - } - - Write(true); - WriteCommonVal(val.Value); - } - - /// - /// Write List - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(List lst) - { - //null - if (lst == null) - { - Write(false); - return; - } - - Write(true); - int len = lst.Count; - //write len - Write(lst.Count); - //empty - if (len == 0) - { - return; - } - - //write item - foreach (var c in lst) - { - WriteCommonVal(c); - } - } - - /// - /// Write List - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(HashSet lst) - { - //null - if (lst == null) - { - Write(false); - return; - } - - Write(true); - int len = lst.Count; - //write len - Write(len); - //empty - if (len == 0) - { - //write len - return; - } - - //write item - foreach (var c in lst) - { - WriteCommonVal(c); - } - } - - /// - /// Write List - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(Queue lst) - { - //null - if (lst == null) - { - Write(false); - return; - } - - Write(true); - int len = lst.Count; - //write len - Write(len); - //empty - if (len == 0) - { - //write len - return; - } - - //write item - foreach (var c in lst) - { - WriteCommonVal(c); - } - } - - /// - /// Write List - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(Stack lst) - { - //null - if (lst == null) - { - Write(false); - return; - } - - Write(true); - int len = lst.Count; - //write len - Write(len); - //empty - if (len == 0) - { - //write len - return; - } - - //write item - foreach (var c in lst) - { - WriteCommonVal(c); - } - } - - /// - /// Write dictionary - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(Dictionary dictionary) - { - //null - if (dictionary == null) - { - Write(false); - return; - } - - Write(true); - int len = dictionary.Count; - //write len - Write(len); - //empty - if (len == 0) - { - //write len - return; - } - - //record keys - var keys = dictionary.Keys; - //write items - foreach (var c in keys) - { - //write key - WriteCommonVal(c); - //write val - var val = dictionary[c]; - WriteCommonVal(val); - } - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Serialization/Writer.cs b/Nino_Unity/Assets/Nino/Serialization/Writer.cs deleted file mode 100644 index 3325915..0000000 --- a/Nino_Unity/Assets/Nino/Serialization/Writer.cs +++ /dev/null @@ -1,338 +0,0 @@ -using System; -using System.IO; -using Nino.Shared.Mgr; -using System.Collections; -using System.Runtime.CompilerServices; - -namespace Nino.Serialization -{ - /// - /// A writer that writes serialization Data - /// - public ref partial struct Writer - { - /// - /// Buffer that stores data - /// - private Span buffer; - - /// - /// Position of the current buffer - /// - public int Position; - - /// - /// Create a nino writer - /// - /// - /// - public Writer(Span buffer, int position) - { - this.buffer = buffer; - Position = position; - } - - /// - /// Write primitive values, DO NOT USE THIS FOR CUSTOM IMPORTER - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void WriteCommonVal(Type type, object val) => - Position = Serializer.Serialize(type, val, null, buffer, Position); - - /// - /// Write byte[] - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal unsafe void Write(byte* data, ref int len) - { - if (len <= 8) - { - while (len-- > 0) - { - buffer[Position++] = *data++; - } - - return; - } - - Unsafe.CopyBlockUnaligned(ref buffer[Position], ref *data, (uint)len); - Position += len; - } - - /// - /// Write a double - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(double value) - { - Write(ref value, ConstMgr.SizeOfULong); - } - - /// - /// Write a float - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(float value) - { - Write(ref value, ConstMgr.SizeOfUInt); - } - - /// - /// Write a DateTime - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(DateTime value) - { - Write(ref value, ConstMgr.SizeOfLong); - } - - /// - /// Write decimal - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(decimal d) - { - Write(ref d, ConstMgr.SizeOfDecimal); - } - - /// - /// Writes a boolean to this stream. A single byte is written to the stream - /// with the value 0 representing false or the value 1 representing true. - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(bool value) - { - Unsafe.WriteUnaligned(ref buffer[Position++], value); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(char value) - { - Write(ref value, ConstMgr.SizeOfUShort); - } - - /// - /// Write string - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe void Write(string val) - { - if (val is null) - { - Write(false); - return; - } - - Write(true); - - if (val == string.Empty) - { - Write(0); - return; - } - - var strSpan = val.AsSpan(); // 2*len, utf16 str - int len = strSpan.Length * ConstMgr.SizeOfUShort; - fixed (char* first = &strSpan.GetPinnableReference()) - { - Write(len); - Write((byte*)first, ref len); - } - } - - #region write whole num - - /// - /// Write byte val to binary writer - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(byte num) - { - buffer[Position++] = num; - } - - /// - /// Write byte val to binary writer - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(sbyte num) - { - Unsafe.WriteUnaligned(ref buffer[Position++], num); - } - - /// - /// Write int val to binary writer - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(int num) - { - Write(ref num, ConstMgr.SizeOfInt); - } - - /// - /// Write uint val to binary writer - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(uint num) - { - Write(ref num, ConstMgr.SizeOfUInt); - } - - /// - /// Write short val to binary writer - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(short num) - { - Write(ref num, ConstMgr.SizeOfShort); - } - - /// - /// Write ushort val to binary writer - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(ushort num) - { - Write(ref num, ConstMgr.SizeOfUShort); - } - - /// - /// Write long val to binary writer - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(long num) - { - Write(ref num, ConstMgr.SizeOfLong); - } - - /// - /// Write ulong val to binary writer - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(ulong num) - { - Write(ref num, ConstMgr.SizeOfULong); - } - - #endregion - - /// - /// Write array - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(Array arr) - { - //null - if (arr == null) - { - Write(false); - return; - } - - Write(true); - //write len - int len = arr.Length; - //empty - Write(len); - //write item - int i = 0; - while (i < len) - { - var obj = arr.GetValue(i++); - var eType = obj.GetType(); - WriteCommonVal(eType, obj); - } - } - - /// - /// Write list - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(IList arr) - { - //null - if (arr == null) - { - Write(false); - return; - } - - Write(true); - var len = arr.Count; - //write len - Write(len); - //empty - if (len == 0) - { - return; - } - - //write item - foreach (var c in arr) - { - var eType = c.GetType(); - WriteCommonVal(eType, c); - } - } - - /// - /// Write dictionary - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Write(IDictionary dictionary) - { - //null - if (dictionary == null) - { - Write(false); - return; - } - - Write(true); - //write len - int len = dictionary.Count; - Write(len); - //empty - if (dictionary.Count == 0) - { - return; - } - - //record keys - var keys = dictionary.Keys; - //write items - foreach (var c in keys) - { - //write key - var eType = c.GetType(); - WriteCommonVal(eType, c); - //write val - var val = dictionary[c]; - eType = val.GetType(); - WriteCommonVal(eType, val); - } - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Shared/Attributes/MonoPInvokeCallbackAttribute.cs b/Nino_Unity/Assets/Nino/Shared/Attributes/MonoPInvokeCallbackAttribute.cs deleted file mode 100644 index 7a8ea37..0000000 --- a/Nino_Unity/Assets/Nino/Shared/Attributes/MonoPInvokeCallbackAttribute.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace Nino.Shared.IO -{ - public class MonoPInvokeCallbackAttribute : Attribute - { - public MonoPInvokeCallbackAttribute() - { - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Shared/Collections/FunctorComparer.cs b/Nino_Unity/Assets/Nino/Shared/Collections/FunctorComparer.cs deleted file mode 100644 index d7155aa..0000000 --- a/Nino_Unity/Assets/Nino/Shared/Collections/FunctorComparer.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Nino.Shared -{ - internal sealed class FunctorComparer : IComparer { - Comparison comparison; - - public FunctorComparer(Comparison comparison) { - this.comparison = comparison; - } - - public int Compare(T x, T y) { - return comparison(x, y); - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Shared/Collections/UncheckedList.cs b/Nino_Unity/Assets/Nino/Shared/Collections/UncheckedList.cs deleted file mode 100644 index 170974e..0000000 --- a/Nino_Unity/Assets/Nino/Shared/Collections/UncheckedList.cs +++ /dev/null @@ -1,978 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; - -// ReSharper disable CognitiveComplexity -namespace Nino.Shared -{ - [Serializable] - public class UncheckedList : IList, System.Collections.IList, IReadOnlyList - { - private const int DefaultCapacity = 4; - /// - /// here we made it public for faster access than indexer, but we dont recommend modify this - /// direct calling is way faster in debug mode, when in release mode, calling indexer has same performance as direct call - /// https://stackoverflow.com/questions/17105773/poor-c-sharp-optimizer-performance - /// - internal T[] items; - private int size; - private int version; - [NonSerialized] private Object syncRoot; - - static readonly T[] - EmptyArray = - Array.Empty(); // Constructs a UncheckedList. The UncheckedList is initially empty and has a capacity - - // of zero. Upon adding the first element to the UncheckedList the capacity is - // increased to 16, and then increased in multiples of two as required. - public UncheckedList() - { - items = EmptyArray; - } // Constructs a UncheckedList with a given initial capacity. The UncheckedList is - - // initially empty, but will have room for the given number of elements - // before any reallocations are required. - // - public UncheckedList(int capacity) - { - if (capacity == 0) - items = EmptyArray; - else - items = new T[capacity]; - } // Constructs a UncheckedList, copying the contents of the given collection. The - - // size and capacity of the new UncheckedList will both be equal to the size of the - // given collection. - // - public UncheckedList(IEnumerable collection) - { - ICollection c = collection as ICollection; - if (c != null) - { - int count = c.Count; - if (count == 0) - { - items = EmptyArray; - } - else - { - items = new T[count]; - c.CopyTo(items, 0); - size = count; - } - } - else - { - size = 0; - items = EmptyArray; - // This enumerable could be empty. Let Add allocate a new array, if needed. - // Note it will also go to _defaultCapacity first, not 1, then 2, etc. using (IEnumerator en = collection.GetEnumerator()) - using (IEnumerator en = collection.GetEnumerator()) - { - while (en.MoveNext()) - { - Add(en.Current); - } - } - } - } // Gets and sets the capacity of this UncheckedList. The capacity is the size of - - // the internal array used to hold items. When set, the internal - // array of the UncheckedList is reallocated to the given capacity. - // - public int Capacity - { - get => items.Length; - set - { - if (value != items.Length) - { - if (value > 0) - { - T[] newItems = new T[value]; - if (size > 0) - { - Array.Copy(items, 0, newItems, 0, size); - } - - items = newItems; - } - else - { - items = EmptyArray; - } - } - } - } // Read-only property describing how many elements are in the UncheckedList. - - public int Count => size; - - bool System.Collections.IList.IsFixedSize => false; - - // Is this UncheckedList read-only? - bool ICollection.IsReadOnly => false; - - bool System.Collections.IList.IsReadOnly => false; // Is this UncheckedList synchronized (thread-safe)? - - bool System.Collections.ICollection.IsSynchronized => false; // Synchronization root for this object. - - Object System.Collections.ICollection.SyncRoot - { - get - { - if (syncRoot == null) - { - System.Threading.Interlocked.CompareExchange(ref syncRoot, new Object(), null); - } - - return syncRoot; - } - } // Sets or Gets the element at the given index. - - // - public T this[int index] - { - get => items[index]; - set - { - items[index] = value; - version++; - } - } - - private static bool IsCompatibleObject(object value) - { - // Non-null values are fine. Only accept nulls if T is a class or Nullable. - // Note that default(T) is not equal to null for value types except when T is Nullable. - return ((value is T) || (value == null && default(T) == null)); - } - - Object System.Collections.IList.this[int index] - { - get => this[index]; - set => this[index] = (T)value; - } // Adds the given object to the end of this UncheckedList. The size of the UncheckedList is - - // increased by one. If required, the capacity of the UncheckedList is doubled - // before adding the new element. - // - public void Add(T item) - { - if (size == items.Length) EnsureCapacity(size + 1); - items[size++] = item; - version++; - } - - int System.Collections.IList.Add(Object item) - { - Add((T)item); - return Count - 1; - } - - // Adds the elements of the given collection to the end of this UncheckedList. If - // required, the capacity of the UncheckedList is increased to twice the previous - // capacity or the new size, whichever is larger. - // - public void AddRange(IEnumerable collection) - { - InsertRange(size, collection); - } - - public ReadOnlyCollection AsReadOnly() - { - return new ReadOnlyCollection(this); - } // Searches a section of the UncheckedList for a given element using a binary search - - // algorithm. Elements of the UncheckedList are compared to the search value using - // the given IComparer interface. If comparer is null, elements of - // the UncheckedList are compared to the search value using the IComparable - // interface, which in that case must be implemented by all elements of the - // UncheckedList and the given search value. This method assumes that the given - // section of the UncheckedList is already sorted; if this is not the case, the - // result will be incorrect. - // - // The method returns the index of the given value in the UncheckedList. If the - // UncheckedList does not contain the given value, the method returns a negative - // integer. The bitwise complement operator (~) can be applied to a - // negative result to produce the index of the first element (if any) that - // is larger than the given search value. This is also the index at which - // the search value should be inserted into the UncheckedList in order for the UncheckedList - // to remain sorted. - // - // The method uses the Array.BinarySearch method to perform the - // search. - // - public int BinarySearch(int index, int count, T item, IComparer comparer) - { - return Array.BinarySearch(items, index, count, item, comparer); - } - - public int BinarySearch(T item) - { - return BinarySearch(0, Count, item, null); - } - - public int BinarySearch(T item, IComparer comparer) - { - return BinarySearch(0, Count, item, comparer); - } - - // Clears the contents of UncheckedList. - public void Clear() - { - if (size > 0) - { - Array.Clear(items, 0, - size); // Don't need to doc this but we clear the elements so that the gc can reclaim the references. - size = 0; - } - - version++; - } // Contains returns true if the specified element is in the UncheckedList. - - // It does a linear, O(n) search. Equality is determined by calling - // item.Equals(). - // - public bool Contains(T item) - { - if (item == null) - { - for (int i = 0; i < size; i++) - if (items[i] == null) - return true; - return false; - } - else - { - EqualityComparer c = EqualityComparer.Default; - for (int i = 0; i < size; i++) - { - if (c.Equals(items[i], item)) return true; - } - - return false; - } - } - - bool System.Collections.IList.Contains(Object item) - { - if (IsCompatibleObject(item)) - { - return Contains((T)item); - } - - return false; - } - - public UncheckedList ConvertAll(Converter converter) - { - UncheckedList uncheckedList = new UncheckedList(size); - for (int i = 0; i < size; i++) - { - uncheckedList.items[i] = converter(items[i]); - } - - uncheckedList.size = size; - return uncheckedList; - } // Copies this UncheckedList into array, which must be of a - - // compatible array type. - // - // Copies this UncheckedList into array, which must be of a - - // compatible array type. - // - void System.Collections.ICollection.CopyTo(Array array, int arrayIndex) - { - // Array.Copy will check for NULL. - Array.Copy(items, 0, array, arrayIndex, size); - } // Copies a section of this UncheckedList to the given array at the given index. - - // - // The method uses the Array.Copy method to copy the elements. - // - public void CopyTo(int index, T[] array, int arrayIndex, int count) - { - // Delegate rest of error checking to Array.Copy. - Array.Copy(items, index, array, arrayIndex, count); - } - - public void CopyTo(T[] array, int arrayIndex = 0) - { - // Delegate rest of error checking to Array.Copy. - Array.Copy(items, 0, array, arrayIndex, size); - } // Ensures that the capacity of this UncheckedList is at least the given minimum - - // value. If the currect capacity of the UncheckedList is less than min, the - // capacity is increased to twice the current capacity or to min, - // whichever is larger. - private void EnsureCapacity(int min) - { - if (items.Length < min) - { - int newCapacity = items.Length == 0 ? DefaultCapacity : items.Length * 2; - // Allow the UncheckedList to grow to maximum possible capacity (~2G elements) before encountering overflow. - // Note that this check works even when _items.Length overflowed thanks to the (uint) cast - if ((uint)newCapacity > int.MaxValue) newCapacity = int.MaxValue; - if (newCapacity < min) newCapacity = min; - Capacity = newCapacity; - } - } - - public bool Exists(Predicate match) - { - return FindIndex(match) != -1; - } - - public T Find(Predicate match) - { - for (int i = 0; i < size; i++) - { - if (match(items[i])) - { - return items[i]; - } - } - - return default(T); - } - - public UncheckedList FindAll(Predicate match) - { - UncheckedList uncheckedList = new UncheckedList(); - for (int i = 0; i < size; i++) - { - if (match(items[i])) - { - uncheckedList.Add(items[i]); - } - } - - return uncheckedList; - } - - public int FindIndex(Predicate match) - { - return FindIndex(0, size, match); - } - - public int FindIndex(int startIndex, Predicate match) - { - return FindIndex(startIndex, size - startIndex, match); - } - - public int FindIndex(int startIndex, int count, Predicate match) - { - int endIndex = startIndex + count; - for (int i = startIndex; i < endIndex; i++) - { - if (match(items[i])) return i; - } - - return -1; - } - - public T FindLast(Predicate match) - { - for (int i = size - 1; i >= 0; i--) - { - if (match(items[i])) - { - return items[i]; - } - } - - return default(T); - } - - public int FindLastIndex(Predicate match) - { - return FindLastIndex(size - 1, size, match); - } - - public int FindLastIndex(int startIndex, Predicate match) - { - return FindLastIndex(startIndex, startIndex + 1, match); - } - - public int FindLastIndex(int startIndex, int count, Predicate match) - { - int endIndex = startIndex - count; - for (int i = startIndex; i > endIndex; i--) - { - if (match(items[i])) - { - return i; - } - } - - return -1; - } - - public void ForEach(Action action) - { - int ver = this.version; - for (int i = 0; i < size; i++) - { - if (ver != this.version) - { - break; - } - - action(items[i]); - } - } // Returns an enumerator for this UncheckedList with the given - - // permission for removal of elements. If modifications made to the UncheckedList - // while an enumeration is in progress, the MoveNext and - // GetObject methods of the enumerator will throw an exception. - // - public Enumerator GetEnumerator() - { - return new Enumerator(this); - } - - /// - IEnumerator IEnumerable.GetEnumerator() - { - return new Enumerator(this); - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return new Enumerator(this); - } - - public UncheckedList GetRange(int index, int count) - { - UncheckedList uncheckedList = new UncheckedList(count); - Array.Copy(items, index, uncheckedList.items, 0, count); - uncheckedList.size = count; - return uncheckedList; - } - - // Returns the index of the first occurrence of a given value in a range of - // this UncheckedList. The UncheckedList is searched forwards from beginning to end. - // The elements of the UncheckedList are compared to the given value using the - // Object.Equals method. - // - // This method uses the Array.IndexOf method to perform the - // search. - // - public int IndexOf(T item) - { - return Array.IndexOf(items, item, 0, size); - } - - int System.Collections.IList.IndexOf(Object item) - { - if (IsCompatibleObject(item)) - { - return IndexOf((T)item); - } - - return -1; - } // Returns the index of the first occurrence of a given value in a range of - - // this UncheckedList. The UncheckedList is searched forwards, starting at index - // index and ending at count number of elements. The - // elements of the UncheckedList are compared to the given value using the - // Object.Equals method. - // - // This method uses the Array.IndexOf method to perform the - // search. - // - public int IndexOf(T item, int index) - { - return Array.IndexOf(items, item, index, size - index); - } // Returns the index of the first occurrence of a given value in a range of - - // this UncheckedList. The UncheckedList is searched forwards, starting at index - // index and upto count number of elements. The - // elements of the UncheckedList are compared to the given value using the - // Object.Equals method. - // - // This method uses the Array.IndexOf method to perform the - // search. - // - public int IndexOf(T item, int index, int count) - { - return Array.IndexOf(items, item, index, count); - } // Inserts an element into this UncheckedList at a given index. The size of the UncheckedList - - // is increased by one. If required, the capacity of the UncheckedList is doubled - // before inserting the new element. - // - public void Insert(int index, T item) - { - if (size == items.Length) EnsureCapacity(size + 1); - if (index < size) - { - Array.Copy(items, index, items, index + 1, size - index); - } - - items[index] = item; - size++; - version++; - } - - void System.Collections.IList.Insert(int index, Object item) - { - Insert(index, (T)item); - } // Inserts the elements of the given collection at a given index. If - - // required, the capacity of the UncheckedList is increased to twice the previous - // capacity or the new size, whichever is larger. Ranges may be added - // to the end of the UncheckedList by setting index to the UncheckedList's size. - // - public void InsertRange(int index, IEnumerable collection) - { - if (collection is ICollection c) - { - // if collection is ICollection - int count = c.Count; - if (count > 0) - { - EnsureCapacity(size + count); - if (index < size) - { - Array.Copy(items, index, items, index + count, size - index); - } // If we're inserting a UncheckedList into itself, we want to be able to deal with that. - - // ReSharper disable PossibleUnintendedReferenceComparison - if (this == c) - // ReSharper restore PossibleUnintendedReferenceComparison - { - // Copy first part of _items to insert location - Array.Copy(items, 0, items, index, index); - // Copy last part of _items back to inserted location - Array.Copy(items, index + count, items, index * 2, size - index); - } - else - { - T[] itemsToInsert = new T[count]; - c.CopyTo(itemsToInsert, 0); - itemsToInsert.CopyTo(items, index); - } - - size += count; - } - } - else - { - using (IEnumerator en = collection.GetEnumerator()) - { - while (en.MoveNext()) - { - Insert(index++, en.Current); - } - } - } - - version++; - } // Returns the index of the last occurrence of a given value in a range of - - // this UncheckedList. The UncheckedList is searched backwards, starting at the end - // and ending at the first element in the UncheckedList. The elements of the UncheckedList - // are compared to the given value using the Object.Equals method. - // - // This method uses the Array.LastIndexOf method to perform the - // search. - // - public int LastIndexOf(T item) - { - if (size == 0) - { - // Special case for empty UncheckedList - return -1; - } - else - { - return LastIndexOf(item, size - 1, size); - } - } // Returns the index of the last occurrence of a given value in a range of - - // this UncheckedList. The UncheckedList is searched backwards, starting at index - // index and ending at the first element in the UncheckedList. The - // elements of the UncheckedList are compared to the given value using the - // Object.Equals method. - // - // This method uses the Array.LastIndexOf method to perform the - // search. - // - public int LastIndexOf(T item, int index) - { - return LastIndexOf(item, index, index + 1); - } // Returns the index of the last occurrence of a given value in a range of - - // this UncheckedList. The UncheckedList is searched backwards, starting at index - // index and upto count elements. The elements of - // the UncheckedList are compared to the given value using the Object.Equals - // method. - // - // This method uses the Array.LastIndexOf method to perform the - // search. - // - public int LastIndexOf(T item, int index, int count) - { - if (size == 0) - { - // Special case for empty UncheckedList - return -1; - } - - return Array.LastIndexOf(items, item, index, count); - } // Removes the element at the given index. The size of the UncheckedList is - - // decreased by one. - // - public bool Remove(T item) - { - int index = IndexOf(item); - if (index >= 0) - { - RemoveAt(index); - return true; - } - - return false; - } - - void System.Collections.IList.Remove(Object item) - { - if (IsCompatibleObject(item)) - { - Remove((T)item); - } - } // This method removes all items which matches the predicate. - - // The complexity is O(n). - public int RemoveAll(Predicate match) - { - int freeIndex = - 0; // the first free slot in items array // Find the first item which needs to be removed. - while (freeIndex < size && !match(items[freeIndex])) freeIndex++; - if (freeIndex >= size) return 0; - int current = freeIndex + 1; - while (current < size) - { - // Find the first item which needs to be kept. - while (current < size && match(items[current])) current++; - if (current < size) - { - // copy item to the free slot. - items[freeIndex++] = items[current++]; - } - } - - Array.Clear(items, freeIndex, size - freeIndex); - int result = size - freeIndex; - size = freeIndex; - version++; - return result; - } // Removes the element at the given index. The size of the UncheckedList is - - // decreased by one. - // - public void RemoveAt(int index) - { - size--; - if (index < size) - { - Array.Copy(items, index + 1, items, index, size - index); - } - - items[size] = default(T); - version++; - } // Removes a range of elements from this UncheckedList. - - // - public void RemoveRange(int index, int count) - { - if (count > 0) - { - size -= count; - if (index < size) - { - Array.Copy(items, index + count, items, index, size - index); - } - - Array.Clear(items, size, count); - version++; - } - } // Reverses the elements in this UncheckedList. - - public void Reverse() - { - Reverse(0, Count); - } // Reverses the elements in a range of this UncheckedList. Following a call to this - - // method, an element in the range given by index and count - // which was previously located at index i will now be located at - // index index + (index + count - i - 1). - // - // This method uses the Array.Reverse method to reverse the - // elements. - // - public void Reverse(int index, int count) - { - Array.Reverse(items, index, count); - version++; - } // Sorts the elements in this UncheckedList. Uses the default comparer and - - // Array.Sort. - public void Sort() - { - Sort(0, Count, null); - } // Sorts the elements in this UncheckedList. Uses Array.Sort with the - - // provided comparer. - public void Sort(IComparer comparer) - { - Sort(0, Count, comparer); - } // Sorts the elements in a section of this UncheckedList. The sort compares the - - // elements to each other using the given IComparer interface. If - // comparer is null, the elements are compared to each other using - // the IComparable interface, which in that case must be implemented by all - // elements of the UncheckedList. - // - // This method uses the Array.Sort method to sort the elements. - // - public void Sort(int index, int count, IComparer comparer) - { - Array.Sort(items, index, count, comparer); - version++; - } - - public void Sort(Comparison comparison) - { - if (size > 0) - { - IComparer comparer = new FunctorComparer(comparison); - Array.Sort(items, 0, size, comparer); - } - } // ToArray returns a new Object array containing the contents of the UncheckedList. - - // This requires copying the UncheckedList, which is an O(n) operation. - public T[] ToArray() - { - T[] array = new T[size]; - Array.Copy(items, 0, array, 0, size); - return array; - } // Sets the capacity of this UncheckedList to the size of the UncheckedList. This method can - - // be used to minimize a UncheckedList's memory overhead once it is known that no - // new elements will be added to the UncheckedList. To completely clear a UncheckedList and - // release all memory referenced by the UncheckedList, execute the following - // statements: - // - // UncheckedList.Clear(); - // UncheckedList.TrimExcess(); - // - public void TrimExcess() - { - int threshold = (int)(items.Length * 0.9); - if (size < threshold) - { - Capacity = size; - } - } - - public bool TrueForAll(Predicate match) - { - for (int i = 0; i < size; i++) - { - if (!match(items[i])) - { - return false; - } - } - - return true; - } - - internal static IList Synchronized(UncheckedList uncheckedList) - { - return new SynchronizedList(uncheckedList); - } - - [Serializable()] - internal class SynchronizedList : IList - { - private UncheckedList list; - private Object root; - - internal SynchronizedList(UncheckedList uncheckedList) - { - list = uncheckedList; - root = ((System.Collections.ICollection)uncheckedList).SyncRoot; - } - - public int Count - { - get - { - lock (root) - { - return list.Count; - } - } - } - - // ReSharper disable InconsistentlySynchronizedField - public bool IsReadOnly => ((ICollection)list).IsReadOnly; - // ReSharper restore InconsistentlySynchronizedField - - public void Add(T item) - { - lock (root) - { - list.Add(item); - } - } - - public void Clear() - { - lock (root) - { - list.Clear(); - } - } - - public bool Contains(T item) - { - lock (root) - { - return list.Contains(item); - } - } - - public void CopyTo(T[] array, int arrayIndex) - { - lock (root) - { - list.CopyTo(array, arrayIndex); - } - } - - public bool Remove(T item) - { - lock (root) - { - return list.Remove(item); - } - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - lock (root) - { - return list.GetEnumerator(); - } - } - - IEnumerator IEnumerable.GetEnumerator() - { - lock (root) - { - return ((IEnumerable)list).GetEnumerator(); - } - } - - public T this[int index] - { - get - { - lock (root) - { - return list[index]; - } - } - set - { - lock (root) - { - list[index] = value; - } - } - } - - public int IndexOf(T item) - { - lock (root) - { - return list.IndexOf(item); - } - } - - public void Insert(int index, T item) - { - lock (root) - { - list.Insert(index, item); - } - } - - public void RemoveAt(int index) - { - lock (root) - { - list.RemoveAt(index); - } - } - } - - [Serializable] - public struct Enumerator : IEnumerator - { - private UncheckedList uncheckedList; - private int index; - private int version; - private T current; - - internal Enumerator(UncheckedList uncheckedList) - { - this.uncheckedList = uncheckedList; - index = 0; - version = uncheckedList.version; - current = default(T); - } - - public void Dispose() - { - } - - public bool MoveNext() - { - UncheckedList localList = uncheckedList; - if (version == localList.version && ((uint)index < (uint)localList.size)) - { - current = localList.items[index]; - index++; - return true; - } - - return MoveNextRare(); - } - - private bool MoveNextRare() - { - index = uncheckedList.size + 1; - current = default(T); - return false; - } - - public T Current => current; - - Object System.Collections.IEnumerator.Current => Current; - - void System.Collections.IEnumerator.Reset() - { - index = 0; - current = default(T); - } - } - } - // ReSharper restore CognitiveComplexity -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Shared/Collections/UncheckedStack.cs b/Nino_Unity/Assets/Nino/Shared/Collections/UncheckedStack.cs deleted file mode 100644 index 260ce93..0000000 --- a/Nino_Unity/Assets/Nino/Shared/Collections/UncheckedStack.cs +++ /dev/null @@ -1,261 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Security.Permissions; - -namespace Nino.Shared -{ - [Serializable] - public class UncheckedStack : IEnumerable, - System.Collections.ICollection, - IReadOnlyCollection - { - private T[] _array; // Storage for UncheckedStack elements - private int _size; // Number of items in the UncheckedStack. - private int _version; // Used to keep enumerator in sync w/ collection. - private Object _syncRoot; - - private const int _defaultCapacity = 4; - static T[] _emptyArray = new T[0]; - - public UncheckedStack() - { - _array = _emptyArray; - _size = 0; - _version = 0; - } - - // Create a UncheckedStack with a specific initial capacity. The initial capacity - // must be a non-negative number. - public UncheckedStack(int capacity) - { - _array = new T[capacity]; - _size = 0; - _version = 0; - } - - // Fills a UncheckedStack with the contents of a particular collection. The items are - // pushed onto the UncheckedStack in the same order they are read by the enumerator. - public UncheckedStack(IEnumerable collection) - { - ICollection c = collection as ICollection; - if (c != null) - { - int count = c.Count; - _array = new T[count]; - c.CopyTo(_array, 0); - _size = count; - } - else - { - _size = 0; - _array = new T[_defaultCapacity]; - - using (IEnumerator en = collection.GetEnumerator()) - { - while (en.MoveNext()) - { - Push(en.Current); - } - } - } - } - - public int Count => _size; - - bool System.Collections.ICollection.IsSynchronized => false; - - Object System.Collections.ICollection.SyncRoot - { - get - { - if (_syncRoot == null) - { - System.Threading.Interlocked.CompareExchange(ref _syncRoot, new Object(), null); - } - - return _syncRoot; - } - } - - // Removes all Objects from the UncheckedStack. - public void Clear() - { - Array.Clear(_array, 0, - _size); // Don't need to doc this but we clear the elements so that the gc can reclaim the references. - _size = 0; - _version++; - } - - public bool Contains(T item) - { - int count = _size; - - EqualityComparer c = EqualityComparer.Default; - while (count-- > 0) - { - if (((Object)item) == null) - { - if (((Object)_array[count]) == null) - return true; - } - else if (_array[count] != null && c.Equals(_array[count], item)) - { - return true; - } - } - - return false; - } - - // Copies the UncheckedStack into an array. - public void CopyTo(T[] array, int arrayIndex) - { - Array.Copy(_array, 0, array, arrayIndex, _size); - Array.Reverse(array, arrayIndex, _size); - } - - void System.Collections.ICollection.CopyTo(Array array, int arrayIndex) - { - Array.Copy(_array, 0, array, arrayIndex, _size); - Array.Reverse(array, arrayIndex, _size); - } - - // Returns an IEnumerator for this UncheckedStack. - public Enumerator GetEnumerator() - { - return new Enumerator(this); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return new Enumerator(this); - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return new Enumerator(this); - } - - public void TrimExcess() - { - int threshold = (int)(((double)_array.Length) * 0.9); - if (_size < threshold) - { - T[] newarray = new T[_size]; - Array.Copy(_array, 0, newarray, 0, _size); - _array = newarray; - _version++; - } - } - - // Returns the top object on the UncheckedStack without removing it. If the UncheckedStack - // is empty, Peek throws an InvalidOperationException. - public T Peek() - { - return _array[_size - 1]; - } - - // Pops an item from the top of the UncheckedStack. If the UncheckedStack is empty, Pop - // throws an InvalidOperationException. - public T Pop() - { - _version++; - T item = _array[--_size]; - _array[_size] = default(T); // Free memory quicker. - return item; - } - - // Pushes an item to the top of the UncheckedStack. - public void Push(T item) - { - if (_size == _array.Length) - { - T[] newArray = new T[(_array.Length == 0) ? _defaultCapacity : 2 * _array.Length]; - Array.Copy(_array, 0, newArray, 0, _size); - _array = newArray; - } - - _array[_size++] = item; - _version++; - } - - // Copies the UncheckedStack to an array, in the same order Pop would return the items. - public T[] ToArray() - { - T[] objArray = new T[_size]; - int i = 0; - while (i < _size) - { - objArray[i] = _array[_size - i - 1]; - i++; - } - - return objArray; - } - - [Serializable()] - [SuppressMessage("Microsoft.Performance", "CA1815:OverrideEqualsAndOperatorEqualsOnValueTypes", - Justification = "not an expected scenario")] - public struct Enumerator : IEnumerator, - System.Collections.IEnumerator - { - private UncheckedStack _stack; - private int _index; - private int _version; - private T currentElement; - - internal Enumerator(UncheckedStack UncheckedStack) - { - _stack = UncheckedStack; - _version = _stack._version; - _index = -2; - currentElement = default(T); - } - - public void Dispose() - { - _index = -1; - } - - public bool MoveNext() - { - bool retval; - if (_index == -2) - { - // First call to enumerator. - _index = _stack._size - 1; - retval = (_index >= 0); - if (retval) - currentElement = _stack._array[_index]; - return retval; - } - - if (_index == -1) - { - // End of enumeration. - return false; - } - - retval = (--_index >= 0); - if (retval) - currentElement = _stack._array[_index]; - else - currentElement = default(T); - return retval; - } - - public T Current => currentElement; - - Object System.Collections.IEnumerator.Current => currentElement; - - void System.Collections.IEnumerator.Reset() - { - _index = -2; - currentElement = default(T); - } - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Shared/IO/Buffer/ExtensibleBuffer.cs b/Nino_Unity/Assets/Nino/Shared/IO/Buffer/ExtensibleBuffer.cs deleted file mode 100644 index 4302438..0000000 --- a/Nino_Unity/Assets/Nino/Shared/IO/Buffer/ExtensibleBuffer.cs +++ /dev/null @@ -1,208 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using System.Runtime.CompilerServices; - -namespace Nino.Shared.IO -{ - /// - /// A buffer that can dynamically extend - /// - /// - public sealed unsafe class ExtensibleBuffer where T : unmanaged - { - /// - /// Default size of the buffer - /// - private const int DefaultBufferSize = 128; - - /// - /// Data that stores everything - /// - public T* Data { get; private set; } - - /// - /// Size of T - /// - private readonly byte sizeOfT; - - /// - /// expand size for each block - /// - public readonly int ExpandSize; - - /// - /// Total length of the buffer - /// - public int TotalLength { get; private set; } - - /// - /// Init buffer - /// - public ExtensibleBuffer() : this(DefaultBufferSize) - { - - } - - /// - /// Init extensible buffer with a capacity - /// - /// - public ExtensibleBuffer([In] int size = DefaultBufferSize) - { - sizeOfT = (byte)sizeof(T); - ExpandSize = size; - Data = (T*)Marshal.AllocHGlobal(sizeOfT * ExpandSize); - TotalLength = ExpandSize; - GC.AddMemoryPressure(sizeOfT * ExpandSize); - } - - /// - /// Get element at index - /// - /// - public T this[in int index] - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => *(Data + index); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - set - { - EnsureCapacity(in index); - *(Data + index) = value; - } - } - - /// - /// Ensure index exists - /// - /// - private void EnsureCapacity(in int index) - { - if (index < TotalLength) return; - GC.RemoveMemoryPressure(TotalLength * sizeOfT); - while (index >= TotalLength) - { - TotalLength += ExpandSize; - } - Extend(); - GC.AddMemoryPressure(TotalLength * sizeOfT); - } - - /// - /// Extend buffer - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void Extend() - { - Data = (T*)Marshal.ReAllocHGlobal((IntPtr)Data, new IntPtr(TotalLength * sizeOfT)); - } - - /// - /// Convert buffer data to an Array (will create a new array and copy values) - /// - /// - /// - /// - public T[] ToArray([In] int startIndex, [In] int length) - { - T[] ret = new T[length]; - CopyTo(ref ret, startIndex, length); - return ret; - } - - /// - /// convert an extensible to buffer from start index with provided length - /// - /// - /// - /// - public Span AsSpan([In] int startIndex, [In] int length) - { - var l = startIndex + length; - //size check - EnsureCapacity(in l); - return new Span(Data + startIndex, length); - } - - /// - /// Convert to span - /// - /// - /// - public static implicit operator Span(ExtensibleBuffer buffer) => buffer.AsSpan(0, buffer.TotalLength); - - /// - /// Copy data to extensible buffer - /// - /// - /// - /// - /// - /// - public void CopyFrom(T[] src, [In] int srcIndex, [In] int dstIndex, [In] int length) - { - fixed (T* ptr = src) - { - CopyFrom(ptr, srcIndex, dstIndex, length); - } - } - - /// - /// Copy data to extensible buffer - /// why unaligned? https://stackoverflow.com/a/72418388 - /// - /// - /// - /// - /// - /// - public void CopyFrom([In] T* src, [In] int srcIndex, [In] int dstIndex, [In] int length) - { - var l = dstIndex + length; - //size check - EnsureCapacity(in l); - //copy - Unsafe.CopyBlock(Data + dstIndex, src + srcIndex, (uint)length); - } - - /// - /// Copy data from buffer to dst from dst[0] - /// - /// - /// - /// - /// - public void CopyTo(ref T[] dst, [In] int srcIndex, [In] int length) - { - fixed (T* ptr = dst) - { - CopyTo(ptr, srcIndex, length); - } - } - - /// - /// Copy data from buffer to dst from dst[0] - /// - /// - /// - /// - /// - public void CopyTo([In] T* dst, [In] int srcIndex, [In] int length) - { - var l = srcIndex + length; - //size check - EnsureCapacity(in l); - //copy - Unsafe.CopyBlock(dst, Data + srcIndex, (uint)length); - } - - /// - /// Free allocated memories - /// - ~ExtensibleBuffer() - { - Marshal.FreeHGlobal((IntPtr)Data); - GC.RemoveMemoryPressure(sizeOfT * TotalLength); - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Shared/IO/Buffer/ExtensibleBufferExtensions.cs b/Nino_Unity/Assets/Nino/Shared/IO/Buffer/ExtensibleBufferExtensions.cs deleted file mode 100644 index 643f2e2..0000000 --- a/Nino_Unity/Assets/Nino/Shared/IO/Buffer/ExtensibleBufferExtensions.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System; -using System.IO; - -namespace Nino.Shared.IO -{ - /// - /// Extensible buffer ext - /// - public static class ExtensibleBufferExtensions - { - /// - /// Write data to stream - /// - /// - /// - /// - public static void WriteToStream(this ExtensibleBuffer buffer, Stream stream, int length) - { - byte[] bytes = ArrayPool.Request(4096); - if (length <= 4096) - { - buffer.CopyTo(ref bytes, 0, length); - stream.Write(bytes, 0, length); - ArrayPool.Return(bytes); - return; - } - - int wrote = 0; - while(length > 0) - { - int sizeToWrite = length <= 4096 ? length : 4096; - buffer.CopyTo(ref bytes, wrote, sizeToWrite); - stream.Write(bytes, 0, sizeToWrite); - length -= sizeToWrite; - wrote += sizeToWrite; - } - ArrayPool.Return(bytes); - } - - /// - /// Write data to stream - /// - /// - /// - /// - // ReSharper disable RedundantNameQualifier - public static unsafe void WriteToStream(this ExtensibleBuffer buffer, Nino.Shared.IO.DeflateStream stream, int length) - // ReSharper restore RedundantNameQualifier - { - stream.Write(buffer.Data, 0, length); - } - -#if !NETSTANDARD && !NET461 && !UNITY_2017_1_OR_NEWER - /// - /// Write data to stream - /// - /// - /// - /// - public static unsafe void WriteToStream(this ExtensibleBuffer buffer, System.IO.Compression.DeflateStream stream, int length) - { - stream.Write(new ReadOnlySpan(buffer.Data,length)); - } -#endif - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Shared/IO/Pool/ArrayPool.cs b/Nino_Unity/Assets/Nino/Shared/IO/Pool/ArrayPool.cs deleted file mode 100644 index d3b6957..0000000 --- a/Nino_Unity/Assets/Nino/Shared/IO/Pool/ArrayPool.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Nino.Shared.IO -{ - /// - /// Thread safe array pool - /// - /// - public static class ArrayPool - { - /// - /// Shared pool - /// - private static readonly Dictionary> Pool = new Dictionary>(3); - - /// - /// lock obj - /// - // ReSharper disable StaticMemberInGenericType - private static readonly object Lock = new object(); - // ReSharper restore StaticMemberInGenericType - - /// - /// Check pool size - /// - /// - private static void CheckPool(int size) - { - lock (Lock) - { - if (!Pool.TryGetValue(size, out _)) - { - //new queue - Pool.Add(size, new UncheckedStack()); - } - } - } - - /// - /// Request a T arr with internal length of size - /// - /// - /// - public static T[] Request(int size) - { - CheckPool(size); - lock (Lock) - { - var queue = Pool[size]; - //get from queue - if (queue.Count > 0) - { - var ret = queue.Pop(); - //double check - if (ret.Length != size) - { - Array.Resize(ref ret, size); - } - return ret; - } - //return new obj[] - return new T[size]; - } - } - - /// - /// Return arr to pool - /// - /// - /// - public static void Return(int size, T[] arr) - { - CheckPool(size); - lock (Lock) - { - Pool[size].Push(arr); - } - } - - /// - /// Return arr to pool - /// - /// - public static void Return(T[] arr) - { - Return(arr.Length, arr); - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Shared/IO/Pool/BufferPool.cs b/Nino_Unity/Assets/Nino/Shared/IO/Pool/BufferPool.cs deleted file mode 100644 index 18f01d4..0000000 --- a/Nino_Unity/Assets/Nino/Shared/IO/Pool/BufferPool.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System; - -namespace Nino.Shared.IO -{ - /// - /// Thread safe byte array (buffer) pool - /// - public static class BufferPool - { - /// - /// A shared buffer queue - /// - private static readonly UncheckedStack Buffers = new UncheckedStack(3); - - /// - /// Request a buffer - /// - /// - /// - public static byte[] RequestBuffer(int size = 0) - { - lock (Buffers) - { - byte[] ret; - if (Buffers.Count > 0) - { - ret = Buffers.Peek(); - if (ret.Length < size) - { - byte[] buffer = new byte[size]; - return buffer; - } - - ret = Buffers.Pop(); - } - else - { - ret = new byte[size]; - } - - return ret; - } - } - - /// - /// Request a buffer from a source - /// - /// - /// - public static byte[] RequestBuffer(byte[] original) - { - byte[] ret = RequestBuffer(original.Length); - Buffer.BlockCopy(original,0,ret,0,original.Length); - return ret; - } - - /// - /// Request a buffer from a source - /// - /// - /// - /// - public static byte[] RequestBuffer(int len, byte[] original) - { - byte[] ret = RequestBuffer(len); - var bLen = Math.Min(original.Length, len); - Buffer.BlockCopy(original,0,ret,0,bLen); - return ret; - } - - /// - /// Return buffer to the pool - /// - /// - public static void ReturnBuffer(byte[] buffer) - { - lock (Buffers) - { - Buffers.Push(buffer); - } - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Shared/IO/Pool/ObjectPool.cs b/Nino_Unity/Assets/Nino/Shared/IO/Pool/ObjectPool.cs deleted file mode 100644 index 203beda..0000000 --- a/Nino_Unity/Assets/Nino/Shared/IO/Pool/ObjectPool.cs +++ /dev/null @@ -1,73 +0,0 @@ -namespace Nino.Shared.IO -{ - /// - /// Thread safe object pool - /// - /// - public static class ObjectPool where T: class, new() - { - /// - /// A shared buffer queue - /// - private static readonly UncheckedStack Pool = new UncheckedStack(3); - - /// - /// lock obj - /// - // ReSharper disable StaticMemberInGenericType - private static readonly object Lock = new object(); - // ReSharper restore StaticMemberInGenericType - - /// - /// Request an obj - /// - /// - public static T Request() - { - lock (Lock) - { - T ret; - if (Pool.Count > 0) - { - ret = Pool.Pop(); - return ret; - } - else - { - ret = new T(); - } - - return ret; - } - } - - /// - /// Preview the next object from stack, wont take - /// - /// - public static T Peak() - { - lock (Lock) - { - if (Pool.Count > 0) - { - return Pool.Peek(); - } - - return null; - } - } - - /// - /// Return an obj to pool - /// - /// - public static void Return(T obj) - { - lock (Lock) - { - Pool.Push(obj); - } - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Shared/IO/Stream/DeflateStream.cs b/Nino_Unity/Assets/Nino/Shared/IO/Stream/DeflateStream.cs deleted file mode 100644 index f361f5f..0000000 --- a/Nino_Unity/Assets/Nino/Shared/IO/Stream/DeflateStream.cs +++ /dev/null @@ -1,608 +0,0 @@ -using System; -using System.IO; -using System.Threading; -using System.IO.Compression; -using System.Runtime.InteropServices; - -namespace Nino.Shared.IO -{ - public class DeflateStream : Stream - { - private delegate int ReadMethod(byte[] array, int offset, int count); - - private delegate void WriteMethod(byte[] array, int offset, int count); - - private FlexibleStream baseStream; - - private CompressionMode mode; - - private readonly bool leaveOpen; - - private bool disposed; - - private readonly DeflateStreamNative native; - - public FlexibleStream BaseStream => baseStream; - - public override bool CanRead - { - get - { - if (!disposed && mode == CompressionMode.Decompress) - { - return baseStream.CanRead; - } - return false; - } - } - - public override bool CanSeek => false; - - public override bool CanWrite - { - get - { - if (!disposed && mode == CompressionMode.Compress) - { - return baseStream.CanWrite; - } - return false; - } - } - - public override long Length => throw new NotSupportedException(); - - public override long Position - { - get => throw new NotSupportedException(); - set => throw new NotSupportedException(); - } - - public DeflateStream(FlexibleStream stream, CompressionMode mode) - : this(stream, mode, false, false) - { - } - - public DeflateStream(FlexibleStream stream, CompressionMode mode, bool leaveOpen) - : this(stream, mode, leaveOpen, false) - { - } - - private DeflateStream(FlexibleStream compressedStream, CompressionMode mode, bool leaveOpen, bool gzip) - { - if (mode != CompressionMode.Compress && mode != 0) - { - throw new ArgumentException("mode"); - } - baseStream = compressedStream ?? throw new ArgumentNullException(nameof(compressedStream)); - native = DeflateStreamNative.Create(compressedStream, mode, gzip); - if (native == null) - { - throw new NotImplementedException("Failed to initialize zlib. You probably have an old zlib installed. Version 1.2.0.4 or later is required."); - } - this.mode = mode; - this.leaveOpen = leaveOpen; - } - - ~DeflateStream() - { - Dispose(false); - } - - /// - /// Finish compressing - /// - public void Finish() - { - native.DisposeZStream(); - } - - /// - /// Reset deflate stream - /// - public void Reset() - { - baseStream.Position = 0; - baseStream.SetLength(0); - native.ResetZStream(mode, false); - } - - /// - /// Get decompressed bytes - /// - /// - /// - /// - public unsafe IntPtr GetDecompressedBytes(out int length, int minLen) - { - int read; - length = 0; - var expandSize = minLen * 10; - IntPtr buffer = Marshal.AllocHGlobal(expandSize); - int maxLen = minLen * 5; - //开始写 - while ((read = Read((byte*)buffer, length, expandSize)) != 0) - { - length += read; - //如果目前读取的长度达到了buffer的一半,就需要扩容 - if (length >= maxLen) - { - maxLen += expandSize; - buffer = Marshal.ReAllocHGlobal(buffer, new IntPtr(maxLen + expandSize)); - } - } - - return buffer; - } - - protected override void Dispose(bool disposing) - { - if (disposing) - { - GC.SuppressFinalize(this); - } - native?.Dispose(disposing); - if (disposing && !disposed) - { - disposed = true; - if (!leaveOpen) - { - baseStream?.Close(); - baseStream = null; - } - } - base.Dispose(disposing); - } - - private unsafe int ReadInternal(byte[] array, int offset, int count) - { - if (count == 0) - { - return 0; - } - fixed (byte* ptr = array) - { - IntPtr buffer = new IntPtr(ptr + offset); - return native.ReadZStream(buffer, count); - } - } - - private unsafe int ReadInternal(byte* ptr, int offset, int count) - { - if (count == 0) - { - return 0; - } - IntPtr buffer = new IntPtr(ptr + offset); - return native.ReadZStream(buffer, count); - } - - public unsafe int Read(byte* array, int offset, int count) - { - if (disposed) - { - throw new ObjectDisposedException(GetType().FullName); - } - if (array == null) - { - throw new ArgumentNullException(nameof(array)); - } - if (!CanRead) - { - throw new InvalidOperationException("Stream does not support reading."); - } - if (offset < 0 || count < 0) - { - throw new ArgumentException("Dest or count is negative."); - } - return ReadInternal(array, offset, count); - } - - public override int Read(byte[] array, int offset, int count) - { - if (disposed) - { - throw new ObjectDisposedException(GetType().FullName); - } - if (array == null) - { - throw new ArgumentNullException(nameof(array)); - } - if (!CanRead) - { - throw new InvalidOperationException("Stream does not support reading."); - } - int num = array.Length; - if (offset < 0 || count < 0) - { - throw new ArgumentException("Dest or count is negative."); - } - if (offset > num) - { - throw new ArgumentException("destination offset is beyond array size"); - } - if (offset + count > num) - { - throw new ArgumentException("Reading would overrun buffer"); - } - return ReadInternal(array, offset, count); - } - - private unsafe void WriteInternal(byte[] array, int offset, int count) - { - if (count != 0) - { - fixed (byte* ptr = array) - { - IntPtr buffer = new IntPtr(ptr + offset); - native.WriteZStream(buffer, count); - } - } - } - - public unsafe void Write(byte* array, int offset, int count) - { - if (count != 0) - { - IntPtr buffer = new IntPtr(array + offset); - native.WriteZStream(buffer, count); - } - } - - public override void Write(byte[] array, int offset, int count) - { - if (disposed) - { - throw new ObjectDisposedException(GetType().FullName); - } - if (array == null) - { - throw new ArgumentNullException(nameof(array)); - } - if (offset < 0) - { - throw new ArgumentOutOfRangeException(nameof(offset)); - } - if (count < 0) - { - throw new ArgumentOutOfRangeException(nameof(count)); - } - if (!CanWrite) - { - throw new NotSupportedException("Stream does not support writing"); - } - if (offset > array.Length - count) - { - throw new ArgumentException("Buffer too small. count/offset wrong."); - } - WriteInternal(array, offset, count); - } - - public override void Flush() - { - if (disposed) - { - throw new ObjectDisposedException(GetType().FullName); - } - if (CanWrite) - { - native.Flush(); - } - } - - public override IAsyncResult BeginRead(byte[] array, int offset, int count, AsyncCallback asyncCallback, object asyncState) - { - if (disposed) - { - throw new ObjectDisposedException(GetType().FullName); - } - if (!CanRead) - { - throw new NotSupportedException("This stream does not support reading"); - } - if (array == null) - { - throw new ArgumentNullException(nameof(array)); - } - if (count < 0) - { - throw new ArgumentOutOfRangeException(nameof(count), "Must be >= 0"); - } - if (offset < 0) - { - throw new ArgumentOutOfRangeException(nameof(offset), "Must be >= 0"); - } - if (count + offset > array.Length) - { - throw new ArgumentException("Buffer too small. count/offset wrong."); - } - return new ReadMethod(ReadInternal).BeginInvoke(array, offset, count, asyncCallback, asyncState); - } - - public override IAsyncResult BeginWrite(byte[] array, int offset, int count, AsyncCallback asyncCallback, object asyncState) - { - if (disposed) - { - throw new ObjectDisposedException(GetType().FullName); - } - if (!CanWrite) - { - throw new InvalidOperationException("This stream does not support writing"); - } - if (array == null) - { - throw new ArgumentNullException(nameof(array)); - } - if (count < 0) - { - throw new ArgumentOutOfRangeException(nameof(count), "Must be >= 0"); - } - if (offset < 0) - { - throw new ArgumentOutOfRangeException(nameof(offset), "Must be >= 0"); - } - if (count + offset > array.Length) - { - throw new ArgumentException("Buffer too small. count/offset wrong."); - } - return new WriteMethod(WriteInternal).BeginInvoke(array, offset, count, asyncCallback, asyncState); - } - - public override long Seek(long offset, SeekOrigin origin) - { - throw new NotSupportedException(); - } - - public override void SetLength(long value) - { - throw new NotSupportedException(); - } - } - - internal class DeflateStreamNative - { -#if UNITY_2017_1_OR_NEWER - private const string DllName = "MonoPosixHelper"; -#else - private const string DllName = "Deflate"; -#endif - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int UnmanagedReadOrWrite(IntPtr buffer, int length, IntPtr data); - - // ReSharper disable ClassNeverInstantiated.Local - private sealed class SafeDeflateStreamHandle : SafeHandle - // ReSharper restore ClassNeverInstantiated.Local - { -#if NET7_0_OR_GREATER - public override bool IsInvalid => handle.Equals(IntPtr.Zero); -#else - public override bool IsInvalid => handle == IntPtr.Zero; -#endif - - - // ReSharper disable UnusedMember.Local - private SafeDeflateStreamHandle() - : base(IntPtr.Zero, true) - { - } - - internal SafeDeflateStreamHandle(IntPtr handle) - : base(handle, true) - { - } - // ReSharper restore UnusedMember.Local - - [MonoPInvokeCallback] - protected override bool ReleaseHandle() - { - try - { - CloseZStream(handle); - } - catch - { - // ignored - } - - return true; - } - } - - private const int BufferSize = 4096; - - private UnmanagedReadOrWrite feeder; - - private FlexibleStream baseStream; - - private SafeDeflateStreamHandle zStream; - - private GCHandle data; - - private bool disposed; - - private Exception lastError; - - private DeflateStreamNative() - { - } - - [MonoPInvokeCallback] - public static DeflateStreamNative Create(FlexibleStream compressedStream, CompressionMode mode, bool gzip) - { - DeflateStreamNative deflateStreamNative = new DeflateStreamNative(); - deflateStreamNative.data = GCHandle.Alloc(deflateStreamNative); - deflateStreamNative.feeder = ((mode == CompressionMode.Compress) ? UnmanagedWrite : new UnmanagedReadOrWrite(UnmanagedRead)); - deflateStreamNative.zStream = CreateZStream(mode, gzip, deflateStreamNative.feeder, GCHandle.ToIntPtr(deflateStreamNative.data)); - if (deflateStreamNative.zStream.IsInvalid) - { - deflateStreamNative.Dispose(true); - return null; - } - deflateStreamNative.baseStream = compressedStream; - return deflateStreamNative; - } - - [MonoPInvokeCallback] - public void DisposeZStream() - { - if (zStream != null && !zStream.IsInvalid) - { - zStream.Dispose(); - } - } - - [MonoPInvokeCallback] - public void ResetZStream(CompressionMode mode, bool gzip) - { - zStream = CreateZStream(mode, gzip, this.feeder, GCHandle.ToIntPtr(this.data)); - } - - ~DeflateStreamNative() - { - Dispose(false); - } - - [MonoPInvokeCallback] - public void Dispose(bool disposing) - { - if (disposing && !disposed) - { - disposed = true; - GC.SuppressFinalize(this); - } - else - { - baseStream = Stream.Null as FlexibleStream; - } - if (zStream != null && !zStream.IsInvalid) - { - zStream.Dispose(); - } - _ = data; - if (data.IsAllocated) - { - data.Free(); - } - } - - [MonoPInvokeCallback] - public void Flush() - { - int result = Flush(zStream); - CheckResult(result, "Flush"); - } - - [MonoPInvokeCallback] - public int ReadZStream(IntPtr buffer, int length) - { - int result = ReadZStream(zStream, buffer, length); - CheckResult(result, "ReadInternal"); - return result; - } - - [MonoPInvokeCallback] - public void WriteZStream(IntPtr buffer, int length) - { - int result = WriteZStream(zStream, buffer, length); - CheckResult(result, "WriteInternal"); - } - - [MonoPInvokeCallback] - private static int UnmanagedRead(IntPtr buffer, int length, IntPtr data) - { - if (!(GCHandle.FromIntPtr(data).Target is DeflateStreamNative deflateStreamNative)) - { - return -1; - } - return deflateStreamNative.UnmanagedRead(buffer, length); - } - - [MonoPInvokeCallback] - private unsafe int UnmanagedRead(IntPtr buffer, int length) - { - int count = Math.Min(length, BufferSize); - int num; - try - { - num = baseStream.Read((byte*)buffer, 0, count); - } - catch - { - return -12; - } - return num; - } - - [MonoPInvokeCallback] - private static int UnmanagedWrite(IntPtr buffer, int length, IntPtr data) - { - if (!(GCHandle.FromIntPtr(data).Target is DeflateStreamNative deflateStreamNative)) - { - return -1; - } - return deflateStreamNative.UnmanagedWrite(buffer, length); - } - - [MonoPInvokeCallback] - private unsafe int UnmanagedWrite(IntPtr buffer, int length) - { - baseStream.Write((byte*)buffer, 0, length); - return length; - } - - private void CheckResult(int result, string where) - { - if (result >= 0) - { - return; - } - Exception ex = Interlocked.Exchange(ref lastError, null); - if (ex != null) - { - throw ex; - } - - string R() - { - switch(result) - { - case -1: - return "Unknown error"; - case -2 : - return "Internal error"; - case -3 : - return "Corrupted data"; - case -4 : - return "Not enough memory"; - case -5 : - return "Internal error (no progress possible)"; - case -6 : - return "Invalid version"; - case -10 : - return "Invalid argument(s)"; - case -11 : - return "IO error"; - default: - return "Unknown error"; - } - } - throw new IOException( R() + " " + where); - } - - [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] - private static extern SafeDeflateStreamHandle CreateZStream(CompressionMode compress, bool gzip, UnmanagedReadOrWrite feeder, IntPtr data); - - [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] - private static extern int CloseZStream(IntPtr stream); - - [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] - private static extern int Flush(SafeDeflateStreamHandle stream); - - [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] - private static extern int ReadZStream(SafeDeflateStreamHandle stream, IntPtr buffer, int length); - - [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] - private static extern int WriteZStream(SafeDeflateStreamHandle stream, IntPtr buffer, int length); - } -} diff --git a/Nino_Unity/Assets/Nino/Shared/IO/Stream/FlexibleStream.cs b/Nino_Unity/Assets/Nino/Shared/IO/Stream/FlexibleStream.cs deleted file mode 100644 index d6fd07a..0000000 --- a/Nino_Unity/Assets/Nino/Shared/IO/Stream/FlexibleStream.cs +++ /dev/null @@ -1,533 +0,0 @@ -using System; -using System.IO; -using Nino.Shared.Mgr; -using Nino.Shared.Util; - -namespace Nino.Shared.IO -{ - /// - /// Can change the buffer in anytime - /// This stream provides no GC write and read method, require to use it with stackalloc - /// - public sealed class FlexibleStream : Stream - { - private byte[] internalBuffer; // Either allocated internally or externally. - private int origin; // For user-provided arrays, start at this origin - private int position; // read/write head. - private int length; // Number of bytes within the memory stream - private int capacity; // length of usable portion of buffer for stream - - // Note that _capacity == _buffer.Length for non-user-provided byte[]'s - - private bool expandable; // User-provided buffers aren't expandable. - private readonly bool exposable; // Whether the array can be returned to the user. - private bool isOpen; // Is this stream open or closed? - - private readonly uint maxLength = 2147483648; - private const int MemStreamMaxLength = Int32.MaxValue; - - public void ChangeBuffer(byte[] data, int offset, int count) - { - Reset(); - internalBuffer = data; - origin = offset; - position = offset; - length = data.Length; - capacity = length; - } - - public void ChangeBuffer(ArraySegment data) - { - ChangeBuffer(data.Array, data.Offset, data.Count); - } - - public void Reset() - { - position = 0; - origin = 0; - length = 0; - isOpen = true; - expandable = true; - } - - public FlexibleStream(): this(ConstMgr.Null) - { - //for object pool to be able to call - } - - public FlexibleStream(byte[] internalBuffer) - { - this.internalBuffer = internalBuffer ?? throw new ArgumentNullException(nameof(internalBuffer), "buffer == null"); - length = capacity = internalBuffer.Length; - exposable = true; - expandable = true; - isOpen = true; - origin = 0; - } - - public FlexibleStream(ArraySegment internalBuffer) - { - this.internalBuffer = internalBuffer.Array ?? throw new ArgumentNullException(nameof(internalBuffer), "buffer == null"); - length = capacity = internalBuffer.Array.Length; - exposable = true; - expandable = true; - isOpen = true; - origin = internalBuffer.Offset; - position = internalBuffer.Offset; - } - - public override bool CanRead => isOpen; - - public override bool CanSeek => isOpen; - - public override bool CanWrite => isOpen; - - protected override void Dispose(bool disposing) - { - try - { - if (disposing) - { - isOpen = false; - expandable = false; - // Don't set buffer to null - allow TryGetBuffer, GetBuffer & ToArray to work. - } - } - finally - { - // Call base.Close() to cleanup async IO resources - base.Dispose(disposing); - } - } - - // returns a bool saying whether we allocated a new array. - private bool EnsureCapacity(int value) - { - // Check for overflow - if (value < 0) - throw new IOException("Stream too long, value < capacity of stream is invalid"); - if (value > capacity) - { - int newCapacity = value; - if (newCapacity < 256) - newCapacity = 256; - // We are ok with this overflowing since the next statement will deal - // with the cases where _capacity*2 overflows. - if (newCapacity < capacity * 2) - newCapacity = capacity * 2; - // We want to expand the array up to Array.MaxArrayLengthOneDimensional - // And we want to give the user the value that they asked for - if ((uint)(capacity * 2) > maxLength) - newCapacity = value < maxLength ? value : (int)(maxLength / 2); - - Capacity = newCapacity; - return true; - } - - return false; - } - - public override void Flush() - { - } - - /// - /// Get original buffer - /// - /// - /// - public byte[] GetBuffer() - { - if (!exposable) - throw new UnauthorizedAccessException("UnauthorizedAccess to get member buffer"); - return internalBuffer; - } - - /// - /// Try get original buffer - /// - /// - /// - public bool TryGetBuffer(out ArraySegment buffer) - { - if (!exposable) - { - buffer = default(ArraySegment); - return false; - } - - buffer = new ArraySegment(this.internalBuffer, offset: origin, count: (length - origin)); - return true; - } - - // Gets & sets the capacity (number of bytes allocated) for this stream. - // The capacity cannot be set to a value less than the current length - // of the stream. - // - public int Capacity - { - get - { - if (!isOpen) Logger.E("stream is closed"); - return capacity - origin; - } - set - { - // Only update the capacity if the MS is expandable and the value is different than the current capacity. - // Special behavior if the MS isn't expandable: we don't throw if value is the same as the current capacity - if (value < Length) - throw new ArgumentOutOfRangeException(nameof(value), "value < capcacity is invalid"); - - if (!isOpen) Logger.E("stream is closed"); - if (!expandable && (value != Capacity)) Logger.E("FlexibleStream is not expandable"); - - // FlexibleStream has this invariant: _origin > 0 => !expandable (see ctors) - if (expandable && value != capacity) - { - if (value > 0) - { - byte[] newBuffer = new byte[value]; - if (length > 0) Buffer.BlockCopy(internalBuffer, 0, newBuffer, 0, length); - internalBuffer = newBuffer; - } - else - { - internalBuffer = null; - } - - capacity = value; - } - } - } - - /// - /// Length of written buffer or the buffer provided - /// - public override long Length - { - get - { - if (!isOpen) Logger.E("stream is closed"); - return length - origin; - } - } - - /// - /// Position of the current stream - /// - /// - public override long Position - { - get - { - if (!isOpen) Logger.E("stream is closed"); - return position - origin; - } - set - { - if (value < 0) - throw new ArgumentOutOfRangeException(nameof(value), "value < 0 is invalid"); - if (!isOpen) Logger.E("stream is closed"); - - if (value > MemStreamMaxLength) - throw new ArgumentOutOfRangeException(nameof(value), "value > stream length is invalid"); - position = origin + (int)value; - } - } - - /// - /// Read a byte from current position - /// - /// - public override int ReadByte() - { - if (!isOpen) Logger.E("stream is closed"); - - if (position >= length) return -1; - - return internalBuffer[position++]; - } - - /// - /// Read and copy some bytes to the provided buffer - has gc if buffer is a new byte[count] or byte[moreThanCount] - /// - /// - /// - /// - /// - /// - /// - /// - public override int Read(byte[] buffer, int offset, int count) - { - if (buffer == null) - throw new ArgumentNullException(nameof(buffer), "buffer == null"); - if (offset < 0) - throw new ArgumentOutOfRangeException(nameof(offset), "offset < 0"); - if (count < 0) - throw new ArgumentOutOfRangeException(nameof(count), "count < 0"); - if (buffer.Length - offset < count) - throw new ArgumentException("invalid buffer length"); - - if (!isOpen) Logger.E("stream is closed"); - - int n = length - position; - if (n > count) n = count; - if (n <= 0) - return 0; - - if (n <= 8) - { - int byteCount = n; - while (--byteCount >= 0) - buffer[offset + byteCount] = this.internalBuffer[position + byteCount]; - } - else - Buffer.BlockCopy(this.internalBuffer, position, buffer, offset, n); - - position += n; - - return n; - } - - /// - /// Read and copy some bytes to a byte array pointer - has no gc when buffer is stackalloc byte[count] - /// - /// - /// - /// - /// - public unsafe int Read(byte* buffer, int offset, int count) - { - if (!isOpen) Logger.E("stream is closed"); - - int n = length - position; - if (n > count) n = count; - if (n <= 0) - return 0; - - fixed (byte* internalPtr = internalBuffer) - { - Buffer.MemoryCopy(internalPtr + position, buffer + offset, count,n); - } - position += n; - - return n; - } - - /// - /// Write a byte to the stream - /// - /// - /// - public override void WriteByte(byte value) { - if (!isOpen) - throw new InvalidOperationException("this stream is closed"); - - if (position >= length) { - int newLength = position + 1; - bool mustZero = position > length; - if (newLength >= capacity) { - bool allocatedNewArray = EnsureCapacity(newLength); - if (allocatedNewArray) - mustZero = false; - } - if (mustZero) - Array.Clear(internalBuffer, length, position - length); - length = newLength; - } - internalBuffer[position++] = value; - } - - /// - /// Write some bytes to the stream from a byte[count] or byte[moreThanCount] - /// - /// - /// - /// - /// - /// - /// - /// - /// - public override void Write(byte[] buffer, int offset, int count) - { - if (buffer==null) - throw new ArgumentNullException(nameof(buffer),"null"); - if (offset < 0) - throw new ArgumentOutOfRangeException(nameof(offset), "cannot be negative"); - if (count < 0) - throw new ArgumentOutOfRangeException(nameof(count),"cannot be negative"); - if (buffer.Length - offset < count) - throw new ArgumentException("invalid length"); - - if (!isOpen) - throw new InvalidOperationException("this stream is closed"); - - int i = position + count; - // Check for overflow - if (i < 0) - throw new IOException("Stream Too Long"); - - if (i > length) { - bool mustZero = position > length; - if (i > capacity) { - bool allocatedNewArray = EnsureCapacity(i); - if (allocatedNewArray) - mustZero = false; - } - if (mustZero) - Array.Clear(internalBuffer, length, i - length); - length = i; - } - if ((count <= 8) && (buffer != internalBuffer)) - { - int byteCount = count; - while (--byteCount >= 0) - internalBuffer[position + byteCount] = buffer[offset + byteCount]; - } - else - Buffer.BlockCopy(buffer, offset, internalBuffer, position, count); - position = i; - } - - /// - /// Write some bytes to the stream from a stackalloc byte[count] - /// - /// - /// - /// - /// - /// - /// - /// - /// - public unsafe void Write(byte* buffer, int offset, int count) - { - if (buffer==null) - throw new ArgumentNullException(nameof(buffer),"null"); - if (offset < 0) - throw new ArgumentOutOfRangeException(nameof(offset), "cannot be negative"); - if (count < 0) - throw new ArgumentOutOfRangeException(nameof(count),"cannot be negative"); - - if (!isOpen) - throw new InvalidOperationException("this stream is closed"); - - int i = position + count; - // Check for overflow - if (i < 0) - throw new IOException("Stream Too Long"); - - if (i > length) { - bool mustZero = position > length; - if (i > capacity) { - bool allocatedNewArray = EnsureCapacity(i); - if (allocatedNewArray) - mustZero = false; - } - if (mustZero) - Array.Clear(internalBuffer, length, i - length); - length = i; - } - - fixed (byte* internalPtr = internalBuffer) - { - Buffer.MemoryCopy(buffer + offset, internalPtr + position, count, count); - } - - position = i; - } - - /// - /// Seek the stream - /// - /// - /// - /// - /// - /// - /// - public override long Seek(long offset, SeekOrigin loc) - { - if (!isOpen) Logger.E("stream is closed"); - - if (offset > MemStreamMaxLength) - throw new ArgumentOutOfRangeException(nameof(offset), "offset > stream length is invalid"); - switch (loc) - { - case SeekOrigin.Begin: - { - int tempPosition = unchecked(origin + (int)offset); - if (offset < 0 || tempPosition < origin) - throw new IOException("offset < 0 from the beginning of stream is invalid"); - position = tempPosition; - break; - } - case SeekOrigin.Current: - { - int tempPosition = unchecked(position + (int)offset); - if (unchecked(position + offset) < origin || tempPosition < origin) - throw new IOException("offset is before the stream which is invalid"); - position = tempPosition; - break; - } - case SeekOrigin.End: - { - int tempPosition = unchecked(length + (int)offset); - if (unchecked(length + offset) < origin || tempPosition < origin) - throw new IOException("offset is before the stream which is invalid"); - position = tempPosition; - break; - } - default: - throw new ArgumentException("invalid seek origin"); - } - - return position; - } - - // Sets the length of the stream to a given value. The new - // value must be nonnegative and less than the space remaining in - // the array, Int32.MaxValue - origin - // Origin is 0 in all cases other than a FlexibleStream created on - // top of an existing array and a specific starting offset was passed - // into the FlexibleStream constructor. The upper bounds prevents any - // situations where a stream may be created on top of an array then - // the stream is made longer than the maximum possible length of the - // array (Int32.MaxValue). - // - public override void SetLength(long value) - { - if (value < 0 || value > Int32.MaxValue) - { - throw new ArgumentOutOfRangeException(nameof(value), "value does not fit the length (out of range)"); - } - - // Origin wasn't publicly exposed above. - if (value > (Int32.MaxValue - origin)) - { - throw new ArgumentOutOfRangeException(nameof(value), "value is too big"); - } - - int newLength = origin + (int)value; - bool allocatedNewArray = EnsureCapacity(newLength); - if (!allocatedNewArray && newLength > length) - Array.Clear(internalBuffer, length, newLength - length); - length = newLength; - if (position > newLength) position = newLength; - - } - - /// - /// Get written bytes to array - will cause GC - /// - /// - public byte[] ToArray() - { - byte[] copy = new byte[length - origin]; - Buffer.BlockCopy(internalBuffer, origin, copy, 0, length - origin); - return copy; - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Shared/Mgr/CompressMgr.cs b/Nino_Unity/Assets/Nino/Shared/Mgr/CompressMgr.cs deleted file mode 100644 index 59e9703..0000000 --- a/Nino_Unity/Assets/Nino/Shared/Mgr/CompressMgr.cs +++ /dev/null @@ -1,352 +0,0 @@ -using System; -using System.IO; -using Nino.Shared.IO; -using System.IO.Compression; -using System.Runtime.InteropServices; -using DeflateStream = Nino.Shared.IO.DeflateStream; -// ReSharper disable UnusedMember.Local -// ReSharper disable HeuristicUnreachableCode -#pragma warning disable 162 - -namespace Nino.Shared.Mgr -{ - public static class CompressMgr - { - /// - /// static ctor - /// - static CompressMgr() - { - if (!ConstMgr.EnableNativeDeflate) return; - GetCompressInformation(out _, out _); - var compressedStream = new FlexibleStream(BufferPool.RequestBuffer(10240)); - var zipStream = new DeflateStream(compressedStream, CompressionMode.Compress, true); - CompressStreams.Push(zipStream); - var empty = new ArraySegment(Array.Empty()); - GetDecompressInformation(out _, ref empty); - compressedStream = new FlexibleStream(BufferPool.RequestBuffer(10240)); - zipStream = new DeflateStream(compressedStream, CompressionMode.Decompress, true); - DecompressStreams.Push(zipStream); - } - - /// - /// compress stream pool (deflateStream compress + flexibleStream) - /// - private static readonly UncheckedStack CompressStreams = new UncheckedStack(); - - /// - /// decompress stream pool (deflateStream decompress + flexibleStream) - /// - private static readonly UncheckedStack DecompressStreams = new UncheckedStack(); - - /// - /// lock compressed streams - /// - private static readonly object CompressedLock = new object(); - - - /// - /// lock decompressed streams - /// - private static readonly object DecompressedLock = new object(); - - /// - /// Compress the given bytes - /// - /// - /// - public static byte[] Compress(byte[] data) - { - return Compress(new ArraySegment(data)); - } - - /// - /// Compress the given bytes - /// - /// - /// - public static byte[] Compress(ArraySegment data) - { - lock (CompressedLock) - { - if (!ConstMgr.EnableNativeDeflate) - { - return CompressOnNative(data); - } - - GetCompressInformation(out var zipStream, out var compressedStream); - // ReSharper disable AssignNullToNotNullAttribute - zipStream.Write(data.Array, data.Offset, data.Count); - // ReSharper restore AssignNullToNotNullAttribute - return GetCompressBytes(zipStream, compressedStream); - } - } - - /// - /// Compress the given bytes - /// - /// - /// - /// - public static byte[] Compress(ExtensibleBuffer data, int length) - { - lock (CompressedLock) - { - if (!ConstMgr.EnableNativeDeflate) - { - return CompressOnNative(data, length); - } - - GetCompressInformation(out var zipStream, out var compressedStream); - data.WriteToStream(zipStream, length); - return GetCompressBytes(zipStream, compressedStream); - } - } - - - /// - /// Get compressed data - /// - /// - /// - /// - private static byte[] GetCompressBytes(DeflateStream zipStream, FlexibleStream compressedStream) - { - zipStream.Finish(); - //push - CompressStreams.Push(zipStream); - return compressedStream.ToArray(); - } - - /// - /// Get relevant data - /// - /// - /// - private static void GetCompressInformation(out DeflateStream zipStream, out FlexibleStream compressedStream) - { - lock (CompressedLock) - { - //try get stream - if (CompressStreams.Count > 0) - { - zipStream = CompressStreams.Pop(); - zipStream.Reset(); - compressedStream = zipStream.BaseStream; - } - else - { - //create - compressedStream = new FlexibleStream(); - zipStream = new DeflateStream(compressedStream, CompressionMode.Compress, true); - } - } - } - - /// - /// Decompress thr given bytes (NEED TO BE AWARE OF UNMANAGED INTPTR, REMEMBER TO FREE IT) - /// - /// - /// - /// - public static IntPtr Decompress(byte[] data, out int outputLength) - { - lock (DecompressedLock) - { - var seg = new ArraySegment(data); - if (!ConstMgr.EnableNativeDeflate) - { - return DecompressOnNative(seg, out outputLength); - } - - GetDecompressInformation(out var zipStream, ref seg); - var ret = zipStream.GetDecompressedBytes(out outputLength, data.Length); - //push - DecompressStreams.Push(zipStream); - return ret; - } - } - - /// - /// Decompress thr given bytes (NEED TO BE AWARE OF UNMANAGED INTPTR, REMEMBER TO FREE IT) - /// - /// - /// - /// - public static IntPtr Decompress(ArraySegment data, out int outputLength) - { - lock (DecompressedLock) - { - if (!ConstMgr.EnableNativeDeflate) - { - return DecompressOnNative(data, out outputLength); - } - - GetDecompressInformation(out var zipStream, ref data); - var ret = zipStream.GetDecompressedBytes(out outputLength, data.Count); - //push - DecompressStreams.Push(zipStream); - return ret; - } - } - - /// - /// Decompress thr given bytes - /// - /// - /// - public static byte[] Decompress(byte[] data) - { - lock (DecompressedLock) - { - var seg = new ArraySegment(data); - if (!ConstMgr.EnableNativeDeflate) - { - var ptr = DecompressOnNative(seg, out var length); - byte[] buf = new byte[length]; - Marshal.Copy(ptr, buf, 0, length); - Marshal.FreeHGlobal(ptr); - return buf; - } - - GetDecompressInformation(out var zipStream, ref seg); - var ret = zipStream.GetDecompressedBytes(out var len, data.Length); - //push - DecompressStreams.Push(zipStream); - var buffer = new byte[len]; - Marshal.Copy(ret, buffer, 0, len); - Marshal.FreeHGlobal(ret); - return buffer; - } - } - - /// - /// Decompress thr given bytes - /// - /// - /// - public static byte[] Decompress(ArraySegment data) - { - lock (DecompressedLock) - { - if (!ConstMgr.EnableNativeDeflate) - { - var ptr = DecompressOnNative(data, out var length); - byte[] buf = new byte[length]; - Marshal.Copy(ptr, buf, 0, length); - Marshal.FreeHGlobal(ptr); - return buf; - } - - GetDecompressInformation(out var zipStream, ref data); - var ret = zipStream.GetDecompressedBytes(out var len, data.Count); - //push - DecompressStreams.Push(zipStream); - var buffer = new byte[len]; - Marshal.Copy(ret, buffer, 0, len); - Marshal.FreeHGlobal(ret); - return buffer; - } - } - - - /// - /// Get relevant data - /// - /// - /// - private static void GetDecompressInformation(out DeflateStream zipStream, ref ArraySegment data) - { - lock (DecompressedLock) - { - //try get stream - if (DecompressStreams.Count > 0) - { - zipStream = DecompressStreams.Pop(); - zipStream.Reset(); - var dataStream = zipStream.BaseStream; - dataStream.ChangeBuffer(data); - } - else - { - //create - var dataStream = new FlexibleStream(data); - zipStream = new DeflateStream(dataStream, CompressionMode.Decompress, true); - } - } - } - - #region NON_UNITY - - /// - /// Compress the given bytes - /// - /// - /// - private static byte[] CompressOnNative(ArraySegment data) - { - using (var compressedStream = new MemoryStream()) - using (var zipStream = new System.IO.Compression.DeflateStream(compressedStream, CompressionMode.Compress)) - { - // ReSharper disable AssignNullToNotNullAttribute - zipStream.Write(data.Array, data.Offset, data.Count); - // ReSharper restore AssignNullToNotNullAttribute - zipStream.Close(); - return compressedStream.ToArray(); - } - } - - /// - /// Compress the given bytes - /// - /// - /// - /// - private static byte[] CompressOnNative(ExtensibleBuffer data, int length) - { - using (var compressedStream = new MemoryStream(length)) - using (var zipStream = new System.IO.Compression.DeflateStream(compressedStream, CompressionMode.Compress)) - { - data.WriteToStream(zipStream, length); - zipStream.Close(); - return compressedStream.ToArray(); - } - } - - /// - /// Decompress thr given bytes - /// - /// - /// - /// - private static IntPtr DecompressOnNative(ArraySegment data, out int len) - { - FlexibleStream result = ObjectPool.Request(); - result.Reset(); - FlexibleStream compressedStream; - if (ObjectPool.Peak() != null) - { - compressedStream = ObjectPool.Request(); - compressedStream.ChangeBuffer(data.Array, data.Offset, data.Count); - } - else - { - compressedStream = new FlexibleStream(data); - } - - using (var zipStream = - new System.IO.Compression.DeflateStream(compressedStream, CompressionMode.Decompress)) - { - zipStream.CopyTo(result); - ObjectPool.Return(compressedStream); - len = (int)result.Length; - IntPtr ptr = Marshal.AllocHGlobal(len); - Marshal.Copy(result.GetBuffer(), 0, ptr, len); - ObjectPool.Return(result); - return ptr; - } - } - - #endregion - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Shared/Mgr/ConstMgr.cs b/Nino_Unity/Assets/Nino/Shared/Mgr/ConstMgr.cs deleted file mode 100644 index 8d3780d..0000000 --- a/Nino_Unity/Assets/Nino/Shared/Mgr/ConstMgr.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Nino.Shared.Mgr -{ - public static class ConstMgr - { -#if UNITY_2017_1_OR_NEWER - /// - /// Asset path - /// - public static string AssetPath => UnityEngine.Application.dataPath; - - /// - /// Whether or not enable native deflate (no gc compress/decompress) - /// - public static bool EnableNativeDeflate - { - get => true; - set - { - //ignore - } - } -#else - /// - /// Asset path - /// - public static string AssetPath => System.IO.Directory.GetCurrentDirectory(); - - /// - /// Whether or not enable native deflate (no gc compress/decompress) - /// - public static bool EnableNativeDeflate = false; -#endif - /// - /// Whether is mono or not - /// - public static readonly bool IsMono = Type.GetType("Mono.Runtime") != null; - - /// - /// Null value - /// - public static readonly byte[] Null = Array.Empty(); - - /// - /// Empty param - /// - public static readonly object[] EmptyParam = Array.Empty(); - - #region basic types - - public static readonly Type ObjectType = typeof(object); - public static readonly Type ByteType = typeof(byte); - public static readonly Type SByteType = typeof(sbyte); - public static readonly Type ShortType = typeof(short); - public static readonly Type UShortType = typeof(ushort); - public static readonly Type IntType = typeof(int); - public static readonly Type UIntType = typeof(uint); - public static readonly Type LongType = typeof(long); - public static readonly Type ULongType = typeof(ulong); - public static readonly Type StringType = typeof(string); - public static readonly Type BoolType = typeof(bool); - public static readonly Type DecimalType = typeof(decimal); - public static readonly Type DoubleType = typeof(double); - public static readonly Type FloatType = typeof(float); - public static readonly Type CharType = typeof(char); - public static readonly Type DateTimeType = typeof(DateTime); - public static readonly Type ByteArrType = typeof(byte[]); - public static readonly Type ByteListType = typeof(List); - public static readonly Type ListDefType = typeof(List<>); - public static readonly Type DictDefType = typeof(Dictionary<,>); - public static readonly Type NullableDefType = typeof(Nullable<>); - - #endregion - - public const byte SizeOfUInt = sizeof(uint); - public const byte SizeOfInt = sizeof(int); - public const byte SizeOfUShort = sizeof(ushort); - public const byte SizeOfShort = sizeof(short); - public const byte SizeOfULong = sizeof(ulong); - public const byte SizeOfLong = sizeof(long); - public const byte SizeOfDecimal = sizeof(decimal); - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Shared/Mgr/StringMgr.cs b/Nino_Unity/Assets/Nino/Shared/Mgr/StringMgr.cs deleted file mode 100644 index 60384f4..0000000 --- a/Nino_Unity/Assets/Nino/Shared/Mgr/StringMgr.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System; -using Nino.Shared.IO; - -namespace Nino.Shared.Mgr -{ - public static class StringMgr - { - /// - /// Use Span to optimize string split - /// Useless since .net core 6.0, but useful for .net framework - /// - /// - /// - /// - public static unsafe string[] Split(this ReadOnlySpan str, char separator) - { - if (str.IsEmpty) - { - return Array.Empty(); - } - - var indexes = ObjectPool>.Request(); - var index = 0; - int i = 0; - int max = str.Length; - fixed (char* ptr = &str.GetPinnableReference()) - { - var cPtr = ptr; - while (i < max) - { - if (*cPtr++ == separator) - { - indexes[index++] = i; - } - - i++; - } - - string[] ret = new string[index + 1]; - var retSpan = ret.AsSpan(); - - int start = 0; - - for (i = 0; i < index; i++) - { - ref int end = ref indexes.Data[i]; - if(start >= max || start == end) - { - retSpan[i] = string.Empty; - } - else - { - retSpan[i] = new string(ptr, start, end - start); - } - start = end + 1; - } - - if (start < max) - { - retSpan[index] = new string(ptr, start, max - start); - } - else - { - retSpan[index] = string.Empty; - } - - ObjectPool>.Return(indexes); - return ret; - } - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Shared/Nino.Shared.asmdef b/Nino_Unity/Assets/Nino/Shared/Nino.Shared.asmdef deleted file mode 100644 index 962fe85..0000000 --- a/Nino_Unity/Assets/Nino/Shared/Nino.Shared.asmdef +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "Nino.Shared", - "references": [], - "includePlatforms": [], - "excludePlatforms": [], - "allowUnsafeCode": true, - "overrideReferences": false, - "precompiledReferences": [], - "autoReferenced": true, - "defineConstraints": [], - "versionDefines": [], - "noEngineReferences": false -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Shared/ThirdParty/System.IO.Pipelines.dll b/Nino_Unity/Assets/Nino/Shared/ThirdParty/System.IO.Pipelines.dll deleted file mode 100755 index ddb8567bfacd1e80d8163ba5619007e1cd222f80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83048 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 Nujl?~wu9if{{>?*2&Di3 diff --git a/Nino_Unity/Assets/Nino/Shared/ThirdParty/System.Numerics.Vectors.dll b/Nino_Unity/Assets/Nino/Shared/ThirdParty/System.Numerics.Vectors.dll deleted file mode 100755 index 08659724d4f8534ee97a543e93dd6d3c702fcd15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 115856 zcmeFad0<_|c{eFC<>BFUC5+gxnfc*C{~1{>ReS&bKvWm1rBVGGNWkz@h{ zr_P(LY1|S*;0-Bh$U;feG;NkPdqNUQNM1q$Nt>i0RLM(7($9TE+N5pLCV79q=ggTi zbME!M7Yp%ye|&~J^DMu4X3m^BGtV<;(UpB~Q3<6~62IU5PN`2I=f91TR!&Yp-8lDC zjp}3Bug&{J?250=+jVGgtn=vT$idP6Bc1#EhlfYTJNFHAjvgEC931Z4a`n#6BO?a} zmgV!g1={rXtx8=HOQ^(!|J4`NHlgNs*2k7Bb!!Y2_|i|^3%V2ZgUFR?7CP>?n*z39 z{!Ks+`Id|0IIfMaCzSt(xn_N|x(Rl#CJnnk$!Q_8H^kIiEYfz-{B;A328hLMO+HcH93tmAY}+=-B9f2&HXkqcr9=a%h~7wnxx{APZ8J~V%zuTld(XJ9X+l15W%}1`JNLU9>7|VHG)bXD&iN2V@zL@>$nSM6Q&u05s8#BKz-h?rO z;pVldJ25@v?(ATKPDoDFLo^56L_;RMXU5)}2lLYl$#0+!+N9IJfsqvxsyG*@?#zrr za@~4ZvmiJ*C6E~|1gFe_%!HL+;7}|pIFb?wMuiQ*Q96*>u<{`nf*vS=yxE1IcWg-A zoI-NRVXGnNwi5m2mLA>a=+TNLODsLciKD0edR`T&u}*a19a%5A*B_$^buCUh&b=4^ z?Q{&)w&J^h>Ny6|vKKi6E92qWt4~klS{s%WQkmYwNuINZ2;PyI(c6$I&O>D@f7Cir zzt}PsIalkoF|;mONP5YMd~2a@No&@t3krSC}ZY zv=*kpa*H?Zn{!N?S!%a84VI^Q(?ZJy+j3;g2bSSkBnzz``fhq_VFoNu_hwj@S!%a8 z1D0oaGeXO)w&lpx5?J0y%d@;$6NQ+CpMnJks! zIxHharDddOa~UaCjxtiL8)c-JK*~t5UX+ny1t=rM{8L5>hqjCqPDdFjypS?dbYU4O zRcViBgKVLMv9fU zj1)_887Y?JGEywTWu#bD%1AN&myyE3C?kby;dH+{q4#_k3#il4)E{3EH6_x8Wu=SC zO3x}QEtZv@T~>;9)IA(&!xBjCi`iX8N)Lzn<6KjmgB0n~veIQ`rRS8DE-x!xQC7OL ztaKHm_Tfa9u02kxsXWeAtW_iqf*AA7(xz0IuM0#Pw4i_cM6?Xf8%Hv$s96KW2R91RXS?T6T zo$eyn-R)SX^7xjh9g%LOokj6PYY|s`ZgF9GQr(K_AG3PkYbKV~GrCKS;o{HTk!)Sr zkoe=ly4ml5J6(r$t~jh-onx7+LBwbsxQlw+ZsF+&9p5hF_<9{qEu11E9x!XE zt&CfwuKcINaZ=9I(F&GshdX3J`F(B#T$>Y;HjU0uuE251_} zmdQhtFRN*U#=S}dYfaEJm6pNjn`=7>oc+SZs>eEgGIh@L=1mkjy-w%!`7>r`$?4Pb zlGCT+7idaP zU!W;HeWJnXn`fUst}NE+`;qa$@07Kv%j=pb%=hLyr_W!F=HoQES6?8P9TN8f)T&vc za<4(Hnk_2#GSsRzQMp&5R<(=Dy%@EsLsahdC@OS8m)!+i`O0^Jtep$Jg%gDZ-U6o! z{MB+nNf!iisoU)Wtt!_AT2-zKw5nVeXjQo`(5iA>AS!ghLc0sNGKXEzeY>9KWnn+d zJ8Pn_$XnzbzrU0(!jq*dkGBr3G&Y`aa7NFi_%#dTQXEtx1R_7*#B@|}gnm_gir5;?3d zv8_kqhrqgc4NJYH6NPTC+p+HZ3Ed^uMGosrZR=d|%k-x>4Ci>~Oca)R%N*;zi?FPu zKefDEe`-~^{uCA3bdKGoNYrtW?Ov?#R!kI@d&`|R`3}YMk|P#5tgrB65o`|lvB-B3 zIbbg-h()XoYA$nDcdSU{Qpw(&ZU7paY{*R1x8|2Lq_e%LZ0{vIvNL+~S$`MrRO>{8 zeHffsEn6EC+~Q957Ici}2N5YRHBqQ*Eu@#Ucy(U7*GnR~c!!t9{vbB5eaqNJFQjbK zoUts^+Y;QwPI7uFWOQQ}@QMgGsb>ZrzL)VgtG7km`hP+lj$6+u!L6ggYw+u6&~?a6 zh^=UN>#c>RB{RLe*ThD^)tCIzon8};qseRXkArnI+Q-35+^qv!)Je_-g=Src%r-4v z%S6FzEfi3P=M@O>n*IFpU0wloU;{d=qs6X+m#kX{HlqDHrs+Cl_6RqcXNm{TI;LU6 z8Tn5;bsaJrU^^M!bZemv$1%%mBLJ?rRPW0b-+ak>zHrX5xKf?99TyE<5-~U z*ut@k#Rcn8YvC-^vCun9j$?tJUwxf-7V5wn6xOk5v2~McO+0Z6H{_4=PNRSEFCqm$ zrht3l4`VL^yT)G0CPXTUU5J%!qnC5P0dqkrDfH!+Sq`!-HG3k#`kOf;w`g^^pgq~1%l-o@!jPd%O3yTG*58^?qbR_FVS z&P4R>X%*+8y@_$$5NP9Mw6Ksvl{sBy7FFh2@8YzjZ<=ApA?elka<+)$E?HQs@25F; z&%QOS;>?6val@glfaz&rp%Jw<>RR)twXyXsPGow9>hkhQuSwV1WYy}sM$Tk~S}V;} zs1>8AjoS|k3oWR%Mc3+~)|S@0IJN0Hs|(u^UZIy)NgUHuc&x-krZ3c5Y4$>`7>jMZ zm$tCbidtKBt?0&`L(i{uhE=QY-Z=NoP-~_647FnOt&Nk~!oqCS zI$PH|3$@N}y^GVIp4Ym(SxK+0mse{XQ(1VdzR%-Kaj3P@42N2=NVjpCTUeNbTIc9m zJ5cMK*1I?%>Y1(!I}F}jUF%${R^JzLCOySv`oh~fQN3HX9t@BXp{MNfT zMe4b)%bS<bLI4=G+&V~yMi%{_*UGYLxyr}gq&YOBd z?D7^Sy|eV;o@G@m4v#xGqT)sN^y_*!J(%fGF()H>&cSrVY2xf9xnMq`XPxZzC+An; z;F3GQ&%k^k&jP#(+o>X%X(VWeNM;!cZ#A;iY$HLPB55;{td_JJ32!g5RELr9)*>Zy zj09JqNDy}i4dOjTg68Io2;rhZ(Uv~zgu&?I@qOh-d z$50A}eT_Q?=<7-gQO`H9(Cf7b(UH3rEk$RWwFm)}xU_mCFM#Qt5MkQn!sHKcgbgB` zX$#>_h;WuI0a%vc9-sR z(JZrcpX;3~9=PrU#wxoZLbJGz`yIpkn!78n*r-fa>^0sRcg0?d%FK$r)>~^=#-L?4 zL{4SA`H9LZE!606S*X`}>)eI92bGzHy2tCWJDkzWwGcTSzDWz64(AP0BApK3Oku^9 zy!#rxjIa0ByUX}_XqH*V&-2c+`(O*~UI&rW2U{uR>Mb$LyW$8~7_&&ob51hRdQPi^ zC!TgoG2XALjE?QvTADgqD=2OI@bC z>>^~n>;z+z1h4GNPZC;Ep3ZTZ^1M*_I3M;%yquK3OuD_KJl)(fY8?{rm34t+^%b@szl) zO))<&V!6w)aB4q-m>FW&TB+coY7s^SR(?`Er+aYOAADwG0CmB6`?)2XCm2kXqhSvp2+K0I? zRFSj~b5W=wX%6$OP)^buCY@cMA0`(f zZIGmWnDm^rillv*^q;kgq&ZBw&{|H?945VJEhlLXb44g8X%3UVw8oP(he>x@%SlEL zlPh32mv-;hmoOJgU5ccs{oGJa($u~tl#?{IuMOoSqqRqt+MsqWwYqkaruLptPSVuA zK9rL*wVxNtNk(hO6>J~-Dt+u+sCDfmjkOJ-oMhA*F8XrTxNK`{B#kw?w^~jzYK<#% zne(zSEJf1v%%)II()7$lp`4_teRC)$8Lb`5pj~^=GjsuTn@JjLTSGZXv1U00T=#Fm zYKKJv?x|GXo(kb$>oZl#;$t~+tT&=?%21STVq%t zoYv!J-NKZ!jZQ=%*^(^cD%IAkP4#a&*4+87dmZ0TDW>9h7X{Od-j*k(kZMU4acOIN z?i(v#cTBo-3r(iQqFqsvT_RRxg3b~eC5fe&a5{F%Y zQ|#YFaZN@pPMEA0llE3UF@=Vfh9c&oz@)Qr@0yHUaWI(|lXa;Ol58skZ`IDK%dDb-(i0g2fmJy=~ z<-~M-%b@A@mJw&mi|Ou`LDSVOBW@@!ri)t!P4~8pnBHv}F`e5oV$3k*#F(|piRsze zM(hB^oq(M4LBH0Tb%OJO66M60SIUVoH#Up@*Gf4t{nj$=rq5bN zOn9?Vmhm3#Pn6mi0P`@V*7l!Q+Us(;IalCzktQUSvwHZNi8E@R9;N~ zv<#Z=X&EuS(=uW@r)9+SO>MD#T<$vJ92Y%PYv~A%i(Y9NF+I{UVmhQ{#PmnYi0O`& z5z`wjBc?NIi|ylzEM~tKw4Sc0wRi<$%$McFYs!n)M#Of-ktNSmypCnUB`&DAr@VN5 zdGUD>v0X72J^ZhAk`;E{{RQbUJOZy-Z#lAH}N8ZV}#dUY&|(LMLDxlX)zW9KlJ- zjo_5z7NycUpWEq|315Vsv1jEMQ*rTNX6&hGW9|ih+0+P5ng9NLQhg0e9IEs8&3ewk znK|wH-@RFCnfPr}4sP^WsdR6X@;%F@n4cGM((MOIEKmBW)ELgL^Awo7nuXRI;8&lO z$-=ttWH!b8+_KK1_VaO1WlF5Ob946&zwI->``e~MlCJi0JUCIu-Qp&tUGAosCaj8R zWvADK4DcxE4$qH z*1zoKO1d#JTj|Q?@W}AedLETEczNz{G^{>xr-NoA2)&OS1{M_)i?EqK7uKQcd1KxIB*RYohgvCpC)(u;^7{;j`wj$$=;{sg>x6fNJ3*s0>jM3posy7Brwce3}Xy!ha@n} zTnqyajUfpPGZ(|?Lt{t+!_37n6ww%xz%X+$j7v0zBrwce41*MnAqfmK7sH4}V@LwS z%*8N#(HN4zFmo}CWi*B)Fw9&G0~?JY2@EqAWfnnxiumA)YlE5%?F_^al3`t;^xfo2h z0frjM3Fg(*3lE5%?F`XfXBrwce3A~q3-4CZQMfuZL$X&sk>J*JZU`aSdz`5YSrbA?_8w>ILe_>5 zlD)^7uKQyw?$#NnqgS!H>q09ed*$m2ZbdyIgkZC2qD>foT&>rFNBcnJ}6J-)wMe zL0A<)NcJ9Qx~|~Xf=kb;rRS|BBV}V~g=FvHrT+G%GLlPKf-ZV^C5_`Y2u`N1c3S-;QI((3+ zjBUe;xWG+uY#Ua_rC^F<+pscDno}IxhLv&3o8s6utc(-Z6vwtjM3Fp|}F zNCLym#pFT^Nnn_{7)G+%4oP5`xfn*W8bcBoW-f-2tj3T8hM9|DB&#tbfnnxi7|Ci3 zNnn_{7)G)hLlPKfF2)NnB!OY(Vp>8BNnn_{7)G+XE|S17n`~^mr-s-T7_2Li=3oH` znnMy8W^R))ZwDBXz%X+$m~I0MNnn_{7|fCZh9oe|Tnr|+07DWOW-bPEQh*@|3^NzQ zNLF_jL0G9y{t%_M;72@EqA!$?-!Aqfn#$;P&OYKU!tsT$h?Q#G~)rfO^pOx4&Hm=z`6 zvoh=+lE5%?yO5Er?n08lFq>>_yQg|=yQg|=yQg|=yXPf|ZTD1R`O!q_&nKE<(ZSkcQ6+lH0B46$uk*~<{yhLybxv29q{%Mja!mAwqHZCKgM z5Zi{8AxwOkV%xqNVq0LU#HMRw&YHSNk)z}u8sZg!%rCjT7|H5OkR&k7CL7!K)ezePQ#G~)rfO^pOx4&Hn5wZYFjZq)V5-Kp zz`PW(ZC?$sEihGMTVSfjw!l=4ZGov8+X7QHwgskYYzxdw5!?1vk8S&^$F_adW81!$ zB)09V9^3X+k8S&^$F_Zwk8S&^$F_Zwk8S&^$F_YhNo?C!Lu?C7)z}soIE@hxhLNnE zVo3tS?95}^z8Yd%VC>iy-_V2ig%w@D%b!n-p$)ls5%+;}i(6Dpj~l9z#|^{p+`%=0 zL!QK+2g9%I;k#3+*SueC)LG>+v;HGq`H_|-B!npJZ|WBA@?}ono!~nF*>QbDvhDU#n4H0 zG2*s5bom3YiZmWZ#lj>r`ZFMko zQeBL=tqw+R$vFKiZmWZlTQUwt+*Su8w`3fQxUCL`PO94;aa$b>om3YiZmWaoD#1`v zi`(j$SrD4x?iO4(O5EW?Csj8`V<>SkbW&Z6xUEiIbW&Z6xUCL`PO6I$x7ESWNp&&e zwmKL(sV;^Rx6O1?T}-WRt5a2XXoh=saNQ_ztD=*ttI`;8TOB)eQeBL=tqz7xs*4e~ z)xpq7bur?$Iv6^sE=Jr|2SX>-#faPLVCbZ}m|ERd$BaB~=wCS8iPUbZ135RW$%jzj zcJi7igaQ|`HVUDjmd6d9wyX=Sa4%E4tq!Co3ZcMl%lasU0vB>#6hcAO#|@o^oFAIN zB#X9E;MTGs3ZbCtom3YiZmWZ#lj>q9sqD5o2DXF-;M2tdx7ERHEx}MCfB&|`XN`-`nm7ZWReRs) zj%3`w&fwU@T%T2A>Pj$_=yRzt^iW+pl(-mrs4m9xS+yN{s4m9xSv7_ps*ACFR*j*D z>S8RPRb%L(x){r6)fjrHF2?d%HHIFli?MuGjiHC?Vl1CkW9Xr}7|UnX7<#BK#`0M; zh90Vmp~O8G^iW-l<+Ex#^iW;Qi}P8v8G5MNjP^$@pH*Y%p}H7K+$O`*h+rsjF<43? z7)o3WJyf?YN?Z&*R2M^ui=l_=VkmJj^iW+4B`$^@s*ACFR^31JP+g4WvuX@IR2O6U ztQtcP)x}sotH#hnbupIDsxkCXU5w?kY79M87i0OX8bc4&#k@G5RhwB5n!%We_^cYU zumnSidn)Lm>gH%Wl(-mrs4m9xS#@3XP+g4WvuX@IR2O6UtQtcP)x}sotH#hnbull_ zXVqrtp=vX@WFkJR#?V7`F_zD&G4xPfjODXx3_VmAWBIHaLl4!(SU#)9&_i`Gl(?sh z9;%D6d{%9T9;%CZaXzayL!VWf@f}hM+}6-Vbs!YDkTp>V1uldxs$+$M+I?2tT>7lq z3MMz#XVnn8s1Aezw=Hy09S8+3gf6NBp`b>eRX2n#sy2a1*7aF6gf6NBc@aLVHbECv zo4_>f`m7p47uA8hIGv$X_6iTJE9^|v2jcnY5(3a!HdnacNL!iu=kO!50MVP%}#r}+Jturkhq zQ~Z8RSQ+QADSkgDtc;V;6u%!6R>rw#ir*Z za-X$96N5WdB!OY(Vi?BiiI5~P%v=n^SdAeG3^NzQFjiwo0>jM3FpSk0lE5%?F$`lh zh9oe|TnxiljUfq)1h&riGZ@Bd3`t;^xpo-FY79wWn7J5+u^K}X7-lYpVXVfG1csT5 zVHm41B!OY(Vi?A13`t;^xfq7A8bcBoW|MtCW^WD85CJ2Bt<%j|0D|U_1csU0WX#(E zh9oe|TnxileOM%cVdi2mO9mK{z%X+$nA`#kNnn_{7|cllh9oe|Tnxil-5!#_NMP$6 zJHuFwAqfmK*ABy2jUfq)1h$SHhOrt$5*TK#9fq+QLlPKfE{0*O#*hStnTufj zVdi2O#%c^nV3^f%GsZbA2DaJ^$-Ol^Lj=r1K;7mn3hj^thM9|D7^~|d2@EqA!!TB3 zNCLym#W0N37?Qv+b1@8KHHIWG%v=n^SdAeG4716;AG5cHXNZ82z}7hx3}bb3NCLym zZ8F1HjUfpPGZ(`!R%1v4!_37njMW&Dz%X+$3}ZEhBrwce48vHBAqfn#$-W4zA-eu0d4_0j^=F9oR)2wNeTzw--D+-+-8(*%r_rJ)t_g8Owzi#`=SHow*183Vfgcdcag#UMDmf`!JmqFBu z@6fN&!)5GpVhnes!(HWYS3BHxhr7n%b~xNlhuh_FyUEG7PJY*<6g*G;9nTF(=QB4R z!nyFPJmHr%Px~EDEahE}lmBDpSP4Qk%SQ%mfROWn$zlQI4?)1OC8h*!fMTPHpN@dB`n=$qfO{5~5 zIgeHUkf&Xne8_V}g%5dJwIMD+ZO-TWAFKW)&ujf-ldrGJmpoTj_>!m8mPSyb6b=tT zPAama^QG!v^X#)aQ@-Z8uEN(mrNVkdIQ~CWil`|S+1dI0X};>2#vhlmzSrbVB0aao z`6aUQAM{*irVjmKPx~QTf1Trojs^4gcQh;&u9ze(7+F&(+7~RWBrOnPS}?N4T4M+!X~D=E z7*>kF8c7RA*1(!W7)c98*1#|<0&65K7+C{r31K8H7+C`=gfNm8jBLxav1_^FS)-D7 z1Hz@v9hH2XL3bNT-x!x1{Vh=4yWIHEFp?IGtZ5qeel(1v1tV)BrO6{%s+PTz7MX0F~$cc^q?f^8>0uRcb;_bo*TkQS}?N4+L{nX(t?pS zu(ctKqy-~e<_It~p7sdVg~mww#^~1S%_w~YJt2&w1tV*kwmyWBv|wZn?7R?0(t?pK za|D)k3{<%J=R zq>UqArb+~G2Qj@NvgBGV_ELMX`ylp+JYD1?%XKq)fN%^{Rz1WHkv zBZ7Zw9Z~m9#@d$98p&lPKDqw9sqV|IA)I6xIK@E&tgrD;!Ct_1Q@R%rTE|s8m3skU zMYy=8dM_ZX442hZ?*)XFaVDPPy@0SXPMTA^7a)~|Q`{8q1z5Gs#j#ECUVzl*%xY7- z7a$du%sW%Q7qGIny#NbVCsUiA2{EGv9tTMaM%K))jQF)kMHeEf`q?n-{`JS}?K(#)x0Hjid!5YhaA{HH@SMBOAD6)(#a$ zgyj?VRN4#hjnO};xEEl-7TQf)6gG{d1tV*YfDykw0+JSttbsA&*D#V6jI4n%;@2>e z7L2TcG2+)Sk`|1tfidFOFp?IGY?>59jqC;Z#^{h$+zYT^mG%NGSf#xH3sz|_ zz=BoU3$S37_5v(erM&30X++KPJt7OY3=)Sk-v&>Be#M%Ik*^FkO&3r4og2*-3_9l`1M0@j9(a>cy> z8@Hi+mAFRASIG?k-D4zI`c=|fuDBOq<1Q>;<%`%0Sm}7p$1CjxM4*-S0wT~#djS#X zB=-VVmiXiq_X5hmU%tJ7-YMM+2(9C)oyxs{up(SsQ@s}uR)))Js`moI$~Y5G@m@e! z87Ivt-V2b*!YOWw_X4ciIJ-^pUVzl*%xY7-7a$du%sW%Q7qGmxy#NbVX)nNnRoV-% zV3qa)ELf$z01H-WFTjFT+6%B?mG%NGSf#xH3sz|_z=BoU3$S37_5v(erM&qiJuwawl3-FC`$*H&(V8JTw1z503djS@#(q4cCn<EU$4dz{XuzzRDM|7qHy%nvYl73y44~?FB@jmG%N6&`ItE zEHClNEA9o9fuCkCU~5ih<1Trysa;W1?&$@gdy>eKL_ z;e~kC<~DpedvwI(_OqGp&Ud$~grU=yoL!=ncXoRIAnv@^06)yOvDJSx`nOGdui@-e zy0=NCi&%N|XDI~zdt^yH#KeBH;p?d}3?Jv=Qg?H?`!e7D%(4A~&!SQV%iNnVr#_&q~>qPh?6efx~7WgnoQo9w<+?7V4I)@RDBLH)pdVug
A56h=o3u)Ar^3va&BemI`C*}HC8>xqw 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 P)6yq*$X=&d&4~X8FD<25 diff --git a/Nino_Unity/Assets/Nino/Shared/ThirdParty/System.Numerics.dll b/Nino_Unity/Assets/Nino/Shared/ThirdParty/System.Numerics.dll deleted file mode 100644 index 39c5d513936515d7407ffe48e42f8fa9a91e30d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138656 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 rWaXj$@TCg-*qm``j$E;-9;Y36#K)i diff --git a/Nino_Unity/Assets/Nino/Shared/ThirdParty/System.Threading.Tasks.Extensions.dll b/Nino_Unity/Assets/Nino/Shared/ThirdParty/System.Threading.Tasks.Extensions.dll deleted file mode 100755 index e059050bb2066f749b6e37a5b42e4bffc3f48a70..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33048 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 diff --git a/Nino_Unity/Assets/Nino/Shared/Util/Hash.cs b/Nino_Unity/Assets/Nino/Shared/Util/Hash.cs deleted file mode 100644 index b1b2569..0000000 --- a/Nino_Unity/Assets/Nino/Shared/Util/Hash.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; - -namespace Nino.Shared.Util -{ - public static class Hash - { - ///

- /// Get hash code of a string - /// - /// - /// - public static unsafe int GetStringHashCode(this string key) { - int i; - int len = key.Length; - int hash = 1315423911; - fixed (char* ptr = key) - { - for(i = 0; i < len; i++) - { - hash ^= ((hash << 5) + *(ptr + i) + (hash >> 2)); - } - - return hash; - } - } - - public static int GetTypeHashCode(this Type type) - { -#if ILRuntime - return type.GetHashCode(); -#else - //TODO a faster way to get the hash code of a type - return type.TypeHandle.Value.GetHashCode(); -#endif - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Shared/Util/PowOf2.cs b/Nino_Unity/Assets/Nino/Shared/Util/PowOf2.cs deleted file mode 100644 index 82c4622..0000000 --- a/Nino_Unity/Assets/Nino/Shared/Util/PowOf2.cs +++ /dev/null @@ -1,69 +0,0 @@ -using System; - -namespace Nino.Shared -{ - public static class PowerOf2 - { - /// - /// Get whether or not n is power of 2 - /// - /// - /// - public static bool IsPowerOf2(int n) - { - /* - * 4 -> 100 - * 3 -> 011 - * 4 & 3 -> 000 - * - * 8 -> 1000 - * 7 -> 0111 - * 8 & 7 -> 0000 - * - * 15 -> 1111 - * 14 -> 1110 - * 15 & 14 -> 1110 - */ - return (n & (n - 1)) == 0; - } - - /// - /// if n is power of 2, get its power - /// - /// - /// - public static byte GetPower(int n) - { - byte ret = 0; - while (n >> 1 != 0) - { - ret++; - n = n >> 1; - } - - return ret; - } - - /// - /// if n is not power of 2, get the next power of 2 from n - /// - /// - /// - /// - public static int RoundUpToPowerOf2(int n) - { - if (n < 0 || n > 0x40000000) - { - throw new ArgumentOutOfRangeException("n"); - } - - n = n - 1; - n = n | (n >> 1); - n = n | (n >> 2); - n = n | (n >> 4); - n = n | (n >> 8); - n = n | (n >> 16); - return n + 1; - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test5.cs b/Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test5.cs deleted file mode 100644 index 1736345..0000000 --- a/Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test5.cs +++ /dev/null @@ -1,248 +0,0 @@ -using System; -using System.IO; -using System.Text; -using Nino.Shared.Util; -using MongoDB.Bson.IO; -using System.Diagnostics; -using MongoDB.Bson.Serialization; - -// ReSharper disable RedundantJumpStatement - -namespace Nino.Test.Editor.Serialization -{ - public class Test5 - { - private const string SerializationTest5 = - "Nino/Test/Serialization/Test5 - Serialize and Deserialize (Nino vs MongoDB.Bson)"; - - private static string GetString(int len) - { - StringBuilder sb = new StringBuilder(); - sb.Append('a', len); - return sb.ToString(); - } - -#if UNITY_2017_1_OR_NEWER - [UnityEditor.MenuItem(SerializationTest5, priority = 5)] -#endif - public static void Main() - { - //reg - BsonClassMap.RegisterClassMap(); - BsonClassMap.RegisterClassMap(); - BsonClassMap.RegisterClassMap(); - Logger.W("1/5"); - DoTest(10); - Logger.W("2/5"); - DoTest(100); - Logger.W("3/5"); - DoTest(1000); - Logger.W("4/5"); - DoTest(10000); - Logger.W("5/5"); - DoTest(100000); - } - - private static void BeginSample(string name) - { -#if UNITY_2017_1_OR_NEWER - UnityEngine.Profiling.Profiler.BeginSample(name); -#endif - return; - } - - private static void EndSample() - { -#if UNITY_2017_1_OR_NEWER - UnityEngine.Profiling.Profiler.EndSample(); -#endif - return; - } - - private static void DoTest(int max) - { - #region Test data - - Data[] ps = new Data[max]; - for (int i = 0, cnt = max; i < cnt; i++) - { - ps[i] = new Data() - { - x = short.MaxValue, - y = byte.MaxValue, - z = short.MaxValue, - f = 1234.56789f, - d = 66.66666666m, - db = 999.999999999999, - bo = true, - en = TestEnum.A, - }; - } - - NestedData points = new NestedData() - { - name = "测试", - ps = ps - }; - - #endregion - - #region Test - - Logger.D("Serialization Test", $"testing {max} objs"); - Logger.D("Serialization Test", "======================================"); - - //Nino - var sw = new Stopwatch(); - BeginSample("Nino - Serialize"); - sw.Restart(); - int size = Nino.Serialization.Serializer.GetSize(points); - long len; - byte[] bs; - if (size <= 1024) - { - Span ret = stackalloc byte[size]; - Nino.Serialization.Serializer.Serialize(ret, points); - sw.Stop(); - EndSample(); - Logger.D("Serialization Test", $"Nino: {ret.Length} bytes in {sw.ElapsedMilliseconds}ms"); - len = ret.Length; - var tm = sw.ElapsedMilliseconds; - //Logger.D("Serialization Test",string.Join(",", bs)); - - //MongoDB.Bson - BeginSample("MongoDB.Bson - Serialize"); - byte[] bs2; - sw.Restart(); - //we want byte[], MongoDB.Bson returns stream - //to be able to make it fair, we need to convert stream to byte[] - using (MemoryStream ms = new MemoryStream()) - { - using (BsonBinaryWriter bsonWriter = new BsonBinaryWriter(ms, BsonBinaryWriterSettings.Defaults)) - { - BsonSerializationContext context = BsonSerializationContext.CreateRoot(bsonWriter); - BsonSerializationArgs args = default; - args.NominalType = typeof(object); - IBsonSerializer serializer = BsonSerializer.LookupSerializer(args.NominalType); - serializer.Serialize(context, args, points); - bs2 = ms.ToArray(); - } - } - - sw.Stop(); - EndSample(); - - Logger.D("Serialization Test", $"MongoDB.Bson: {bs2.Length} bytes in {sw.ElapsedMilliseconds}ms"); - //Logger.D("Serialization Test",string.Join(",", bs)); - - Logger.D("Serialization Test", "======================================"); - Logger.D("Serialization Test", $"size diff (nino - MongoDB.Bson): {len - bs2.Length} bytes"); - Logger.D("Serialization Test", - $"size diff pct => diff/MongoDB.Bson : {((len - bs2.Length) * 100f / bs2.Length):F2}%"); - - Logger.D("Serialization Test", "======================================"); - Logger.D("Serialization Test", $"time diff (nino - MongoDB.Bson): {tm - sw.ElapsedMilliseconds} ms"); - Logger.D("Serialization Test", - $"time diff pct => time/MongoDB.Bson : {((tm - sw.ElapsedMilliseconds) * 100f / sw.ElapsedMilliseconds):F2}%"); - - BeginSample("Nino - Deserialize"); - sw.Restart(); - var d = Nino.Serialization.Deserializer.Deserialize(ret); - sw.Stop(); - EndSample(); - Logger.D("Deserialization Test", d); - Logger.D("Deserialization Test", - $"Nino: extracted {len} bytes and deserialized {points.ps.Length} entries in {sw.ElapsedMilliseconds}ms"); - tm = sw.ElapsedMilliseconds; - - //MongoDB.Bson - BeginSample("MongoDB.Bson - Deserialize"); - sw.Restart(); - d = (NestedData)BsonSerializer.Deserialize(bs2, typeof(NestedData)); - sw.Stop(); - EndSample(); - Logger.D("Deserialization Test", d); - Logger.D("Deserialization Test", - $"MongoDB.Bson: extracted {bs2.Length} bytes and deserialized {points.ps.Length} entries in {sw.ElapsedMilliseconds}ms"); - - Logger.D("Deserialization Test", "======================================"); - Logger.D("Deserialization Test", $"time diff (nino - MongoDB.Bson): {tm - sw.ElapsedMilliseconds} ms"); - Logger.D("Deserialization Test", - $"time diff pct => time/MongoDB.Bson : {((tm - sw.ElapsedMilliseconds) * 100f / sw.ElapsedMilliseconds):F2}%"); - } - else - { - byte[] ret = new byte[size]; - Nino.Serialization.Serializer.Serialize(ret, points); - sw.Stop(); - EndSample(); - Logger.D("Serialization Test", $"Nino: {ret.Length} bytes in {sw.ElapsedMilliseconds}ms"); - len = ret.Length; - var tm = sw.ElapsedMilliseconds; - //Logger.D("Serialization Test",string.Join(",", bs)); - - //MongoDB.Bson - BeginSample("MongoDB.Bson - Serialize"); - byte[] bs2; - sw.Restart(); - //we want byte[], MongoDB.Bson returns stream - //to be able to make it fair, we need to convert stream to byte[] - using (MemoryStream ms = new MemoryStream()) - { - using (BsonBinaryWriter bsonWriter = new BsonBinaryWriter(ms, BsonBinaryWriterSettings.Defaults)) - { - BsonSerializationContext context = BsonSerializationContext.CreateRoot(bsonWriter); - BsonSerializationArgs args = default; - args.NominalType = typeof(object); - IBsonSerializer serializer = BsonSerializer.LookupSerializer(args.NominalType); - serializer.Serialize(context, args, points); - bs2 = ms.ToArray(); - } - } - - sw.Stop(); - EndSample(); - - Logger.D("Serialization Test", $"MongoDB.Bson: {bs2.Length} bytes in {sw.ElapsedMilliseconds}ms"); - //Logger.D("Serialization Test",string.Join(",", bs)); - - Logger.D("Serialization Test", "======================================"); - Logger.D("Serialization Test", $"size diff (nino - MongoDB.Bson): {len - bs2.Length} bytes"); - Logger.D("Serialization Test", - $"size diff pct => diff/MongoDB.Bson : {((len - bs2.Length) * 100f / bs2.Length):F2}%"); - - Logger.D("Serialization Test", "======================================"); - Logger.D("Serialization Test", $"time diff (nino - MongoDB.Bson): {tm - sw.ElapsedMilliseconds} ms"); - Logger.D("Serialization Test", - $"time diff pct => time/MongoDB.Bson : {((tm - sw.ElapsedMilliseconds) * 100f / sw.ElapsedMilliseconds):F2}%"); - - BeginSample("Nino - Deserialize"); - sw.Restart(); - var d = Nino.Serialization.Deserializer.Deserialize(ret); - sw.Stop(); - EndSample(); - Logger.D("Deserialization Test", d); - Logger.D("Deserialization Test", - $"Nino: extracted {ret.Length} bytes and deserialized {points.ps.Length} entries in {sw.ElapsedMilliseconds}ms"); - tm = sw.ElapsedMilliseconds; - - //MongoDB.Bson - BeginSample("MongoDB.Bson - Deserialize"); - sw.Restart(); - d = (NestedData)BsonSerializer.Deserialize(bs2, typeof(NestedData)); - sw.Stop(); - EndSample(); - Logger.D("Deserialization Test", d); - Logger.D("Deserialization Test", - $"MongoDB.Bson: extracted {bs2.Length} bytes and deserialized {points.ps.Length} entries in {sw.ElapsedMilliseconds}ms"); - - Logger.D("Deserialization Test", "======================================"); - Logger.D("Deserialization Test", $"time diff (nino - MongoDB.Bson): {tm - sw.ElapsedMilliseconds} ms"); - Logger.D("Deserialization Test", - $"time diff pct => time/MongoDB.Bson : {((tm - sw.ElapsedMilliseconds) * 100f / sw.ElapsedMilliseconds):F2}%"); - } - - #endregion - } - } -} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test9.cs b/Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test9.cs deleted file mode 100644 index 40986fd..0000000 --- a/Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test9.cs +++ /dev/null @@ -1,59 +0,0 @@ -using Nino.Shared.Util; -using Nino.Serialization; -using System.Collections.Generic; -using System.Linq; - -// ReSharper disable RedundantTypeArgumentsOfMethod -namespace Nino.Test.Editor.Serialization -{ - public class Test9 - { - private const string SerializationTest9 = "Nino/Test/Serialization/Test9 - Basic Types"; - -#if UNITY_2017_1_OR_NEWER - [UnityEditor.MenuItem(SerializationTest9,priority=9)] -#endif - public static void Main() - { - int a = int.MaxValue; - uint b = uint.MaxValue; - long c = long.MaxValue; - ulong d = ulong.MaxValue; - float e = float.MaxValue; - double f = double.MaxValue; - decimal g = decimal.MaxValue; - string h = "Hello World"; - bool i = true; - char j = 'a'; - byte k = byte.MaxValue; - sbyte l = sbyte.MaxValue; - ushort m = ushort.MaxValue; - short n = short.MaxValue; - int[] o = new int[]{ 1, 2, 3, 4, 5 }; - List p = new List() { 1, 2, 3, 4, 5 }; - Dictionary q = new Dictionary() - { { "a", 1 }, { "b", 2 }, { "c", 3 }, { "d", 4 }, { "e", 5 } }; - - Logger.D($"Serialized a as: {(Serializer.Serialize(((a))).Length)} bytes: {(string.Join(",",Serializer.Serialize(((a)))))}, deserialized as:{Deserializer.Deserialize(Serializer.Serialize(a))}"); - Logger.D($"Serialized b as: {(Serializer.Serialize(((b))).Length)} bytes: {(string.Join(",",Serializer.Serialize(((b)))))}, deserialized as:{Deserializer.Deserialize(Serializer.Serialize(b))}"); - Logger.D($"Serialized c as: {(Serializer.Serialize(((c))).Length)} bytes: {(string.Join(",",Serializer.Serialize(((c)))))}, deserialized as:{Deserializer.Deserialize(Serializer.Serialize(c))}"); - Logger.D($"Serialized d as: {(Serializer.Serialize(((d))).Length)} bytes: {(string.Join(",",Serializer.Serialize(((d)))))}, deserialized as:{Deserializer.Deserialize(Serializer.Serialize(d))}"); - Logger.D($"Serialized e as: {(Serializer.Serialize(((e))).Length)} bytes: {(string.Join(",",Serializer.Serialize(((e)))))}, deserialized as:{Deserializer.Deserialize(Serializer.Serialize(e))}"); - Logger.D($"Serialized f as: {(Serializer.Serialize(((f))).Length)} bytes: {(string.Join(",",Serializer.Serialize(((f)))))}, deserialized as:{Deserializer.Deserialize(Serializer.Serialize(f))}"); - Logger.D($"Serialized g as: {(Serializer.Serialize(((g))).Length)} bytes: {(string.Join(",",Serializer.Serialize(((g)))))}, deserialized as:{Deserializer.Deserialize(Serializer.Serialize(g))}"); - Logger.D($"Serialized h as: {(Serializer.Serialize(((h))).Length)} bytes: {(string.Join(",",Serializer.Serialize(((h)))))}, deserialized as:{Deserializer.Deserialize(Serializer.Serialize(h))}"); - Logger.D($"Serialized i as: {(Serializer.Serialize(((i))).Length)} bytes: {(string.Join(",",Serializer.Serialize(((i)))))}, deserialized as:{Deserializer.Deserialize(Serializer.Serialize(i))}"); - Logger.D($"Serialized j as: {(Serializer.Serialize(((j))).Length)} bytes: {(string.Join(",",Serializer.Serialize(((j)))))}, deserialized as:{Deserializer.Deserialize(Serializer.Serialize(j))}"); - Logger.D($"Serialized k as: {(Serializer.Serialize(((k))).Length)} bytes: {(string.Join(",",Serializer.Serialize(((k)))))}, deserialized as:{Deserializer.Deserialize(Serializer.Serialize(k))}"); - Logger.D($"Serialized l as: {(Serializer.Serialize(((l))).Length)} bytes: {(string.Join(",",Serializer.Serialize(((l)))))}, deserialized as:{Deserializer.Deserialize(Serializer.Serialize(l))}"); - Logger.D($"Serialized m as: {(Serializer.Serialize(((m))).Length)} bytes: {(string.Join(",",Serializer.Serialize(((m)))))}, deserialized as:{Deserializer.Deserialize(Serializer.Serialize(m))}"); - Logger.D($"Serialized n as: {(Serializer.Serialize(((n))).Length)} bytes: {(string.Join(",",Serializer.Serialize(((n)))))}, deserialized as:{Deserializer.Deserialize(Serializer.Serialize(n))}"); - Logger.D($"Serialized o as: {(Serializer.Serialize(((o))).Length)} bytes: {(string.Join(",",Serializer.Serialize(((o)))))}, deserialized as:{Deserializer.Deserialize(Serializer.Serialize(o))}"); - Logger.D($"Serialized p as: {(Serializer.Serialize(((p))).Length)} bytes: {(string.Join(",",Serializer.Serialize(((p)))))}, deserialized as:{string.Join(",",Deserializer.Deserialize>(Serializer.Serialize(p)))}"); - Logger.D( - $"Serialized q as: {(Serializer.Serialize(((q))).Length)} bytes: {(string.Join(",", Serializer.Serialize(((q)))))}, " + - $"deserialized as:{string.Join(",", Deserializer.Deserialize>(Serializer.Serialize(q)).ToList().SelectMany(kvp => $"{kvp.Key}-{kvp.Value}"))}"); - } - } -} -// ReSharper restore RedundantTypeArgumentsOfMethod \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Test/BuildTest.cs b/Nino_Unity/Assets/Test/BuildTest.cs similarity index 56% rename from Nino_Unity/Assets/Nino/Test/BuildTest.cs rename to Nino_Unity/Assets/Test/BuildTest.cs index ed13cd1..ef6d25e 100644 --- a/Nino_Unity/Assets/Nino/Test/BuildTest.cs +++ b/Nino_Unity/Assets/Test/BuildTest.cs @@ -1,5 +1,4 @@ using System; -using System.Buffers; using System.IO; using System.Linq; using UnityEngine; @@ -12,11 +11,12 @@ using MongoDB.Bson.Serialization; using UnityEngine.SceneManagement; using System.Runtime.Serialization.Formatters.Binary; -using Logger = Nino.Shared.Util.Logger; +using Test_Nino; +using Debug = UnityEngine.Debug; namespace Nino.Test { - public class BuildTest: MonoBehaviour + public class BuildTest : MonoBehaviour { public Text ninoResultText; public Text pbNetResultText; @@ -34,10 +34,8 @@ public class BuildTest: MonoBehaviour private byte[] ninoBuffer = Array.Empty(); private byte[] pbNetBuffer = Array.Empty(); private byte[] binaryFormatterBuffer1 = Array.Empty(); - private byte[] binaryFormatterBuffer2 = Array.Empty(); private byte[] bsonBuffer = Array.Empty(); private byte[] msgPackBuffer = Array.Empty(); - private BuildTestDataNoCodeGen d1; private BuildTestDataCodeGen d2; private void OnGUI() @@ -104,68 +102,16 @@ private void Awake() }, v = new Dictionary() { - { new NotIncludeAllClass() { a = 30, b = 20, c = 12938, d = 19283 }, new NotIncludeAllClass() { a = 30, b = 20, c = 12938, d = 19283 } } - } - }; - d1 = new BuildTestDataNoCodeGen() - { - a = 1, - b = 2, - c = 100, - d = 500, - e = 666, - f = 99999999, - g = 123456788765, - h = 123456321, - i = 6.6f, - j = 9.9, - k = 1.23456789012345m, - l = true, - m = 'a', - n = "aksjdfhgheuwi", - o = new List() { 1, 2, 3, 4, 5 }, - p = new List() - { - new NotIncludeAllClass() - { - a = 30, b = 20, c = 12938, d = 19283 - } - }, - q = new byte[] { 1, 2, 3 }, - r = new NotIncludeAllClass[] - { - new NotIncludeAllClass() { - a = 30, b = 20, c = 12938, d = 19283 + new NotIncludeAllClass() { a = 30, b = 20, c = 12938, d = 19283 }, + new NotIncludeAllClass() { a = 30, b = 20, c = 12938, d = 19283 } } - }, - s = new Dictionary() - { - { - "ks", new NotIncludeAllClass() - { - a = 30, b = 20, c = 12938, d = 19283 - } - } - }, - t = new Dictionary() - { - { new NotIncludeAllClass() { a = 30, b = 20, c = 12938, d = 19283 }, 39 } - }, - u = new Dictionary() - { - { "usd", 7 } - }, - v = new Dictionary() - { - { new NotIncludeAllClass() { a = 30, b = 20, c = 12938, d = 19283 }, new NotIncludeAllClass() { a = 30, b = 20, c = 12938, d = 19283 } } } }; //reg try { BsonClassMap.RegisterClassMap(); - BsonClassMap.RegisterClassMap(); BsonClassMap.RegisterClassMap(); StaticCompositeResolver.Instance.Register( GeneratedResolver.Instance, @@ -200,53 +146,32 @@ private void Start() { sw.Reset(); sw.Start(); - var dd1 = Nino.Serialization.Deserializer.Deserialize(ninoBuffer); + Deserializer.Deserialize(ninoBuffer, out BuildTestDataCodeGen dd1); sw.Stop(); var m1 = sw.ElapsedTicks; sw.Reset(); - sw.Start(); - //as everything are same, buffer can be shared across two classes - var dd2 = Nino.Serialization.Deserializer.Deserialize(ninoBuffer); - sw.Stop(); - var m2 = sw.ElapsedTicks; - ninoBuffer = Array.Empty(); ninoResultText.text = - $"Deserialized BuildTestDataCodeGen in {((float)m1 / Stopwatch.Frequency) * 1000} ms: \n{dd1}\n" + - $"Deserialized BuildTestDataNoCodeGen in {((float)m2 / Stopwatch.Frequency) * 1000} ms:\n{dd2}"; + $"Deserialized BuildTestDataCodeGen in {((float)m1 / Stopwatch.Frequency) * 1000} ms: \n{dd1}"; ninoBtn.GetComponentInChildren().text = "NinoSerialize"; + ninoBuffer = Array.Empty(); } //serialize else { - if(ninoBuffer.Length == 0) - { - ninoBuffer = new byte[Nino.Serialization.Serializer.GetSize(d2)]; - } sw.Reset(); sw.Start(); - Span arr = stackalloc byte[Nino.Serialization.Serializer.GetSize(d2)]; - Nino.Serialization.Serializer.Serialize(arr, d2); + ninoBuffer = d2.Serialize(); sw.Stop(); - arr.CopyTo(ninoBuffer); var m1 = sw.ElapsedTicks; - sw.Reset(); - sw.Start(); - //as everything are same, buffer has same length - arr = stackalloc byte[Nino.Serialization.Serializer.GetSize(d1)]; - Nino.Serialization.Serializer.Serialize(arr, d1); - sw.Stop(); - arr.CopyTo(ninoBuffer); - var m2 = sw.ElapsedTicks; ninoResultText.text = - $"Serialized BuildTestDataCodeGen as {ninoBuffer.Length} bytes in {((float)m1 / Stopwatch.Frequency) * 1000} ms,\n" + - $"Serialized BuildTestDataNoCodeGen as {ninoBuffer.Length} bytes in {((float)m2 / Stopwatch.Frequency) * 1000} ms:\n{string.Join(",", ninoBuffer)}"; + $"Serialized BuildTestDataCodeGen as {ninoBuffer.Length} bytes in {((float)m1 / Stopwatch.Frequency) * 1000} ms\n{string.Join(",", ninoBuffer)}"; ninoBtn.GetComponentInChildren().text = "NinoDeserialize"; } } catch (Exception ex) { ninoResultText.text = ex.ToString(); - Logger.D(ex); + Debug.LogException(ex); } }); pbNetBtn.onClick.AddListener(() => @@ -256,7 +181,6 @@ private void Start() //deserialize if (pbNetBuffer.Length > 0) { - BuildTestDataNoCodeGen dd1; BuildTestDataCodeGen dd2; sw.Reset(); sw.Start(); @@ -267,22 +191,11 @@ private void Start() sw.Stop(); var m1 = sw.ElapsedTicks; - sw.Reset(); - sw.Start(); - //as everything are same, buffer can be shared across two classes - using (MemoryStream ms = new MemoryStream(pbNetBuffer)) - { - dd1 = ProtoBuf.Serializer.Deserialize(ms); - } - sw.Stop(); - sw.Stop(); - var m2 = sw.ElapsedTicks; - pbNetBuffer = Array.Empty(); pbNetResultText.text = - $"Deserialized BuildTestDataCodeGen (no code gen for this class for pbnet) in {((float)m1 / Stopwatch.Frequency) * 1000} ms: \n{dd2}\n" + - $"Deserialized BuildTestDataNoCodeGen in {((float)m2 / Stopwatch.Frequency) * 1000} ms:\n{dd1}"; + $"Deserialized BuildTestDataCodeGen (no code gen for this class for pbnet) in {((float)m1 / Stopwatch.Frequency) * 1000} ms: \n{dd2}"; pbNetBtn.GetComponentInChildren().text = "PbNetSerialize"; + pbNetBuffer = Array.Empty(); } //serialize else @@ -291,33 +204,22 @@ private void Start() sw.Start(); using (MemoryStream ms = new MemoryStream()) { - ProtoBuf.Serializer.Serialize(ms, d2); + ProtoBuf.Serializer.Serialize(ms, d2); pbNetBuffer = ms.ToArray(); } sw.Stop(); var m1 = sw.ElapsedTicks; - sw.Reset(); - sw.Start(); - //as everything are same, buffer has same length - using (MemoryStream ms = new MemoryStream()) - { - ProtoBuf.Serializer.Serialize(ms, d1); - pbNetBuffer = ms.ToArray(); - } - sw.Stop(); - var m2 = sw.ElapsedTicks; pbNetResultText.text = - $"Serialized BuildTestDataCodeGen (no code gen for this class for pbnet) as {pbNetBuffer.Length} bytes in {((float)m1 / Stopwatch.Frequency) * 1000} ms,\n" + - $"Serialized BuildTestDataNoCodeGen as {pbNetBuffer.Length} bytes in {((float)m2 / Stopwatch.Frequency) * 1000} ms:\n{string.Join(",", pbNetBuffer.Take(300))}"; + $"Serialized BuildTestDataCodeGen (no code gen for this class for pbnet) as {pbNetBuffer.Length} bytes in {((float)m1 / Stopwatch.Frequency) * 1000} ms:\n{string.Join(",", pbNetBuffer.Take(300))}"; pbNetBtn.GetComponentInChildren().text = "PbNetDeserialize"; } } - catch(Exception ex) + catch (Exception ex) { pbNetResultText.text = ex.ToString(); - Logger.D(ex); + Debug.LogException(ex); } }); binaryFormatterBtn.onClick.AddListener(() => @@ -327,7 +229,6 @@ private void Start() //deserialize if (binaryFormatterBuffer1.Length > 0) { - BuildTestDataNoCodeGen dd1; BuildTestDataCodeGen dd2; sw.Reset(); sw.Start(); @@ -339,23 +240,10 @@ private void Start() sw.Stop(); var m1 = sw.ElapsedTicks; - sw.Reset(); - sw.Start(); - //as everything are same, buffer can be shared across two classes - using (var ms = new MemoryStream(binaryFormatterBuffer2)) - { - BinaryFormatter bFormatter = new BinaryFormatter(); - dd1 = (BuildTestDataNoCodeGen)bFormatter.Deserialize(ms); - } - - sw.Stop(); - var m2 = sw.ElapsedTicks; - binaryFormatterBuffer1 = Array.Empty(); - binaryFormatterBuffer2 = Array.Empty(); binaryFormatterResultText.text = - $"Deserialized BuildTestDataCodeGen in {((float)m1 / Stopwatch.Frequency) * 1000} ms: \n{dd2}\n" + - $"Deserialized BuildTestDataNoCodeGen in {((float)m2 / Stopwatch.Frequency) * 1000} ms:\n{dd1}"; + $"Deserialized BuildTestDataCodeGen in {((float)m1 / Stopwatch.Frequency) * 1000} ms: \n{dd2}"; binaryFormatterBtn.GetComponentInChildren().text = "BinaryFormatterSerialize"; + binaryFormatterBuffer1 = Array.Empty(); } //serialize else @@ -371,20 +259,8 @@ private void Start() sw.Stop(); var m1 = sw.ElapsedTicks; - sw.Reset(); - sw.Start(); - using (var ms = new MemoryStream()) - { - BinaryFormatter bFormatter = new BinaryFormatter(); - bFormatter.Serialize(ms, d1); - binaryFormatterBuffer2 = ms.ToArray(); - } - - sw.Stop(); - var m2 = sw.ElapsedTicks; binaryFormatterResultText.text = - $"Serialized BuildTestDataCodeGen (no code gen for this class for bf) as {binaryFormatterBuffer1.Length} bytes in {((float)m1 / Stopwatch.Frequency) * 1000} ms,\n" + - $"Serialized BuildTestDataNoCodeGen as {binaryFormatterBuffer2.Length} bytes in {((float)m2 / Stopwatch.Frequency) * 1000} ms:\n" + + $"Serialized BuildTestDataCodeGen (no code gen for this class for bf) as {binaryFormatterBuffer1.Length} bytes in {((float)m1 / Stopwatch.Frequency) * 1000} ms:\n" + $"{string.Join(",", binaryFormatterBuffer1.Length > 300 ? binaryFormatterBuffer1.Take(300) : binaryFormatterBuffer1)}"; binaryFormatterBtn.GetComponentInChildren().text = "BinaryFormatterDeserialize"; } @@ -392,7 +268,7 @@ private void Start() catch (Exception ex) { binaryFormatterResultText.text = ex.ToString(); - Logger.D(ex); + Debug.LogException(ex); } }); bsonBtn.onClick.AddListener(() => @@ -402,7 +278,6 @@ private void Start() //deserialize if (bsonBuffer.Length > 0) { - BuildTestDataNoCodeGen dd1; BuildTestDataCodeGen dd2; sw.Reset(); sw.Start(); @@ -411,19 +286,10 @@ private void Start() sw.Stop(); var m1 = sw.ElapsedTicks; - sw.Reset(); - sw.Start(); - //as everything are same, buffer can be shared across two classes - dd1 = (BuildTestDataNoCodeGen)BsonSerializer.Deserialize(bsonBuffer, - typeof(BuildTestDataNoCodeGen)); - - sw.Stop(); - var m2 = sw.ElapsedTicks; - bsonBuffer = Array.Empty(); bsonResultText.text = - $"Deserialized BuildTestDataCodeGen (no code gen for this class for bson) in {((float)m1 / Stopwatch.Frequency) * 1000} ms: \n{dd1}\n" + - $"Deserialized BuildTestDataNoCodeGen in {((float)m2 / Stopwatch.Frequency) * 1000} ms:\n{dd2}"; + $"Deserialized BuildTestDataCodeGen (no code gen for this class for bson) in {((float)m1 / Stopwatch.Frequency) * 1000} ms: \n{dd2}\n"; bsonBtn.GetComponentInChildren().text = "BsonSerialize"; + bsonBuffer = Array.Empty(); } //serialize else @@ -433,7 +299,7 @@ private void Start() using (MemoryStream ms = new MemoryStream()) { using (BsonBinaryWriter bsonWriter = - new BsonBinaryWriter(ms, BsonBinaryWriterSettings.Defaults)) + new BsonBinaryWriter(ms, BsonBinaryWriterSettings.Defaults)) { BsonSerializationContext context = BsonSerializationContext.CreateRoot(bsonWriter); BsonSerializationArgs args = default; @@ -446,35 +312,15 @@ private void Start() sw.Stop(); var m1 = sw.ElapsedTicks; - sw.Reset(); - sw.Start(); - //as everything are same, buffer has same length - using (MemoryStream ms = new MemoryStream()) - { - using (BsonBinaryWriter bsonWriter = - new BsonBinaryWriter(ms, BsonBinaryWriterSettings.Defaults)) - { - BsonSerializationContext context = BsonSerializationContext.CreateRoot(bsonWriter); - BsonSerializationArgs args = default; - args.NominalType = typeof(object); - IBsonSerializer serializer = BsonSerializer.LookupSerializer(args.NominalType); - serializer.Serialize(context, args, d1); - bsonBuffer = ms.ToArray(); - } - } - - sw.Stop(); - var m2 = sw.ElapsedTicks; bsonResultText.text = - $"Serialized BuildTestDataCodeGen (no code gen for this class for bson) as {bsonBuffer.Length} bytes in {((float)m1 / Stopwatch.Frequency) * 1000} ms,\n" + - $"Serialized BuildTestDataNoCodeGen as {bsonBuffer.Length} bytes in {((float)m2 / Stopwatch.Frequency) * 1000} ms:\n{string.Join(",", bsonBuffer)}"; + $"Serialized BuildTestDataCodeGen (no code gen for this class for bson) as {bsonBuffer.Length} bytes in {((float)m1 / Stopwatch.Frequency) * 1000} ms:\n{string.Join(",", bsonBuffer)}"; bsonBtn.GetComponentInChildren().text = "BsonDeserialize"; } } - catch(Exception ex) + catch (Exception ex) { bsonResultText.text = ex.ToString(); - Logger.D(ex); + Debug.LogException(ex); } }); msgPackBtn.onClick.AddListener(() => @@ -484,7 +330,6 @@ private void Start() //deserialize if (msgPackBuffer.Length > 0) { - BuildTestDataNoCodeGen dd1; BuildTestDataCodeGen dd2; sw.Reset(); sw.Start(); @@ -492,46 +337,31 @@ private void Start() sw.Stop(); var m1 = sw.ElapsedTicks; - sw.Reset(); - sw.Start(); - //as everything are same, buffer can be shared across two classes - dd1 = MessagePackSerializer.Deserialize(msgPackBuffer); - - sw.Stop(); - var m2 = sw.ElapsedTicks; - msgPackBuffer = Array.Empty(); msgPackResultText.text = - $"Deserialized BuildTestDataCodeGen in {((float)m1 / Stopwatch.Frequency) * 1000} ms: \n{dd1}\n" + - $"Deserialized BuildTestDataNoCodeGen (THIS CLASS HAS CODE GEN OTHERWISE WONT WORK IN IL2CPP) in {((float)m2 / Stopwatch.Frequency) * 1000} ms:\n{dd2}"; + $"Deserialized BuildTestDataCodeGen in {((float)m1 / Stopwatch.Frequency) * 1000} ms: \n{dd2}\n"; msgPackBtn.GetComponentInChildren().text = "MsgPackSerialize"; + msgPackBuffer = Array.Empty(); } //serialize else { sw.Reset(); sw.Start(); - var lz4Options = MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.None); + var lz4Options = + MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.None); msgPackBuffer = MessagePackSerializer.Serialize(d2, lz4Options); sw.Stop(); var m1 = sw.ElapsedTicks; - sw.Reset(); - sw.Start(); - //as everything are same, buffer has same length - msgPackBuffer = MessagePackSerializer.Serialize(d1); - - sw.Stop(); - var m2 = sw.ElapsedTicks; msgPackResultText.text = - $"Serialized BuildTestDataCodeGen as {msgPackBuffer.Length} bytes in {((float)m1 / Stopwatch.Frequency) * 1000} ms,\n" + - $"Serialized BuildTestDataCodeGen (THIS CLASS HAS CODE GEN OTHERWISE WONT WORK IN IL2CPP) as {msgPackBuffer.Length} bytes in {((float)m2 / Stopwatch.Frequency) * 1000} ms:\n{string.Join(",", msgPackBuffer)}"; + $"Serialized BuildTestDataCodeGen as {msgPackBuffer.Length} bytes in {((float)m1 / Stopwatch.Frequency) * 1000} ms:\n{string.Join(",", msgPackBuffer)}"; msgPackBtn.GetComponentInChildren().text = "MsgPackDeserialize"; } } catch (Exception ex) { msgPackResultText.text = ex.ToString(); - Logger.D(ex); + Debug.LogException(ex); } }); } diff --git a/Nino_Unity/Assets/Nino/Test/BuildTest2.cs b/Nino_Unity/Assets/Test/BuildTest2.cs similarity index 92% rename from Nino_Unity/Assets/Nino/Test/BuildTest2.cs rename to Nino_Unity/Assets/Test/BuildTest2.cs index 099e8fa..c69a06c 100644 --- a/Nino_Unity/Assets/Nino/Test/BuildTest2.cs +++ b/Nino_Unity/Assets/Test/BuildTest2.cs @@ -11,7 +11,9 @@ using MongoDB.Bson.Serialization; using UnityEngine.SceneManagement; using System.Runtime.Serialization.Formatters.Binary; -using Logger = Nino.Shared.Util.Logger; +using Test_Nino; +using Debug = UnityEngine.Debug; + namespace Nino.Test { @@ -36,7 +38,7 @@ public class BuildTest2 : MonoBehaviour private byte[] bsonBuffer = Array.Empty(); private byte[] msgPackBuffer = Array.Empty(); private NestedData nd; - + private void OnGUI() { if (GUI.Button(new Rect(Screen.width - 300, Screen.height - 100, 200, 50), "Small Object Test")) @@ -44,7 +46,7 @@ private void OnGUI() SceneManager.LoadScene(0); } } - + /// /// Prepare data /// @@ -111,7 +113,7 @@ private void Start() { sw.Reset(); sw.Start(); - var dd1 = Nino.Serialization.Deserializer.Deserialize(ninoBuffer); + Deserializer.Deserialize(ninoBuffer, out NestedData dd1); sw.Stop(); var m1 = sw.ElapsedTicks; sw.Reset(); @@ -123,17 +125,10 @@ private void Start() //serialize else { - if(ninoBuffer.Length == 0) - { - ninoBuffer = new byte[Nino.Serialization.Serializer.GetSize(nd)]; - } sw.Reset(); sw.Start(); - var arr = ArrayPool.Shared.Rent(Nino.Serialization.Serializer.GetSize(nd)); - Nino.Serialization.Serializer.Serialize(arr, nd); + ninoBuffer = nd.Serialize(); sw.Stop(); - Array.Copy(arr, ninoBuffer, ninoBuffer.Length); - ArrayPool.Shared.Return(arr); var m1 = sw.ElapsedTicks; ninoResultText.text = $"Serialized NestedData as {ninoBuffer.Length} bytes in {((float)m1 / Stopwatch.Frequency) * 1000} ms,\n{string.Join(",", ninoBuffer.Take(200))}"; @@ -143,7 +138,7 @@ private void Start() catch (Exception ex) { ninoResultText.text = ex.ToString(); - Logger.D(ex); + Debug.LogException(ex); } }); pbNetBtn.onClick.AddListener(() => @@ -190,7 +185,7 @@ private void Start() catch (Exception ex) { pbNetResultText.text = ex.ToString(); - Logger.D(ex); + Debug.LogException(ex); } }); binaryFormatterBtn.onClick.AddListener(() => @@ -239,7 +234,7 @@ private void Start() catch (Exception ex) { binaryFormatterResultText.text = ex.ToString(); - Logger.D(ex); + Debug.LogException(ex); } }); bsonBtn.onClick.AddListener(() => @@ -270,7 +265,7 @@ private void Start() using (MemoryStream ms = new MemoryStream()) { using (BsonBinaryWriter bsonWriter = - new BsonBinaryWriter(ms, BsonBinaryWriterSettings.Defaults)) + new BsonBinaryWriter(ms, BsonBinaryWriterSettings.Defaults)) { BsonSerializationContext context = BsonSerializationContext.CreateRoot(bsonWriter); BsonSerializationArgs args = default; @@ -291,7 +286,7 @@ private void Start() catch (Exception ex) { bsonResultText.text = ex.ToString(); - Logger.D(ex); + Debug.LogException(ex); } }); msgPackBtn.onClick.AddListener(() => @@ -319,8 +314,9 @@ private void Start() { sw.Reset(); sw.Start(); - - var lz4Options = MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.None); + + var lz4Options = + MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.None); msgPackBuffer = MessagePackSerializer.Serialize(nd, lz4Options); sw.Stop(); @@ -333,7 +329,7 @@ private void Start() catch (Exception ex) { msgPackResultText.text = ex.ToString(); - Logger.D(ex); + Debug.LogException(ex); } }); } diff --git a/Nino_Unity/Assets/Nino/Test/Data.cs b/Nino_Unity/Assets/Test/Data.cs similarity index 66% rename from Nino_Unity/Assets/Nino/Test/Data.cs rename to Nino_Unity/Assets/Test/Data.cs index 706c9da..b7fe7d0 100644 --- a/Nino_Unity/Assets/Nino/Test/Data.cs +++ b/Nino_Unity/Assets/Test/Data.cs @@ -3,15 +3,15 @@ using System.Linq; using UnityEngine; using MessagePack; -using Nino.Serialization; using System.Collections.Generic; using MongoDB.Bson.Serialization.Attributes; using MongoDB.Bson.Serialization.Options; +using Nino.Core; namespace Nino.Test { - [NinoSerialize()] - public partial class CollectionTest + [NinoType()] + public class CollectionTest { [NinoMember(0)] public List a = new List(); [NinoMember(1)] public List b = new List(); @@ -20,8 +20,8 @@ public partial class CollectionTest [NinoMember(4)] public Dictionary e = new Dictionary(); } - [NinoSerialize] - public partial class ComplexData + [NinoType] + public class ComplexData { [NinoMember(0)] public int[][] a; @@ -67,9 +67,9 @@ private string GetDictString(Dictionary> ddd) [Serializable] [ProtoContract] - [NinoSerialize] + [NinoType] [MessagePackObject] - public partial struct Data + public struct Data { [ProtoMember(1)] [NinoMember(1)] [BsonElement] [Key(1)] public int x; @@ -111,9 +111,9 @@ public enum TestEnum : byte [Serializable] [ProtoContract] - [NinoSerialize] + [NinoType] [MessagePackObject] - public partial class NestedData + public class NestedData { [ProtoMember(1)] [NinoMember(1)] [BsonElement] [Key(1)] public string name; @@ -129,8 +129,8 @@ public override string ToString() [Serializable] [ProtoContract] - [NinoSerialize] - public partial class NestedData2 + [NinoType] + public class NestedData2 { [ProtoMember(1)] [NinoMember(1)] public string name; @@ -144,8 +144,8 @@ public override string ToString() } } - [NinoSerialize(false)] - public partial class CustomTypeTest + [NinoType(false)] + public class PrimitiveTypeTest { [NinoMember(1)] public Vector3 v3; @@ -170,23 +170,8 @@ public override string ToString() } } - [NinoSerialize(true)] - [CodeGenIgnore] - public partial class IncludeAllClass - { - public int a; - public long b; - public float c; - public double d; - - public override string ToString() - { - return $"{a}, {b}, {c}, {d}"; - } - } - - [NinoSerialize(true)] - public partial class IncludeAllClassCodeGen + [NinoType] + public class IncludeAllClassCodeGen { public int a; public long b; @@ -201,9 +186,9 @@ public override string ToString() [Serializable] [ProtoContract] - [NinoSerialize] + [NinoType] [MessagePackObject] - public partial class NotIncludeAllClass + public class NotIncludeAllClass { [ProtoMember(10)] [BsonElement] [Key(0)] [NinoMember(0)] public int a; @@ -225,122 +210,9 @@ public override string ToString() [Serializable] [ProtoContract] - [CodeGenIgnore] - [NinoSerialize] - [MessagePackObject] - public partial class BuildTestDataNoCodeGen - { - [ProtoMember(100)] [BsonElement] [Key(0)] [NinoMember(0)] - public byte a; - - [ProtoMember(1)] [BsonElement] [Key(1)] [NinoMember(1)] - public sbyte b; - - [ProtoMember(2)] [BsonElement] [Key(2)] [NinoMember(2)] - public short c; - - [ProtoMember(3)] [BsonElement] [Key(3)] [NinoMember(3)] - public ushort d; - - [ProtoMember(4)] [BsonElement] [Key(4)] [NinoMember(4)] - public int e; - - [ProtoMember(5)] [BsonElement] [Key(5)] [NinoMember(5)] - public uint f; - - [ProtoMember(6)] [BsonElement] [Key(6)] [NinoMember(6)] - public long g; - - [ProtoMember(7)] [BsonElement] [Key(7)] [NinoMember(7)] - public ulong h; - - [ProtoMember(8)] [BsonElement] [Key(8)] [NinoMember(8)] - public float i; - - [ProtoMember(9)] [BsonElement] [Key(9)] [NinoMember(9)] - public double j; - - [ProtoMember(10)] [BsonElement] [Key(10)] [NinoMember(10)] - public decimal k; - - [ProtoMember(11)] [BsonElement] [Key(11)] [NinoMember(11)] - public bool l; - - [ProtoMember(12)] [BsonElement] [Key(12)] [NinoMember(12)] - public char m; - - [ProtoMember(13)] [BsonElement] [Key(13)] [NinoMember(13)] - public string n; - - [ProtoMember(14)] [BsonElement] [Key(14)] [NinoMember(14)] - public List o = new List(); - - [ProtoMember(15)] [BsonElement] [Key(15)] [NinoMember(15)] - public List p = new List(); - - [ProtoMember(16)] [BsonElement] [Key(16)] [NinoMember(16)] - public byte[] q = Array.Empty(); - - [ProtoMember(17)] [BsonElement] [Key(17)] [NinoMember(17)] - public NotIncludeAllClass[] r = Array.Empty(); - - [Key(18)] - [NinoMember(18)] - -#if !IL2CPP || UNITY_EDITOR - [ProtoMember(18)] - [BsonElement] - [BsonDictionaryOptions(DictionaryRepresentation.ArrayOfArrays)] -#endif - public Dictionary s = new Dictionary(); - - [Key(19)] - [NinoMember(19)] - -#if !IL2CPP || UNITY_EDITOR - [ProtoMember(19)] - [BsonElement] - [BsonDictionaryOptions(DictionaryRepresentation.ArrayOfArrays)] -#endif - public Dictionary t = new Dictionary(); - - [Key(20)] - [NinoMember(20)] - -#if !IL2CPP || UNITY_EDITOR - [ProtoMember(20)] - [BsonElement] - [BsonDictionaryOptions(DictionaryRepresentation.ArrayOfArrays)] -#endif - public Dictionary u = new Dictionary(); - - [Key(21)] - [NinoMember(21)] - -#if !IL2CPP || UNITY_EDITOR - [ProtoMember(21)] - [BsonElement] - [BsonDictionaryOptions(DictionaryRepresentation.ArrayOfArrays)] -#endif - public Dictionary v = - new Dictionary(); - - public override string ToString() - { - return $"{a},{b},{c},{d},{e},{f},{g},{h},{i},{j},{k},{l},{m},{n},{string.Join("/", o)}," + - $"{string.Join("/", p)},{string.Join("/", q)},{string.Join("/", r.ToList())}," + - $"{string.Join("/", s.Keys.ToList())}-{string.Join("/", s.Values.ToList())}," + - $"{string.Join("/", t.Keys.ToList())}-{string.Join("/", t.Values.ToList())}," + - $"{string.Join("/", u.Keys.ToList())}-{string.Join("/", v.Values.ToList())}," + - $"{string.Join("/", v.Keys.ToList())}-{string.Join("/", v.Values.ToList())}"; - } - } - - [Serializable] - [ProtoContract] - [NinoSerialize] + [NinoType] [MessagePackObject] - public partial class BuildTestDataCodeGen + public class BuildTestDataCodeGen { [ProtoMember(100)] [BsonElement] [Key(0)] [NinoMember(0)] public byte a; diff --git a/Nino_Unity/Assets/Nino/Shared/Util/Logger.cs b/Nino_Unity/Assets/Test/Editor/Logger.cs similarity index 98% rename from Nino_Unity/Assets/Nino/Shared/Util/Logger.cs rename to Nino_Unity/Assets/Test/Editor/Logger.cs index 848d494..38004e7 100644 --- a/Nino_Unity/Assets/Nino/Shared/Util/Logger.cs +++ b/Nino_Unity/Assets/Test/Editor/Logger.cs @@ -1,10 +1,11 @@ #if UNITY_2017_1_OR_NEWER using UnityEngine; + #else using System; #endif -namespace Nino.Shared.Util +namespace Nino.Test.Editor { public static class Logger { diff --git a/Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test1.cs b/Nino_Unity/Assets/Test/Editor/Serialization/Test1.cs similarity index 81% rename from Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test1.cs rename to Nino_Unity/Assets/Test/Editor/Serialization/Test1.cs index 9f2d3eb..7494b04 100644 --- a/Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test1.cs +++ b/Nino_Unity/Assets/Test/Editor/Serialization/Test1.cs @@ -1,8 +1,10 @@ using System; using System.IO; using System.Text; -using Nino.Shared.Util; using System.Diagnostics; +using Test_Nino; + + // ReSharper disable RedundantJumpStatement namespace Nino.Test.Editor.Serialization @@ -88,26 +90,11 @@ private static void DoTest(int max) var sw = new Stopwatch(); BeginSample("Nino"); sw.Restart(); - int size = Nino.Serialization.Serializer.GetSize(points); - long len; - if (size <= 1024) - { - Span ret = stackalloc byte[size]; - Nino.Serialization.Serializer.Serialize(ret, points); - sw.Stop(); - EndSample(); - Logger.D("Serialization Test", $"Nino: {ret.Length} bytes in {sw.ElapsedMilliseconds}ms"); - len = ret.Length; - } - else - { - byte[] ret = new byte[size]; - Nino.Serialization.Serializer.Serialize(ret, points); - sw.Stop(); - EndSample(); - Logger.D("Serialization Test", $"Nino: {ret.Length} bytes in {sw.ElapsedMilliseconds}ms"); - len = ret.Length; - } + var ret = points.Serialize(); + sw.Stop(); + EndSample(); + Logger.D("Serialization Test", $"Nino: {ret.Length} bytes in {sw.ElapsedMilliseconds}ms"); + var len = ret.Length; var tm = sw.ElapsedMilliseconds; //Logger.D("Serialization Test",string.Join(",", bs)); diff --git a/Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test10.cs b/Nino_Unity/Assets/Test/Editor/Serialization/Test10.cs similarity index 98% rename from Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test10.cs rename to Nino_Unity/Assets/Test/Editor/Serialization/Test10.cs index 1c29e8b..972d619 100644 --- a/Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test10.cs +++ b/Nino_Unity/Assets/Test/Editor/Serialization/Test10.cs @@ -1,6 +1,6 @@ -using Nino.Shared.Util; -using Nino.Serialization; using System.Collections.Generic; +using Test_Nino; + // ReSharper disable RedundantTypeArgumentsOfMethod namespace Nino.Test.Editor.Serialization @@ -226,7 +226,8 @@ public static void Main() Logger.D(data); var buf = Serializer.Serialize(data); Logger.D($"Serialized data: {buf.Length} bytes, {string.Join(",",buf)}"); - Logger.D($"Deserialized as: {Deserializer.Deserialize(buf)}"); + Deserializer.Deserialize(buf, out ComplexData result); + Logger.D($"Deserialized as: {result}"); } } } diff --git a/Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test2.cs b/Nino_Unity/Assets/Test/Editor/Serialization/Test2.cs similarity index 82% rename from Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test2.cs rename to Nino_Unity/Assets/Test/Editor/Serialization/Test2.cs index 05d812e..5896ce0 100644 --- a/Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test2.cs +++ b/Nino_Unity/Assets/Test/Editor/Serialization/Test2.cs @@ -1,9 +1,9 @@ -using System; using System.IO; using System.Text; -using Nino.Shared.Util; using System.Diagnostics; using System.Runtime.Serialization.Formatters.Binary; +using Test_Nino; + // ReSharper disable RedundantJumpStatement namespace Nino.Test.Editor.Serialization @@ -89,27 +89,12 @@ private static void DoTest(int max) var sw = new Stopwatch(); BeginSample("Nino"); sw.Restart(); - int size = Nino.Serialization.Serializer.GetSize(points); - long len; byte[] bs; - if (size <= 1024) - { - Span ret = stackalloc byte[size]; - Nino.Serialization.Serializer.Serialize(ret, points); - sw.Stop(); - EndSample(); - Logger.D("Serialization Test", $"Nino: {ret.Length} bytes in {sw.ElapsedMilliseconds}ms"); - len = ret.Length; - } - else - { - byte[] ret = new byte[size]; - Nino.Serialization.Serializer.Serialize(ret, points); - sw.Stop(); - EndSample(); - Logger.D("Serialization Test", $"Nino: {ret.Length} bytes in {sw.ElapsedMilliseconds}ms"); - len = ret.Length; - } + var ret = points.Serialize(); + sw.Stop(); + EndSample(); + Logger.D("Serialization Test", $"Nino: {ret.Length} bytes in {sw.ElapsedMilliseconds}ms"); + var len = ret.Length; var tm = sw.ElapsedMilliseconds; //Logger.D("Serialization Test",string.Join(",", bs)); diff --git a/Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test3.cs b/Nino_Unity/Assets/Test/Editor/Serialization/Test3.cs similarity index 91% rename from Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test3.cs rename to Nino_Unity/Assets/Test/Editor/Serialization/Test3.cs index a46fdd1..2724ed4 100644 --- a/Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test3.cs +++ b/Nino_Unity/Assets/Test/Editor/Serialization/Test3.cs @@ -1,8 +1,10 @@ using System.IO; using System.Text; -using Nino.Shared.Util; using System.Diagnostics; using System.Collections.Generic; +using Test_Nino; + + // ReSharper disable RedundantJumpStatement namespace Nino.Test.Editor.Serialization @@ -19,7 +21,7 @@ private static string GetString(int len) } #if UNITY_2017_1_OR_NEWER - [UnityEditor.MenuItem(SerializationTest3,priority=3)] + [UnityEditor.MenuItem(SerializationTest3, priority = 3)] #endif public static void Main() { @@ -82,14 +84,13 @@ private static void DoTest(int max) #region Test Logger.D("Deserialization Test", $"testing {max} objs"); - NestedData2 d; //Nino var sw = new Stopwatch(); - var bs = Nino.Serialization.Serializer.Serialize(points); + var bs = points.Serialize(); BeginSample("Nino"); sw.Restart(); - d = Nino.Serialization.Deserializer.Deserialize(bs); + Deserializer.Deserialize(bs, out NestedData d); sw.Stop(); EndSample(); Logger.D("Deserialization Test", d); @@ -108,7 +109,7 @@ private static void DoTest(int max) BeginSample("PB-net"); sw.Restart(); - d = ProtoBuf.Serializer.Deserialize(new MemoryStream(bs)); + d = ProtoBuf.Serializer.Deserialize(new MemoryStream(bs)); sw.Stop(); EndSample(); Logger.D("Deserialization Test", d); diff --git a/Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test4.cs b/Nino_Unity/Assets/Test/Editor/Serialization/Test4.cs similarity index 95% rename from Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test4.cs rename to Nino_Unity/Assets/Test/Editor/Serialization/Test4.cs index 5b17464..d816623 100644 --- a/Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test4.cs +++ b/Nino_Unity/Assets/Test/Editor/Serialization/Test4.cs @@ -1,11 +1,13 @@ using System.IO; using System.Text; -using Nino.Shared.Util; using System.Diagnostics; using System.Collections.Generic; using System.Runtime.Serialization.Formatters.Binary; +using Test_Nino; + // ReSharper disable RedundantJumpStatement + namespace Nino.Test.Editor.Serialization { public class Test4 @@ -86,14 +88,13 @@ private static void DoTest(int max) Logger.D("Deserialization Test", $"testing {max} objs"); Logger.D("Deserialization Test", "======================================"); - NestedData2 d; //Nino var sw = new Stopwatch(); - var bs = Nino.Serialization.Serializer.Serialize(points); + var bs = points.Serialize(); BeginSample("Nino"); sw.Restart(); - d = Nino.Serialization.Deserializer.Deserialize(bs); + Deserializer.Deserialize(bs, out NestedData2 d); sw.Stop(); EndSample(); Logger.D("Deserialization Test", d); diff --git a/Nino_Unity/Assets/Test/Editor/Serialization/Test5.cs b/Nino_Unity/Assets/Test/Editor/Serialization/Test5.cs new file mode 100644 index 0000000..81559be --- /dev/null +++ b/Nino_Unity/Assets/Test/Editor/Serialization/Test5.cs @@ -0,0 +1,171 @@ +using System; +using System.IO; +using System.Text; +using MongoDB.Bson.IO; +using System.Diagnostics; +using Test_Nino; +using MongoDB.Bson.Serialization; + + +// ReSharper disable RedundantJumpStatement + +namespace Nino.Test.Editor.Serialization +{ + public class Test5 + { + private const string SerializationTest5 = + "Nino/Test/Serialization/Test5 - Serialize and Deserialize (Nino vs MongoDB.Bson)"; + + private static string GetString(int len) + { + StringBuilder sb = new StringBuilder(); + sb.Append('a', len); + return sb.ToString(); + } + +#if UNITY_2017_1_OR_NEWER + [UnityEditor.MenuItem(SerializationTest5, priority = 5)] +#endif + public static void Main() + { + //reg + BsonClassMap.RegisterClassMap(); + BsonClassMap.RegisterClassMap(); + BsonClassMap.RegisterClassMap(); + Logger.W("1/5"); + DoTest(10); + Logger.W("2/5"); + DoTest(100); + Logger.W("3/5"); + DoTest(1000); + Logger.W("4/5"); + DoTest(10000); + Logger.W("5/5"); + DoTest(100000); + } + + private static void BeginSample(string name) + { +#if UNITY_2017_1_OR_NEWER + UnityEngine.Profiling.Profiler.BeginSample(name); +#endif + return; + } + + private static void EndSample() + { +#if UNITY_2017_1_OR_NEWER + UnityEngine.Profiling.Profiler.EndSample(); +#endif + return; + } + + private static void DoTest(int max) + { + #region Test data + + Data[] ps = new Data[max]; + for (int i = 0, cnt = max; i < cnt; i++) + { + ps[i] = new Data() + { + x = short.MaxValue, + y = byte.MaxValue, + z = short.MaxValue, + f = 1234.56789f, + d = 66.66666666m, + db = 999.999999999999, + bo = true, + en = TestEnum.A, + }; + } + + NestedData points = new NestedData() + { + name = "测试", + ps = ps + }; + + #endregion + + #region Test + + Logger.D("Serialization Test", $"testing {max} objs"); + Logger.D("Serialization Test", "======================================"); + + //Nino + var sw = new Stopwatch(); + BeginSample("Nino - Serialize"); + sw.Restart(); + byte[] ret = Serializer.Serialize(points); + sw.Stop(); + EndSample(); + Logger.D("Serialization Test", $"Nino: {ret.Length} bytes in {sw.ElapsedMilliseconds}ms"); + var len = ret.Length; + var tm = sw.ElapsedMilliseconds; + //Logger.D("Serialization Test",string.Join(",", bs)); + + //MongoDB.Bson + BeginSample("MongoDB.Bson - Serialize"); + byte[] bs2; + sw.Restart(); + //we want byte[], MongoDB.Bson returns stream + //to be able to make it fair, we need to convert stream to byte[] + using (MemoryStream ms = new MemoryStream()) + { + using (BsonBinaryWriter bsonWriter = new BsonBinaryWriter(ms, BsonBinaryWriterSettings.Defaults)) + { + BsonSerializationContext context = BsonSerializationContext.CreateRoot(bsonWriter); + BsonSerializationArgs args = default; + args.NominalType = typeof(object); + IBsonSerializer serializer = BsonSerializer.LookupSerializer(args.NominalType); + serializer.Serialize(context, args, points); + bs2 = ms.ToArray(); + } + } + + sw.Stop(); + EndSample(); + + Logger.D("Serialization Test", $"MongoDB.Bson: {bs2.Length} bytes in {sw.ElapsedMilliseconds}ms"); + //Logger.D("Serialization Test",string.Join(",", bs)); + + Logger.D("Serialization Test", "======================================"); + Logger.D("Serialization Test", $"size diff (nino - MongoDB.Bson): {len - bs2.Length} bytes"); + Logger.D("Serialization Test", + $"size diff pct => diff/MongoDB.Bson : {((len - bs2.Length) * 100f / bs2.Length):F2}%"); + + Logger.D("Serialization Test", "======================================"); + Logger.D("Serialization Test", $"time diff (nino - MongoDB.Bson): {tm - sw.ElapsedMilliseconds} ms"); + Logger.D("Serialization Test", + $"time diff pct => time/MongoDB.Bson : {((tm - sw.ElapsedMilliseconds) * 100f / sw.ElapsedMilliseconds):F2}%"); + + BeginSample("Nino - Deserialize"); + sw.Restart(); + Deserializer.Deserialize(ret, out NestedData d); + sw.Stop(); + EndSample(); + Logger.D("Deserialization Test", d); + Logger.D("Deserialization Test", + $"Nino: extracted {ret.Length} bytes and deserialized {points.ps.Length} entries in {sw.ElapsedMilliseconds}ms"); + tm = sw.ElapsedMilliseconds; + + //MongoDB.Bson + BeginSample("MongoDB.Bson - Deserialize"); + sw.Restart(); + d = (NestedData)BsonSerializer.Deserialize(bs2, typeof(NestedData)); + sw.Stop(); + EndSample(); + Logger.D("Deserialization Test", d); + Logger.D("Deserialization Test", + $"MongoDB.Bson: extracted {bs2.Length} bytes and deserialized {points.ps.Length} entries in {sw.ElapsedMilliseconds}ms"); + + Logger.D("Deserialization Test", "======================================"); + Logger.D("Deserialization Test", $"time diff (nino - MongoDB.Bson): {tm - sw.ElapsedMilliseconds} ms"); + Logger.D("Deserialization Test", + $"time diff pct => time/MongoDB.Bson : {((tm - sw.ElapsedMilliseconds) * 100f / sw.ElapsedMilliseconds):F2}%"); + + #endregion + } + } +} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test6.cs b/Nino_Unity/Assets/Test/Editor/Serialization/Test6.cs similarity index 64% rename from Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test6.cs rename to Nino_Unity/Assets/Test/Editor/Serialization/Test6.cs index ee5da79..99f52ff 100644 --- a/Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test6.cs +++ b/Nino_Unity/Assets/Test/Editor/Serialization/Test6.cs @@ -1,8 +1,8 @@ using System; using MessagePack; using System.Text; -using Nino.Shared.Util; using System.Diagnostics; +using Test_Nino; using MessagePack.Resolvers; // ReSharper disable RedundantJumpStatement @@ -120,74 +120,12 @@ private static void DoTest(int max) var sw = new Stopwatch(); BeginSample("Nino - Serialize"); sw.Restart(); - int size = Nino.Serialization.Serializer.GetSize(points); - long len; - byte[] bs; - if (size <= 1024) - { - Span ret = stackalloc byte[size]; - Nino.Serialization.Serializer.Serialize(ret, points); - sw.Stop(); - EndSample(); - Logger.D("Serialization Test", $"Nino: {ret.Length} bytes in {sw.ElapsedMilliseconds}ms"); - len = ret.Length; - var tm = sw.ElapsedMilliseconds; - - //MsgPack - BeginSample("MsgPack - Serialize"); - byte[] bs2; - sw.Restart(); - var lz4Options = MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.None); - bs2 = MessagePackSerializer.Serialize(points, lz4Options); - sw.Stop(); - EndSample(); - - Logger.D("Serialization Test", $"MsgPack: {bs2.Length} bytes in {sw.ElapsedMilliseconds}ms"); - //Logger.D("Serialization Test",string.Join(",", bs)); - - Logger.D("Serialization Test", "======================================"); - Logger.D("Serialization Test", $"size diff (nino - MsgPack): {len - bs2.Length} bytes"); - Logger.D("Serialization Test", - $"size diff pct => diff/MsgPack : {((len - bs2.Length) * 100f / bs2.Length):F2}%"); - - Logger.D("Serialization Test", "======================================"); - Logger.D("Serialization Test", $"time diff (nino - MsgPack): {tm - sw.ElapsedMilliseconds} ms"); - Logger.D("Serialization Test", - $"time diff pct => time/MsgPack : {((tm - sw.ElapsedMilliseconds) * 100f / sw.ElapsedMilliseconds):F2}%"); - - BeginSample("Nino - Deserialize"); - sw.Restart(); - var d = Nino.Serialization.Deserializer.Deserialize(ret); - sw.Stop(); - EndSample(); - Logger.D("Deserialization Test", d); - Logger.D("Deserialization Test", - $"Nino: extracted {len} bytes and deserialized {points.ps.Length} entries in {sw.ElapsedMilliseconds}ms"); - tm = sw.ElapsedMilliseconds; - - //MsgPack - BeginSample("MsgPack - Deserialize"); - sw.Restart(); - d = MessagePackSerializer.Deserialize(bs2); - sw.Stop(); - EndSample(); - Logger.D("Deserialization Test", d); - Logger.D("Deserialization Test", - $"MsgPack: extracted {bs2.Length} bytes and deserialized {points.ps.Length} entries in {sw.ElapsedMilliseconds}ms"); - - Logger.D("Deserialization Test", "======================================"); - Logger.D("Deserialization Test", $"time diff (nino - MsgPack): {tm - sw.ElapsedMilliseconds} ms"); - Logger.D("Deserialization Test", - $"time diff pct => time/MsgPack : {((tm - sw.ElapsedMilliseconds) * 100f / sw.ElapsedMilliseconds):F2}%"); - } - else - { - byte[] ret = new byte[size]; - Nino.Serialization.Serializer.Serialize(ret, points); + + byte[] ret = points.Serialize(); sw.Stop(); EndSample(); Logger.D("Serialization Test", $"Nino: {ret.Length} bytes in {sw.ElapsedMilliseconds}ms"); - len = ret.Length; + var len = ret.Length; var tm = sw.ElapsedMilliseconds; //MsgPack @@ -214,7 +152,7 @@ private static void DoTest(int max) BeginSample("Nino - Deserialize"); sw.Restart(); - var d = Nino.Serialization.Deserializer.Deserialize(ret); + Deserializer.Deserialize(ret, out NestedData d); sw.Stop(); EndSample(); Logger.D("Deserialization Test", d); @@ -236,7 +174,6 @@ private static void DoTest(int max) Logger.D("Deserialization Test", $"time diff (nino - MsgPack): {tm - sw.ElapsedMilliseconds} ms"); Logger.D("Deserialization Test", $"time diff pct => time/MsgPack : {((tm - sw.ElapsedMilliseconds) * 100f / sw.ElapsedMilliseconds):F2}%"); - } //Logger.D("Serialization Test",string.Join(",", bs)); diff --git a/Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test7.cs b/Nino_Unity/Assets/Test/Editor/Serialization/Test7.cs similarity index 50% rename from Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test7.cs rename to Nino_Unity/Assets/Test/Editor/Serialization/Test7.cs index 910998f..ca48aa1 100644 --- a/Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test7.cs +++ b/Nino_Unity/Assets/Test/Editor/Serialization/Test7.cs @@ -1,61 +1,21 @@ -using Nino.Serialization; using System.Collections.Generic; +using Test_Nino; using UnityEngine; -using Logger = Nino.Shared.Util.Logger; // ReSharper disable RedundantTypeArgumentsOfMethod namespace Nino.Test.Editor.Serialization { - public class CustomTypeTestWrapper : NinoWrapperBase - { - public override void Serialize(CustomTypeTest val, ref Writer writer) - { - writer.Write(ref val.v3, sizeof(float) * 3); - writer.Write(ref val.m, sizeof(float) * 16); - writer.Write(val.ni); - writer.Write(val.qs); - writer.Write(val.dict); - writer.Write(val.dict2); - } - - public override CustomTypeTest Deserialize(Reader reader) - { - var ret = new CustomTypeTest(); - reader.Read(ref ret.v3, sizeof(float) * 3); - reader.Read(ref ret.m, sizeof(float) * 16); - ret.ni = reader.ReadNullable(); - ret.qs = reader.ReadList(); - ret.dict = reader.ReadDictionary(); - ret.dict2 = reader.ReadDictionary(); - return ret; - } - - public override int GetSize(CustomTypeTest val) - { - int ret = 1; - ret += sizeof(float) * 3; - ret += sizeof(float) * 16; - ret += Serializer.GetSize(val.ni); - ret += Serializer.GetSize(val.qs); - ret += Serializer.GetSize(val.dict); - ret += Serializer.GetSize(val.dict2); - return ret; - } - } - public class Test7 { - private const string SerializationTest7 = "Nino/Test/Serialization/Test7 - Custom Type Importer Exporter"; + private const string SerializationTest7 = "Nino/Test/Serialization/Test7 - Primitive Type Serialization"; #if UNITY_2017_1_OR_NEWER [UnityEditor.MenuItem(SerializationTest7, priority = 7)] #endif public static void Main() { - //register wrappers - WrapperManifest.AddWrapper(typeof(CustomTypeTest), new CustomTypeTestWrapper()); //custom type - CustomTypeTest c = new CustomTypeTest() + PrimitiveTypeTest c = new PrimitiveTypeTest() { ni = null, v3 = UnityEngine.Vector3.one, @@ -85,7 +45,7 @@ public static void Main() var bs = Serializer.Serialize(c); Logger.D($"serialized to {bs.Length} bytes: {string.Join(",", bs)}"); Logger.D("will deserialize"); - var cc = Deserializer.Deserialize(bs); + Deserializer.Deserialize(bs, out PrimitiveTypeTest cc); Logger.D($"deserialized as cc: {cc}"); } } diff --git a/Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test8.cs b/Nino_Unity/Assets/Test/Editor/Serialization/Test8.cs similarity index 63% rename from Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test8.cs rename to Nino_Unity/Assets/Test/Editor/Serialization/Test8.cs index d8f156c..dde383c 100644 --- a/Nino_Unity/Assets/Nino/Test/Editor/Serialization/Test8.cs +++ b/Nino_Unity/Assets/Test/Editor/Serialization/Test8.cs @@ -1,6 +1,6 @@ -using Nino.Shared.Util; -using Nino.Serialization; using System.Diagnostics; +using Test_Nino; + // ReSharper disable RedundantTypeArgumentsOfMethod namespace Nino.Test.Editor.Serialization @@ -16,31 +16,6 @@ public static void Main() { Stopwatch sw = new Stopwatch(); - IncludeAllClass c = new IncludeAllClass() - { - a = 100, - b = 199, - c = 5.5f, - d = 1.23456 - }; - Logger.D( - "serialize an 'include all' class will make serialization " + - "and deserialization result larger and slower, it is recommended to use NinoMember Attributes"); - Logger.D($"will serialize c: {c}"); - sw.Reset(); - sw.Start(); - var bs = Serializer.Serialize(c); - sw.Stop(); - Logger.D( - $"serialized to {bs.Length} bytes in {((float)sw.ElapsedTicks / Stopwatch.Frequency) * 1000} ms: {string.Join(",", bs)}"); - - Logger.D("will deserialize"); - sw.Reset(); - sw.Start(); - var cc = Deserializer.Deserialize(bs); - sw.Stop(); - Logger.D($"deserialized as cc in {((float)sw.ElapsedTicks / Stopwatch.Frequency) * 1000} ms: {cc}"); - IncludeAllClassCodeGen codeGen = new IncludeAllClassCodeGen() { a = 100, @@ -53,14 +28,14 @@ public static void Main() Logger.D($"will serialize codeGen: {codeGen}"); sw.Reset(); sw.Start(); - bs = Serializer.Serialize(codeGen); + var bs = codeGen.Serialize(); sw.Stop(); Logger.D($"serialized to {bs.Length} bytes in {((float)sw.ElapsedTicks / Stopwatch.Frequency) * 1000} ms: {string.Join(",", bs)}"); Logger.D("will deserialize"); sw.Reset(); sw.Start(); - var codeGenR = Deserializer.Deserialize(bs); + Deserializer.Deserialize(bs,out IncludeAllClassCodeGen codeGenR); sw.Stop(); Logger.D($"deserialized as codeGenR in {((float)sw.ElapsedTicks / Stopwatch.Frequency) * 1000} ms: {codeGenR}"); @@ -76,14 +51,14 @@ public static void Main() Logger.D($"will serialize d in {((float)sw.ElapsedTicks / Stopwatch.Frequency) * 1000} ms: {d}"); sw.Reset(); sw.Start(); - bs = Serializer.Serialize(d); + bs = d.Serialize(); sw.Stop(); Logger.D($"serialized to {bs.Length} bytes: {string.Join(",", bs)}"); Logger.D("will deserialize"); sw.Reset(); sw.Start(); - var dd = Deserializer.Deserialize(bs); + Deserializer.Deserialize(bs, out NotIncludeAllClass dd); sw.Stop(); Logger.D($"deserialized as dd in {((float)sw.ElapsedTicks / Stopwatch.Frequency) * 1000} ms: {dd}"); } diff --git a/Nino_Unity/Assets/Test/Editor/Serialization/Test9.cs b/Nino_Unity/Assets/Test/Editor/Serialization/Test9.cs new file mode 100644 index 0000000..2ea4ef7 --- /dev/null +++ b/Nino_Unity/Assets/Test/Editor/Serialization/Test9.cs @@ -0,0 +1,81 @@ +using System.Collections.Generic; +using System.Linq; +using Test_Nino; + + +// ReSharper disable RedundantTypeArgumentsOfMethod +namespace Nino.Test.Editor.Serialization +{ + public class Test9 + { + private const string SerializationTest9 = "Nino/Test/Serialization/Test9 - Basic Types"; + +#if UNITY_2017_1_OR_NEWER + [UnityEditor.MenuItem(SerializationTest9,priority=9)] +#endif + public static void Main() + { + int a = int.MaxValue; + uint b = uint.MaxValue; + long c = long.MaxValue; + ulong d = ulong.MaxValue; + float e = float.MaxValue; + double f = double.MaxValue; + decimal g = decimal.MaxValue; + string h = "Hello World"; + bool i = true; + char j = 'a'; + byte k = byte.MaxValue; + sbyte l = sbyte.MaxValue; + ushort m = ushort.MaxValue; + short n = short.MaxValue; + int[] o = new int[]{ 1, 2, 3, 4, 5 }; + List p = new List() { 1, 2, 3, 4, 5 }; + Dictionary q = new Dictionary() + { { "a", 1 }, { "b", 2 }, { "c", 3 }, { "d", 4 }, { "e", 5 } }; + + T Deserialize(byte[] bytes) where T : unmanaged + { + Deserializer.Deserialize(bytes, out T value); + return value; + } + T[] DeserializeArray(byte[] bytes) where T : unmanaged + { + Deserializer.Deserialize(bytes, out T[] value); + return value; + } + List DeserializeList(byte[] bytes) where T : unmanaged + { + Deserializer.Deserialize(bytes, out List value); + return value; + } + string DeserializeString(byte[] bytes) + { + Deserializer.Deserialize(bytes, out string value); + return value; + } + + Logger.D($"Serialized a as: {(((a)).Serialize().Length)} bytes: {(string.Join(",",((a)).Serialize()))}, deserialized as:{Deserialize(a.Serialize())}"); + Logger.D($"Serialized b as: {(((b)).Serialize().Length)} bytes: {(string.Join(",",((b)).Serialize()))}, deserialized as:{Deserialize(b.Serialize())}"); + Logger.D($"Serialized c as: {(((c)).Serialize().Length)} bytes: {(string.Join(",",((c)).Serialize()))}, deserialized as:{Deserialize(c.Serialize())}"); + Logger.D($"Serialized d as: {(((d)).Serialize().Length)} bytes: {(string.Join(",",((d)).Serialize()))}, deserialized as:{Deserialize(d.Serialize())}"); + Logger.D($"Serialized e as: {(((e)).Serialize().Length)} bytes: {(string.Join(",",((e)).Serialize()))}, deserialized as:{Deserialize(e.Serialize())}"); + Logger.D($"Serialized f as: {(((f)).Serialize().Length)} bytes: {(string.Join(",",((f)).Serialize()))}, deserialized as:{Deserialize(f.Serialize())}"); + Logger.D($"Serialized g as: {(((g)).Serialize().Length)} bytes: {(string.Join(",",((g)).Serialize()))}, deserialized as:{Deserialize(g.Serialize())}"); + Logger.D($"Serialized h as: {(((h)).Serialize().Length)} bytes: {(string.Join(",",((h)).Serialize()))}, deserialized as:{DeserializeString(h.Serialize())}"); + Logger.D($"Serialized i as: {(((i)).Serialize().Length)} bytes: {(string.Join(",",((i)).Serialize()))}, deserialized as:{Deserialize(i.Serialize())}"); + Logger.D($"Serialized j as: {(((j)).Serialize().Length)} bytes: {(string.Join(",",((j)).Serialize()))}, deserialized as:{Deserialize(j.Serialize())}"); + Logger.D($"Serialized k as: {(((k)).Serialize().Length)} bytes: {(string.Join(",",((k)).Serialize()))}, deserialized as:{Deserialize(k.Serialize())}"); + Logger.D($"Serialized l as: {(((l)).Serialize().Length)} bytes: {(string.Join(",",((l)).Serialize()))}, deserialized as:{Deserialize(l.Serialize())}"); + Logger.D($"Serialized m as: {(((m)).Serialize().Length)} bytes: {(string.Join(",",((m)).Serialize()))}, deserialized as:{Deserialize(m.Serialize())}"); + Logger.D($"Serialized n as: {(((n)).Serialize().Length)} bytes: {(string.Join(",",((n)).Serialize()))}, deserialized as:{Deserialize(n.Serialize())}"); + Logger.D($"Serialized o as: {(((o)).Serialize().Length)} bytes: {(string.Join(",",((o)).Serialize()))}, deserialized as:{DeserializeArray(o.Serialize())}"); + Logger.D($"Serialized p as: {(((p)).Serialize().Length)} bytes: {(string.Join(",",((p)).Serialize()))}, deserialized as:{string.Join(",",DeserializeList(p.Serialize()))}"); + Deserializer.Deserialize(q.Serialize(), out Dictionary dict); + Logger.D( + $"Serialized q as: {(((q)).Serialize().Length)} bytes: {(string.Join(",", ((q)).Serialize()))}, " + + $"deserialized as:{string.Join(",", dict.ToList().SelectMany(kvp => $"{kvp.Key}-{kvp.Value}"))}"); + } + } +} +// ReSharper restore RedundantTypeArgumentsOfMethod \ No newline at end of file diff --git a/Nino_Unity/Assets/Test/Editor/Test.Editor.asmdef b/Nino_Unity/Assets/Test/Editor/Test.Editor.asmdef new file mode 100644 index 0000000..6a35c79 --- /dev/null +++ b/Nino_Unity/Assets/Test/Editor/Test.Editor.asmdef @@ -0,0 +1,16 @@ +{ + "name": "Test.Editor", + "rootNamespace": "", + "references": ["GUID:0371820e3c81945b3853517b36266c3a","GUID:8cb834c2cb7b04c2391ea9063c36e935","GUID:b4ba1c6530914478f9c4dc9b75d56ac4","GUID:0062188b04f3b485c8cd32a3cac02b12","GUID:bbde805d927e795439d7a746d1749cab","GUID:5a46ad82eac024e4fbb6a0516a5def17"], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Nino_Unity/Assets/Nino/Test/MessagePackGenerated.cs b/Nino_Unity/Assets/Test/MessagePackGenerated.cs similarity index 74% rename from Nino_Unity/Assets/Nino/Test/MessagePackGenerated.cs rename to Nino_Unity/Assets/Test/MessagePackGenerated.cs index 89ec334..3972988 100644 --- a/Nino_Unity/Assets/Nino/Test/MessagePackGenerated.cs +++ b/Nino_Unity/Assets/Test/MessagePackGenerated.cs @@ -50,7 +50,7 @@ internal static class GeneratedResolverGetFormatterHelper static GeneratedResolverGetFormatterHelper() { - lookup = new global::System.Collections.Generic.Dictionary(14) + lookup = new global::System.Collections.Generic.Dictionary(13) { { typeof(global::Nino.Test.Data[]), 0 }, { typeof(global::Nino.Test.NotIncludeAllClass[]), 1 }, @@ -62,10 +62,9 @@ static GeneratedResolverGetFormatterHelper() { typeof(global::System.Collections.Generic.List), 7 }, { typeof(global::Nino.Test.TestEnum), 8 }, { typeof(global::Nino.Test.BuildTestDataCodeGen), 9 }, - { typeof(global::Nino.Test.BuildTestDataNoCodeGen), 10 }, - { typeof(global::Nino.Test.Data), 11 }, - { typeof(global::Nino.Test.NestedData), 12 }, - { typeof(global::Nino.Test.NotIncludeAllClass), 13 }, + { typeof(global::Nino.Test.Data), 10 }, + { typeof(global::Nino.Test.NestedData), 11 }, + { typeof(global::Nino.Test.NotIncludeAllClass), 12 }, }; } @@ -89,10 +88,9 @@ internal static object GetFormatter(Type t) case 7: return new global::MessagePack.Formatters.ListFormatter(); case 8: return new MessagePack.Formatters.Nino.Test.TestEnumFormatter(); case 9: return new MessagePack.Formatters.Nino.Test.BuildTestDataCodeGenFormatter(); - case 10: return new MessagePack.Formatters.Nino.Test.BuildTestDataNoCodeGenFormatter(); - case 11: return new MessagePack.Formatters.Nino.Test.DataFormatter(); - case 12: return new MessagePack.Formatters.Nino.Test.NestedDataFormatter(); - case 13: return new MessagePack.Formatters.Nino.Test.NotIncludeAllClassFormatter(); + case 10: return new MessagePack.Formatters.Nino.Test.DataFormatter(); + case 11: return new MessagePack.Formatters.Nino.Test.NestedDataFormatter(); + case 12: return new MessagePack.Formatters.Nino.Test.NotIncludeAllClassFormatter(); default: return null; } } @@ -306,136 +304,6 @@ public void Serialize(ref global::MessagePack.MessagePackWriter writer, global:: } } - public sealed class BuildTestDataNoCodeGenFormatter : global::MessagePack.Formatters.IMessagePackFormatter - { - - public void Serialize(ref global::MessagePack.MessagePackWriter writer, global::Nino.Test.BuildTestDataNoCodeGen value, global::MessagePack.MessagePackSerializerOptions options) - { - if (value == null) - { - writer.WriteNil(); - return; - } - - global::MessagePack.IFormatterResolver formatterResolver = options.Resolver; - writer.WriteArrayHeader(22); - writer.Write(value.a); - writer.Write(value.b); - writer.Write(value.c); - writer.Write(value.d); - writer.Write(value.e); - writer.Write(value.f); - writer.Write(value.g); - writer.Write(value.h); - writer.Write(value.i); - writer.Write(value.j); - formatterResolver.GetFormatterWithVerify().Serialize(ref writer, value.k, options); - writer.Write(value.l); - writer.Write(value.m); - formatterResolver.GetFormatterWithVerify().Serialize(ref writer, value.n, options); - formatterResolver.GetFormatterWithVerify>().Serialize(ref writer, value.o, options); - formatterResolver.GetFormatterWithVerify>().Serialize(ref writer, value.p, options); - writer.Write(value.q); - formatterResolver.GetFormatterWithVerify().Serialize(ref writer, value.r, options); - formatterResolver.GetFormatterWithVerify>().Serialize(ref writer, value.s, options); - formatterResolver.GetFormatterWithVerify>().Serialize(ref writer, value.t, options); - formatterResolver.GetFormatterWithVerify>().Serialize(ref writer, value.u, options); - formatterResolver.GetFormatterWithVerify>().Serialize(ref writer, value.v, options); - } - - public global::Nino.Test.BuildTestDataNoCodeGen Deserialize(ref global::MessagePack.MessagePackReader reader, global::MessagePack.MessagePackSerializerOptions options) - { - if (reader.TryReadNil()) - { - return null; - } - - options.Security.DepthStep(ref reader); - global::MessagePack.IFormatterResolver formatterResolver = options.Resolver; - var length = reader.ReadArrayHeader(); - var ____result = new global::Nino.Test.BuildTestDataNoCodeGen(); - - for (int i = 0; i < length; i++) - { - switch (i) - { - case 0: - ____result.a = reader.ReadByte(); - break; - case 1: - ____result.b = reader.ReadSByte(); - break; - case 2: - ____result.c = reader.ReadInt16(); - break; - case 3: - ____result.d = reader.ReadUInt16(); - break; - case 4: - ____result.e = reader.ReadInt32(); - break; - case 5: - ____result.f = reader.ReadUInt32(); - break; - case 6: - ____result.g = reader.ReadInt64(); - break; - case 7: - ____result.h = reader.ReadUInt64(); - break; - case 8: - ____result.i = reader.ReadSingle(); - break; - case 9: - ____result.j = reader.ReadDouble(); - break; - case 10: - ____result.k = formatterResolver.GetFormatterWithVerify().Deserialize(ref reader, options); - break; - case 11: - ____result.l = reader.ReadBoolean(); - break; - case 12: - ____result.m = reader.ReadChar(); - break; - case 13: - ____result.n = formatterResolver.GetFormatterWithVerify().Deserialize(ref reader, options); - break; - case 14: - ____result.o = formatterResolver.GetFormatterWithVerify>().Deserialize(ref reader, options); - break; - case 15: - ____result.p = formatterResolver.GetFormatterWithVerify>().Deserialize(ref reader, options); - break; - case 16: - ____result.q = reader.ReadBytes()?.ToArray(); - break; - case 17: - ____result.r = formatterResolver.GetFormatterWithVerify().Deserialize(ref reader, options); - break; - case 18: - ____result.s = formatterResolver.GetFormatterWithVerify>().Deserialize(ref reader, options); - break; - case 19: - ____result.t = formatterResolver.GetFormatterWithVerify>().Deserialize(ref reader, options); - break; - case 20: - ____result.u = formatterResolver.GetFormatterWithVerify>().Deserialize(ref reader, options); - break; - case 21: - ____result.v = formatterResolver.GetFormatterWithVerify>().Deserialize(ref reader, options); - break; - default: - reader.Skip(); - break; - } - } - - reader.Depth--; - return ____result; - } - } - public sealed class DataFormatter : global::MessagePack.Formatters.IMessagePackFormatter { diff --git a/Nino_Unity/Assets/Test/Nino/Nino.Core.dll b/Nino_Unity/Assets/Test/Nino/Nino.Core.dll new file mode 100644 index 0000000000000000000000000000000000000000..20d3ca48d0d7005e742dab29b5d9c96d1b6d85a8 GIT binary patch literal 10752 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 bx_&7lfQjNe{A<+>_m{%yUpe{z6@mW&R;Kvf literal 0 HcmV?d00001 diff --git a/Nino_Unity/Assets/Test/Nino/Nino.Generator.dll b/Nino_Unity/Assets/Test/Nino/Nino.Generator.dll new file mode 100644 index 0000000000000000000000000000000000000000..90b09c293a4044dec45e9d8e14caa26888446dcb GIT binary patch literal 55808 zcmeHw3t(HtmG;~#>FR0OlI=KeE98L^J5C%YAt52e? z#*EKt8@@54YgZK{dT$=- z!Z#5B#%;CuMvDIuLR{8j=FA?XByVV&fy8$hTntvDyIRb2UlxeOs{qd|gC7)8II>!Z zGu$~sTugGsAMvIOpIG}gA^!DdOUev+ZNYRsSt~?n-rM9;Z`i*c#AZ+M+_eu(dFP#K z<$Fq#)Rzt@bkaKyRo5=`GSes=^CTP5{!q1+tV0z>5_wHYlxqrCYyJ@*O3a?$FlPk4 z=sjjE25PPWc(V%xNrGS#2u@iT5V;_WCze}IN<+4AWx-Vs=tnLewTP zHG(8jN7IPkjkA<+rZ5gclBl*R3GAkQAta4q3bWGz&!HKiu$7TOyw+%%8#j_ODC+l{ zXxD%d^Jh;5!JE#8_+tL#Nq}W%BA5fjS$NL>=1-z=%0+MW5tSZ}zikf}T{;S94gS*|y^j4y3Gp#6-vRVAb!`Ve3G~b_VBgVtAutJIf zY4-eCbF8%WIA)wi&A>Ph&91H9M@X^iECwq2&6cyd)+Yv}pj_Ek+u7l)9D~aq#=y(1 z0nyr;SWPUnZvv65u?FV8dZdD}nqhk4K|t03^G=XT&OtG&8i~RRV}6vXfnf+`F$_bs zF;$S&N+R+wuZ=q)a@0JCvavWDfaEeFF%!X@F?iGVpTic`{Ab|bGrIu@#Ns`(Cz=t1 zawf%M_spJb)^K7<5j@pQP)-s?upDXDm6~J5+M=$I%}YWRnrdrZOeoBCMNH&0#cGrD zNtAW5x+IKAQxaX>gp?&Y7C>DrmR$)XXQpgB?B+l$W_IJ@)EY-&iMIm?QZANRJaxsf zS6?l)jIN$%u}Td=K8<19&^qPpRHD0x9f{0RbMh3dlMRhnwZtOkPlzjSn3IUjtBaq1 zDK^2CJ=L#T=F0wR`Rt#U%_bf~bAEDuZM`(aQ|;g^-F(x^;Kh-Y(y4zGcI36zpB zJR!;+!EEB3qoCdfjXX@&1WCetG$k>jn{rSplrT?0>BjheC^meF7?iugPh9hqL*vge z?_g>(p!6nBEoEVo$)g(JaXY5m6!WS`CD>H+ri!p>=GKZdr<)(GSgtW>K2#YPGQV6I z7&d=Y85l8hMSkqLQp%>W%KTHYFL@@?^F;dw>6*R=lNRivcmf}o2mXUAC#qp(o`N0zvCqyY;3NQ_2J8hm zROcfNd#jOecmd)b%sWLZ*oWGn9&G<=qpZ|AX>udSr}*xfJ=MH`;;hRd!#s!t2Od^W zw$>q!!HIcrXU}53sjgd57g&hF0qsC$B(9IZ!Gs>y&Z#?QU@A3o@YbNilshuf24QR% zIaq0cC^s30W{*r}IQ&((mGD?G!) zrg>ZR!Da|#en=lgCixHZ8s@=w)&vT|s|U{_c`ncyEo3z7#=N?DQx^KfnE*nhu^a?x zguJzWIG)4j0dwD6aDn(1#EoOdg;ZfDRfxtljlj*7<5w~daTvKSKxY>Sl0++;My9%P zAQ~fwt^*E1k|^0Uf?7jKw6|$wnj0I^GIHA(n;=P$Z5n~!?5q{4q-rGy*O~BL|xW@em|?38L&?M{<`UTE$_lH;eTd`Ky1zcz^-kPN`rlSeLzwVxeFxluaSF z{6~Ptg4u4wX;~O*Otf7H?{XFmn@B9ud`>Kq?WH1B@v3ARk%qQqj;smE9mun&Mgy@Z zSz`lUZi&OX%(Ux~*yi0BPsyDq-JDYuR>!KFcfdJwRXDM&(~;$>u*LysaB>n0z%h%_ z_$kNBFJL#oVXzuA=PocXe<380L1g4)x2$2RjojM-m|Y-95*pUDynvCS7>>u{;67f; z@MVrH7sIsSlocY67Qln%Qa)v)?bcdn~lm}+AaigivXtrOzi4SuGzObWy% zV3lMw6SKF)RMR~30`x{~g4u%ydrh?s61PDTvvJ3Yq-kQn+)2el=CCSmIeUR*KPo=; zPp`1E7dSQn)+CX9oadK=um6LQ|CUW&#&89A>qN=FD22;o$I0Hh)pCX0@=t?5q~{_~ony9*7qc zPp}wk4407R$@Az0Ce4%Q4U;H7#Y2~TY(Chi zh)KPoInyU#JNQp;tWtt$PS^xwqbGrz$!5b0%9n!K$MI>%pKjjEaU~c_Oksc;Bj!UV zl~k&njM{}BaWV8JK>EQ}dup3LVV;aO*0t#k^K{xI!t{-pTy}Geto#`3dzQ}DKJ0H^ z<>xUEe}ygm#J2gx3_03qKh0>aFXl=U#<}yTezu|5xpK}|8)=+K8%mHQf+jc?^@gg; zK^i0+EdCDdmlMQ7$zoNoc}`FjvnHeZV#ZiHYC>Bqi_?OlIT`boP=M`HIZhH2sE<8j zA$mB-awZGb7-r$Jz|e?^vJr6V;Bv|No3 zDOdV|^BE355FQ--K)3+P4Nt^^l|TYli> zRH5w$wz!#x)1urRf=C}~fg1s5$<);NOto^i8;!Mv<%=x)GUH2QcB)(Gu=vWD5rmCd z^DLs77?)<#pu6d|XVubo42IqBcR@hMTB^}oW2X_&O9n;l6te>&X^ufxso zT5d+SZvFwt9`j3cE$`Es<{hrV>SnHd0hJEL#mFkvz|#;pX7p17&n9&* z5M<A+7na(S+cAhbki8acy_16GXO9>yUE9Yv8}@t~gFi_DQVZfsO#6YZ-OZVv5U3ezSz)(xpFdDaGYl=e-mk)24D}XQ{Q>mM4|5^a!qwT=ymC zqDw-$hYlW%upw8aRR$jy`FVvr&tEj$K8fQz@0_}(P!=oAP<8|XQ5(4ik$HxliQ1VqTpY5`v0MQNAwArbF#Oq3#A&r~ zEuPuy5csp#Bjh0v_RoJ7yQA+wTGH?c&=%F8;nA}T3_6kya|!8;V&(g zvWxAfVs&!A^IY&!L$cyJAt2OFe1PpaO-l`%c2(TNq_a0uMc%lVTN`Pr^Jm}d&e7{4 z0rva9q=7KW3L-%lk|{Cf8@XGkdfj0a*1E?q41%%>1d&!@of~J6aHLfr2q{U^$a*&p zz((!>Dw|y(2q{q0$eC`OD+%XT#vuruXE)IibrYRYH9?H?J#|e{fAThj!XXIbU>6!%D6=_(j}&K*Y;hNb(i*wDm^?wU zcT*H)p|LWbb09pn3$Ve0x^?`!CFiRuwjy%OfZnRRB?NKaE%{UsZaL`)l#=h3TnYr- zErFKP-4c4xrng*_NNP6{HJA#>j3DxE$%Ss5cN5MO#vzE~Zpp<+8p9O2?v`){6cl3! zcT0ToZi%7pmKdb<*4+}rdAEdT6nVGAS8}(6S>NVn3xia#MG(i`lI_HnyjyaK9leaA z!wfrSV3<|9TY|w2JPJ#1m7Ih^76j6Bp8Gi^=g2 z5dld{alprcvk8LH<${#lL~)cUxrxG%t4X%6 z6G!`Kv|4SD*Ilr0j{7rKA?l_W#0#@{BKKz^svJ{|*aThoXTs|K%vU^rZ8_8MvsxDq z@ok&sqdF?Z{U)go-9X@*HZpBxA2TrPsGBy?eS{Q?%9}P0X_}udFMCG^hO!B^NXssO z$)zd9sKwDxEVyqck*v1N)V>{@8m33tTQoQx8m1Dq4i`6ie+?es)B%A?lPjz4z|`<| z?Q-SASqfN6$eaQUCwYsKZ7-cyM4Y8rH>!^rm>@0P@M7r6`!X>nMV5S9n4YdSCHU%tBDY0;lZ77YUne^4v)0l#U5f!lsnH z_#$Cb%U*nuuxVxQwn*4?^IdCERoVJ*DW=@j7FiIB&2kr1EMU0o1r-YzkzH-wP4VJx z$_Ky$79#MKPvCCKG|ZfDhvj;wVee^S?ht3fhIRvXzyCOQQ>?A7F-vS~tBdcZJOhr# zE;Glwo6ci0tDaEvg*r}-DVhCyN=_~&??cjJ=EI0KH7ZC$?juOgcEFf@KS&Uw ztZn|g{n>v&YQiyE-%nX+h#Am}I>^G4y&w6ZW&a7;#6|L>M2lE4!m}m+v?Mdo_OMyA zPTis9wQBQ9o$oXj=dx1)$Czeqq1(q8zZl<>&Fd-OaT9MD%!DxSL9RUBttwB)IwEk) ziLe-Bsma2{>r~dI(lJat$jnUviK%=`)5#Fp{Q%m1>ML>z62~TBX0uM`A+F*cF|<;I zA-6a_=rsPL{SIIY*tD2bB2Sk3ip32jBDM0`IpMfwBtHgtQB}Jgs;#sBO->$hB79Ak zw}VM9JW?&Dxw5D_U0w`*kP1$i=cWmj_mxig^}1*`<^aXi68ce!L3!g%!Lp*|X(@^Dt};mm=&Ca~^(9Q>M}LD$Ih)wqX` z9k6LC&vT%yIR3=g^@!Cd)4*jiC^M2kr9AOa?Z=GGG#uX!!0ZA+)TVKbJQsz~+qTO zSkh=%L)#=fr?ft%VjZ5@CrFAM?x-|3!RqybjFVh3r-WQXxjy;k_&RaEM^^8ZkIBhT zpt5pwepHFhMAohHvj^$h66hOr3uAgN`oQDZDD=cNxgqFJ9!0IBte?cQIbcPgWGy+k zKSlv&^h8F+bl{fb{q>9s%&bzCsP1D1mOg4+5ah2oF32WMK9O-DRsIw=pF38%41Me`^VGpHmTvbuQ9iHJ;PG(iN%ak(&KA4-Q7@wMO{#_2g_Jaajg}0 zG1$4xDmQ0HCb z$v%VxJ3i*WtC2Zxk0<+SWXp2^UzXvgc$56eXM^LX9_XL}09pC(R1`KeT%{hRr55AVd|3@u`0zW~f;Z$r3A zpAhz2jXN6`tFJ}AiM!)+1{;Ulr6+*1p@{Q(+Qah`{184j@~{)fn{04(EdyyE2{Z2B zVa!frc|AgM*oj$W&aI3?kkTUzKeff5y$uL78{UrR z;38<;eH4%dc^o;iz1&XZJb@gmjoeQQ(5ILru;gFo7H!;@S!XqZUy=&1v#`HiTxVT^xG_vQYMpgyF-NVGu+DlL zWgasiwi8%q5ryNgv$hkKz0SIflf`wGm6Yo&Vvmo(ip`6#SZXuzRtTC`|fhXx@@!9JZM;3`%=c53*&L~~Cz=15KiFFICl(msc zEb6>(dLru9|NDaR-J5dI1ZJQHT5DOE_+FoaNea;jW1SHcpJBF z2B;aLio%15QZ1$oT=LxuoHt`ly(~;Tq=ZU$}LzqAo-11aDEX15iVlC>s?oG7swlL~|3D zYGKM3L3$yvpq3=CrS?L6t#x&f!W%u*mhZD{&j~(-0sDo93xZKBbE)12uJO0v&=5~C zZ&T`s^T$FIj-nPw50VLq|6n7Ne`uJ#cED{11xRDj?Efz9m<`~R2sy3 z2hB;80_^upb1rWD*qHOgHV0-irHYs<#oHaQ(_l#m2GwxJDarK?aR>Gc~b&Jpjcx&xu8{y=c4__hD;-~`bv4kNr%d$e~)kh=XVBPLHv7u>^6$;2fGbJ z{3nOgJOSjqCqy}Gypa%0Sg;1+PXp6KRC^2J-C_~K8Tx4m|Ci@1g#YZ_ig2N)8{uIe z<-gra@e2)t{>q@7m41r<-beYj_$lW_|89gIG$=~{v|ao7*nIVjS){?kf*xO!DMF7_^xuoO}g#E-4iZ)4f;WKq*5VbS=W z@KkXL4c~Ve2{(%0Ehfy{#Cg7va6&9xLMh4T4Dn4)Nj^^!KeJNA=Pcn} zN|=(*Iil}WN*xfX>UV^b;#n(2yv!GWuu{a!0x@p|VM<;WiN&0fyetxTtt8m{#k297 z!);>fX_Pu3ei}L$ULxMbsrMr_0_}OoN_{eRD13@|#!5Yn)C%!CEA^d*RpHYG-ApB# zze8$`_?eZuG}Ne{DY{OVHEgN7KYX_6<<$GduYyOz=ZHfV?1O>Ng*S>^HN22+x ze|jV%zRD>{<#O?D3)bTQbNF)cFAi9r_;(9d9eBpuCuW}~sdR$t-C`A|B$a-#-hw@- z{W;t(a#rdp&!59t@g7bcV7Uy4I~?T(#D^@*%f+n7fVj^}&C{DASBM9!)YG0t5mP*9 zrGD*Q5y^?qSgDWtnj(4exRpB9voLsHovRCZ2 zQtSMSB17V8D|OJ{6uC+~(<#fn>RTHb76ul(B*FjmpA)%SOtn(~V62Udh)q^1Ec}sc z#3h`Paw&*j3$|X{8YzhTI3*=9DvmlZN5#VyCP`vcJZ7ax64#0^St*jlb>b^liX?Hp zc-l&lB;Fx@V5LYBH;Bkq$u&vho#H|(MUr@zc(;`zN!%!Iu~H<7cZ=Jt6iMPe;-T{; zmF1AcP2v|;iX^dLykezDO79gd7f4K!#4Tbar=%nfh_x1sBym8zgHuuxw~7M}%v;4l z3v)!gEpn?kY^A=e?TXwk?zd8RLbKj4K5nHBi(KRm@radrK^u+SDZXo^{#m>$a!|Zv zrRua? zudLKb#(N_l7SU~zv#%R>Mm{2@TB*679H zPDz@d5;t2gvP+*5hpZIYrH91Fuxh4pM0V-Z;;c($s#8pld{&HdN>X`P+-SkbER*+UsUghoOdy)qqsL#n4v>cE;=8OT-)0Fo!z(#o_TBfHtGjCn z|FaxFkIQyB%6^iy#YsWN=>;j8h;w_L;r(3WZVsgmIO9&;koogj_d20_nvgk?Ls{>e zQw#C0i#6QpPdC_c*;1X`LXy#h49Dik{7SNN;ydF`niSWCQ}WK7zkZ(@SgHH*3E&gL zCn#uD6GQ03ZX3mCAPk9Cgf-Yjps=084i3-ba2tmy4l^8H!Ql|XdU*Ck=ODr<;xNaT zYq!Q`h#NWnu(-ZvwOFpV*L5J=5bDP6|e=lz1P`q8Q4L532Io_c!t!vjh z^k3I?YqP}n>NN2()0rhE#jeqs#YgIH(YEQyy7y@>i}ui6$XQZ;Idu9SL@T;^&9HKdMo&>5!>{-x<>tZu`f7B-=^Ibx(8+V zRL$3CF@;N*0&#MhzD<9B;4Fmx*d~O@x-AIn>MjJey85u*p?B21O((AQfbzWHCWH?J zHt8Ff!{p4EE{V1^4bCYQBJd5x&@AID9IsYyWJAmo+{=LN1_t!1= z61S_oALE>d#M0of_Yo^jEqxMkO+3Uhe~RUHQ2S=phrCaUp@0uk`a$)Fz1y@egg)k- zp}ko9N$)e_r&UiP{CxB)-fjAI6TgY@k5$hA=j8Ygz5m3N+x7g!-*^vee+W_8eF4Mw z6ia5C{%?e-@2`saw&~xho8spdL3l%5hw)WCAH2l4Uwo;GWPZoQZX*IrP5e;*PR&)u6WZDJoAikG zld6Jog?3lnUe7lD&(RwYpAvk)cwYFTM~xTs*60_Em-H@h`?9{E`fG;f*%g189|17b;>X?5qdSOyvoA!~=jKE^CYobqI49TAyn1%d; zF$+@iiCN-Hbx(SyYBXy4G#WL18jY0m^ia))z&8DR@$-OBW8t8dhpukZ!{K)aCVA>= z?h4$mQR_7Q_V^Ql7)x@J{%GwC#69)T1!j1jul+^fYV8KloS_G*{}lMD7^xM(xt@Qo zn-ZL)-B;Thyop<}QX?K#YF~^_3f!(`s_xNlhcs@{R%*m;l=u6ibQ+7}nHe0es`1gK(z!4}?wP6@+bKZB>g{Aud9=hU4dmorrge zA0WI~{2XDAm=tZn+MB|hm>*puhCy=;?C_T(>#$2ZDcr+3J)F}6|MYOQ7w7r!kER)V z9Ye2U=yia8C3+aUFN4v0IsabHzZdy0M!zWD1Dem_EI$+dsTC6apK`v?DBoj+l<(09 zeD|qZ}UQ@Cgo|=THPs0=^ccQVEXF;P`5ew{!e5j;A|^Yy{7jD?|Z%P_deqNsrP!{J-!EgKljxdIpfE8 z=iy}k0{ZpL#7J{R-n zQn3Q?L42+h1NsVlmW!M98^vM$pqS*j8=oe8=8JYutLXM@6fb!m5YxTO#X|29k3)WJiuk^d_(9OR8=qf`fAYO3JjVCMG~ffx7?;Ya8o4UUa#ld;RXy9cug&BJ`cgw{`ck=ED`%qGMPmtYR%wAYRRApk zJttSLR+g*FDp4vrCgaN7xqW*_t}|`22vXgBX_DgA5PhqZ5lIozij@=4*>bDc!tEu6 z9CEZ!S_!42M2^UEQX`a7v2Z!+2ryYeJ#5y;<6LYS?CYZ@U)Cx**7XnWhMvh(XFk<) zIda!zcMqh@OfK6`DE&QVdUv`%pXxh5)i;k($0Y);C;#gEc9>{0SMPD+Ct==w0BA`?Hi_qqLn^kz>_L8EG9wn49+HRF=ljU4W z$Aj2{L%~W2yLeh8)(`ggT((HC%)15$&|Ql}drv-tPFW<@W;m8IhmasCfoDi*QHhiQ zLnW$h(0S-{NAJ}|7F*jYNDlc*a*R?*atd!dBB~m)L6jaV8VkFPpylkF1&3%Dp+co? zQZz+kt&7W3E0fQoo<{n)(7xU2eA=WTkMgRqOsYb?3a@Q@g$ivtwn@*}}p@)r0ZD znTq`K^5l{2D8WeOssLbPws){Ey$bX;i|wL4k4uK#nDW=A@+pz)Ms|Nn;7(~}5Lfnvv;JJ{Wq=~0UdBC}jH5rcy`;sED+c6sVXIYt!9>J9n}Jq6SgXS+cPd6J41+Je4A1SIUGC z*3-OlW!Ajh2CUngPxt3AZ`)al#CkAzKK%Bwz>aO6foDjCEb_W%P|LBH4;u? z?_f{frl|mHvI9eAX6G&kNV%qH75!FNxiWA~`-g16mcjmfW_OzPC7`m|8yhE(-OYKx9q-&R%PW9pnx5}_;Z?U?E zAYEB`%Nr4E8Dyo;9n9_Gnm4fN5bOGTa~EXty9Dg0nU~R2A6cBvG=^I~(*whv?h~}) zlGZwv&zdd0eSM;%b7*%rzO)8hWpS*Wj`f*zAG~S?chGoJaq2xDzg7kr3}?E7oo+`7 z8i%Sd`fwm^=7+3wPSPg~_N2I3QCyj*%siMr0mS4ut z&Sv_BB}Fc@Zts8z0}o`j1sPco=7dHy6Ja#je3>S8oax={Q9E;#EwJao;u4V9f;{Eq z#iBSKlI?@LiCA+jMwB(zGNYTJ=@|^^mQ79wBstYN#hCyU zc(x#*V;WQw1;D77_FfQc>5(Bntd3oqN$u><<}f~UMTOy=j$%!6MlFFlsw#yms|VS^ zP?kc^*)!kisk+}*=D7b&Qq@v1pEhqZb<`tQ_oY*ZNWcpK? zevqSdaq`SzX-mrN$Z+(#ONX5(t{nvjV5~#TQnB{YsF_7(*@}QY>q*iFYpl>Y(T=g0 zgN~F4iuJ*E#iegx;g~zI<8&9yK{jKRV~I=v$`*q0aUGiEMt zC$Ss=w=5mldKFzWXj*Yt%uEls%;imVn?zib#jK1OG>17ubY>}#zB|nX)Giw1^dMoj z_dtZXtZ8Rh^56{S29|GNFprhUP85P(^P*z&V4gBJX7{8wrT0=5yvFIGIML;ZLr03X zp*YF&v|+g#V3RglVaLc>fq7Q>#bUAvD!WH|C>506vb-&_jG&=qMcE{=Fl_a(KpU|5 zG*eJ{HS<~dyw1Xa&-Tc9iOen-9D_$bIZywNDbFH7j%H^M=I~w~<+Owwi$vwe0V|79 zzM!u+MN6px5;tT!44#-$&DO*^>l!#Z2uhM+dFO}!eL6xOE zdsW zhs8qtvP%M|E);J?T=R6{g}*CB7rrqiPQDVqDUuc@J_+O`#HsiUihi+Mq!6a?jm5O+ z#R*E6z!iUgm$(=wD583U$l!E8FDxppYmx3jIwP`N$`nHkI|rqQL^IPqAJqClJ5BXY zqmmV&+udAAyh^+!a6;s4gI!Oh5+c|QKC|Ek$7WU34ilXB)3-A{EkZQr0UH2+LkLMO z)Yb&xgD8PAg>NYVtLMdd5i%C}U?U4*bwGFnKung+-3*u#R8F+u;@M98qYlX7Uq7H-oF0x9nBpbFZA+q*>|rWFToGTY*Vlk9^>&)|n(Al~n=B1b zII^b7^^7ME#S67D54t8KG9J(S%CtwUP%WS??g6(c(2*)Yj(9e*o&5xXfe)D z#ayZTgWN{K-i`0sQM<=r7k=~Rs|cyx4lqx{EO2Jedb_nGT^2MikH9` zQXL>wK};#dSLtEABtga1Q+T!u(WX+Bo;{F24w6u&9N!k3TM4%`UwAOOtJQ!@gLkC; zNgf_zc`0_Kbm`C)o)tnYsf1mc-wl<10zK5RooYo*dE->pHA zT;Tx)I^L6vxrwnrm8#0gEX(RMuoz^>$u8RCZ5_s05AtjSpTv#Clh~ZwsDm1yA zihrs)x{l;4li zWT=U2GOOcL+5%j{%0MbPvCm zIbf!^9%Vy9P`P2pgo3Y~I#T2|swpl3zDY&NeN=h&gh!YQEvT9t-OyGG>XvdRB%xd` zH~yls_#Lb*_H-=!)?Ko#Y)Qpc3OY!#qLz~rtcK4#XtYgd0DVSy(t{!`wEZcPAvqe- zhe|-6G~JTVR>{LM9h9ZKsrE&vokq|wuG6a6;$mz`F}AcAJEa&~#xcdadJ?VWMVwZ4 z_+<^P+*TF0Yi@Pa-74(bTX89?oTDM7COIPc5l5=_eO!Vy-?9P^V0 zUyHlkZ3rrvTerz>u~v%bW5CH3k&2-_+uJfxsQDy=hK3g$Nz7zf({#a?Gx0J*JB9XM$k5LYKVx!|NToeTL$GNbG*K%6%Y2=mDaT4EKBT;R`SKci7?;DBbR~*7e zuC*w9b`>@WD-ZAg-f=6>RmyqQqVUdD;Qw+g6$ValIIFqCHU@OI(Tjgci;i;RNivdh zi?A!NU>w%`<+eeLPLb0+EeB2Bwo%L;&$7u9&Q(%nd#0vASw@{FsB@0v*;rd_(r&xA zE}gbs@&4LOLn(c=rzvWays=^Oo}*=vugjc{KC+8A1+WDcNgc|Rns<8?DkjU>GzD{t z^8eN29b1N#Jwzps(r2X(F2!^D9;L9cJ)$s_y5_M%LiSbe^Bv!7E8S76P$IvQI3C6ctH_T&o^f!r)pErzifZY z_C&{-(eTxazrINmvuSFhI}hc$K(!XHt5mFvhju*Okrg>@v(uuw=TlX+dLECq)T`G= zyHqFDR5MQJoK9|%-5yDyd<)9z@ig~VUneXYU0<>GnX5LSOVs*G;5C=D8A{6}ac%ak z&A7KV<9c8jPW-S(9=18J(u_Umskjl>t~TP_ROG=!xub?Ln{b80Z;pvRQIqU$2;D3a zRdg?67q$ZEY>e(w*cQQQQ7(WpPIoEj%!Mv-*{QiyZuA=WW}9+YY+|p~$97iHf;WAu z3X?EC&TY84#iLI578UK{SGomM&X8Af;G8Dxjp517r#z-|J7!M)D%WYt7Wd!^54bI` zT&$A!uWr8(I`y6G#oZk1M`)8d-m*uPq?ZVlp1mbOTW%sb8FuqTqNI-~d_zrb>iOmj z6IGjfzW!n38Z_4qRbGMFiaU1PjP>`2AsxkB=~E4<8IB%n5oe)SbFP(nWeVd_SG75N z@68x?s$TW1Gz=A7J)Of+<*DZz+Xi(Tq4E$_^{S^mqMUmsuXofas^wZN3cplf_58ni zB#q;Aj?S&TBzWV-n6u|3GkE^VjCVlVja3yn3vw@S z>~ujFENzjn3vulfw+lgFvYFkO?$xa_cTdxi30*$OyKbI2apdhu+aiu-B zvzwOFvZ{Ryax_SXLg=VB<5v85Dr4V)AKOb}t5aR5pE@e``AYPmR6ep8m1RRa{vUCx zoKviBCs%C<$^$(oUUHl&oPM0G?XPvv<2Fv=Z(vB<{ZoEFLY$T?Ui;sS6?-3g!Cu=t z`=l4TPPg@_AB$I=3LkR!g>#76Ti7(@)fNQ}4h2c#=t2^8D}8xZ?L8>FSDcF-8Y+si zq(^=5zyFrTNTr4;p}dYB7~Sq1WV9G?I*fm7{qbfREn0h0`^kWp?mirESlGHIdYtlg z>YM5`xwv*~pSu?-b$f9bokn#yX}hVFw@A{uCGqtGnu+)Deke@~qS_w7{0+20<<6+* zn=vHB1*$gne1q0)ODgq;)4sdsfw^UF^W*Cxkb3!lYSCuf8IrZMV)FVCC|*;(tetx$ z+yk}wV!IRcwXip0FGMV`YbqZj9kMSrRQ@_i=@)M7R-=_oz|L^R4*N}k!Pc@-ds$bnpmuH4*vR&x9HmPW-=lC@$EaxO> zFG60ML`wTy(N<4+3tXkf%0@v>L<(JS8ix4$9l^7w1^&GC5n+Z(0!l4Og+ajP_9lCRO0j<=^WR%6E>Ta|QzJQKQzNjreY8#9&K zMV4S4EVfhoE7j-TG;nJlEx_z=6{RHf9DN|*Z{ zp@OTY#G{s|9LIM~V$Ovge?M<|`NMBIGd|Au>{d`swkA||&z;KyvI5v-ncEBc>g5RZ z6)bh?Vt-l7da*}`YQ^!M$6Yc{8*jNR!nEk8@9*OK|9+ZJuy5E<{=1DLY<~}uaLU~_ z7BMAP)iN=&G^ZVlE%}{W(pRcqR5@p5QLjpL;Cnsvg>bTecCOrE?na&|#Ddqh-6*g$ zYFq#HPyF~JtMC2fj%_a=dGE*Q#RQr+p=kjhf>=F8qrQZ$MG+#SgTiUiiGIC4meS(s z`dCJ*kL}juSJcM_kq#sTWyP);syiCr7me1(3hzJ*@VF5i z;NLP(AJw89#tZx7g##3SAFx+O12Q*l0}oQxeR@2tPpr}O`uM1io5T$xz;vN2jOb)) z9%E<5!g6s1u3f5@)(#Mvn%O2Sq3x)f-3?SgVT#SrNiT z6)qgD19piH7milDRJCx_=Z6H2f=94+u76_uEEF0=))DA$yznJfQiPtN<^bou0kH87C)m=tA$l7P&xp93r7)AO*;bZvX$J@b*uYX2uD|+7mh%Q`3bEf>jg5afe)yL9?;`xC_2$Oj+xN|O!+*o zABFu1JrIqJZY6~dMC<)Nm$YSqyYRpn{#d+AHAZ#b_}y08XCMSktpbsva;Ck|k93Ia z!ss?FKB_?$GExIH=;ElfGx5=2qr)mF>9cjR>=E@9G;1_yNnkXn(-V`HFr2XJEj+B#2(@fkeDqQl;SVFoD-K#Nn4(@A&FDt73d1#Ccotom zjuoD#K1Q5mUU;5{b}ifkNS-N1C;5$d;pg$f3-Q8l;)RzmUZD%WM?b#6ls34wD^aRV|hi5Ff5GmsJS1>k>aY}jcy z?zfZ|KM6G&V@Xm(Wya#8^_)o&7QoBU!l`7$K?7O~a|$ENrZ_-Ps-qfDnpL==sKHP3 z1D;Aj_jBd%qsqHbrq`O#cph_4XMIeON4=z7*pDYoX9Lz8SDeihJYF~$aTtd*Szj`& zfm%`L_s16(DUyn(c^pt9G!kp!0JR9oYQGmPBtx_xl^-dN)BPAafdIx`AP^89^d$yR z(2ps45U58Yesr0#R}-m!$$rHP-?rc~je-F#81U<{!at%%(ZPstZ==>n)mU^FD|Yy3 z(CYBfV2G-wo*s>{RvfUAVhTw@>Wc%du-_VJh5ZKc`x~8$9z>JT)R#f;zq9}=ER4|I zvdfU9F@lHe_<+xki90~@+*K;iFnLgx=mJj-*S`9V`OlsgXnkzi`A3#+S`zrg>D#Y~ z{bT4rLMblI`3XHWOSr5&L#pn?|qH>Q=hpPnH`y$c-otY*5 zJ_17L;&UPULB$HvF{_|$<5X$bu41&RSQ`&cRof_y#Ttu3ageD}h5d>E^;(gW{koyE z;?w8T;4KSshkazDrg0d%v`Tp3>`F1lhWx_I({2#+jE(V%=(5l!mHAV*** zV-baoHl}4w`{{vRlojqr>%G)j0S&)-Mt{>ap@}Yi!Ubk(U=zLg)p~C@UPqt3GN%Dg zXS_2tF{x$Kx-PshmVdgV*?OV+X?qs6EChvUUGe7$tTzeM>t172B%#VAfQn!EtT{V{ zpMSb=aBX@|x{qGHDnvvRe!S>EjkmE1F`(gvEBwaXMDYc=3H)9`BEKu0*oBw+Cs2le zzW^^tPJo?6U-rsG4nH@Rz|T_PcZ(8uH?aKiEqa%2BA4wOq)2lDKQO{SBhfd+^tR$< z=|i|OOtpixme!Vqc(t7-S~$_vyR2>D;^p0Ki8x?@K=)w49cWNCU??Sv-HTJbZ8!vY?>iwQ*dgEWp6(^I4Rt4kMl~Og+GJUO*zsm}AHA^`FB*biC7;wB zi%%UW;k!UQ~3dP7Rcsr@zg0T5ii&kyK_BR{9FzHW&@XbbvB5Uio#9pt<;+= z0T?^fI1zWI+!gcq##=7N<`dpo_*@9B@8!WGOZIvfBXT}2l5I!04j0TiarJLAUQM_i z&rM=I;`H~Z_r+s!#L#FWt(Q-{2buqfB;`2&)*_*SDs3{a$NdW0aHbdk(N`zvZx)YY zI!2+dr{w^r8$j~=8jK)5;eC?kP4HyDB5y3ELyWT!?Uw%*%m4mP<3_(=-pTT-DG&@;n=Hs-quTFvtg2^m=9DSiZZHaMt73 zOtoTf$*tWU=GcCZC*i3LQs)aLmHY_45PpD7=X`FpdSx8J7lGr2__Xqq>a7JnX$Nh` z())i&LN@o~)z<>a^Sh`)cRkC1zT&u(DbS(v0OUh5ryj&CcS3U5#Qbcw%E=z=E6Rnq z+l@NLmxGh9RV>$YL62UFE#EP0w{Cnos773iS2JqDUA|PRwoIE)$1>3d2`|RW5W5ju zESBP#LbwC6Z$(J25v4CLEyZ&Qhs#jv6nt9o=|&!XF=H{pUX-W5W!$Ij&>_-ddONbz e#>#w9AHVhYhDhK!xIG|rHD0#&*5Chs68Jx8;VozY literal 0 HcmV?d00001 diff --git a/Nino_Unity/Assets/Nino/Shared/ThirdParty/System.Buffers.dll b/Nino_Unity/Assets/Test/Nino/ThirdParty/System.Buffers.dll similarity index 100% rename from Nino_Unity/Assets/Nino/Shared/ThirdParty/System.Buffers.dll rename to Nino_Unity/Assets/Test/Nino/ThirdParty/System.Buffers.dll diff --git a/Nino_Unity/Assets/Nino/Shared/ThirdParty/System.Memory.dll b/Nino_Unity/Assets/Test/Nino/ThirdParty/System.Memory.dll similarity index 100% rename from Nino_Unity/Assets/Nino/Shared/ThirdParty/System.Memory.dll rename to Nino_Unity/Assets/Test/Nino/ThirdParty/System.Memory.dll diff --git a/Nino_Unity/Assets/Nino/Shared/ThirdParty/System.Runtime.CompilerServices.Unsafe.dll b/Nino_Unity/Assets/Test/Nino/ThirdParty/System.Runtime.CompilerServices.Unsafe.dll similarity index 100% rename from Nino_Unity/Assets/Nino/Shared/ThirdParty/System.Runtime.CompilerServices.Unsafe.dll rename to Nino_Unity/Assets/Test/Nino/ThirdParty/System.Runtime.CompilerServices.Unsafe.dll diff --git a/Nino_Unity/Assets/Nino/Editor/Nino.Editor.asmdef b/Nino_Unity/Assets/Test/Test.asmdef similarity index 59% rename from Nino_Unity/Assets/Nino/Editor/Nino.Editor.asmdef rename to Nino_Unity/Assets/Test/Test.asmdef index d7c3961..6a9304f 100644 --- a/Nino_Unity/Assets/Nino/Editor/Nino.Editor.asmdef +++ b/Nino_Unity/Assets/Test/Test.asmdef @@ -1,11 +1,14 @@ { - "name": "Nino.Editor", + "name": "Test", + "rootNamespace": "", "references": [ - "Nino.Serialization" - ], - "includePlatforms": [ - "Editor" + "Nino", + "Mongo", + "Protobuf", + "MessagePack", + "MessagePack.Annotations" ], + "includePlatforms": [], "excludePlatforms": [], "allowUnsafeCode": false, "overrideReferences": false, diff --git a/Nino_Unity/ProjectSettings/BurstAotSettings_Android.json b/Nino_Unity/ProjectSettings/BurstAotSettings_Android.json new file mode 100644 index 0000000..ce2d8aa --- /dev/null +++ b/Nino_Unity/ProjectSettings/BurstAotSettings_Android.json @@ -0,0 +1,17 @@ +{ + "MonoBehaviour": { + "Version": 4, + "EnableBurstCompilation": true, + "EnableOptimisations": true, + "EnableSafetyChecks": false, + "EnableDebugInAllBuilds": false, + "DebugDataKind": 1, + "EnableArmv9SecurityFeatures": false, + "CpuMinTargetX32": 0, + "CpuMaxTargetX32": 0, + "CpuMinTargetX64": 0, + "CpuMaxTargetX64": 0, + "CpuTargetsArm64": 512, + "OptimizeFor": 0 + } +} diff --git a/Nino_Unity/ProjectSettings/CommonBurstAotSettings.json b/Nino_Unity/ProjectSettings/CommonBurstAotSettings.json new file mode 100644 index 0000000..0293daf --- /dev/null +++ b/Nino_Unity/ProjectSettings/CommonBurstAotSettings.json @@ -0,0 +1,6 @@ +{ + "MonoBehaviour": { + "Version": 4, + "DisabledWarnings": "" + } +} diff --git a/Nino_Unity/ProjectSettings/MemorySettings.asset b/Nino_Unity/ProjectSettings/MemorySettings.asset new file mode 100644 index 0000000..5b5face --- /dev/null +++ b/Nino_Unity/ProjectSettings/MemorySettings.asset @@ -0,0 +1,35 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!387306366 &1 +MemorySettings: + m_ObjectHideFlags: 0 + m_EditorMemorySettings: + m_MainAllocatorBlockSize: -1 + m_ThreadAllocatorBlockSize: -1 + m_MainGfxBlockSize: -1 + m_ThreadGfxBlockSize: -1 + m_CacheBlockSize: -1 + m_TypetreeBlockSize: -1 + m_ProfilerBlockSize: -1 + m_ProfilerEditorBlockSize: -1 + m_BucketAllocatorGranularity: -1 + m_BucketAllocatorBucketsCount: -1 + m_BucketAllocatorBlockSize: -1 + m_BucketAllocatorBlockCount: -1 + m_ProfilerBucketAllocatorGranularity: -1 + m_ProfilerBucketAllocatorBucketsCount: -1 + m_ProfilerBucketAllocatorBlockSize: -1 + m_ProfilerBucketAllocatorBlockCount: -1 + m_TempAllocatorSizeMain: -1 + m_JobTempAllocatorBlockSize: -1 + m_BackgroundJobTempAllocatorBlockSize: -1 + m_JobTempAllocatorReducedBlockSize: -1 + m_TempAllocatorSizeGIBakingWorker: -1 + m_TempAllocatorSizeNavMeshWorker: -1 + m_TempAllocatorSizeAudioWorker: -1 + m_TempAllocatorSizeCloudWorker: -1 + m_TempAllocatorSizeGfx: -1 + m_TempAllocatorSizeJobWorker: -1 + m_TempAllocatorSizeBackgroundWorker: -1 + m_TempAllocatorSizePreloadManager: -1 + m_PlatformMemorySettings: {} diff --git a/Nino_Unity/ProjectSettings/ProjectSettings.asset b/Nino_Unity/ProjectSettings/ProjectSettings.asset index 7440861..6e77f88 100644 --- a/Nino_Unity/ProjectSettings/ProjectSettings.asset +++ b/Nino_Unity/ProjectSettings/ProjectSettings.asset @@ -3,7 +3,7 @@ --- !u!129 &1 PlayerSettings: m_ObjectHideFlags: 0 - serializedVersion: 23 + serializedVersion: 26 productGUID: 68b1aad519424499bae0af33f13e893b AndroidProfiler: 0 AndroidFilterTouchesWhenObscured: 0 @@ -48,14 +48,16 @@ PlayerSettings: defaultScreenHeightWeb: 600 m_StereoRenderingPath: 0 m_ActiveColorSpace: 0 + unsupportedMSAAFallback: 0 + m_SpriteBatchVertexThreshold: 300 m_MTRendering: 1 mipStripping: 0 numberOfMipsStripped: 0 + numberOfMipsStrippedPerMipmapLimitGroup: {} m_StackTraceTypes: 010000000100000001000000010000000100000001000000 iosShowActivityIndicatorOnLoading: -1 androidShowActivityIndicatorOnLoading: -1 iosUseCustomAppBackgroundBehavior: 0 - iosAllowHTTPDownload: 1 allowedAutorotateToPortrait: 1 allowedAutorotateToPortraitUpsideDown: 1 allowedAutorotateToLandscapeRight: 1 @@ -74,6 +76,7 @@ PlayerSettings: androidMinimumWindowWidth: 400 androidMinimumWindowHeight: 300 androidFullscreenMode: 1 + androidAutoRotationBehavior: 1 defaultIsNativeResolution: 1 macRetinaSupport: 1 runInBackground: 1 @@ -85,6 +88,7 @@ PlayerSettings: hideHomeButton: 0 submitAnalytics: 1 usePlayerLog: 1 + dedicatedServerOptimizations: 0 bakeCollisionMeshes: 0 forceSingleInstance: 0 useFlipModelSwapchain: 1 @@ -119,8 +123,12 @@ PlayerSettings: switchNVNShaderPoolsGranularity: 33554432 switchNVNDefaultPoolsGranularity: 16777216 switchNVNOtherPoolsGranularity: 16777216 + switchGpuScratchPoolGranularity: 2097152 + switchAllowGpuScratchShrinking: 0 switchNVNMaxPublicTextureIDCount: 0 switchNVNMaxPublicSamplerIDCount: 0 + switchNVNGraphicsFirmwareMemory: 32 + switchMaxWorkerMultiple: 8 stadiaPresentMode: 0 stadiaTargetFramerate: 0 vulkanNumSwapchainBuffers: 3 @@ -128,12 +136,9 @@ PlayerSettings: vulkanEnablePreTransform: 0 vulkanEnableLateAcquireNextImage: 0 vulkanEnableCommandBufferRecycling: 1 - m_SupportedAspectRatios: - 4:3: 1 - 5:4: 1 - 16:10: 1 - 16:9: 1 - Others: 1 + loadStoreDebugModeEnabled: 0 + visionOSBundleVersion: 1.0 + tvOSBundleVersion: 1.0 bundleVersion: 0.1 preloadedAssets: [] metroInputSource: 0 @@ -145,8 +150,10 @@ PlayerSettings: enable360StereoCapture: 0 isWsaHolographicRemotingEnabled: 0 enableFrameTimingStats: 0 + enableOpenGLProfilerGPURecorders: 1 + allowHDRDisplaySupport: 0 useHDRDisplay: 0 - D3DHDRBitDepth: 0 + hdrBitDepth: 0 m_ColorGamuts: 00000000 targetPixelDensity: 30 resolutionScalingMode: 0 @@ -155,13 +162,15 @@ PlayerSettings: androidMaxAspectRatio: 2.1 applicationIdentifier: Android: com.DefaultCompany.Nino + iPhone: com.DefaultCompany.Nino buildNumber: Standalone: 0 + VisionOS: 0 iPhone: 0 tvOS: 0 overrideDefaultApplicationIdentifier: 0 AndroidBundleVersionCode: 1 - AndroidMinSdkVersion: 19 + AndroidMinSdkVersion: 22 AndroidTargetSdkVersion: 0 AndroidPreferredInstallLocation: 1 aotOptions: @@ -174,12 +183,15 @@ PlayerSettings: APKExpansionFiles: 0 keepLoadedShadersAlive: 0 StripUnusedMeshComponents: 1 + strictShaderVariantMatching: 0 VertexChannelCompressionMask: 4054 iPhoneSdkVersion: 988 - iOSTargetOSVersionString: 11.0 + iOSTargetOSVersionString: 12.0 tvOSSdkVersion: 0 tvOSRequireExtendedGameController: 0 - tvOSTargetOSVersionString: 11.0 + tvOSTargetOSVersionString: 12.0 + VisionOSSdkVersion: 0 + VisionOSTargetOSVersionString: 1.0 uIPrerenderedIcon: 0 uIRequiresPersistentWiFi: 0 uIRequiresFullScreen: 1 @@ -217,6 +229,7 @@ PlayerSettings: iOSLaunchScreeniPadCustomStoryboardPath: iOSDeviceRequirements: [] iOSURLSchemes: [] + macOSURLSchemes: [] iOSBackgroundModes: 0 iOSMetalForceHardShadows: 0 metalEditorSupport: 1 @@ -226,8 +239,10 @@ PlayerSettings: appleDeveloperTeamID: iOSManualSigningProvisioningProfileID: tvOSManualSigningProvisioningProfileID: + VisionOSManualSigningProvisioningProfileID: iOSManualSigningProvisioningProfileType: 0 tvOSManualSigningProvisioningProfileType: 0 + VisionOSManualSigningProvisioningProfileType: 0 appleEnableAutomaticSigning: 0 iOSRequireARKit: 0 iOSAutomaticallyDetectAndAddCapabilities: 1 @@ -242,6 +257,7 @@ PlayerSettings: useCustomLauncherGradleManifest: 0 useCustomBaseGradleTemplate: 0 useCustomGradlePropertiesTemplate: 0 + useCustomGradleSettingsTemplate: 0 useCustomProguardFile: 0 AndroidTargetArchitectures: 1 AndroidTargetDevices: 0 @@ -249,6 +265,7 @@ PlayerSettings: androidSplashScreen: {fileID: 0} AndroidKeystoreName: AndroidKeyaliasName: + AndroidEnableArmv9SecurityFeatures: 0 AndroidBuildApkPerCpuArchitecture: 0 AndroidTVCompatibility: 0 AndroidIsGame: 1 @@ -262,7 +279,6 @@ PlayerSettings: banner: {fileID: 0} androidGamepadSupportLevel: 0 chromeosInputEmulation: 1 - AndroidMinifyWithR8: 0 AndroidMinifyRelease: 0 AndroidMinifyDebug: 0 AndroidValidateAppBundleSize: 1 @@ -361,7 +377,105 @@ PlayerSettings: m_Height: 36 m_Kind: 1 m_SubKind: + - m_BuildTarget: iPhone + m_Icons: + - m_Textures: [] + m_Width: 180 + m_Height: 180 + m_Kind: 0 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 120 + m_Height: 120 + m_Kind: 0 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 167 + m_Height: 167 + m_Kind: 0 + m_SubKind: iPad + - m_Textures: [] + m_Width: 152 + m_Height: 152 + m_Kind: 0 + m_SubKind: iPad + - m_Textures: [] + m_Width: 76 + m_Height: 76 + m_Kind: 0 + m_SubKind: iPad + - m_Textures: [] + m_Width: 120 + m_Height: 120 + m_Kind: 3 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 80 + m_Height: 80 + m_Kind: 3 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 80 + m_Height: 80 + m_Kind: 3 + m_SubKind: iPad + - m_Textures: [] + m_Width: 40 + m_Height: 40 + m_Kind: 3 + m_SubKind: iPad + - m_Textures: [] + m_Width: 87 + m_Height: 87 + m_Kind: 1 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 58 + m_Height: 58 + m_Kind: 1 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 29 + m_Height: 29 + m_Kind: 1 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 58 + m_Height: 58 + m_Kind: 1 + m_SubKind: iPad + - m_Textures: [] + m_Width: 29 + m_Height: 29 + m_Kind: 1 + m_SubKind: iPad + - m_Textures: [] + m_Width: 60 + m_Height: 60 + m_Kind: 2 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 40 + m_Height: 40 + m_Kind: 2 + m_SubKind: iPhone + - m_Textures: [] + m_Width: 40 + m_Height: 40 + m_Kind: 2 + m_SubKind: iPad + - m_Textures: [] + m_Width: 20 + m_Height: 20 + m_Kind: 2 + m_SubKind: iPad + - m_Textures: [] + m_Width: 1024 + m_Height: 1024 + m_Kind: 4 + m_SubKind: App Store m_BuildTargetBatching: [] + m_BuildTargetShaderSettings: [] m_BuildTargetGraphicsJobs: - m_BuildTarget: MacStandaloneSupport m_GraphicsJobs: 0 @@ -402,6 +516,8 @@ PlayerSettings: m_APIs: 10000000 m_Automatic: 1 m_BuildTargetVRSettings: [] + m_DefaultShaderChunkSizeInMB: 16 + m_DefaultShaderChunkCount: 0 openGLRequireES31: 0 openGLRequireES31AEP: 0 openGLRequireES32: 0 @@ -411,8 +527,11 @@ PlayerSettings: iPhone: 1 tvOS: 1 m_BuildTargetGroupLightmapEncodingQuality: [] + m_BuildTargetGroupHDRCubemapEncodingQuality: [] m_BuildTargetGroupLightmapSettings: [] + m_BuildTargetGroupLoadStoreDebugModeSettings: [] m_BuildTargetNormalMapEncoding: [] + m_BuildTargetDefaultTextureCompressionFormat: [] playModeTestRunnerEnabled: 0 runPlayModeTestAsEditModeTest: 0 actionOnDotNetUnhandledException: 1 @@ -423,6 +542,7 @@ PlayerSettings: locationUsageDescription: microphoneUsageDescription: bluetoothUsageDescription: + macOSTargetOSVersion: 10.13.0 switchNMETAOverride: switchNetLibKey: switchSocketMemoryPoolSize: 6144 @@ -430,9 +550,11 @@ PlayerSettings: switchSocketConcurrencyLimit: 14 switchScreenResolutionBehavior: 2 switchUseCPUProfiler: 0 - switchUseGOLDLinker: 0 + switchEnableFileSystemTrace: 0 + switchLTOSetting: 0 switchApplicationID: 0x01004b9000490000 switchNSODependencies: + switchCompilerFlags: switchTitleNames_0: switchTitleNames_1: switchTitleNames_2: @@ -506,7 +628,6 @@ PlayerSettings: switchReleaseVersion: 0 switchDisplayVersion: 1.0.0 switchStartupUserAccount: 0 - switchTouchScreenUsage: 0 switchSupportedLanguagesMask: 0 switchLogoType: 0 switchApplicationErrorCodeCategory: @@ -548,6 +669,7 @@ PlayerSettings: switchNativeFsCacheSize: 32 switchIsHoldTypeHorizontal: 0 switchSupportedNpadCount: 8 + switchEnableTouchScreen: 1 switchSocketConfigEnabled: 0 switchTcpInitialSendBufferSize: 32 switchTcpInitialReceiveBufferSize: 64 @@ -558,9 +680,8 @@ PlayerSettings: switchSocketBufferEfficiency: 4 switchSocketInitializeEnabled: 1 switchNetworkInterfaceManagerInitializeEnabled: 1 - switchPlayerConnectionEnabled: 1 switchUseNewStyleFilepaths: 0 - switchUseLegacyFmodPriorities: 1 + switchUseLegacyFmodPriorities: 0 switchUseMicroSleepForYield: 1 switchEnableRamDiskSupport: 0 switchMicroSleepForYieldTime: 25 @@ -648,6 +769,7 @@ PlayerSettings: webGLMemorySize: 16 webGLExceptionSupport: 1 webGLNameFilesAsHashes: 0 + webGLShowDiagnostics: 0 webGLDataCaching: 1 webGLDebugSymbols: 0 webGLEmscriptenArgs: @@ -660,6 +782,13 @@ PlayerSettings: webGLLinkerTarget: 1 webGLThreadsSupport: 0 webGLDecompressionFallback: 0 + webGLInitialMemorySize: 32 + webGLMaximumMemorySize: 2048 + webGLMemoryGrowthMode: 2 + webGLMemoryLinearGrowthStep: 16 + webGLMemoryGeometricGrowthStep: 0.2 + webGLMemoryGeometricGrowthCap: 96 + webGLPowerPreference: 2 scriptingDefineSymbols: 7: IL2CPP additionalCompilerArguments: {} @@ -667,17 +796,30 @@ PlayerSettings: scriptingBackend: Android: 1 il2cppCompilerConfiguration: {} - managedStrippingLevel: {} + il2cppCodeGeneration: {} + managedStrippingLevel: + Android: 1 + EmbeddedLinux: 1 + GameCoreScarlett: 1 + GameCoreXboxOne: 1 + Nintendo Switch: 1 + PS4: 1 + PS5: 1 + QNX: 1 + Stadia: 1 + VisionOS: 1 + WebGL: 1 + Windows Store Apps: 1 + XboxOne: 1 + iPhone: 1 + tvOS: 1 incrementalIl2cppBuild: {} suppressCommonWarnings: 1 allowUnsafeCode: 1 useDeterministicCompilation: 1 - useReferenceAssemblies: 1 - enableRoslynAnalyzers: 1 additionalIl2CppArgs: scriptingRuntimeVersion: 1 gcIncremental: 0 - assemblyVersionValidation: 1 gcWBarrierValidation: 0 apiCompatibilityLevelPerPlatform: Android: 3 @@ -706,6 +848,7 @@ PlayerSettings: metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, a: 1} metroSplashScreenUseBackgroundColor: 0 + syncCapabilities: 0 platformCapabilities: {} metroTargetDeviceFamilies: {} metroFTAName: @@ -753,6 +896,11 @@ PlayerSettings: luminVersion: m_VersionCode: 1 m_VersionName: + hmiPlayerDataPath: + hmiForceSRGBBlit: 1 + embeddedLinuxEnableGamepadInput: 1 + hmiLogStartupTiming: 0 + hmiCpuConfiguration: apiCompatibilityLevel: 6 activeInputHandler: 0 windowsGamepadBackendHint: 0 @@ -763,4 +911,7 @@ PlayerSettings: organizationId: cloudEnabled: 0 legacyClampBlendShapeWeights: 0 + hmiLoadingImage: {fileID: 0} + platformRequiresReadableAssets: 0 virtualTexturingSupportEnabled: 0 + insecureHttpOption: 0 diff --git a/Nino_Unity/ProjectSettings/ProjectVersion.txt b/Nino_Unity/ProjectSettings/ProjectVersion.txt index d58dcc0..bc915f1 100644 --- a/Nino_Unity/ProjectSettings/ProjectVersion.txt +++ b/Nino_Unity/ProjectSettings/ProjectVersion.txt @@ -1,2 +1,2 @@ -m_EditorVersion: 2020.3.47f1 -m_EditorVersionWithRevision: 2020.3.47f1 (5ef4f5b5e2d4) +m_EditorVersion: 2022.3.24f1 +m_EditorVersionWithRevision: 2022.3.24f1 (334eb2a0b267)