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.

126 lines
4.6KB

  1. using System;
  2. using Svelto.DataStructures;
  3. namespace Svelto.ECS
  4. {
  5. /// <summary>
  6. /// DynamicEntityDescriptor can be used to add entity components to an existing EntityDescriptor that act as flags,
  7. /// at building time.
  8. /// This method allocates, so it shouldn't be abused
  9. /// </summary>
  10. /// <typeparam name="TType"></typeparam>
  11. public struct DynamicEntityDescriptor<TType> : IDynamicEntityDescriptor where TType : IEntityDescriptor, new()
  12. {
  13. internal DynamicEntityDescriptor(bool isExtendible) : this()
  14. {
  15. var defaultEntities = EntityDescriptorTemplate<TType>.descriptor.componentsToBuild;
  16. var length = defaultEntities.Length;
  17. ComponentsToBuild = new IComponentBuilder[length + 1];
  18. Array.Copy(defaultEntities, 0, ComponentsToBuild, 0, length);
  19. //assign it after otherwise the previous copy will overwrite the value in case the item
  20. //is already present
  21. ComponentsToBuild[length] = new ComponentBuilder<EntityInfoComponent>
  22. (
  23. new EntityInfoComponent
  24. {
  25. componentsToBuild = ComponentsToBuild
  26. }
  27. );
  28. }
  29. public DynamicEntityDescriptor(IComponentBuilder[] extraEntityBuilders) : this()
  30. {
  31. var extraEntitiesLength = extraEntityBuilders.Length;
  32. ComponentsToBuild = Construct(extraEntitiesLength, extraEntityBuilders,
  33. EntityDescriptorTemplate<TType>.descriptor.componentsToBuild);
  34. }
  35. public DynamicEntityDescriptor(FasterList<IComponentBuilder> extraEntityBuilders) : this()
  36. {
  37. var extraEntities = extraEntityBuilders.ToArrayFast(out _);
  38. var extraEntitiesLength = extraEntityBuilders.count;
  39. ComponentsToBuild = Construct((int) extraEntitiesLength, extraEntities,
  40. EntityDescriptorTemplate<TType>.descriptor.componentsToBuild);
  41. }
  42. public void ExtendWith<T>() where T : IEntityDescriptor, new()
  43. {
  44. var newEntitiesToBuild = EntityDescriptorTemplate<T>.descriptor.componentsToBuild;
  45. ComponentsToBuild = Construct(newEntitiesToBuild.Length, newEntitiesToBuild, ComponentsToBuild);
  46. }
  47. public void ExtendWith(IComponentBuilder[] extraEntities)
  48. {
  49. ComponentsToBuild = Construct(extraEntities.Length, extraEntities, ComponentsToBuild);
  50. }
  51. static IComponentBuilder[] Construct(int extraEntitiesLength, IComponentBuilder[] extraEntities,
  52. IComponentBuilder[] startingEntities)
  53. {
  54. IComponentBuilder[] localEntitiesToBuild;
  55. if (extraEntitiesLength == 0)
  56. {
  57. localEntitiesToBuild = startingEntities;
  58. return localEntitiesToBuild;
  59. }
  60. var defaultEntities = startingEntities;
  61. var index = SetupEntityInfoComponent(defaultEntities, out localEntitiesToBuild, extraEntitiesLength);
  62. Array.Copy(extraEntities, 0, localEntitiesToBuild, defaultEntities.Length, extraEntitiesLength);
  63. //assign it after otherwise the previous copy will overwrite the value in case the item
  64. //is already present
  65. localEntitiesToBuild[index] = new ComponentBuilder<EntityInfoComponent>
  66. (
  67. new EntityInfoComponent
  68. {
  69. componentsToBuild = localEntitiesToBuild
  70. }
  71. );
  72. return localEntitiesToBuild;
  73. }
  74. static int SetupEntityInfoComponent(IComponentBuilder[] defaultEntities, out IComponentBuilder[] componentsToBuild,
  75. int extraLenght)
  76. {
  77. int length = defaultEntities.Length;
  78. int index = -1;
  79. for (var i = 0; i < length; i++)
  80. {
  81. //the special entity already exists
  82. if (defaultEntities[i].GetEntityComponentType() == ComponentBuilderUtilities.ENTITY_INFO_COMPONENT)
  83. {
  84. index = i;
  85. break;
  86. }
  87. }
  88. if (index == -1)
  89. {
  90. index = length + extraLenght;
  91. componentsToBuild = new IComponentBuilder[index + 1];
  92. }
  93. else
  94. componentsToBuild = new IComponentBuilder[length + extraLenght];
  95. Array.Copy(defaultEntities, 0, componentsToBuild, 0, length);
  96. return index;
  97. }
  98. public IComponentBuilder[] componentsToBuild => ComponentsToBuild;
  99. IComponentBuilder[] ComponentsToBuild;
  100. }
  101. }