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.

92 lines
3.6KB

  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. if (groupEntityComponentsByType.current.TryGetValue(groupID, out var group) == false)
  28. {
  29. group = new FasterDictionary<RefWrapperType, ITypeSafeDictionary>();
  30. groupEntityComponentsByType.current.Add(groupID, group);
  31. }
  32. //track the number of entities created so far in the group.
  33. groupEntityComponentsByType.IncrementEntityCount(groupID);
  34. return group;
  35. }
  36. static void BuildEntitiesAndAddToGroup
  37. (EGID entityID, FasterDictionary<RefWrapperType, ITypeSafeDictionary> @group
  38. , IComponentBuilder[] componentBuilders, IEnumerable<object> implementors
  39. #if DEBUG && !PROFILE_SVELTO
  40. , Type descriptorType
  41. #endif
  42. )
  43. {
  44. #if DEBUG && !PROFILE_SVELTO
  45. DBC.ECS.Check.Require(componentBuilders != null, $"Invalid Entity Descriptor {descriptorType}");
  46. #endif
  47. var numberOfComponents = componentBuilders.Length;
  48. #if DEBUG && !PROFILE_SVELTO
  49. HashSet<Type> types = new HashSet<Type>();
  50. for (var index = 0; index < numberOfComponents; ++index)
  51. {
  52. var entityComponentType = componentBuilders[index].GetEntityComponentType();
  53. if (types.Contains(entityComponentType))
  54. {
  55. throw new ECSException(
  56. $"EntityBuilders must be unique inside an EntityDescriptor. Descriptor Type {descriptorType} Component Type: {entityComponentType}");
  57. }
  58. types.Add(entityComponentType);
  59. }
  60. #endif
  61. for (var index = 0; index < numberOfComponents; ++index)
  62. {
  63. var entityComponentBuilder = componentBuilders[index];
  64. BuildEntity(entityID, @group, entityComponentBuilder, implementors);
  65. }
  66. }
  67. static void BuildEntity(EGID entityID, FasterDictionary<RefWrapperType, ITypeSafeDictionary> group
  68. , IComponentBuilder componentBuilder, IEnumerable<object> implementors)
  69. {
  70. var entityComponentType = componentBuilder.GetEntityComponentType();
  71. var safeDictionary = group.GetOrCreate(new RefWrapperType(entityComponentType)
  72. , (ref IComponentBuilder cb) => cb.CreateDictionary(1)
  73. , ref componentBuilder);
  74. //if the safeDictionary hasn't been created yet, it will be created inside this method.
  75. componentBuilder.BuildEntityAndAddToList(safeDictionary, entityID, implementors);
  76. }
  77. }
  78. }