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.

238 line
6.6KB

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