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.

128 lines
4.5KB

  1. using System;
  2. using Svelto.DataStructures;
  3. namespace Svelto.ECS
  4. {
  5. /// <summary>
  6. /// DynamicEntityDescriptor can be used to add entity views 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> : IEntityDescriptor where TType : IEntityDescriptor, new()
  12. {
  13. internal DynamicEntityDescriptor(bool isExtendible) : this()
  14. {
  15. var defaultEntities = EntityDescriptorTemplate<TType>.descriptor.entitiesToBuild;
  16. var length = defaultEntities.Length;
  17. _entitiesToBuild = new IEntityBuilder[length + 1];
  18. Array.Copy(defaultEntities, 0, _entitiesToBuild, 0, length);
  19. //assign it after otherwise the previous copy will overwrite the value in case the item
  20. //is already present
  21. _entitiesToBuild[length] = new EntityBuilder<EntityStructInfoView>
  22. (
  23. new EntityStructInfoView
  24. {
  25. entitiesToBuild = _entitiesToBuild
  26. }
  27. );
  28. }
  29. public DynamicEntityDescriptor(IEntityBuilder[] extraEntityBuilders) : this()
  30. {
  31. var extraEntitiesLength = extraEntityBuilders.Length;
  32. _entitiesToBuild = Construct(extraEntitiesLength, extraEntityBuilders,
  33. EntityDescriptorTemplate<TType>.descriptor.entitiesToBuild);
  34. }
  35. public DynamicEntityDescriptor(FasterList<IEntityBuilder> extraEntityBuilders) : this()
  36. {
  37. var extraEntities = extraEntityBuilders.ToArrayFast();
  38. var extraEntitiesLength = extraEntityBuilders.Count;
  39. _entitiesToBuild = Construct(extraEntitiesLength, extraEntities,
  40. EntityDescriptorTemplate<TType>.descriptor.entitiesToBuild);
  41. }
  42. public void ExtendWith<T>() where T : IEntityDescriptor, new()
  43. {
  44. var newEntitiesToBuild = EntityDescriptorTemplate<T>.descriptor.entitiesToBuild;
  45. _entitiesToBuild = Construct(newEntitiesToBuild.Length, newEntitiesToBuild, _entitiesToBuild);
  46. }
  47. public void ExtendWith(IEntityBuilder[] extraEntities)
  48. {
  49. _entitiesToBuild = Construct(extraEntities.Length, extraEntities, _entitiesToBuild);
  50. }
  51. static IEntityBuilder[] Construct(int extraEntitiesLength, IEntityBuilder[] extraEntities,
  52. IEntityBuilder[] startingEntities)
  53. {
  54. IEntityBuilder[] localEntitiesToBuild;
  55. if (extraEntitiesLength == 0)
  56. {
  57. localEntitiesToBuild = startingEntities;
  58. return localEntitiesToBuild;
  59. }
  60. var defaultEntities = startingEntities;
  61. var length = defaultEntities.Length;
  62. var index = SetupSpecialEntityStruct(defaultEntities, out localEntitiesToBuild, extraEntitiesLength);
  63. Array.Copy(extraEntities, 0, localEntitiesToBuild, length, extraEntitiesLength);
  64. //assign it after otherwise the previous copy will overwrite the value in case the item
  65. //is already present
  66. localEntitiesToBuild[index] = new EntityBuilder<EntityStructInfoView>
  67. (
  68. new EntityStructInfoView
  69. {
  70. entitiesToBuild = localEntitiesToBuild
  71. }
  72. );
  73. return localEntitiesToBuild;
  74. }
  75. static int SetupSpecialEntityStruct(IEntityBuilder[] defaultEntities, out IEntityBuilder[] entitiesToBuild,
  76. int extraLenght)
  77. {
  78. int length = defaultEntities.Length;
  79. int index = -1;
  80. for (var i = 0; i < length; i++)
  81. {
  82. //the special entity already exists
  83. if (defaultEntities[i].GetEntityType() == EntityBuilderUtilities.ENTITY_STRUCT_INFO_VIEW)
  84. {
  85. index = i;
  86. break;
  87. }
  88. }
  89. if (index == -1)
  90. {
  91. index = length + extraLenght;
  92. entitiesToBuild = new IEntityBuilder[index + 1];
  93. }
  94. else
  95. entitiesToBuild = new IEntityBuilder[length + extraLenght];
  96. Array.Copy(defaultEntities, 0, entitiesToBuild, 0, length);
  97. return index;
  98. }
  99. public IEntityBuilder[] entitiesToBuild => _entitiesToBuild;
  100. IEntityBuilder[] _entitiesToBuild;
  101. }
  102. }