饭太稀
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
|
||||
Reference in New Issue
Block a user