Reworked BinarySerializer to use BitWriter
This commit is contained in:
parent
20b315b7fc
commit
3624ec4809
@ -45,6 +45,124 @@ namespace MLAPI.Data
|
||||
|
||||
internal static class FieldTypeHelper
|
||||
{
|
||||
internal static object ReadFieldType(BitReader reader, FieldType fieldType)
|
||||
{
|
||||
switch (fieldType)
|
||||
{
|
||||
case FieldType.Bool:
|
||||
return reader.ReadBool();
|
||||
case FieldType.Byte:
|
||||
return reader.ReadByte();
|
||||
case FieldType.Double:
|
||||
return reader.ReadDouble();
|
||||
case FieldType.Single:
|
||||
return reader.ReadFloat();
|
||||
case FieldType.Int:
|
||||
return reader.ReadInt();
|
||||
case FieldType.Long:
|
||||
return reader.ReadLong();
|
||||
case FieldType.SByte:
|
||||
return reader.ReadSByte();
|
||||
case FieldType.Short:
|
||||
return reader.ReadShort();
|
||||
case FieldType.UInt:
|
||||
return reader.ReadUInt();
|
||||
case FieldType.ULong:
|
||||
return reader.ReadULong();
|
||||
case FieldType.UShort:
|
||||
return reader.ReadUShort();
|
||||
case FieldType.String:
|
||||
return reader.ReadString();
|
||||
case FieldType.Vector3:
|
||||
Vector3 vector3 = Vector3.zero;
|
||||
vector3.x = reader.ReadFloat();
|
||||
vector3.y = reader.ReadFloat();
|
||||
vector3.z = reader.ReadFloat();
|
||||
return vector3;
|
||||
case FieldType.Vector2:
|
||||
Vector2 vector2 = Vector2.zero;
|
||||
vector2.x = reader.ReadFloat();
|
||||
vector2.y = reader.ReadFloat();
|
||||
return vector2;
|
||||
case FieldType.Quaternion:
|
||||
Vector3 eulerAngle = Vector3.zero;
|
||||
eulerAngle.x = reader.ReadFloat();
|
||||
eulerAngle.y = reader.ReadFloat();
|
||||
eulerAngle.z = reader.ReadFloat();
|
||||
return Quaternion.Euler(eulerAngle);
|
||||
case FieldType.BoolArray:
|
||||
ushort boolCount = reader.ReadUShort();
|
||||
bool[] bools = new bool[boolCount];
|
||||
for (int j = 0; j < boolCount; j++)
|
||||
bools[j] = reader.ReadBool();
|
||||
return bools;
|
||||
case FieldType.ByteArray:
|
||||
return reader.ReadByteArray();
|
||||
case FieldType.DoubleArray:
|
||||
return reader.ReadDoubleArray();
|
||||
case FieldType.SingleArray:
|
||||
return reader.ReadFloatArray();
|
||||
case FieldType.IntArray:
|
||||
return reader.ReadIntArray();
|
||||
case FieldType.LongArray:
|
||||
return reader.ReadLongArray();
|
||||
case FieldType.SByteArray:
|
||||
return reader.ReadSByteArray();
|
||||
case FieldType.ShortArray:
|
||||
return reader.ReadShortArray();
|
||||
case FieldType.UIntArray:
|
||||
return reader.ReadUIntArray();
|
||||
case FieldType.ULongArray:
|
||||
return reader.ReadULongArray();
|
||||
case FieldType.UShortArray:
|
||||
return reader.ReadUShortArray();
|
||||
case FieldType.StringArray:
|
||||
ushort stringCount = reader.ReadUShort();
|
||||
string[] strings = new string[stringCount];
|
||||
for (int j = 0; j < stringCount; j++)
|
||||
strings[j] = reader.ReadString();
|
||||
return strings;
|
||||
case FieldType.Vector3Array:
|
||||
ushort vector3Count = reader.ReadUShort();
|
||||
Vector3[] vector3s = new Vector3[vector3Count];
|
||||
for (int j = 0; j < vector3Count; j++)
|
||||
{
|
||||
Vector3 vec3 = Vector3.zero;
|
||||
vec3.x = reader.ReadFloat();
|
||||
vec3.y = reader.ReadFloat();
|
||||
vec3.z = reader.ReadFloat();
|
||||
vector3s[j] = vec3;
|
||||
}
|
||||
return vector3s;
|
||||
case FieldType.Vector2Array:
|
||||
ushort vector2Count = reader.ReadUShort();
|
||||
Vector2[] vector2s = new Vector2[vector2Count];
|
||||
for (int j = 0; j < vector2Count; j++)
|
||||
{
|
||||
Vector2 vec2 = Vector2.zero;
|
||||
vec2.x = reader.ReadFloat();
|
||||
vec2.y = reader.ReadFloat();
|
||||
vector2s[j] = vec2;
|
||||
}
|
||||
return vector2s;
|
||||
case FieldType.QuaternionArray:
|
||||
ushort quaternionCount = reader.ReadUShort();
|
||||
Quaternion[] quaternions = new Quaternion[quaternionCount];
|
||||
for (int j = 0; j < quaternionCount; j++)
|
||||
{
|
||||
Vector3 vec3 = Vector3.zero;
|
||||
vec3.x = reader.ReadFloat();
|
||||
vec3.y = reader.ReadFloat();
|
||||
vec3.z = reader.ReadFloat();
|
||||
quaternions[j] = Quaternion.Euler(vec3);
|
||||
}
|
||||
return quaternions;
|
||||
case FieldType.Invalid:
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static void WriteFieldType(BitWriter writer, object value, FieldType fieldType)
|
||||
{
|
||||
switch (fieldType)
|
||||
@ -440,8 +558,10 @@ namespace MLAPI.Data
|
||||
break;
|
||||
case FieldType.BoolArray:
|
||||
ushort boolCount = reader.ReadUShort();
|
||||
bool[] bools = new bool[boolCount];
|
||||
for (int j = 0; j < boolCount; j++)
|
||||
returnVal[i] = reader.ReadBool();
|
||||
bools[j] = reader.ReadBool();
|
||||
returnVal[i] = bools;
|
||||
break;
|
||||
case FieldType.ByteArray:
|
||||
returnVal[i] = reader.ReadByteArray();
|
||||
|
@ -284,6 +284,17 @@ namespace MLAPI.MonoBehaviours.Core
|
||||
return counter;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes a message that has been serialized by the BinarySerializer. This is the same as calling BinarySerializer.Deserialize
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type</typeparam>
|
||||
/// <param name="binary">The serialized version</param>
|
||||
/// <returns>Instance of type</returns>
|
||||
protected T DeserializeMessage<T>(byte[] binary) where T : new()
|
||||
{
|
||||
return BinarySerializer.Deserialize<T>(binary);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deregisters a given message handler
|
||||
/// </summary>
|
||||
|
@ -1,9 +1,8 @@
|
||||
using MLAPI.Attributes;
|
||||
using MLAPI.Data;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MLAPI.NetworkingManagerComponents.Binary
|
||||
@ -41,90 +40,19 @@ namespace MLAPI.NetworkingManagerComponents.Binary
|
||||
cachedFields.Add(instance.GetType().FullName, sortedFields);
|
||||
}
|
||||
|
||||
int outputSize = 0;
|
||||
//Calculate output size
|
||||
for (int i = 0; i < sortedFields.Length; i++)
|
||||
using (BitWriter writer = new BitWriter())
|
||||
{
|
||||
if (sortedFields[i].FieldType == typeof(bool))
|
||||
outputSize += 1;
|
||||
else if (sortedFields[i].FieldType == typeof(byte))
|
||||
outputSize += 1;
|
||||
else if (sortedFields[i].FieldType == typeof(char))
|
||||
outputSize += 2;
|
||||
else if (sortedFields[i].FieldType == typeof(double))
|
||||
outputSize += 8;
|
||||
else if (sortedFields[i].FieldType == typeof(float))
|
||||
outputSize += 4;
|
||||
else if (sortedFields[i].FieldType == typeof(decimal))
|
||||
outputSize += 16;
|
||||
else if (sortedFields[i].FieldType == typeof(int))
|
||||
outputSize += 4;
|
||||
else if (sortedFields[i].FieldType == typeof(long))
|
||||
outputSize += 8;
|
||||
else if (sortedFields[i].FieldType == typeof(sbyte))
|
||||
outputSize += 1;
|
||||
else if (sortedFields[i].FieldType == typeof(short))
|
||||
outputSize += 2;
|
||||
else if (sortedFields[i].FieldType == typeof(uint))
|
||||
outputSize += 4;
|
||||
else if (sortedFields[i].FieldType == typeof(ulong))
|
||||
outputSize += 8;
|
||||
else if (sortedFields[i].FieldType == typeof(ushort))
|
||||
outputSize += 2;
|
||||
else if (sortedFields[i].FieldType == typeof(string))
|
||||
outputSize += Encoding.UTF8.GetByteCount((string)sortedFields[i].GetValue(instance)) + 2;
|
||||
else if (sortedFields[i].FieldType == typeof(byte[]))
|
||||
outputSize += ((byte[])sortedFields[i].GetValue(instance)).Length + 2; //Two bytes to specify the size
|
||||
else
|
||||
Debug.LogWarning("MLAPI: The type \"" + sortedFields[i].FieldType.Name + "\" is not supported by the Binary Serializer. It will be ignored");
|
||||
}
|
||||
|
||||
//Write data
|
||||
using (MemoryStream stream = new MemoryStream(outputSize))
|
||||
{
|
||||
using (BinaryWriter writer = new BinaryWriter(stream))
|
||||
for (int i = 0; i < sortedFields.Length; i++)
|
||||
{
|
||||
for (int i = 0; i < sortedFields.Length; i++)
|
||||
FieldType fieldType = FieldTypeHelper.GetFieldType(sortedFields[i].FieldType);
|
||||
if (fieldType == FieldType.Invalid)
|
||||
{
|
||||
if (sortedFields[i].FieldType == typeof(bool))
|
||||
writer.Write((bool)sortedFields[i].GetValue(instance));
|
||||
else if (sortedFields[i].FieldType == typeof(byte))
|
||||
writer.Write((byte)sortedFields[i].GetValue(instance));
|
||||
else if (sortedFields[i].FieldType == typeof(char))
|
||||
writer.Write((char)sortedFields[i].GetValue(instance));
|
||||
else if (sortedFields[i].FieldType == typeof(double))
|
||||
writer.Write((double)sortedFields[i].GetValue(instance));
|
||||
else if (sortedFields[i].FieldType == typeof(float))
|
||||
writer.Write((float)sortedFields[i].GetValue(instance));
|
||||
else if (sortedFields[i].FieldType == typeof(decimal))
|
||||
writer.Write((decimal)sortedFields[i].GetValue(instance));
|
||||
else if (sortedFields[i].FieldType == typeof(int))
|
||||
writer.Write((int)sortedFields[i].GetValue(instance));
|
||||
else if (sortedFields[i].FieldType == typeof(long))
|
||||
writer.Write((long)sortedFields[i].GetValue(instance));
|
||||
else if (sortedFields[i].FieldType == typeof(sbyte))
|
||||
writer.Write((sbyte)sortedFields[i].GetValue(instance));
|
||||
else if (sortedFields[i].FieldType == typeof(short))
|
||||
writer.Write((short)sortedFields[i].GetValue(instance));
|
||||
else if (sortedFields[i].FieldType == typeof(uint))
|
||||
writer.Write((uint)sortedFields[i].GetValue(instance));
|
||||
else if (sortedFields[i].FieldType == typeof(ulong))
|
||||
writer.Write((ulong)sortedFields[i].GetValue(instance));
|
||||
else if (sortedFields[i].FieldType == typeof(ushort))
|
||||
writer.Write((ushort)sortedFields[i].GetValue(instance));
|
||||
else if (sortedFields[i].FieldType == typeof(string))
|
||||
{
|
||||
writer.Write((ushort)Encoding.UTF8.GetByteCount((string)sortedFields[i].GetValue(instance))); //Size of string in bytes
|
||||
writer.Write(Encoding.UTF8.GetBytes((string)sortedFields[i].GetValue(instance)));
|
||||
}
|
||||
else if (sortedFields[i].FieldType == typeof(byte[]))
|
||||
{
|
||||
writer.Write((ushort)((byte[])sortedFields[i].GetValue(instance)).Length); //Size of byte array
|
||||
writer.Write((byte[])sortedFields[i].GetValue(instance));
|
||||
}
|
||||
Debug.LogWarning("MLAPI: The field " + sortedFields[i].Name + " will not be serialized as it's not of a supported type. Add the BinaryIgnore attribute to prevent this message from shwoing up.");
|
||||
continue;
|
||||
}
|
||||
FieldTypeHelper.WriteFieldType(writer, sortedFields[i].GetValue(instance), fieldType);
|
||||
}
|
||||
return stream.ToArray();
|
||||
return writer.Finalize();
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,52 +76,16 @@ namespace MLAPI.NetworkingManagerComponents.Binary
|
||||
cachedFields.Add(instance.GetType().FullName, sortedFields);
|
||||
}
|
||||
|
||||
using (MemoryStream stream = new MemoryStream(binary))
|
||||
BitReader reader = new BitReader(binary);
|
||||
for (int i = 0; i < sortedFields.Length; i++)
|
||||
{
|
||||
using (BinaryReader reader = new BinaryReader(stream))
|
||||
FieldType fieldType = FieldTypeHelper.GetFieldType(sortedFields[i].FieldType);
|
||||
if (fieldType == FieldType.Invalid)
|
||||
{
|
||||
for (int i = 0; i < sortedFields.Length; i++)
|
||||
{
|
||||
if (sortedFields[i].FieldType == typeof(bool))
|
||||
sortedFields[i].SetValue(instance, reader.ReadBoolean());
|
||||
else if (sortedFields[i].FieldType == typeof(byte))
|
||||
sortedFields[i].SetValue(instance, reader.ReadByte());
|
||||
else if (sortedFields[i].FieldType == typeof(char))
|
||||
sortedFields[i].SetValue(instance, reader.ReadChar());
|
||||
else if (sortedFields[i].FieldType == typeof(double))
|
||||
sortedFields[i].SetValue(instance, reader.ReadDouble());
|
||||
else if (sortedFields[i].FieldType == typeof(float))
|
||||
sortedFields[i].SetValue(instance, reader.ReadSingle());
|
||||
else if (sortedFields[i].FieldType == typeof(decimal))
|
||||
sortedFields[i].SetValue(instance, reader.ReadDecimal());
|
||||
else if (sortedFields[i].FieldType == typeof(int))
|
||||
sortedFields[i].SetValue(instance, reader.ReadInt32());
|
||||
else if (sortedFields[i].FieldType == typeof(long))
|
||||
sortedFields[i].SetValue(instance, reader.ReadInt64());
|
||||
else if (sortedFields[i].FieldType == typeof(sbyte))
|
||||
sortedFields[i].SetValue(instance, reader.ReadSByte());
|
||||
else if (sortedFields[i].FieldType == typeof(short))
|
||||
sortedFields[i].SetValue(instance, reader.ReadInt16());
|
||||
else if (sortedFields[i].FieldType == typeof(uint))
|
||||
sortedFields[i].SetValue(instance, reader.ReadUInt32());
|
||||
else if (sortedFields[i].FieldType == typeof(ulong))
|
||||
sortedFields[i].SetValue(instance, reader.ReadUInt64());
|
||||
else if (sortedFields[i].FieldType == typeof(ushort))
|
||||
sortedFields[i].SetValue(instance, reader.ReadUInt64());
|
||||
else if (sortedFields[i].FieldType == typeof(string))
|
||||
{
|
||||
ushort size = reader.ReadUInt16();
|
||||
sortedFields[i].SetValue(instance, Encoding.UTF8.GetString(reader.ReadBytes(size)));
|
||||
}
|
||||
else if (sortedFields[i].FieldType == typeof(byte[]))
|
||||
{
|
||||
ushort size = reader.ReadUInt16();
|
||||
sortedFields[i].SetValue(instance, reader.ReadBytes(size));
|
||||
}
|
||||
else
|
||||
Debug.LogWarning("MLAPI: The type \"" + sortedFields[i].FieldType.Name + "\" is not supported by the Binary Serializer. It will be ignored");
|
||||
}
|
||||
Debug.LogWarning("MLAPI: The field " + sortedFields[i].Name + " will not be deserialized as it's not of a supported type. Add the BinaryIgnore attribute to prevent this message from shwoing up.");
|
||||
continue;
|
||||
}
|
||||
sortedFields[i].SetValue(instance, FieldTypeHelper.ReadFieldType(reader, fieldType));
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user