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.

123 lines
4.7KB

  1. using System;
  2. using System.Reflection;
  3. using System.Text;
  4. using Svelto.DataStructures;
  5. using Svelto.Utilities;
  6. namespace Svelto.ECS.Serialization
  7. {
  8. public static class DesignatedHash
  9. {
  10. public static readonly Func<byte[], uint> Hash = Murmur3.MurmurHash3_x86_32;
  11. }
  12. public abstract class SerializableEntityDescriptor<TType> : ISerializableEntityDescriptor
  13. where TType : IEntityDescriptor, new()
  14. {
  15. static SerializableEntityDescriptor()
  16. {
  17. IEntityBuilder[] defaultEntities = EntityDescriptorTemplate<TType>.descriptor.entitiesToBuild;
  18. var hashNameAttribute = _type.GetCustomAttribute<HashNameAttribute>();
  19. if (hashNameAttribute == null)
  20. {
  21. throw new Exception("HashName attribute not found on the serializable type ".FastConcat(_type.FullName));
  22. }
  23. _hash = DesignatedHash.Hash(Encoding.ASCII.GetBytes(hashNameAttribute._name));
  24. var (index, dynamicIndex) = SetupSpecialEntityStruct(defaultEntities, out _entitiesToBuild);
  25. if (index == -1)
  26. {
  27. index = _entitiesToBuild.Length - 1;
  28. }
  29. // Stores the hash of this EntityDescriptor
  30. _entitiesToBuild[index] = new EntityBuilder<SerializableEntityStruct>
  31. (
  32. new SerializableEntityStruct
  33. {
  34. descriptorHash = _hash
  35. }
  36. );
  37. // If the current serializable is an ExtendibleDescriptor, I have to update it.
  38. if (dynamicIndex != -1)
  39. {
  40. _entitiesToBuild[dynamicIndex] = new EntityBuilder<EntityStructInfoView>
  41. (
  42. new EntityStructInfoView
  43. {
  44. entitiesToBuild = _entitiesToBuild
  45. }
  46. );
  47. }
  48. /////
  49. var entitiesToSerialize = new FasterList<ISerializableEntityBuilder>();
  50. _entitiesToSerializeMap = new FasterDictionary<RefWrapper<Type>, ISerializableEntityBuilder>();
  51. foreach (IEntityBuilder e in defaultEntities)
  52. {
  53. if (e is ISerializableEntityBuilder serializableEntityBuilder)
  54. {
  55. var entityType = serializableEntityBuilder.GetEntityType();
  56. _entitiesToSerializeMap[new RefWrapper<Type>(entityType)] = serializableEntityBuilder;
  57. entitiesToSerialize.Add(serializableEntityBuilder);
  58. }
  59. }
  60. _entitiesToSerialize = entitiesToSerialize.ToArray();
  61. }
  62. static (int indexSerial, int indexDynamic) SetupSpecialEntityStruct(IEntityBuilder[] defaultEntities,
  63. out IEntityBuilder[] entitiesToBuild)
  64. {
  65. int length = defaultEntities.Length;
  66. int newLenght = length + 1;
  67. int indexSerial = -1;
  68. int indexDynamic = -1;
  69. for (var i = 0; i < length; ++i)
  70. {
  71. if (defaultEntities[i].GetEntityType() == _serializableStructType)
  72. {
  73. indexSerial = i;
  74. --newLenght;
  75. }
  76. if (defaultEntities[i].GetEntityType() == EntityBuilderUtilities.ENTITY_STRUCT_INFO_VIEW)
  77. {
  78. indexDynamic = i;
  79. }
  80. }
  81. entitiesToBuild = new IEntityBuilder[newLenght];
  82. Array.Copy(defaultEntities, 0, entitiesToBuild, 0, length);
  83. return (indexSerial, indexDynamic);
  84. }
  85. public void CopySerializedEntityStructs(in EntityStructInitializer sourceInitializer, in EntityStructInitializer destinationInitializer, SerializationType serializationType)
  86. {
  87. foreach (ISerializableEntityBuilder e in entitiesToSerialize)
  88. {
  89. e.CopySerializedEntityStructs(sourceInitializer, destinationInitializer, serializationType);
  90. }
  91. }
  92. public IEntityBuilder[] entitiesToBuild => _entitiesToBuild;
  93. public uint hash => _hash;
  94. public ISerializableEntityBuilder[] entitiesToSerialize => _entitiesToSerialize;
  95. static readonly IEntityBuilder[] _entitiesToBuild;
  96. static readonly FasterDictionary<RefWrapper<Type>, ISerializableEntityBuilder> _entitiesToSerializeMap;
  97. static readonly ISerializableEntityBuilder[] _entitiesToSerialize;
  98. static readonly uint _hash;
  99. static readonly Type _serializableStructType = typeof(SerializableEntityStruct);
  100. static readonly Type _type = typeof(TType);
  101. }
  102. }