Mirror of Svelto.ECS because we're a fan of it
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
4.2KB

  1. using System;
  2. using Svelto.Common;
  3. using Svelto.ECS.Internal;
  4. namespace Svelto.ECS.Serialization
  5. {
  6. public struct SerializersInfo<SerializationEnum>
  7. where SerializationEnum : Enum
  8. {
  9. public uint numberOfSerializationTypes => (uint)length;
  10. static readonly int length = Enum.GetNames(typeof(SerializationEnum)).Length;
  11. }
  12. public class SerializableComponentBuilder<T>: ComponentBuilder<T>, ISerializableComponentBuilder
  13. where T : unmanaged, IEntityComponent
  14. {
  15. public static uint SIZE => (uint)MemoryUtilities.SizeOf<T>();
  16. protected SerializableComponentBuilder() { }
  17. public void Serialize(uint entityID, ITypeSafeDictionary dictionary, ISerializationData serializationData
  18. , int serializationType)
  19. {
  20. IComponentSerializer<T> componentSerializer = _serializers[serializationType];
  21. var safeDictionary = (ITypeSafeDictionary<T>)dictionary;
  22. if (safeDictionary.TryFindIndex(entityID, out uint index) == false)
  23. {
  24. throw new ECSException("Entity Serialization failed");
  25. }
  26. ref T val = ref safeDictionary.GetDirectValueByRef(index);
  27. serializationData.dataPos = (uint)serializationData.data.count;
  28. serializationData.data.IncrementCountBy((uint)componentSerializer.size);
  29. componentSerializer.SerializeSafe(val, serializationData);
  30. }
  31. public void Deserialize(uint entityID, ITypeSafeDictionary dictionary, ISerializationData serializationData
  32. , int serializationType)
  33. {
  34. IComponentSerializer<T> componentSerializer = _serializers[(int)serializationType];
  35. // Handle the case when an entity struct is gone
  36. var safeDictionary = (ITypeSafeDictionary<T>)dictionary;
  37. if (safeDictionary.TryFindIndex(entityID, out uint index) == false)
  38. {
  39. throw new ECSException("Entity Deserialization failed");
  40. }
  41. ref T val = ref safeDictionary.GetDirectValueByRef(index);
  42. componentSerializer.DeserializeSafe(ref val, serializationData);
  43. }
  44. public void Deserialize(ISerializationData serializationData, in EntityInitializer initializer
  45. , int serializationType)
  46. {
  47. IComponentSerializer<T> componentSerializer = _serializers[(int)serializationType];
  48. componentSerializer.DeserializeSafe(ref initializer.GetOrAdd<T>(), serializationData);
  49. }
  50. public int Size(int serializationType)
  51. {
  52. return (int)_serializers[(int)serializationType].size;
  53. }
  54. public void Deserialize(ISerializationData serializationData, ref T entityComponent, int serializationType)
  55. {
  56. IComponentSerializer<T> componentSerializer = _serializers[(int)serializationType];
  57. componentSerializer.DeserializeSafe(ref entityComponent, serializationData);
  58. }
  59. private protected IComponentSerializer<T>[] _serializers;
  60. }
  61. public class SerializableComponentBuilder<SerializationType, T>: SerializableComponentBuilder<T>
  62. where T : unmanaged, IEntityComponent
  63. where SerializationType : Enum
  64. {
  65. static SerializableComponentBuilder() { }
  66. public SerializableComponentBuilder(params ValueTuple<int, IComponentSerializer<T>>[] serializers)
  67. {
  68. var length = new SerializersInfo<SerializationType>().numberOfSerializationTypes;
  69. _serializers = new IComponentSerializer<T>[(int)length];
  70. for (int i = 0; i < serializers.Length; i++)
  71. {
  72. ref (int, IComponentSerializer<T>) s = ref serializers[i];
  73. _serializers[(int)s.Item1] = s.Item2;
  74. }
  75. // Just in case the above are the same type
  76. if (serializers.Length > 0)
  77. {
  78. for (int i = 0; i < (int)length; i++)
  79. {
  80. if (_serializers[i] == null)
  81. _serializers[i] = new DontSerialize<T>();
  82. }
  83. }
  84. else
  85. for (int i = 0; i < (int)length; i++)
  86. {
  87. _serializers[i] = new DefaultSerializer<T>();
  88. }
  89. }
  90. }
  91. }