饭太稀
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Fantasy.Serialize
|
||||
{
|
||||
/// <summary>
|
||||
/// 代表是一个ProtoBuf协议
|
||||
/// </summary>
|
||||
public interface IProto
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user