/// <summary> /// Serializes all entities matching the specified filter /// </summary> /// <param name="filter">Filter</param> public byte[] Serialize(EcsFilter filter) { IEcsGroup group = Filter(filter); byte[] data; using (BinaryDataWriter writer = new BinaryDataWriter()) { foreach (IEcsArchetype archetype in group) { byte[] indices = archetype.Indices; for (int i = 0; i < archetype.EntitiesCount; i++) { IEcsEntity entity = archetype[i]; BinaryDataWriter entityWriter = writer.TryWriteNode(sizeof(uint)); foreach (byte index in indices) { CompositeBinarySerializer ser = Serializer.GetSerializer(EcsTypeManager.Types[index]); BinaryDataWriter componentWriter = entityWriter.TryWriteNode(sizeof(byte)); ser.Serialize(archetype.GetComponentPool(index).Get(i), componentWriter); entityWriter.WriteByte(index); componentWriter.PushNode(); } writer.WriteUInt(entity.Id); entityWriter.PushNode(); } } data = writer.GetData(); } return(data); }
public static byte[] Serialize(object obj, Baseline <byte> baseline) { CompositeBinarySerializer serializer = GetSerializer(obj.GetType()); if (!baseline.HasValues) { baseline.CreateValues(serializer.Count); } using (BinaryDataWriter writer = new BinaryDataWriter()) { serializer.Serialize(obj, writer, baseline); return(writer.GetData()); } }
public static CompositeBinarySerializer RegisterType(Type ownerType) { if (Serializers.TryGetValue(ownerType, out CompositeBinarySerializer item)) { return(item); } FieldInfo[] fields = ownerType.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); List <IBinarySerializer> serializers = new List <IBinarySerializer>(fields.Length); for (byte index = 0; index < fields.Length; index++) { FieldInfo field = fields[index]; BinaryItemAttribute attr = (BinaryItemAttribute)field.GetCustomAttribute(typeof(BinaryItemAttribute), true); if (attr == null) { continue; } Type fieldType = field.FieldType; if (fieldType.IsPrimitive) { if (fieldType == typeof(bool)) { serializers.Add(new BoolBinarySerializer(index, ownerType, field, BoolWriter)); } else if (fieldType == typeof(byte)) { serializers.Add(new ByteBinarySerializer(index, ownerType, field, ByteWriter)); } else if (fieldType == typeof(sbyte)) { serializers.Add(new SByteBinarySerializer(index, ownerType, field, SbyteWriter)); } else if (fieldType == typeof(short)) { serializers.Add(new ShortBinarySerializer(index, ownerType, field, ShortWriter)); } else if (fieldType == typeof(ushort)) { serializers.Add(new UShortBinarySerializer(index, ownerType, field, UShortWriter)); } else if (fieldType == typeof(int)) { serializers.Add(new IntBinarySerializer(index, ownerType, field, IntWriter)); } else if (fieldType == typeof(uint)) { serializers.Add(new UIntBinarySerializer(index, ownerType, field, UIntWriter)); } else if (fieldType == typeof(long)) { serializers.Add(new LongBinarySerializer(index, ownerType, field, LongWriter)); } else if (fieldType == typeof(ulong)) { serializers.Add(new ULongBinarySerializer(index, ownerType, field, UlongWriter)); } else if (fieldType == typeof(double)) { serializers.Add(new DoubleBinarySerializer(index, ownerType, field, DoubleWriter)); } else if (fieldType == typeof(char)) { serializers.Add(new CharBinarySerializer(index, ownerType, field, CharWriter)); } else if (fieldType == typeof(float)) { serializers.Add(attr.IsShort ? (IBinarySerializer) new ShortFloatBinarySerializer(index, ownerType, field, ShortFloatWriter) : new FloatBinarySerializer(index, ownerType, field, FloatWriter)); } else { throw new ArgumentException(); } } else if (fieldType.IsEnum) { Type underlyingType = Enum.GetUnderlyingType(fieldType); if (underlyingType == typeof(byte)) { serializers.Add(new ByteEnumBinarySerializer(index, ownerType, field)); } else if (underlyingType == typeof(int)) { serializers.Add(new IntEnumBinarySerializer(index, ownerType, field)); } else { throw new ArgumentException("Not supported enum underlying type: " + underlyingType.Name); } } else if (fieldType == typeof(string)) { serializers.Add(new StringBinarySerializer(index, ownerType, field, StringWriter)); } else if (typeof(IProperty).IsAssignableFrom(fieldType)) { if (fieldType == typeof(Property <bool>)) { serializers.Add(new BoolPropertyBinarySerializer(index, ownerType, field, BoolWriter)); } else if (fieldType == typeof(Property <byte>)) { serializers.Add(new BytePropertyBinarySerializer(index, ownerType, field, ByteWriter)); } else if (fieldType == typeof(Property <sbyte>)) { serializers.Add(new SBytePropertyBinarySerializer(index, ownerType, field, SbyteWriter)); } else if (fieldType == typeof(Property <short>)) { serializers.Add(new ShortPropertyBinarySerializer(index, ownerType, field, ShortWriter)); } else if (fieldType == typeof(Property <ushort>)) { serializers.Add(new UShortPropertyBinarySerializer(index, ownerType, field, UShortWriter)); } else if (fieldType == typeof(Property <int>)) { serializers.Add(new IntPropertyBinarySerializer(index, ownerType, field, IntWriter)); } else if (fieldType == typeof(Property <uint>)) { serializers.Add(new UIntPropertyBinarySerializer(index, ownerType, field, UIntWriter)); } else if (fieldType == typeof(Property <long>)) { serializers.Add(new LongPropertyBinarySerializer(index, ownerType, field, LongWriter)); } else if (fieldType == typeof(Property <ulong>)) { serializers.Add(new ULongPropertyBinarySerializer(index, ownerType, field, UlongWriter)); } else if (fieldType == typeof(Property <double>)) { serializers.Add(new DoublePropertyBinarySerializer(index, ownerType, field, DoubleWriter)); } else if (fieldType == typeof(Property <char>)) { serializers.Add(new CharPropertyBinarySerializer(index, ownerType, field, CharWriter)); } else if (fieldType == typeof(Property <string>)) { serializers.Add(new StringPropertyBinarySerializer(index, ownerType, field, StringWriter)); } else if (fieldType == typeof(Property <float>)) { serializers.Add(attr.IsShort ? (IBinarySerializer) new ShortFloatPropertyBinarySerializer(index, ownerType, field, ShortFloatWriter) : new FloatPropertyBinarySerializer(index, ownerType, field, FloatWriter)); } else { throw new ArgumentException(); } } else if (fieldType.IsClass) { if (Serializers.TryGetValue(fieldType, out CompositeBinarySerializer ser)) { serializers.Add(new ByteWrapperBinarySerializer <byte>(index, ownerType, field, ser, ser.Count)); } else if (typeof(IBinaryObjectCollection).IsAssignableFrom(fieldType)) { Type valueType = fieldType.GenericTypeArguments[0]; CompositeBinarySerializer valueSer = GetSerializer(valueType); if (!Creators.TryGetValue(valueType, out ObjectActivator itemCreator)) { itemCreator = Expressions.Expressions.InstantiateCreator(valueType.GetConstructor(new Type[] { })); Creators.Add(valueType, itemCreator); } if (typeof(IBinaryObjectCollection <byte>).IsAssignableFrom(fieldType)) { serializers.Add(new ByteWrapperBinarySerializer <byte>(index, ownerType, field, new DictionaryByteKeyBinarySerializer(itemCreator, valueSer, ByteWriter))); } else if (typeof(IBinaryObjectCollection <short>).IsAssignableFrom(fieldType)) { serializers.Add(new ByteWrapperBinarySerializer <short>(index, ownerType, field, new DictionaryShortKeyBinarySerializer(itemCreator, valueSer, ShortWriter))); } else if (typeof(IBinaryObjectCollection <ushort>).IsAssignableFrom(fieldType)) { serializers.Add(new ByteWrapperBinarySerializer <ushort>(index, ownerType, field, new DictionaryUShortKeyBinarySerializer(itemCreator, valueSer, UShortWriter))); } else if (typeof(IBinaryObjectCollection <int>).IsAssignableFrom(fieldType)) { serializers.Add(new ByteWrapperBinarySerializer <int>(index, ownerType, field, new DictionaryIntKeyBinarySerializer(itemCreator, valueSer, IntWriter))); } else if (typeof(IBinaryObjectCollection <uint>).IsAssignableFrom(fieldType)) { serializers.Add(new ByteWrapperBinarySerializer <uint>(index, ownerType, field, new DictionaryUIntKeyBinarySerializer(itemCreator, valueSer, UIntWriter))); } else if (typeof(IBinaryObjectCollection <long>).IsAssignableFrom(fieldType)) { serializers.Add(new ByteWrapperBinarySerializer <long>(index, ownerType, field, new DictionaryLongKeyBinarySerializer(itemCreator, valueSer, LongWriter))); } else if (typeof(IBinaryObjectCollection <ulong>).IsAssignableFrom(fieldType)) { serializers.Add(new ByteWrapperBinarySerializer <ulong>(index, ownerType, field, new DictionaryULongKeyBinarySerializer(itemCreator, valueSer, UlongWriter))); } else { throw new ArgumentException(); } } else { ser = RegisterType(fieldType); serializers.Add(new ByteWrapperBinarySerializer <byte>(index, ownerType, field, ser, ser.Count)); } } else { throw new ArgumentException(); } } CompositeBinarySerializer serializer = new CompositeBinarySerializer(serializers); Serializers.Add(ownerType, new CompositeBinarySerializer(serializers)); return(serializer); }
/// <summary> /// Serializes all objects matching the specified filter. Regarding baseline /// </summary> /// <param name="filter">Filter</param> /// <param name="baseline">Baseline</param> public byte[] Serialize(EcsFilter filter, Baseline <uint> baseline) { IEcsGroup group = Filter(filter); byte[] data; using (BinaryDataWriter writer = new BinaryDataWriter()) { List <uint> entitiesBaseKeys = new List <uint>(baseline.BaselineKeys); foreach (IEcsArchetype archetype in group) { byte[] indices = archetype.Indices; for (int i = 0; i < archetype.EntitiesCount; i++) { IEcsEntity entity = archetype[i]; uint entityId = entity.Id; BinaryDataWriter entityWriter = writer.TryWriteNode(sizeof(uint)); Baseline <byte> entityBaseline = baseline.GetOrCreateBaseline <Baseline <byte> >(entityId, 0, out bool entIsNew); List <byte> entityBaseKeys = new List <byte>(entityBaseline.BaselineKeys); foreach (byte index in indices) { CompositeBinarySerializer ser = Serializer.GetSerializer(EcsTypeManager.Types[index]); BinaryDataWriter compWriter = entityWriter.TryWriteNode(sizeof(byte)); Baseline <byte> compBaseline = entityBaseline.GetOrCreateBaseline <Baseline <byte> >(index, ser.Count, out bool compIsNew); ser.Serialize(archetype.GetComponentPool(index).Get(i), compWriter, compBaseline); if (compWriter.Length > 0 || compIsNew) { entityWriter.WriteByte(index); compWriter.PushNode(); } entityBaseKeys.Remove(index); } if (entityBaseKeys.Count > 0) { entityWriter.WriteByte(byte.MaxValue); foreach (byte key in entityBaseKeys) { entityWriter.WriteByte(key); entityBaseline.DestroyBaseline(key); } } if (entityWriter.Length > 0 || entIsNew) { writer.WriteUInt(entityId); entityWriter.PushNode(); } entitiesBaseKeys.Remove(entityId); } } if (entitiesBaseKeys.Count > 0) { writer.WriteUInt(uint.MaxValue); foreach (uint key in entitiesBaseKeys) { writer.WriteUInt(key); baseline.DestroyBaseline(key); } } data = writer.GetData(); } return(data); }