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.

339 lines
12KB

  1. using Svelto.DataStructures;
  2. using Svelto.ECS.Internal;
  3. namespace Svelto.ECS
  4. {
  5. /// <summary>
  6. /// NOTE THESE ENUMERABLES EXIST TO AVOID BOILERPLATE CODE AS THEY SKIP 0 SIZED GROUPS
  7. /// However if the normal pattern with the double foreach is used, this is not necessary
  8. /// </summary>
  9. /// <typeparam name="T1"></typeparam>
  10. /// <typeparam name="T2"></typeparam>
  11. /// <typeparam name="T3"></typeparam>
  12. /// <typeparam name="T4"></typeparam>
  13. public readonly ref struct GroupsEnumerable<T1, T2, T3, T4> where T1 : struct, _IInternalEntityComponent
  14. where T2 : struct, _IInternalEntityComponent
  15. where T3 : struct, _IInternalEntityComponent
  16. where T4 : struct, _IInternalEntityComponent
  17. {
  18. public GroupsEnumerable(EntitiesDB db, in LocalFasterReadOnlyList<ExclusiveGroupStruct> groups)
  19. {
  20. _db = db;
  21. _groups = groups;
  22. }
  23. public ref struct GroupsIterator
  24. {
  25. public GroupsIterator(EntitiesDB db, in LocalFasterReadOnlyList<ExclusiveGroupStruct> groups) : this()
  26. {
  27. _groups = groups;
  28. _indexGroup = -1;
  29. _entitiesDB = db;
  30. }
  31. public bool MoveNext()
  32. {
  33. //attention, the while is necessary to skip empty groups
  34. while (++_indexGroup < _groups.count)
  35. {
  36. var exclusiveGroupStruct = _groups[_indexGroup];
  37. if (exclusiveGroupStruct.IsEnabled() == false)
  38. continue;
  39. var entityCollection = _entitiesDB.QueryEntities<T1, T2, T3, T4>(exclusiveGroupStruct);
  40. if (entityCollection.count == 0)
  41. continue;
  42. _buffers = entityCollection;
  43. break;
  44. }
  45. var moveNext = _indexGroup < _groups.count;
  46. if (moveNext == false)
  47. Reset();
  48. return moveNext;
  49. }
  50. public void Reset() { _indexGroup = -1; }
  51. public RefCurrent Current => new RefCurrent(_buffers, _groups[_indexGroup]);
  52. public bool isValid => _indexGroup != -1;
  53. readonly LocalFasterReadOnlyList<ExclusiveGroupStruct> _groups;
  54. int _indexGroup;
  55. EntityCollection<T1, T2, T3, T4> _buffers;
  56. readonly EntitiesDB _entitiesDB;
  57. }
  58. public GroupsIterator GetEnumerator() { return new GroupsIterator(_db, _groups); }
  59. readonly EntitiesDB _db;
  60. readonly LocalFasterReadOnlyList<ExclusiveGroupStruct> _groups;
  61. public readonly ref struct RefCurrent
  62. {
  63. public RefCurrent(in EntityCollection<T1, T2, T3, T4> buffers, ExclusiveGroupStruct group)
  64. {
  65. _buffers = buffers;
  66. _group = group;
  67. }
  68. public void Deconstruct(out EntityCollection<T1, T2, T3, T4> buffers, out ExclusiveGroupStruct group)
  69. {
  70. buffers = _buffers;
  71. group = _group;
  72. }
  73. public readonly EntityCollection<T1, T2, T3, T4> _buffers;
  74. public readonly ExclusiveGroupStruct _group;
  75. }
  76. }
  77. public readonly ref struct GroupsEnumerable<T1, T2, T3> where T1 : struct, _IInternalEntityComponent
  78. where T2 : struct, _IInternalEntityComponent
  79. where T3 : struct, _IInternalEntityComponent
  80. {
  81. public GroupsEnumerable(EntitiesDB db, in LocalFasterReadOnlyList<ExclusiveGroupStruct> groups)
  82. {
  83. _db = db;
  84. _groups = groups;
  85. }
  86. public ref struct GroupsIterator
  87. {
  88. public GroupsIterator(EntitiesDB db, in LocalFasterReadOnlyList<ExclusiveGroupStruct> groups) : this()
  89. {
  90. _groups = groups;
  91. _indexGroup = -1;
  92. _entitiesDB = db;
  93. }
  94. public bool MoveNext()
  95. {
  96. //attention, the while is necessary to skip empty groups
  97. while (++_indexGroup < _groups.count)
  98. {
  99. var exclusiveGroupStruct = _groups[_indexGroup];
  100. if (exclusiveGroupStruct.IsEnabled() == false)
  101. continue;
  102. EntityCollection<T1, T2, T3> entityCollection = _entitiesDB.QueryEntities<T1, T2, T3>(exclusiveGroupStruct);
  103. if (entityCollection.count == 0)
  104. continue;
  105. _buffers = entityCollection;
  106. break;
  107. }
  108. var moveNext = _indexGroup < _groups.count;
  109. if (moveNext == false)
  110. Reset();
  111. return moveNext;
  112. }
  113. public void Reset() { _indexGroup = -1; }
  114. public RefCurrent Current => new RefCurrent(_buffers, _groups[_indexGroup]);
  115. public bool isValid => _indexGroup != -1;
  116. readonly LocalFasterReadOnlyList<ExclusiveGroupStruct> _groups;
  117. int _indexGroup;
  118. EntityCollection<T1, T2, T3> _buffers;
  119. readonly EntitiesDB _entitiesDB;
  120. }
  121. //todo: there is a steep cost to pay to copy these structs, one day I may need to investigate this more.
  122. //the structs are quite big, in the order of 100+ bytes.
  123. public GroupsIterator GetEnumerator() { return new GroupsIterator(_db, _groups); }
  124. readonly EntitiesDB _db;
  125. readonly LocalFasterReadOnlyList<ExclusiveGroupStruct> _groups;
  126. public readonly ref struct RefCurrent
  127. {
  128. public RefCurrent(in EntityCollection<T1, T2, T3> buffers, ExclusiveGroupStruct group)
  129. {
  130. _buffers = buffers;
  131. _group = group;
  132. }
  133. public void Deconstruct(out EntityCollection<T1, T2, T3> buffers, out ExclusiveGroupStruct group)
  134. {
  135. buffers = _buffers;
  136. group = _group;
  137. }
  138. public readonly EntityCollection<T1, T2, T3> _buffers;
  139. public readonly ExclusiveGroupStruct _group;
  140. }
  141. }
  142. public readonly ref struct GroupsEnumerable<T1, T2>
  143. where T1 : struct, _IInternalEntityComponent where T2 : struct, _IInternalEntityComponent
  144. {
  145. public GroupsEnumerable(EntitiesDB db, in LocalFasterReadOnlyList<ExclusiveGroupStruct> groups)
  146. {
  147. _db = db;
  148. _groups = groups;
  149. }
  150. public ref struct GroupsIterator
  151. {
  152. public GroupsIterator(EntitiesDB db, in LocalFasterReadOnlyList<ExclusiveGroupStruct> groups) : this()
  153. {
  154. _db = db;
  155. _groups = groups;
  156. _indexGroup = -1;
  157. }
  158. public bool MoveNext()
  159. {
  160. //attention, the while is necessary to skip empty groups
  161. while (++_indexGroup < _groups.count)
  162. {
  163. var exclusiveGroupStruct = _groups[_indexGroup];
  164. if (exclusiveGroupStruct.IsEnabled() == false)
  165. continue;
  166. var entityCollection = _db.QueryEntities<T1, T2>(exclusiveGroupStruct);
  167. if (entityCollection.count == 0)
  168. continue;
  169. _buffers = entityCollection;
  170. break;
  171. }
  172. var moveNext = _indexGroup < _groups.count;
  173. if (moveNext == false)
  174. Reset();
  175. return moveNext;
  176. }
  177. public void Reset() { _indexGroup = -1; }
  178. public RefCurrent Current => new RefCurrent(_buffers, _groups[_indexGroup]);
  179. public bool isValid => _indexGroup != -1;
  180. readonly EntitiesDB _db;
  181. readonly LocalFasterReadOnlyList<ExclusiveGroupStruct> _groups;
  182. int _indexGroup;
  183. EntityCollection<T1, T2> _buffers;
  184. }
  185. public GroupsIterator GetEnumerator() { return new GroupsIterator(_db, _groups); }
  186. readonly EntitiesDB _db;
  187. readonly LocalFasterReadOnlyList<ExclusiveGroupStruct> _groups;
  188. public readonly ref struct RefCurrent
  189. {
  190. public RefCurrent(in EntityCollection<T1, T2> buffers, ExclusiveGroupStruct group)
  191. {
  192. _buffers = buffers;
  193. _group = group;
  194. }
  195. public void Deconstruct(out EntityCollection<T1, T2> buffers, out ExclusiveGroupStruct group)
  196. {
  197. buffers = _buffers;
  198. group = _group;
  199. }
  200. public readonly EntityCollection<T1, T2> _buffers;
  201. public readonly ExclusiveGroupStruct _group;
  202. }
  203. }
  204. public readonly ref struct GroupsEnumerable<T1> where T1 : struct, _IInternalEntityComponent
  205. {
  206. public GroupsEnumerable(EntitiesDB db, in LocalFasterReadOnlyList<ExclusiveGroupStruct> groups)
  207. {
  208. _db = db;
  209. _groups = groups;
  210. }
  211. public ref struct GroupsIterator
  212. {
  213. public GroupsIterator(EntitiesDB db, in LocalFasterReadOnlyList<ExclusiveGroupStruct> groups) : this()
  214. {
  215. _db = db;
  216. _groups = groups;
  217. _indexGroup = -1;
  218. }
  219. public bool MoveNext()
  220. {
  221. //attention, the while is necessary to skip empty groups
  222. while (++_indexGroup < _groups.count)
  223. {
  224. var exclusiveGroupStruct = _groups[_indexGroup];
  225. if (exclusiveGroupStruct.IsEnabled() == false)
  226. continue;
  227. var entityCollection = _db.QueryEntities<T1>(exclusiveGroupStruct);
  228. if (entityCollection.count == 0)
  229. continue;
  230. _buffer = entityCollection;
  231. break;
  232. }
  233. var moveNext = _indexGroup < _groups.count;
  234. if (moveNext == false)
  235. Reset();
  236. return moveNext;
  237. }
  238. public void Reset() { _indexGroup = -1; }
  239. public RefCurrent Current => new RefCurrent(_buffer, _groups[_indexGroup]);
  240. public bool isValid => _indexGroup != -1;
  241. readonly EntitiesDB _db;
  242. readonly LocalFasterReadOnlyList<ExclusiveGroupStruct> _groups;
  243. int _indexGroup;
  244. EntityCollection<T1> _buffer;
  245. }
  246. public GroupsIterator GetEnumerator() { return new GroupsIterator(_db, _groups); }
  247. readonly EntitiesDB _db;
  248. readonly LocalFasterReadOnlyList<ExclusiveGroupStruct> _groups;
  249. public readonly ref struct RefCurrent
  250. {
  251. public RefCurrent(in EntityCollection<T1> buffers, in ExclusiveGroupStruct group)
  252. {
  253. _buffers = buffers;
  254. _group = group;
  255. }
  256. public void Deconstruct(out EntityCollection<T1> buffers, out ExclusiveGroupStruct group)
  257. {
  258. buffers = _buffers;
  259. group = _group;
  260. }
  261. public void Deconstruct(out EntityCollection<T1> buffers)
  262. {
  263. buffers = _buffers;
  264. }
  265. internal readonly EntityCollection<T1> _buffers;
  266. internal readonly ExclusiveGroupStruct _group;
  267. }
  268. }
  269. }