饭太稀

This commit is contained in:
bob
2025-06-30 10:51:37 +08:00
commit 8e45469c83
753 changed files with 87652 additions and 0 deletions

View File

@@ -0,0 +1,311 @@
#if FANTASY_NET
using System.Buffers;
using System.Collections;
using System.ComponentModel;
using System.Reflection;
using Fantasy.Assembly;
using Fantasy.Entitas;
using MongoDB.Bson;
using MongoDB.Bson.IO;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Conventions;
using MongoDB.Bson.Serialization.Serializers;
#pragma warning disable CS8603 // Possible null reference return.
#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type.
#pragma warning disable CS8602 // Dereference of a possibly null reference.
namespace Fantasy.Serialize
{
/// <summary>
/// BSON帮助方法
/// </summary>
public class BsonPackHelper : ISerialize
{
/// <summary>
/// 序列化器的名字
/// </summary>
public string SerializeName { get; } = "Bson";
/// <summary>
/// 构造函数
/// </summary>
public BsonPackHelper()
{
// 清除掉注册过的LookupClassMap。
var classMapRegistryField = typeof(BsonClassMap).GetField("__classMaps", BindingFlags.Static | BindingFlags.NonPublic);
if (classMapRegistryField != null)
{
((Dictionary<Type, BsonClassMap>)classMapRegistryField.GetValue(null)).Clear();
}
// 清除掉注册过的ConventionRegistry。
var registryField = typeof(ConventionRegistry).GetField("_lookup", BindingFlags.Static | BindingFlags.NonPublic);
if (registryField != null)
{
var registry = registryField.GetValue(null);
var dictionaryField = registry.GetType().GetField("_conventions", BindingFlags.Instance | BindingFlags.NonPublic);
if (dictionaryField != null)
{
((IDictionary)dictionaryField.GetValue(registry)).Clear();
}
}
// 初始化ConventionRegistry、注册IgnoreExtraElements。
ConventionRegistry.Register("IgnoreExtraElements", new ConventionPack { new IgnoreExtraElementsConvention(true) }, type => true);
// 注册一个自定义的序列化器。
// BsonSerializer.TryRegisterSerializer(typeof(float2), new StructBsonSerialize<float2>());
// BsonSerializer.TryRegisterSerializer(typeof(float3), new StructBsonSerialize<float3>());
// BsonSerializer.TryRegisterSerializer(typeof(float4), new StructBsonSerialize<float4>());
// BsonSerializer.TryRegisterSerializer(typeof(quaternion), new StructBsonSerialize<quaternion>());
BsonSerializer.RegisterSerializer(new ObjectSerializer(x => true));
// 注册LookupClassMap。
foreach (var type in AssemblySystem.ForEach())
{
if (type.IsInterface || type.IsAbstract || type.IsGenericType || !typeof(Entity).IsAssignableFrom(type))
{
continue;
}
BsonClassMap.LookupClassMap(type);
}
}
/// <summary>
/// 反序列化
/// </summary>
/// <param name="bytes"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T Deserialize<T>(byte[] bytes)
{
var @object = BsonSerializer.Deserialize<T>(bytes);
if (@object is ASerialize aSerialize)
{
aSerialize.AfterDeserialization();
}
return @object;
}
/// <summary>
/// 反序列化
/// </summary>
/// <param name="buffer"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T Deserialize<T>(MemoryStreamBuffer buffer)
{
var @object = BsonSerializer.Deserialize<T>(buffer);
if (@object is ASerialize aSerialize)
{
aSerialize.AfterDeserialization();
}
return @object;
}
/// <summary>
/// 反序列化
/// </summary>
/// <param name="type"></param>
/// <param name="bytes"></param>
/// <returns></returns>
public object Deserialize(Type type, byte[] bytes)
{
var @object = BsonSerializer.Deserialize(bytes, type);
if (@object is ASerialize aSerialize)
{
aSerialize.AfterDeserialization();
}
return @object;
}
/// <summary>
/// 反序列化
/// </summary>
/// <param name="type"></param>
/// <param name="buffer"></param>
/// <returns></returns>
public object Deserialize(Type type, MemoryStreamBuffer buffer)
{
var @object = BsonSerializer.Deserialize(buffer, type);
if (@object is ASerialize aSerialize)
{
aSerialize.AfterDeserialization();
}
return @object;
}
/// <summary>
/// 反序列化
/// </summary>
/// <param name="bytes"></param>
/// <param name="index"></param>
/// <param name="count"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public unsafe T Deserialize<T>(byte[] bytes, int index, int count)
{
T @object;
fixed (byte* ptr = &bytes[index])
{
using var stream = new UnmanagedMemoryStream(ptr, count);
@object = BsonSerializer.Deserialize<T>(stream);
}
if (@object is ASerialize aSerialize)
{
aSerialize.AfterDeserialization();
}
return @object;
}
/// <summary>
/// 反序列化
/// </summary>
/// <param name="type"></param>
/// <param name="bytes"></param>
/// <param name="index"></param>
/// <param name="count"></param>
/// <returns></returns>
public unsafe object Deserialize(Type type, byte[] bytes, int index, int count)
{
object @object;
fixed (byte* ptr = &bytes[index])
{
using var stream = new UnmanagedMemoryStream(ptr, count);
@object = BsonSerializer.Deserialize(stream, type);
}
if (@object is ASerialize aSerialize)
{
aSerialize.AfterDeserialization();
}
return @object;
}
/// <summary>
/// 序列化
/// </summary>
/// <param name="object"></param>
/// <param name="buffer"></param>
/// <typeparam name="T"></typeparam>
public void Serialize<T>(T @object, IBufferWriter<byte> buffer)
{
if (@object is ASerialize aSerialize)
{
aSerialize.BeginInit();
}
using IBsonWriter bsonWriter =
new BsonBinaryWriter((MemoryStream)buffer, BsonBinaryWriterSettings.Defaults);
BsonSerializer.Serialize(bsonWriter, @object);
}
/// <summary>
/// 序列化
/// </summary>
/// <param name="object"></param>
/// <param name="buffer"></param>
public void Serialize(object @object, IBufferWriter<byte> buffer)
{
if (@object is ASerialize aSerialize)
{
aSerialize.BeginInit();
}
using IBsonWriter bsonWriter =
new BsonBinaryWriter((MemoryStream)buffer, BsonBinaryWriterSettings.Defaults);
BsonSerializer.Serialize(bsonWriter, @object.GetType(), @object);
}
/// <summary>
/// 序列化
/// </summary>
/// <param name="type"></param>
/// <param name="object"></param>
/// <param name="buffer"></param>
public void Serialize(Type type, object @object, IBufferWriter<byte> buffer)
{
if (@object is ASerialize aSerialize)
{
aSerialize.BeginInit();
}
using IBsonWriter bsonWriter =
new BsonBinaryWriter((MemoryStream)buffer, BsonBinaryWriterSettings.Defaults);
BsonSerializer.Serialize(bsonWriter, type, @object);
}
/// <summary>
/// 序列化并返回的长度
/// </summary>
/// <param name="type"></param>
/// <param name="object"></param>
/// <param name="buffer"></param>
/// <returns></returns>
public int SerializeAndReturnLength(Type type, object @object, MemoryStreamBuffer buffer)
{
if (@object is ASerialize aSerialize)
{
aSerialize.BeginInit();
}
using IBsonWriter bsonWriter = new BsonBinaryWriter(buffer, BsonBinaryWriterSettings.Defaults);
BsonSerializer.Serialize(bsonWriter, type, @object);
return (int)buffer.Length;
}
/// <summary>
/// 序列化
/// </summary>
/// <param name="object"></param>
/// <returns></returns>
public static byte[] Serialize(object @object)
{
if (@object is ASerialize aSerialize)
{
aSerialize.BeginInit();
}
return @object.ToBson(@object.GetType());
}
/// <summary>
/// 序列化
/// </summary>
/// <param name="object"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static byte[] Serialize<T>(T @object)
{
if (@object is ASerialize aSerialize)
{
aSerialize.BeginInit();
}
return @object.ToBson<T>();
}
/// <summary>
/// 克隆
/// </summary>
/// <param name="t"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T Clone<T>(T t)
{
return Deserialize<T>(Serialize(t));
}
}
}
#endif

View File

@@ -0,0 +1,60 @@
#if FANTASY_UNITY
using System;
using System.Buffers;
namespace Fantasy.Serialize
{
public class BsonPackHelper : ISerialize
{
public string SerializeName { get; } = "Bson";
public T Deserialize<T>(byte[] bytes)
{
throw new NotImplementedException();
}
public T Deserialize<T>(MemoryStreamBuffer buffer)
{
throw new NotImplementedException();
}
public object Deserialize(Type type, byte[] bytes)
{
throw new NotImplementedException();
}
public object Deserialize(Type type, MemoryStreamBuffer buffer)
{
throw new NotImplementedException();
}
public T Deserialize<T>(byte[] bytes, int index, int count)
{
throw new NotImplementedException();
}
public object Deserialize(Type type, byte[] bytes, int index, int count)
{
throw new NotImplementedException();
}
public void Serialize<T>(T @object, IBufferWriter<byte> buffer)
{
throw new NotImplementedException();
}
public void Serialize(object @object, IBufferWriter<byte> buffer)
{
throw new NotImplementedException();
}
public void Serialize(Type type, object @object, IBufferWriter<byte> buffer)
{
throw new NotImplementedException();
}
public T Clone<T>(T t)
{
throw new NotImplementedException();
}
}
}
#endif

View File

@@ -0,0 +1,65 @@
#if FANTASY_NET
using System.Reflection;
using MongoDB.Bson;
using MongoDB.Bson.IO;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Serializers;
namespace Fantasy.Serialize;
/// <summary>
/// 提供对结构体类型进行 BSON 序列化和反序列化的辅助类。
/// </summary>
/// <typeparam name="TValue">要序列化和反序列化的结构体类型。</typeparam>
public class StructBsonSerialize<TValue> : StructSerializerBase<TValue> where TValue : struct
{
/// <summary>
/// 将结构体对象序列化为 BSON 数据。
/// </summary>
/// <param name="context">序列化上下文。</param>
/// <param name="args">序列化参数。</param>
/// <param name="value">要序列化的结构体对象。</param>
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, TValue value)
{
var nominalType = args.NominalType;
var bsonWriter = context.Writer;
bsonWriter.WriteStartDocument();
var fields = nominalType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
foreach (var field in fields)
{
bsonWriter.WriteName(field.Name);
BsonSerializer.Serialize(bsonWriter, field.FieldType, field.GetValue(value));
}
bsonWriter.WriteEndDocument();
}
/// <summary>
/// 将 BSON 数据反序列化为结构体对象。
/// </summary>
/// <param name="context">反序列化上下文。</param>
/// <param name="args">反序列化参数。</param>
/// <returns>反序列化得到的结构体对象。</returns>
public override TValue Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
//boxing is required for SetValue to work
object obj = new TValue();
var actualType = args.NominalType;
var bsonReader = context.Reader;
bsonReader.ReadStartDocument();
while (bsonReader.ReadBsonType() != BsonType.EndOfDocument)
{
var name = bsonReader.ReadName(Utf8NameDecoder.Instance);
var field = actualType.GetField(name,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (field != null)
{
var value = BsonSerializer.Deserialize(bsonReader, field.FieldType);
field.SetValue(obj, value);
}
}
bsonReader.ReadEndDocument();
return (TValue) obj;
}
}
#endif

View File

@@ -0,0 +1,17 @@
#if FANTASY_NET
using System.ComponentModel;
using Fantasy.Entitas;
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
namespace Fantasy.Serialize;
public static class SupportInitializeChecker<T> where T : Entity
{
public static bool IsSupported { get; }
static SupportInitializeChecker()
{
IsSupported = typeof(ISupportInitialize).IsAssignableFrom(typeof(T));
}
}
#endif

View File

@@ -0,0 +1,60 @@
using System;
using System.ComponentModel;
using System.Runtime.Serialization;
using Fantasy.Pool;
#if FANTASY_NET || FANTASY_UNITY || FANTASY_CONSOLE
using MongoDB.Bson.Serialization.Attributes;
#endif
using Newtonsoft.Json;
using ProtoBuf;
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
namespace Fantasy.Serialize
{
public abstract class ASerialize : ISupportInitialize, IDisposable
{
public virtual void Dispose() { }
public virtual void BeginInit() { }
public virtual void EndInit() { }
public virtual void AfterDeserialization() => EndInit();
}
public abstract class AMessage : ASerialize, IPool
{
#if FANTASY_NET || FANTASY_UNITY || FANTASY_CONSOLE
[BsonIgnore]
[JsonIgnore]
[IgnoreDataMember]
[ProtoIgnore]
private Scene _scene;
protected Scene GetScene()
{
return _scene;
}
public void SetScene(Scene scene)
{
_scene = scene;
}
#endif
#if FANTASY_NET
[BsonIgnore]
#endif
[JsonIgnore]
[IgnoreDataMember]
[ProtoIgnore]
private bool _isPool;
public bool IsPool()
{
return _isPool;
}
public void SetIsPool(bool isPool)
{
_isPool = isPool;
}
}
}

View File

@@ -0,0 +1,87 @@
using System;
using System.Buffers;
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
namespace Fantasy.Serialize
{
public interface ISerialize
{
/// <summary>
/// 序列化器的名字,用于在协议里指定用什么协议序列化使用
/// </summary>
string SerializeName { get; }
/// <summary>
/// 反序列化
/// </summary>
/// <param name="bytes"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
T Deserialize<T>(byte[] bytes);
/// <summary>
/// 反序列化
/// </summary>
/// <param name="buffer"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
T Deserialize<T>(MemoryStreamBuffer buffer);
/// <summary>
/// 反序列化
/// </summary>
/// <param name="type"></param>
/// <param name="bytes"></param>
/// <returns></returns>
object Deserialize(Type type, byte[] bytes);
/// <summary>
/// 反序列化
/// </summary>
/// <param name="type"></param>
/// <param name="buffer"></param>
/// <returns></returns>
object Deserialize(Type type, MemoryStreamBuffer buffer);
/// <summary>
/// 反序列化
/// </summary>
/// <param name="bytes"></param>
/// <param name="index"></param>
/// <param name="count"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
T Deserialize<T>(byte[] bytes, int index, int count);
/// <summary>
/// 反序列化
/// </summary>
/// <param name="type"></param>
/// <param name="bytes"></param>
/// <param name="index"></param>
/// <param name="count"></param>
/// <returns></returns>
object Deserialize(Type type, byte[] bytes, int index, int count);
/// <summary>
/// 序列化
/// </summary>
/// <param name="object"></param>
/// <param name="buffer"></param>
/// <typeparam name="T"></typeparam>
void Serialize<T>(T @object, IBufferWriter<byte> buffer);
/// <summary>
/// 序列化
/// </summary>
/// <param name="object"></param>
/// <param name="buffer"></param>
void Serialize(object @object, IBufferWriter<byte> buffer);
/// <summary>
/// 序列化
/// </summary>
/// <param name="type"></param>
/// <param name="object"></param>
/// <param name="buffer"></param>
void Serialize(Type type, object @object, IBufferWriter<byte> buffer);
/// <summary>
/// 克隆
/// </summary>
/// <param name="t"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
T Clone<T>(T t);
}
}

View File

@@ -0,0 +1,73 @@
using System;
using System.Buffers;
using System.IO;
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
namespace Fantasy.Serialize
{
public enum MemoryStreamBufferSource
{
None = 0,
Pack = 1,
UnPack = 2,
}
public sealed class MemoryStreamBuffer : MemoryStream, IBufferWriter<byte>
{
public MemoryStreamBufferSource MemoryStreamBufferSource;
public MemoryStreamBuffer() { }
public MemoryStreamBuffer(MemoryStreamBufferSource memoryStreamBufferSource, int capacity) : base(capacity)
{
MemoryStreamBufferSource = memoryStreamBufferSource;
}
public MemoryStreamBuffer(byte[] buffer): base(buffer) { }
public void Advance(int count)
{
if (count < 0)
{
throw new ArgumentOutOfRangeException(nameof(count), count, "The value of 'count' cannot be negative.");
}
var newLength = Position + count;
if (newLength != Length)
{
SetLength(newLength);
}
Position = newLength;
}
public Memory<byte> GetMemory(int sizeHint = 0)
{
if (sizeHint < 0)
{
throw new ArgumentOutOfRangeException(nameof(sizeHint), sizeHint, "The value of 'count' cannot be negative.");
}
if (Length - Position <= sizeHint)
{
SetLength(Position + sizeHint);
}
return new Memory<byte>(GetBuffer(), (int)Position, (int)(Length - Position));
}
public Span<byte> GetSpan(int sizeHint = 0)
{
if (sizeHint < 0)
{
throw new ArgumentOutOfRangeException(nameof(sizeHint), sizeHint, "The value of 'count' cannot be negative.");
}
if (Length - Position <= sizeHint)
{
SetLength(Position + sizeHint);
}
return new Span<byte>(GetBuffer(), (int)Position, (int)(Length - Position));
}
}
}

View File

@@ -0,0 +1,9 @@
namespace Fantasy.Serialize
{
/// <summary>
/// 代表是一个ProtoBuf协议
/// </summary>
public interface IProto
{
}
}

View File

@@ -0,0 +1,223 @@
#if FANTASY_NET || FANTASY_EXPORTER
using System.Buffers;
using Fantasy.Assembly;
using ProtoBuf.Meta;
namespace Fantasy.Serialize
{
/// <summary>
/// ProtoBufP帮助类Net平台使用
/// </summary>
public sealed class ProtoBufPackHelper : ISerialize
{
/// <summary>
/// 序列化器的名字
/// </summary>
public string SerializeName { get; } = "ProtoBuf";
/// <summary>
/// 构造函数
/// </summary>
public ProtoBufPackHelper ()
{
#if FANTASY_NET
RuntimeTypeModel.Default.AutoAddMissingTypes = true;
RuntimeTypeModel.Default.AllowParseableTypes = true;
RuntimeTypeModel.Default.AutoAddMissingTypes = true;
RuntimeTypeModel.Default.AutoCompile = true;
RuntimeTypeModel.Default.UseImplicitZeroDefaults = true;
RuntimeTypeModel.Default.InferTagFromNameDefault = true;
foreach (var type in AssemblySystem.ForEach(typeof(IProto)))
{
RuntimeTypeModel.Default.Add(type, true);
}
RuntimeTypeModel.Default.CompileInPlace();
#endif
}
/// <summary>
/// 使用ProtoBuf反序列化数据到实例
/// </summary>
/// <param name="bytes"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T Deserialize<T>(byte[] bytes)
{
var memory = new ReadOnlyMemory<byte>(bytes);
var @object = RuntimeTypeModel.Default.Deserialize<T>(memory);
if (@object is ASerialize aSerialize)
{
aSerialize.AfterDeserialization();
}
return @object;
}
/// <summary>
/// 使用ProtoBuf反序列化数据到实例
/// </summary>
/// <param name="buffer"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T Deserialize<T>(MemoryStreamBuffer buffer)
{
var @object = RuntimeTypeModel.Default.Deserialize<T>(buffer);
if (@object is ASerialize aSerialize)
{
aSerialize.AfterDeserialization();
}
return @object;
}
/// <summary>
/// 使用ProtoBuf反序列化数据到实例
/// </summary>
/// <param name="type"></param>
/// <param name="bytes"></param>
/// <returns></returns>
public object Deserialize(Type type, byte[] bytes)
{
var memory = new ReadOnlyMemory<byte>(bytes);
var @object = RuntimeTypeModel.Default.Deserialize(type, memory);
if (@object is ASerialize aSerialize)
{
aSerialize.AfterDeserialization();
}
return @object;
}
/// <summary>
/// 使用ProtoBuf反序列化数据到实例
/// </summary>
/// <param name="type"></param>
/// <param name="buffer"></param>
/// <returns></returns>
public object Deserialize(Type type, MemoryStreamBuffer buffer)
{
var @object = RuntimeTypeModel.Default.Deserialize(type, buffer);
if (@object is ASerialize aSerialize)
{
aSerialize.AfterDeserialization();
}
return @object;
}
/// <summary>
/// 使用ProtoBuf反序列化数据到实例
/// </summary>
/// <param name="bytes"></param>
/// <param name="index"></param>
/// <param name="count"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T Deserialize<T>(byte[] bytes, int index, int count)
{
var memory = new ReadOnlyMemory<byte>(bytes, index, count);
var @object = RuntimeTypeModel.Default.Deserialize<T>(memory);
if (@object is ASerialize aSerialize)
{
aSerialize.AfterDeserialization();
}
return @object;
}
/// <summary>
/// 使用ProtoBuf反序列化数据到实例
/// </summary>
/// <param name="type"></param>
/// <param name="bytes"></param>
/// <param name="index"></param>
/// <param name="count"></param>
/// <returns></returns>
public object Deserialize(Type type, byte[] bytes, int index, int count)
{
var memory = new ReadOnlyMemory<byte>(bytes, index, count);
var @object = RuntimeTypeModel.Default.Deserialize(type, memory);
if (@object is ASerialize aSerialize)
{
aSerialize.AfterDeserialization();
}
return @object;
}
/// <summary>
/// 使用ProtoBuf序列化某一个实例到IBufferWriter中
/// </summary>
/// <param name="object"></param>
/// <param name="buffer"></param>
/// <typeparam name="T"></typeparam>
public void Serialize<T>(T @object, IBufferWriter<byte> buffer)
{
if (@object is ASerialize aSerialize)
{
aSerialize.BeginInit();
}
RuntimeTypeModel.Default.Serialize<T>(buffer, @object);
}
/// <summary>
/// 使用ProtoBuf序列化某一个实例到IBufferWriter中
/// </summary>
/// <param name="object"></param>
/// <param name="buffer"></param>
public void Serialize(object @object, IBufferWriter<byte> buffer)
{
if (@object is ASerialize aSerialize)
{
aSerialize.BeginInit();
}
RuntimeTypeModel.Default.Serialize(buffer, @object);
}
/// <summary>
/// 使用ProtoBuf序列化某一个实例到IBufferWriter中
/// </summary>
/// <param name="type"></param>
/// <param name="object"></param>
/// <param name="buffer"></param>
public void Serialize(Type type, object @object, IBufferWriter<byte> buffer)
{
if (@object is ASerialize aSerialize)
{
aSerialize.BeginInit();
}
RuntimeTypeModel.Default.Serialize(buffer, @object);
}
internal byte[] Serialize(object @object)
{
if (@object is ASerialize aSerialize)
{
aSerialize.BeginInit();
}
using (var buffer = new MemoryStream())
{
RuntimeTypeModel.Default.Serialize(buffer, @object);
return buffer.ToArray();
}
}
private byte[] Serialize<T>(T @object)
{
if (@object is ASerialize aSerialize)
{
aSerialize.BeginInit();
}
using (var buffer = new MemoryStream())
{
RuntimeTypeModel.Default.Serialize<T>(buffer, @object);
return buffer.ToArray();
}
}
/// <summary>
/// 克隆
/// </summary>
/// <param name="t"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T Clone<T>(T t)
{
return Deserialize<T>(Serialize(t));
}
}
}
#endif

View File

@@ -0,0 +1,202 @@
#if FANTASY_UNITY || FANTASY_CONSOLE
using System;
using System.Buffers;
using System.IO;
using Fantasy.Assembly;
using ProtoBuf;
using ProtoBuf.Meta;
namespace Fantasy.Serialize
{
/// <summary>
/// ProtoBufP帮助类Unity平台使用
/// </summary>
public sealed class ProtoBufPackHelper : ISerialize
{
/// <summary>
/// 序列化器的名字
/// </summary>
public string SerializeName { get; } = "ProtoBuf";
/// <summary>
/// 使用ProtoBuf反序列化数据到实例
/// </summary>
/// <param name="bytes"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public unsafe T Deserialize<T>(byte[] bytes)
{
fixed (byte* ptr = bytes)
{
using var stream = new UnmanagedMemoryStream(ptr, bytes.Length);
var @object = ProtoBuf.Serializer.Deserialize<T>(stream);
if (@object is ASerialize aSerialize)
{
aSerialize.AfterDeserialization();
}
return @object;
}
}
/// <summary>
/// 使用ProtoBuf反序列化数据到实例
/// </summary>
/// <param name="buffer"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T Deserialize<T>(MemoryStreamBuffer buffer)
{
var @object = ProtoBuf.Serializer.Deserialize<T>(buffer);
if (@object is ASerialize aSerialize)
{
aSerialize.AfterDeserialization();
}
return @object;
}
/// <summary>
/// 使用ProtoBuf反序列化数据到实例
/// </summary>
/// <param name="type"></param>
/// <param name="bytes"></param>
/// <returns></returns>
public unsafe object Deserialize(Type type, byte[] bytes)
{
fixed (byte* ptr = bytes)
{
using var stream = new UnmanagedMemoryStream(ptr, bytes.Length);
var @object = ProtoBuf.Serializer.Deserialize(type, stream);
if (@object is ASerialize aSerialize)
{
aSerialize.AfterDeserialization();
}
return @object;
}
}
/// <summary>
/// 使用ProtoBuf反序列化数据到实例
/// </summary>
/// <param name="type"></param>
/// <param name="buffer"></param>
/// <returns></returns>
public object Deserialize(Type type, MemoryStreamBuffer buffer)
{
var @object = ProtoBuf.Serializer.Deserialize(type, buffer);
if (@object is ASerialize aSerialize)
{
aSerialize.AfterDeserialization();
}
return @object;
}
/// <summary>
/// 使用ProtoBuf反序列化数据到实例
/// </summary>
/// <param name="bytes"></param>
/// <param name="index"></param>
/// <param name="count"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public unsafe T Deserialize<T>(byte[] bytes, int index, int count)
{
fixed (byte* ptr = &bytes[index])
{
using var stream = new UnmanagedMemoryStream(ptr, count);
var @object = ProtoBuf.Serializer.Deserialize<T>(stream);
if (@object is ASerialize aSerialize)
{
aSerialize.AfterDeserialization();
}
return @object;
}
}
/// <summary>
/// 使用ProtoBuf反序列化数据到实例
/// </summary>
/// <param name="type"></param>
/// <param name="bytes"></param>
/// <param name="index"></param>
/// <param name="count"></param>
/// <returns></returns>
public unsafe object Deserialize(Type type, byte[] bytes, int index, int count)
{
fixed (byte* ptr = &bytes[index])
{
using var stream = new UnmanagedMemoryStream(ptr, count);
var @object = ProtoBuf.Serializer.Deserialize(type, stream);
if (@object is ASerialize aSerialize)
{
aSerialize.AfterDeserialization();
}
return @object;
}
}
/// <summary>
/// 使用ProtoBuf序列化某一个实例到IBufferWriter中
/// </summary>
/// <param name="object"></param>
/// <param name="buffer"></param>
/// <typeparam name="T"></typeparam>
public void Serialize<T>(T @object, IBufferWriter<byte> buffer)
{
if (@object is ASerialize aSerialize)
{
aSerialize.BeginInit();
}
RuntimeTypeModel.Default.Serialize((MemoryStream)buffer, @object);
}
/// <summary>
/// 使用ProtoBuf序列化某一个实例到IBufferWriter中
/// </summary>
/// <param name="object"></param>
/// <param name="buffer"></param>
public void Serialize(object @object, IBufferWriter<byte> buffer)
{
if (@object is ASerialize aSerialize)
{
aSerialize.BeginInit();
}
RuntimeTypeModel.Default.Serialize((MemoryStream)buffer, @object);
}
/// <summary>
/// 使用ProtoBuf序列化某一个实例到IBufferWriter中
/// </summary>
/// <param name="type"></param>
/// <param name="object"></param>
/// <param name="buffer"></param>
public void Serialize(Type type, object @object, IBufferWriter<byte> buffer)
{
if (@object is ASerialize aSerialize)
{
aSerialize.BeginInit();
}
RuntimeTypeModel.Default.Serialize((MemoryStream)buffer, @object);
}
private byte[] Serialize<T>(T @object)
{
if (@object is ASerialize aSerialize)
{
aSerialize.BeginInit();
}
using (var buffer = new MemoryStream())
{
RuntimeTypeModel.Default.Serialize(buffer, @object);
return buffer.ToArray();
}
}
/// <summary>
/// 克隆
/// </summary>
/// <param name="t"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T Clone<T>(T t)
{
return Deserialize<T>(Serialize(t));
}
}
}
#endif

View File

@@ -0,0 +1,152 @@
using System;
using System.Collections.Generic;
using Fantasy.Assembly;
using Fantasy.Helper;
#if !FANTASY_EXPORTER
using Fantasy.Network;
#endif
#pragma warning disable CS8604 // Possible null reference argument.
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
#pragma warning disable CS8625 // Cannot convert null literal to non-nullable reference type.
#pragma warning disable CS8602 // Dereference of a possibly null reference.
#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type.
namespace Fantasy.Serialize
{
/// <summary>
/// 框架内置的序列化器类型
/// </summary>
public static class FantasySerializerType
{
/// <summary>
/// ProtoBuf在SerializerManager的数组下标
/// </summary>
public const int ProtoBuf = 0;
/// <summary>
/// Bson在SerializerManager的数组下标
/// </summary>
public const int Bson = 1;
}
/// <summary>
/// 管理序列化静态方法,主要是优化网络协议时使用。
/// </summary>
public static class SerializerManager
{
private static ISerialize[] _serializers;
private static bool _isInitialized = false;
#if FANTASY_NET || FANTASY_UNITY
/// <summary>
/// 初始化方法
/// </summary>
public static void Initialize()
{
if (_isInitialized)
{
return;
}
try
{
var sort = new SortedList<long, ISerialize>();
foreach (var serializerType in AssemblySystem.ForEach(typeof(ISerialize)))
{
var serializer = (ISerialize)Activator.CreateInstance(serializerType);
var computeHash64 = HashCodeHelper.ComputeHash64(serializer.SerializeName);
sort.Add(computeHash64, serializer);
}
var index = 1;
_serializers = new ISerialize[sort.Count];
foreach (var (_, serialize) in sort)
{
var serializerIndex = 0;
switch (serialize)
{
case ProtoBufPackHelper:
{
serializerIndex = FantasySerializerType.ProtoBuf;
break;
}
case BsonPackHelper:
{
serializerIndex = FantasySerializerType.Bson;
break;
}
default:
{
serializerIndex = ++index;
break;
}
}
_serializers[serializerIndex] = serialize;
}
_isInitialized = true;
Log.Info($"初始化序列化器成功,数量为:{_serializers.Length}");
}
catch (Exception e)
{
Log.Error(e);
Dispose();
}
}
#else
/// <summary>
/// 初始化方法
/// </summary>
public static void Initialize()
{
if (_isInitialized)
{
return;
}
_serializers = new ISerialize[1];
_serializers[0] = new ProtoBufPackHelper();
}
#endif
/// <summary>
/// 销毁方法
/// </summary>
public static void Dispose()
{
_isInitialized = false;
Array.Clear(_serializers, 0, _serializers.Length);
}
/// <summary>
/// 根据协议类型获取序列化器
/// </summary>
/// <param name="opCodeProtocolType"></param>
/// <returns></returns>
public static ISerialize GetSerializer(uint opCodeProtocolType)
{
return _serializers[opCodeProtocolType];
}
/// <summary>
/// 获得一个序列化器
/// </summary>
/// <param name="opCodeProtocolType"></param>
/// <param name="serializer"></param>
/// <returns></returns>
public static bool TryGetSerializer(uint opCodeProtocolType, out ISerialize serializer)
{
if (opCodeProtocolType < _serializers.Length)
{
serializer = _serializers[opCodeProtocolType];
return true;
}
serializer = default;
return false;
}
}
}