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.

204 lines
5.8KB

  1. using System.Collections.Generic;
  2. using System.Runtime.CompilerServices;
  3. using System.Threading;
  4. using Svelto.DataStructures;
  5. namespace Svelto.ECS.Experimental
  6. {
  7. struct GroupsList
  8. {
  9. static GroupsList()
  10. {
  11. groups = new FasterList<ExclusiveGroupStruct>();
  12. sets = new HashSet<ExclusiveGroupStruct>();
  13. }
  14. static readonly FasterList<ExclusiveGroupStruct> groups;
  15. static readonly HashSet<ExclusiveGroupStruct> sets;
  16. public void Reset() { sets.Clear(); }
  17. public void AddRange(ExclusiveGroupStruct[] groupsToAdd, int length)
  18. {
  19. for (int i = 0; i < length; i++)
  20. {
  21. sets.Add(groupsToAdd[i]);
  22. }
  23. }
  24. public void Add(ExclusiveGroupStruct @group) { sets.Add(group); }
  25. public void Exclude(ExclusiveGroupStruct[] groupsToIgnore, int length)
  26. {
  27. for (int i = 0; i < length; i++)
  28. {
  29. sets.Remove(groupsToIgnore[i]);
  30. }
  31. }
  32. public void Exclude(ExclusiveGroupStruct groupsToIgnore) { sets.Remove(groupsToIgnore); }
  33. public void EnsureCapacity(uint preparecount) { groups.EnsureCapacity(preparecount); }
  34. public FasterList<ExclusiveGroupStruct> Evaluate()
  35. {
  36. groups.FastClear();
  37. foreach (var item in sets)
  38. {
  39. groups.Add(item);
  40. }
  41. return groups;
  42. }
  43. }
  44. public ref struct QueryGroups
  45. {
  46. static readonly ThreadLocal<GroupsList> groups = new ThreadLocal<GroupsList>();
  47. public QueryGroups(LocalFasterReadOnlyList<ExclusiveGroupStruct> groups)
  48. {
  49. var groupsValue = QueryGroups.groups.Value;
  50. groupsValue.Reset();
  51. groupsValue.AddRange(groups.ToArrayFast(out var count), count);
  52. }
  53. public QueryGroups(ExclusiveGroupStruct @group)
  54. {
  55. var groupsValue = groups.Value;
  56. groupsValue.Reset();
  57. groupsValue.Add(@group);
  58. }
  59. public QueryGroups(uint preparecount)
  60. {
  61. var groupsValue = groups.Value;
  62. groupsValue.Reset();
  63. groupsValue.EnsureCapacity(preparecount);
  64. }
  65. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  66. public QueryGroups Union(ExclusiveGroupStruct group)
  67. {
  68. var groupsValue = groups.Value;
  69. groupsValue.Add(group);
  70. return this;
  71. }
  72. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  73. public QueryGroups Union(LocalFasterReadOnlyList<ExclusiveGroupStruct> groups)
  74. {
  75. var groupsValue = QueryGroups.groups.Value;
  76. groupsValue.AddRange(groups.ToArrayFast(out var count), count);
  77. return this;
  78. }
  79. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  80. public QueryGroups Except(ExclusiveGroupStruct group)
  81. {
  82. var groupsValue = groups.Value;
  83. groupsValue.Exclude(group);
  84. return this;
  85. }
  86. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  87. public QueryGroups Except(ExclusiveGroupStruct[] groupsToIgnore)
  88. {
  89. var groupsValue = QueryGroups.groups.Value;
  90. groupsValue.Exclude(groupsToIgnore, groupsToIgnore.Length);
  91. return this;
  92. }
  93. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  94. public QueryGroups Except(LocalFasterReadOnlyList<ExclusiveGroupStruct> groupsToIgnore)
  95. {
  96. var groupsValue = QueryGroups.groups.Value;
  97. groupsValue.Exclude(groupsToIgnore.ToArrayFast(out var count), count);
  98. return this;
  99. }
  100. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  101. public QueryGroups Except(FasterList<ExclusiveGroupStruct> groupsToIgnore)
  102. {
  103. var groupsValue = QueryGroups.groups.Value;
  104. groupsValue.Exclude(groupsToIgnore.ToArrayFast(out var count), count);
  105. return this;
  106. }
  107. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  108. public QueryGroups Except(FasterReadOnlyList<ExclusiveGroupStruct> groupsToIgnore)
  109. {
  110. var groupsValue = QueryGroups.groups.Value;
  111. groupsValue.Exclude(groupsToIgnore.ToArrayFast(out var count), count);
  112. return this;
  113. }
  114. // public QueryGroups WithAny<T>(EntitiesDB entitiesDB)
  115. // where T : struct, IEntityComponent
  116. // {
  117. // var group = groups.Value.reference;
  118. // var groupsCount = group.count;
  119. //
  120. // for (uint i = 0; i < groupsCount; i++)
  121. // {
  122. // if (entitiesDB.Count<T>(group[i]) == 0)
  123. // {
  124. // group.UnorderedRemoveAt(i);
  125. // i--;
  126. // groupsCount--;
  127. // }
  128. // }
  129. //
  130. // return this;
  131. // }
  132. public QueryResult Evaluate()
  133. {
  134. var groupsValue = groups.Value;
  135. return new QueryResult(groupsValue.Evaluate());
  136. }
  137. }
  138. public readonly ref struct QueryResult
  139. {
  140. public QueryResult(FasterList<ExclusiveGroupStruct> @group) { _group = @group; }
  141. public LocalFasterReadOnlyList<ExclusiveGroupStruct> result => _group;
  142. readonly FasterReadOnlyList<ExclusiveGroupStruct> _group;
  143. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  144. public int Count<T>(EntitiesDB entitiesDB)
  145. where T : struct, IEntityComponent
  146. {
  147. int count = 0;
  148. var groupsCount = result.count;
  149. for (int i = 0; i < groupsCount; ++i)
  150. {
  151. count += entitiesDB.Count<T>(result[i]);
  152. }
  153. return count;
  154. }
  155. }
  156. }