Mirror of Svelto.ECS because we're a fan of it
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

222 lignes
9.9KB

  1. using System;
  2. using System.Threading;
  3. using Svelto.DataStructures;
  4. using Svelto.ECS.Internal;
  5. namespace Svelto.ECS
  6. {
  7. public partial class EntitiesDB
  8. {
  9. public LocalFasterReadOnlyList<ExclusiveGroupStruct> FindGroups<T1>() where T1 : IEntityComponent
  10. {
  11. FasterList<ExclusiveGroupStruct> result = localgroups.Value.groupArray;
  12. result.FastClear();
  13. if (groupsPerEntity.TryGetValue(TypeRefWrapper<T1>.wrapper
  14. , out FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary> result1)
  15. == false)
  16. return result;
  17. var result1Count = result1.count;
  18. var fasterDictionaryNodes1 = result1.unsafeKeys;
  19. for (int j = 0; j < result1Count; j++)
  20. {
  21. var group = fasterDictionaryNodes1[j].key;
  22. if (group.IsEnabled())
  23. {
  24. result.Add(group);
  25. }
  26. }
  27. return result;
  28. }
  29. public LocalFasterReadOnlyList<ExclusiveGroupStruct> FindGroups<T1, T2>()
  30. where T1 : IEntityComponent where T2 : IEntityComponent
  31. {
  32. FasterList<ExclusiveGroupStruct> result = localgroups.Value.groupArray;
  33. result.FastClear();
  34. if (groupsPerEntity.TryGetValue(TypeRefWrapper<T1>.wrapper
  35. , out FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary> result1)
  36. == false)
  37. return result;
  38. if (groupsPerEntity.TryGetValue(TypeRefWrapper<T2>.wrapper
  39. , out FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary> result2)
  40. == false)
  41. return result;
  42. var result1Count = result1.count;
  43. var result2Count = result2.count;
  44. var fasterDictionaryNodes1 = result1.unsafeKeys;
  45. var fasterDictionaryNodes2 = result2.unsafeKeys;
  46. for (int i = 0; i < result1Count; i++)
  47. {
  48. var groupID = fasterDictionaryNodes1[i].key;
  49. if (!groupID.IsEnabled()) continue;
  50. for (int j = 0; j < result2Count; j++)
  51. {
  52. //if the same group is found used with both T1 and T2
  53. if (groupID == fasterDictionaryNodes2[j].key)
  54. {
  55. result.Add(groupID);
  56. break;
  57. }
  58. }
  59. }
  60. return result;
  61. }
  62. /// <summary>
  63. /// Remember that this operation os O(N*M*P) where N,M,P are the number of groups where each component
  64. /// is found.
  65. /// TODO: I have to find once for ever a solution to be sure that the entities in the groups match
  66. /// Currently this returns group where the entities are found, but the entities may not match in these
  67. /// groups.
  68. /// Checking the size of the entities is an early check, needed, but not sufficient, as entities components may
  69. /// coincidentally match in number but not from which entities they are generated
  70. /// </summary>
  71. /// <typeparam name="T1"></typeparam>
  72. /// <typeparam name="T2"></typeparam>
  73. /// <typeparam name="T3"></typeparam>
  74. /// <returns></returns>
  75. public LocalFasterReadOnlyList<ExclusiveGroupStruct> FindGroups<T1, T2, T3>()
  76. where T1 : IEntityComponent where T2 : IEntityComponent where T3 : IEntityComponent
  77. {
  78. FasterList<FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary>> localArray =
  79. localgroups.Value.listOfGroups;
  80. if (groupsPerEntity.TryGetValue(TypeRefWrapper<T1>.wrapper, out localArray[0]) == false || localArray[0].count == 0)
  81. return new LocalFasterReadOnlyList<ExclusiveGroupStruct>(
  82. FasterReadOnlyList<ExclusiveGroupStruct>.DefaultEmptyList);
  83. if (groupsPerEntity.TryGetValue(TypeRefWrapper<T2>.wrapper, out localArray[1]) == false || localArray[1].count == 0)
  84. return new LocalFasterReadOnlyList<ExclusiveGroupStruct>(
  85. FasterReadOnlyList<ExclusiveGroupStruct>.DefaultEmptyList);
  86. if (groupsPerEntity.TryGetValue(TypeRefWrapper<T3>.wrapper, out localArray[2]) == false || localArray[2].count == 0)
  87. return new LocalFasterReadOnlyList<ExclusiveGroupStruct>(
  88. FasterReadOnlyList<ExclusiveGroupStruct>.DefaultEmptyList);
  89. localgroups.Value.groups.FastClear();
  90. FasterDictionary<ExclusiveGroupStruct, ExclusiveGroupStruct> localGroups = localgroups.Value.groups;
  91. int startIndex = 0;
  92. int min = int.MaxValue;
  93. for (int i = 0; i < 3; i++)
  94. if (localArray[i].count < min)
  95. {
  96. min = localArray[i].count;
  97. startIndex = i;
  98. }
  99. foreach (var value in localArray[startIndex])
  100. {
  101. if (value.key.IsEnabled())
  102. {
  103. localGroups.Add(value.key, value.key);
  104. }
  105. }
  106. var groupData = localArray[++startIndex % 3];
  107. localGroups.Intersect(groupData);
  108. if (localGroups.count == 0)
  109. return new LocalFasterReadOnlyList<ExclusiveGroupStruct>(
  110. FasterReadOnlyList<ExclusiveGroupStruct>.DefaultEmptyList);
  111. groupData = localArray[++startIndex % 3];
  112. localGroups.Intersect(groupData);
  113. return new LocalFasterReadOnlyList<ExclusiveGroupStruct>(localGroups.unsafeValues
  114. , (uint) localGroups.count);
  115. }
  116. public LocalFasterReadOnlyList<ExclusiveGroupStruct> FindGroups<T1, T2, T3, T4>()
  117. where T1 : IEntityComponent
  118. where T2 : IEntityComponent
  119. where T3 : IEntityComponent
  120. where T4 : IEntityComponent
  121. {
  122. FasterList<FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary>> localArray =
  123. localgroups.Value.listOfGroups;
  124. if (groupsPerEntity.TryGetValue(TypeRefWrapper<T1>.wrapper, out localArray[0]) == false || localArray[0].count == 0)
  125. return new LocalFasterReadOnlyList<ExclusiveGroupStruct>(
  126. FasterReadOnlyList<ExclusiveGroupStruct>.DefaultEmptyList);
  127. if (groupsPerEntity.TryGetValue(TypeRefWrapper<T2>.wrapper, out localArray[1]) == false || localArray[1].count == 0)
  128. return new LocalFasterReadOnlyList<ExclusiveGroupStruct>(
  129. FasterReadOnlyList<ExclusiveGroupStruct>.DefaultEmptyList);
  130. if (groupsPerEntity.TryGetValue(TypeRefWrapper<T3>.wrapper, out localArray[2]) == false || localArray[2].count == 0)
  131. return new LocalFasterReadOnlyList<ExclusiveGroupStruct>(
  132. FasterReadOnlyList<ExclusiveGroupStruct>.DefaultEmptyList);
  133. if (groupsPerEntity.TryGetValue(TypeRefWrapper<T4>.wrapper, out localArray[3]) == false || localArray[3].count == 0)
  134. return new LocalFasterReadOnlyList<ExclusiveGroupStruct>(
  135. FasterReadOnlyList<ExclusiveGroupStruct>.DefaultEmptyList);
  136. localgroups.Value.groups.FastClear();
  137. FasterDictionary<ExclusiveGroupStruct, ExclusiveGroupStruct> localGroups = localgroups.Value.groups;
  138. int startIndex = 0;
  139. int min = int.MaxValue;
  140. for (int i = 0; i < 4; i++)
  141. if (localArray[i].count < min)
  142. {
  143. min = localArray[i].count;
  144. startIndex = i;
  145. }
  146. foreach (var value in localArray[startIndex])
  147. {
  148. if (value.key.IsEnabled())
  149. {
  150. localGroups.Add(value.key, value.key);
  151. }
  152. }
  153. var groupData = localArray[++startIndex & 3]; //&3 == %4
  154. localGroups.Intersect(groupData);
  155. if (localGroups.count == 0)
  156. return new LocalFasterReadOnlyList<ExclusiveGroupStruct>(
  157. FasterReadOnlyList<ExclusiveGroupStruct>.DefaultEmptyList);
  158. groupData = localArray[++startIndex & 3];
  159. localGroups.Intersect(groupData);
  160. if (localGroups.count == 0)
  161. return new LocalFasterReadOnlyList<ExclusiveGroupStruct>(
  162. FasterReadOnlyList<ExclusiveGroupStruct>.DefaultEmptyList);
  163. groupData = localArray[++startIndex & 3];
  164. localGroups.Intersect(groupData);
  165. return new LocalFasterReadOnlyList<ExclusiveGroupStruct>(localGroups.unsafeValues
  166. , (uint) localGroups.count);
  167. }
  168. internal FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary> FindGroups_INTERNAL(Type type)
  169. {
  170. if (groupsPerEntity.ContainsKey(new RefWrapperType(type)) == false)
  171. return _emptyDictionary;
  172. return groupsPerEntity[new RefWrapperType(type)];
  173. }
  174. struct GroupsList
  175. {
  176. internal FasterDictionary<ExclusiveGroupStruct, ExclusiveGroupStruct> groups;
  177. internal FasterList<FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary>> listOfGroups;
  178. public FasterList<ExclusiveGroupStruct> groupArray;
  179. }
  180. static readonly ThreadLocal<GroupsList> localgroups = new ThreadLocal<GroupsList>(() =>
  181. {
  182. GroupsList gl = default;
  183. gl.groups = new FasterDictionary<ExclusiveGroupStruct, ExclusiveGroupStruct>();
  184. gl.listOfGroups = FasterList<FasterDictionary<ExclusiveGroupStruct, ITypeSafeDictionary>>.PreInit(4);
  185. gl.groupArray = new FasterList<ExclusiveGroupStruct>(1);
  186. return gl;
  187. });
  188. }
  189. }