Skip to content

Commit

Permalink
[update] Nino.Serialization v1.2.2
Browse files Browse the repository at this point in the history
Nino.Serialization v1.2.2
- [optimization] better generator and better size computation
- [optimization] faster serialization/deserialization
- [optimization] lowerge
- [remove] no longer support ILRuntime
  • Loading branch information
JasonXuDeveloper committed Oct 18, 2023
1 parent c57f969 commit 4217827
Show file tree
Hide file tree
Showing 37 changed files with 1,590 additions and 1,423 deletions.
104 changes: 62 additions & 42 deletions Docs/Serialization.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,16 @@ public partial struct NotIncludeAllClass
> **强烈建议通过生成代码来提高性能,但是需要注意,每次更新字段或属性后需要重新生成代码来更新**
>
> 如果不需要序列化`字符串``非固定长度的集合(例如string[])`,则会生成非常高效的代码
>
> **强烈推荐使用自动收集,这样会最大限度的优化生成出来的代码**


## 版本兼容

- 可以给已序列化的相同类型的字段/属性改名
- 可以给已序列化的字段/属性改成相同大小的类型(`int`->`uint``int`->`float``List<long>`->`List<double``List<int[]>`->`List<float[]`
- 可以加入新的字段/属性(需要确保index在老字段/属性的后面,自动收集的话则将新的字段/属性确保是最后定义的即可)
- **不可以**删除被收集的字段/属性
- **不可以**添加收集字段/属性
- **可以添加**不被收集的字段/属性
Expand All @@ -64,7 +67,7 @@ public partial struct NotIncludeAllClass

支持序列化的成员类型(底层自带支持):

- byte, sbyte, short, ushort, int, uint, long, ulong, double, float, decimal, char, string, bool, enum, DateTime
- byte, sbyte, short, ushort, int, uint, long, ulong, double, float, decimal, char, string, bool, enum, DateTime, [任意UnmanagedType](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/unmanaged-types)
- Nullable<任意支持Nino序列化的struct>
- List<可Nino序列化类型>,HashSet<可Nino序列化类型>,Queue<可Nino序列化类型>,Stack<可Nino序列化类型>,可Nino序列化类型[], ICollection<可Nino序列化>
- Dictionary<Nino支持类型,Nino支持类型>,IDictionary<可Nino序列化>
Expand All @@ -84,37 +87,11 @@ public partial struct NotIncludeAllClass



## ILRuntime

Nino支持ILRuntime的使用,但需要初始化ILRuntime:

1. 把ILRuntime导入Unity工程,并对ILRuntime目录生成assembly definition文件

2. 进入Nino_Unity/Assets/Nino/Serialization,找到```Nino.Serialization.asmdef```,选中后在Inspector上添加对ILRuntime的assembly definition的引用,并apply变动

3. 在PlayerSetting里Symbol区域添加```ILRuntime```(如果Symbol一栏不是空的,记得两个标签之间要用```;```隔开)

4. 调用ILRuntime解析工具

```csharp
Nino.Serialization.ILRuntimeResolver.RegisterILRuntimeClrRedirection(domain);
```
## 代码热更

domain是ILRuntime的AppDomain,该方法应该在domain.LoadAssembly后,进入热更代码前调用,参考Test11
- 暂时因为**ILRuntime**原理限制,Nino无法支持**ILRuntime**

5. 热更工程引用Library/ScriptAssemblies/Nino.Serialization.dll和Library/ScriptAssemblies/Nino.Shared.dll

6. ILRuntime下**非常不建议**给热更工程的结构体生成静态性能优化代码,**因为原理限制会产生负优化!!!**,如果执意要生产代码,请参考后续步骤,反之可以忽略后面的步骤

7. 如果需要给热更工程生成代码,打开```Nino_Unity/Assets/Nino/Editor/SerializationHelper.cs```,修改```ExternalDLLPath```字段内的```Assets/Nino/Test/Editor/Serialization/Test11.bytes```,变为你的热更工程的DLL文件的路径,记得带后缀,修改生效后,在菜单栏点击```Nino/Generator/Serialization Code```即可给热更工程的Nino序列化类型生成代码

8. 生成热更工程的代码后,需要把生成的热更序列化类型的代码从Unity工程移到热更工程,并且在Unity工程删掉会报错的热更类型代码

> 如果用的是assembly definition来生成热更库的,需要把生成的热更代码放到assembly definition的目录内,把外部会报错的代码挪进去就好
>
> 需要注意的是,ILRuntime下生成与不生成代码的差距不是特别大
>
> ILRuntime下也不支持多态!
- Nino支持**HybridCLR**



Expand All @@ -135,28 +112,71 @@ Nino支持ILRuntime的使用,但需要初始化ILRuntime:
示例:

```csharp
public class Vector3Wrapper : NinoWrapperBase<Vector3>
[NinoSerialize(false)]
public partial class CustomTypeTest
{
[NinoMember(1)] public Vector3 v3;

[NinoMember(2)] private DateTime dt = DateTime.Now;

[NinoMember(3)] public int? ni { get; set; }

[NinoMember(4)] public List<Quaternion> qs;

[NinoMember(5)] public Matrix4x4 m;

[NinoMember(6)] public Dictionary<string, int> dict;

[NinoMember(7)] public Dictionary<string, Data> dict2;

public override string ToString()
{
return
$"{v3}, {dt}, {ni}, {String.Join(",", qs)}, {m.ToString()}\n" +
$"dict.keys: {string.Join(",", dict.Keys)},\ndict.values:{string.Join(",", dict.Values)}\n" +
$"dict2.keys: {string.Join(",", dict2.Keys)},\ndict2.values:{string.Join(",", dict2.Values)}\n";
}
}

public class CustomTypeTestWrapper : NinoWrapperBase<CustomTypeTest>
{
public override void Serialize(Vector3 val, ref Writer writer)
public override void Serialize(CustomTypeTest val, ref Writer writer)
{
writer.Write(val.x);
writer.Write(val.y);
writer.Write(val.z);
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 Vector3 Deserialize(Reader reader)
public override CustomTypeTest Deserialize(Reader reader)
{
return new Vector3(reader.Read<float>(4), reader.Read<float>(4), reader.Read<float>(4));
var ret = new CustomTypeTest();
reader.Read(ref ret.v3, sizeof(float) * 3);
reader.Read(ref ret.m, sizeof(float) * 16);
ret.ni = reader.ReadNullable<int>();
ret.qs = reader.ReadList<Quaternion>();
ret.dict = reader.ReadDictionary<string, int>();
ret.dict2 = reader.ReadDictionary<string, Data>();
return ret;
}

public override int GetSize(Vector3 val)
public override int GetSize(CustomTypeTest val)
{
return 12;
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;
}
}

//别忘了在某个地方调用下面的代码:
WrapperManifest.AddWrapper(typeof(Vector3), new Vector3Wrapper());
WrapperManifest.AddWrapper(typeof(CustomTypeTest), new CustomTypeTestWrapper());
```


Expand All @@ -167,7 +187,7 @@ WrapperManifest.AddWrapper(typeof(Vector3), new Vector3Wrapper());

- Unity下直接在菜单栏点击```Nino/Generator/Serialization Code```即可,代码会生成到```Assets/Nino/Generated```,也可以打开```Assets/Nino/Editor/SerializationHelper.cs```并修改内部的```ExportPath```参数
- 非Unity下调用```CodeGenerator.GenerateSerializationCodeForAllTypePossible```接口即可
- **开启了自动收集字段和属性,生成代码和没生成代码,序列化的结果是一样的**
- **开启了自动收集字段和属性,生成代码和没生成代码,序列化的结果是一样的,但是速度会快很多**

> 不想生成代码的类或结构体可以打```[CodeGenIgnore]```标签到该类或结构体上,可以在性能对比的时候用这个(例如[这个真机测试](../Nino_Unity/Assets/Nino/Test/BuildTest.cs)
Expand All @@ -185,7 +205,7 @@ Nino支持以下三种压缩方式:

> 序列化和反序列化的时候可以选择压缩方式,但是需要注意反序列化数据的时候,需要用和序列化时相同的压缩方式去反序列化
>
> 注意,v1.2.0暂时仅支持无压缩
> 注意,v1.2.0~1.2.2暂时仅支持无压缩


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,8 @@ public override void Serialize(BuildTestDataCodeGen value, ref Nino.Serializatio
return;
}
writer.Write(true);
writer.Write(ref value.a, sizeof(System.Byte));
writer.Write(ref value.b, sizeof(System.SByte));
writer.Write(ref value.c, sizeof(System.Int16));
writer.Write(ref value.d, sizeof(System.UInt16));
writer.Write(ref value.e, sizeof(System.Int32));
writer.Write(ref value.f, sizeof(System.UInt32));
writer.Write(ref value.g, sizeof(System.Int64));
writer.Write(ref value.h, sizeof(System.UInt64));
writer.Write(ref value.i, sizeof(System.Single));
writer.Write(ref value.j, sizeof(System.Double));
writer.Write(ref value.k, sizeof(System.Decimal));
writer.Write(ref value.l, sizeof(System.Boolean));
writer.Write(ref value.m, sizeof(System.Char));
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);
Expand All @@ -53,19 +42,8 @@ public override BuildTestDataCodeGen Deserialize(Nino.Serialization.Reader reade
if(!reader.ReadBool())
return null;
BuildTestDataCodeGen value = new BuildTestDataCodeGen();
reader.Read<System.Byte>(ref value.a, sizeof(System.Byte));
reader.Read<System.SByte>(ref value.b, sizeof(System.SByte));
reader.Read<System.Int16>(ref value.c, sizeof(System.Int16));
reader.Read<System.UInt16>(ref value.d, sizeof(System.UInt16));
reader.Read<System.Int32>(ref value.e, sizeof(System.Int32));
reader.Read<System.UInt32>(ref value.f, sizeof(System.UInt32));
reader.Read<System.Int64>(ref value.g, sizeof(System.Int64));
reader.Read<System.UInt64>(ref value.h, sizeof(System.UInt64));
reader.Read<System.Single>(ref value.i, sizeof(System.Single));
reader.Read<System.Double>(ref value.j, sizeof(System.Double));
reader.Read<System.Decimal>(ref value.k, sizeof(System.Decimal));
reader.Read<System.Boolean>(ref value.l, sizeof(System.Boolean));
reader.Read<System.Char>(ref value.m, sizeof(System.Char));
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<System.Int32>();
value.p = reader.ReadList<Nino.Test.NotIncludeAllClass>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,10 @@ public override void Serialize(CustomTypeTest value, ref Nino.Serialization.Writ
return;
}
writer.Write(true);
writer.WriteCommonVal<UnityEngine.Vector3>(value.v3);
writer.Write(ref value.dt, sizeof(System.DateTime));
writer.WriteCommonVal<System.Nullable<System.Int32>>(value.ni);
writer.Write(ref value.v3, sizeof(UnityEngine.Vector3),ref value.dt, sizeof(System.DateTime));
writer.Write(value.ni);
writer.Write(value.qs);
writer.WriteCommonVal<UnityEngine.Matrix4x4>(value.m);
writer.Write(ref value.m, sizeof(UnityEngine.Matrix4x4));
writer.Write(value.dict);
writer.Write(value.dict2);
}
Expand All @@ -38,11 +37,10 @@ public override CustomTypeTest Deserialize(Nino.Serialization.Reader reader)
if(!reader.ReadBool())
return null;
CustomTypeTest value = new CustomTypeTest();
value.v3 = reader.ReadCommonVal<UnityEngine.Vector3>();
reader.Read<System.DateTime>(ref value.dt, sizeof(System.DateTime));
value.ni = reader.ReadCommonVal<System.Nullable<System.Int32>>();
reader.Read(ref value.v3, sizeof(UnityEngine.Vector3),ref value.dt, sizeof(System.DateTime));
value.ni = reader.ReadNullable<System.Int32>();
value.qs = reader.ReadList<UnityEngine.Quaternion>();
value.m = reader.ReadCommonVal<UnityEngine.Matrix4x4>();
reader.Read(ref value.m, sizeof(UnityEngine.Matrix4x4));
value.dict = reader.ReadDictionary<System.String,System.Int32>();
value.dict2 = reader.ReadDictionary<System.String,Nino.Test.Data>();
return value;
Expand Down
18 changes: 2 additions & 16 deletions Nino_Unity/Assets/Nino/Generated/Nino_Test_Data_Serialize.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,7 @@ public override void Serialize(Data value, ref Nino.Serialization.Writer writer)
{

writer.Write(true);
writer.Write(ref value.x, sizeof(System.Int32));
writer.Write(ref value.y, sizeof(System.Int16));
writer.Write(ref value.z, sizeof(System.Int64));
writer.Write(ref value.f, sizeof(System.Single));
writer.Write(ref value.d, sizeof(System.Decimal));
writer.Write(ref value.db, sizeof(System.Double));
writer.Write(ref value.bo, sizeof(System.Boolean));
writer.WriteEnum<Nino.Test.TestEnum>(value.en);
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)]
Expand All @@ -44,14 +37,7 @@ public override Data Deserialize(Nino.Serialization.Reader reader)
if(!reader.ReadBool())
return default;
Data value = new Data();
reader.Read<System.Int32>(ref value.x, sizeof(System.Int32));
reader.Read<System.Int16>(ref value.y, sizeof(System.Int16));
reader.Read<System.Int64>(ref value.z, sizeof(System.Int64));
reader.Read<System.Single>(ref value.f, sizeof(System.Single));
reader.Read<System.Decimal>(ref value.d, sizeof(System.Decimal));
reader.Read<System.Double>(ref value.db, sizeof(System.Double));
reader.Read<System.Boolean>(ref value.bo, sizeof(System.Boolean));
reader.ReadEnum<Nino.Test.TestEnum>(ref value.en);
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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,7 @@ public override void Serialize(IncludeAllClassCodeGen value, ref Nino.Serializat
return;
}
writer.Write(true);
writer.Write(ref value.a, sizeof(System.Int32));
writer.Write(ref value.b, sizeof(System.Int64));
writer.Write(ref value.c, sizeof(System.Single));
writer.Write(ref value.d, sizeof(System.Double));
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)]
Expand All @@ -40,10 +37,7 @@ public override IncludeAllClassCodeGen Deserialize(Nino.Serialization.Reader rea
if(!reader.ReadBool())
return null;
IncludeAllClassCodeGen value = new IncludeAllClassCodeGen();
reader.Read<System.Int32>(ref value.a, sizeof(System.Int32));
reader.Read<System.Int64>(ref value.b, sizeof(System.Int64));
reader.Read<System.Single>(ref value.c, sizeof(System.Single));
reader.Read<System.Double>(ref value.d, sizeof(System.Double));
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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,7 @@ public override void Serialize(NotIncludeAllClass value, ref Nino.Serialization.
return;
}
writer.Write(true);
writer.Write(ref value.a, sizeof(System.Int32));
writer.Write(ref value.b, sizeof(System.Int64));
writer.Write(ref value.c, sizeof(System.Single));
writer.Write(ref value.d, sizeof(System.Double));
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)]
Expand All @@ -40,10 +37,7 @@ public override NotIncludeAllClass Deserialize(Nino.Serialization.Reader reader)
if(!reader.ReadBool())
return null;
NotIncludeAllClass value = new NotIncludeAllClass();
reader.Read<System.Int32>(ref value.a, sizeof(System.Int32));
reader.Read<System.Int64>(ref value.b, sizeof(System.Int64));
reader.Read<System.Single>(ref value.c, sizeof(System.Single));
reader.Read<System.Double>(ref value.d, sizeof(System.Double));
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;
}

Expand Down
Loading

0 comments on commit 4217827

Please sign in to comment.