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.

89 lines
3.4KB

  1. using System;
  2. using System.Collections.Generic;
  3. using Svelto.DataStructures;
  4. namespace Svelto.ECS.Internal
  5. {
  6. static class EntityFactory
  7. {
  8. public static FasterDictionary<RefWrapperType, ITypeSafeDictionary> BuildGroupedEntities
  9. (EGID egid, EnginesRoot.DoubleBufferedEntitiesToAdd groupEntitiesToAdd, IComponentBuilder[] componentsToBuild
  10. , IEnumerable<object> implementors
  11. #if DEBUG && !PROFILE_SVELTO
  12. , Type descriptorType
  13. #endif
  14. )
  15. {
  16. var group = FetchEntityGroup(egid.groupID, groupEntitiesToAdd);
  17. BuildEntitiesAndAddToGroup(egid, group, componentsToBuild, implementors
  18. #if DEBUG && !PROFILE_SVELTO
  19. , descriptorType
  20. #endif
  21. );
  22. return group;
  23. }
  24. static FasterDictionary<RefWrapperType, ITypeSafeDictionary> FetchEntityGroup
  25. (ExclusiveGroupStruct groupID, EnginesRoot.DoubleBufferedEntitiesToAdd groupEntityComponentsByType)
  26. {
  27. var group = groupEntityComponentsByType.current.GetOrCreate(
  28. groupID, () => new FasterDictionary<RefWrapperType, ITypeSafeDictionary>());
  29. //track the number of entities created so far in the group.
  30. groupEntityComponentsByType.IncrementEntityCount(groupID);
  31. return group;
  32. }
  33. static void BuildEntitiesAndAddToGroup
  34. (EGID entityID, FasterDictionary<RefWrapperType, ITypeSafeDictionary> @group
  35. , IComponentBuilder[] componentBuilders, IEnumerable<object> implementors
  36. #if DEBUG && !PROFILE_SVELTO
  37. , Type descriptorType
  38. #endif
  39. )
  40. {
  41. #if DEBUG && !PROFILE_SVELTO
  42. DBC.ECS.Check.Require(componentBuilders != null, $"Invalid Entity Descriptor {descriptorType}");
  43. #endif
  44. var numberOfComponents = componentBuilders.Length;
  45. #if DEBUG && !PROFILE_SVELTO
  46. HashSet<Type> types = new HashSet<Type>();
  47. for (var index = 0; index < numberOfComponents; ++index)
  48. {
  49. var entityComponentType = componentBuilders[index].GetEntityComponentType();
  50. if (types.Contains(entityComponentType))
  51. {
  52. throw new ECSException(
  53. $"EntityBuilders must be unique inside an EntityDescriptor. Descriptor Type {descriptorType} Component Type: {entityComponentType}");
  54. }
  55. types.Add(entityComponentType);
  56. }
  57. #endif
  58. for (var index = 0; index < numberOfComponents; ++index)
  59. {
  60. var entityComponentBuilder = componentBuilders[index];
  61. BuildEntity(entityID, @group, entityComponentBuilder, implementors);
  62. }
  63. }
  64. static void BuildEntity
  65. (EGID entityID, FasterDictionary<RefWrapperType, ITypeSafeDictionary> group
  66. , IComponentBuilder componentBuilder, IEnumerable<object> implementors)
  67. {
  68. var entityComponentType = componentBuilder.GetEntityComponentType();
  69. var safeDictionary = group.GetOrCreate(new RefWrapperType(entityComponentType)
  70. , (ref IComponentBuilder cb) => cb.CreateDictionary(1)
  71. , ref componentBuilder);
  72. // if the safeDictionary hasn't been created yet, it will be created inside this method.
  73. componentBuilder.BuildEntityAndAddToList(safeDictionary, entityID, implementors);
  74. }
  75. }
  76. }