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.

79 lines
3.1KB

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