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.

189 lines
9.4KB

  1. using System;
  2. using Svelto.DataStructures;
  3. using Svelto.ECS.Serialization;
  4. namespace Svelto.ECS
  5. {
  6. public partial class EnginesRoot
  7. {
  8. sealed class EntitySerialization : IEntitySerialization
  9. {
  10. public void SerializeEntity(EGID egid, ISerializationData serializationData, int serializationType)
  11. {
  12. var entitiesDb = _enginesRoot._entitiesDB;
  13. //needs to retrieve the meta data associated with the entity
  14. ref var serializableEntityComponent = ref entitiesDb.QueryEntity<SerializableEntityComponent>(egid);
  15. uint descriptorHash = serializableEntityComponent.descriptorHash;
  16. SerializationDescriptorMap serializationDescriptorMap = _enginesRoot.serializationDescriptorMap;
  17. var entityDescriptor = serializationDescriptorMap.GetDescriptorFromHash(descriptorHash);
  18. var entityComponentsToSerialise = entityDescriptor.entitiesToSerialize;
  19. var header =
  20. new SerializableEntityHeader(descriptorHash, egid, (byte) entityComponentsToSerialise.Length);
  21. header.Copy(serializationData);
  22. for (int index = 0; index < entityComponentsToSerialise.Length; index++)
  23. {
  24. var entityBuilder = entityComponentsToSerialise[index];
  25. serializationData.BeginNextEntityComponent();
  26. SerializeEntityComponent(egid, entityBuilder, serializationData, serializationType);
  27. }
  28. }
  29. public EntityInitializer DeserializeNewEntity
  30. (EGID egid, ISerializationData serializationData, int serializationType)
  31. {
  32. //todo: SerializableEntityHeader may be needed to be customizable
  33. var serializableEntityHeader = new SerializableEntityHeader(serializationData);
  34. uint descriptorHash = serializableEntityHeader.descriptorHash;
  35. SerializationDescriptorMap serializationDescriptorMap = _enginesRoot.serializationDescriptorMap;
  36. var entityDescriptor = serializationDescriptorMap.GetDescriptorFromHash(descriptorHash);
  37. IDeserializationFactory factory = serializationDescriptorMap.GetSerializationFactory(descriptorHash);
  38. return factory.BuildDeserializedEntity(egid, serializationData, entityDescriptor, serializationType
  39. , this, this._enginesRoot.GenerateEntityFactory()
  40. , _enginesRoot._isDeserializationOnly);
  41. }
  42. public void DeserializeEntity(ISerializationData serializationData, int serializationType)
  43. {
  44. var serializableEntityHeader = new SerializableEntityHeader(serializationData);
  45. EGID egid = serializableEntityHeader.egid;
  46. DeserializeEntityInternal(serializationData, egid, serializableEntityHeader, serializationType);
  47. }
  48. public void DeserializeEntity(EGID egid, ISerializationData serializationData, int serializationType)
  49. {
  50. var serializableEntityHeader = new SerializableEntityHeader(serializationData);
  51. DeserializeEntityInternal(serializationData, egid, serializableEntityHeader, serializationType);
  52. }
  53. public void DeserializeEntityComponents
  54. (ISerializationData serializationData, ISerializableEntityDescriptor entityDescriptor
  55. , ref EntityInitializer initializer, int serializationType)
  56. {
  57. foreach (var serializableEntityBuilder in entityDescriptor.entitiesToSerialize)
  58. {
  59. serializationData.BeginNextEntityComponent();
  60. serializableEntityBuilder.Deserialize(serializationData, initializer, serializationType);
  61. }
  62. }
  63. public T DeserializeEntityComponent<T>
  64. (ISerializationData serializationData, ISerializableEntityDescriptor entityDescriptor
  65. , int serializationType) where T : unmanaged, IEntityComponent
  66. {
  67. var readPos = serializationData.dataPos;
  68. T entityComponent = default;
  69. foreach (var serializableEntityBuilder in entityDescriptor.entitiesToSerialize)
  70. {
  71. if (serializableEntityBuilder is SerializableComponentBuilder<T> entityBuilder)
  72. {
  73. entityBuilder.Deserialize(serializationData, ref entityComponent, serializationType);
  74. }
  75. break;
  76. }
  77. serializationData.dataPos = readPos;
  78. return entityComponent;
  79. }
  80. public void DeserializeEntityToSwap(EGID localEgid, EGID toEgid)
  81. {
  82. EntitiesDB entitiesDb = _enginesRoot._entitiesDB;
  83. ref var serializableEntityComponent =
  84. ref entitiesDb.QueryEntity<SerializableEntityComponent>(localEgid);
  85. SerializationDescriptorMap serializationDescriptorMap = _enginesRoot.serializationDescriptorMap;
  86. uint descriptorHash = serializableEntityComponent.descriptorHash;
  87. var entityDescriptor = serializationDescriptorMap.GetDescriptorFromHash(descriptorHash);
  88. var entitySubmitOperation =
  89. new EntitySubmitOperation(EntitySubmitOperationType.Swap, localEgid, toEgid
  90. , entityDescriptor.componentsToBuild);
  91. _enginesRoot.CheckRemoveEntityID(localEgid, entityDescriptor.realType);
  92. _enginesRoot.CheckAddEntityID(toEgid, entityDescriptor.realType);
  93. _enginesRoot.QueueEntitySubmitOperation(entitySubmitOperation);
  94. }
  95. public void DeserializeEntityToDelete(EGID egid)
  96. {
  97. EntitiesDB entitiesDB = _enginesRoot._entitiesDB;
  98. ref var serializableEntityComponent = ref entitiesDB.QueryEntity<SerializableEntityComponent>(egid);
  99. uint descriptorHash = serializableEntityComponent.descriptorHash;
  100. SerializationDescriptorMap serializationDescriptorMap = _enginesRoot.serializationDescriptorMap;
  101. var entityDescriptor = serializationDescriptorMap.GetDescriptorFromHash(descriptorHash);
  102. _enginesRoot.CheckRemoveEntityID(egid, entityDescriptor.realType);
  103. var entitySubmitOperation =
  104. new EntitySubmitOperation(EntitySubmitOperationType.Remove, egid, egid
  105. , entityDescriptor.componentsToBuild);
  106. _enginesRoot.QueueEntitySubmitOperation(entitySubmitOperation);
  107. }
  108. public void RegisterSerializationFactory<T>(IDeserializationFactory deserializationFactory)
  109. where T : ISerializableEntityDescriptor, new()
  110. {
  111. SerializationDescriptorMap serializationDescriptorMap = _enginesRoot.serializationDescriptorMap;
  112. serializationDescriptorMap.RegisterSerializationFactory<T>(deserializationFactory);
  113. }
  114. internal EntitySerialization(EnginesRoot enginesRoot) { _enginesRoot = enginesRoot; }
  115. void SerializeEntityComponent
  116. (EGID entityGID, ISerializableComponentBuilder componentBuilder, ISerializationData serializationData
  117. , int serializationType)
  118. {
  119. ExclusiveGroupStruct groupId = entityGID.groupID;
  120. Type entityType = componentBuilder.GetEntityComponentType();
  121. if (!_enginesRoot._entitiesDB.UnsafeQueryEntityDictionary(groupId, entityType, out var safeDictionary))
  122. {
  123. throw new Exception("Entity Serialization failed");
  124. }
  125. componentBuilder.Serialize(entityGID.entityID, safeDictionary, serializationData, serializationType);
  126. }
  127. void DeserializeEntityInternal
  128. (ISerializationData serializationData, EGID egid, SerializableEntityHeader serializableEntityHeader
  129. , int serializationType)
  130. {
  131. SerializationDescriptorMap descriptorMap = _enginesRoot.serializationDescriptorMap;
  132. var entityDescriptor = descriptorMap.GetDescriptorFromHash(serializableEntityHeader.descriptorHash);
  133. if (_enginesRoot._groupEntityComponentsDB.TryGetValue(egid.groupID, out var entitiesInGroupPerType)
  134. == false)
  135. throw new Exception("Entity Serialization failed");
  136. foreach (var serializableEntityBuilder in entityDescriptor.entitiesToSerialize)
  137. {
  138. entitiesInGroupPerType.TryGetValue(
  139. new RefWrapperType(serializableEntityBuilder.GetEntityComponentType()), out var safeDictionary);
  140. serializationData.BeginNextEntityComponent();
  141. serializableEntityBuilder.Deserialize(egid.entityID, safeDictionary, serializationData
  142. , serializationType);
  143. }
  144. }
  145. readonly EnginesRoot _enginesRoot;
  146. }
  147. public IEntitySerialization GenerateEntitySerializer() { return new EntitySerialization(this); }
  148. readonly bool _isDeserializationOnly;
  149. }
  150. }