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.

331 lines
12KB

  1. using DBC.ECS;
  2. using Svelto.DataStructures;
  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. /// Note: atm cannot be ref structs because they are returned in a valuetuple
  9. /// </summary>
  10. /// <typeparam name="T1"></typeparam>
  11. /// <typeparam name="T2"></typeparam>
  12. /// <typeparam name="T3"></typeparam>
  13. /// <typeparam name="T4"></typeparam>
  14. public readonly ref struct GroupsEnumerable<T1, T2, T3, T4> where T1 : struct, IEntityComponent
  15. where T2 : struct, IEntityComponent
  16. where T3 : struct, IEntityComponent
  17. where T4 : struct, IEntityComponent
  18. {
  19. public GroupsEnumerable(EntitiesDB db, in LocalFasterReadOnlyList<ExclusiveGroupStruct> groups)
  20. {
  21. _db = db;
  22. _groups = groups;
  23. }
  24. public ref struct GroupsIterator
  25. {
  26. public GroupsIterator(EntitiesDB db, in LocalFasterReadOnlyList<ExclusiveGroupStruct> groups) : this()
  27. {
  28. _groups = groups;
  29. _indexGroup = -1;
  30. _entitiesDB = db;
  31. }
  32. public bool MoveNext()
  33. {
  34. //attention, the while is necessary to skip empty groups
  35. while (++_indexGroup < _groups.count)
  36. {
  37. var entityCollection1 = _entitiesDB.QueryEntities<T1, T2, T3>(_groups[_indexGroup]);
  38. if (entityCollection1.count == 0)
  39. continue;
  40. var entityCollection2 = _entitiesDB.QueryEntities<T4>(_groups[_indexGroup]);
  41. if (entityCollection2.count == 0)
  42. continue;
  43. Check.Assert(entityCollection1.count == entityCollection2.count
  44. , "congratulation, you found a bug in Svelto, please report it");
  45. var array = entityCollection1;
  46. var array2 = entityCollection2;
  47. _buffers = new EntityCollection<T1, T2, T3, T4>(array.buffer1, array.buffer2, array.buffer3
  48. , array2);
  49. break;
  50. }
  51. var moveNext = _indexGroup < _groups.count;
  52. if (moveNext == false)
  53. Reset();
  54. return moveNext;
  55. }
  56. public void Reset() { _indexGroup = -1; }
  57. public RefCurrent Current => new RefCurrent(_buffers, _groups[_indexGroup]);
  58. public bool isValid => _indexGroup != -1;
  59. readonly LocalFasterReadOnlyList<ExclusiveGroupStruct> _groups;
  60. int _indexGroup;
  61. EntityCollection<T1, T2, T3, T4> _buffers;
  62. readonly EntitiesDB _entitiesDB;
  63. }
  64. public GroupsIterator GetEnumerator() { return new GroupsIterator(_db, _groups); }
  65. readonly EntitiesDB _db;
  66. readonly LocalFasterReadOnlyList<ExclusiveGroupStruct> _groups;
  67. public ref struct RefCurrent
  68. {
  69. public RefCurrent(in EntityCollection<T1, T2, T3, T4> buffers, ExclusiveGroupStruct group)
  70. {
  71. _buffers = buffers;
  72. _group = group;
  73. }
  74. public void Deconstruct(out EntityCollection<T1, T2, T3, T4> buffers, out ExclusiveGroupStruct group)
  75. {
  76. buffers = _buffers;
  77. group = _group;
  78. }
  79. public readonly EntityCollection<T1, T2, T3, T4> _buffers;
  80. public readonly ExclusiveGroupStruct _group;
  81. }
  82. }
  83. public readonly ref struct GroupsEnumerable<T1, T2, T3> where T1 : struct, IEntityComponent
  84. where T2 : struct, IEntityComponent
  85. where T3 : struct, IEntityComponent
  86. {
  87. public GroupsEnumerable(EntitiesDB db, in LocalFasterReadOnlyList<ExclusiveGroupStruct> groups)
  88. {
  89. DBC.ECS.Check.Require(groups.count > 0, "can't initialise a query without valid groups");
  90. _db = db;
  91. _groups = groups;
  92. }
  93. public ref struct GroupsIterator
  94. {
  95. public GroupsIterator(EntitiesDB db, in LocalFasterReadOnlyList<ExclusiveGroupStruct> groups) : this()
  96. {
  97. _groups = groups;
  98. _indexGroup = -1;
  99. _entitiesDB = db;
  100. }
  101. public bool MoveNext()
  102. {
  103. //attention, the while is necessary to skip empty groups
  104. while (++_indexGroup < _groups.count)
  105. {
  106. var entityCollection = _entitiesDB.QueryEntities<T1, T2, T3>(_groups[_indexGroup]);
  107. if (entityCollection.count == 0)
  108. continue;
  109. _buffers = entityCollection;
  110. break;
  111. }
  112. var moveNext = _indexGroup < _groups.count;
  113. if (moveNext == false)
  114. Reset();
  115. return moveNext;
  116. }
  117. public void Reset() { _indexGroup = -1; }
  118. public RefCurrent Current => new RefCurrent(_buffers, _groups[_indexGroup]);
  119. public bool isValid => _indexGroup != -1;
  120. readonly LocalFasterReadOnlyList<ExclusiveGroupStruct> _groups;
  121. int _indexGroup;
  122. EntityCollection<T1, T2, T3> _buffers;
  123. readonly EntitiesDB _entitiesDB;
  124. }
  125. public GroupsIterator GetEnumerator() { return new GroupsIterator(_db, _groups); }
  126. readonly EntitiesDB _db;
  127. readonly LocalFasterReadOnlyList<ExclusiveGroupStruct> _groups;
  128. public ref struct RefCurrent
  129. {
  130. public RefCurrent(in EntityCollection<T1, T2, T3> buffers, ExclusiveGroupStruct group)
  131. {
  132. _buffers = buffers;
  133. _group = group;
  134. }
  135. public void Deconstruct(out EntityCollection<T1, T2, T3> buffers, out ExclusiveGroupStruct group)
  136. {
  137. buffers = _buffers;
  138. group = _group;
  139. }
  140. public readonly EntityCollection<T1, T2, T3> _buffers;
  141. public readonly ExclusiveGroupStruct _group;
  142. }
  143. }
  144. public readonly ref struct GroupsEnumerable<T1, T2>
  145. where T1 : struct, IEntityComponent where T2 : struct, IEntityComponent
  146. {
  147. public GroupsEnumerable(EntitiesDB db, in LocalFasterReadOnlyList<ExclusiveGroupStruct> groups)
  148. {
  149. _db = db;
  150. _groups = groups;
  151. }
  152. public ref struct GroupsIterator
  153. {
  154. public GroupsIterator(EntitiesDB db, in LocalFasterReadOnlyList<ExclusiveGroupStruct> groups) : this()
  155. {
  156. _db = db;
  157. _groups = groups;
  158. _indexGroup = -1;
  159. }
  160. public bool MoveNext()
  161. {
  162. //attention, the while is necessary to skip empty groups
  163. while (++_indexGroup < _groups.count)
  164. {
  165. var entityCollection = _db.QueryEntities<T1, T2>(_groups[_indexGroup]);
  166. if (entityCollection.count == 0)
  167. continue;
  168. _buffers = entityCollection;
  169. break;
  170. }
  171. var moveNext = _indexGroup < _groups.count;
  172. if (moveNext == false)
  173. Reset();
  174. return moveNext;
  175. }
  176. public void Reset() { _indexGroup = -1; }
  177. public RefCurrent Current => new RefCurrent(_buffers, _groups[_indexGroup]);
  178. public bool isValid => _indexGroup != -1;
  179. readonly EntitiesDB _db;
  180. readonly LocalFasterReadOnlyList<ExclusiveGroupStruct> _groups;
  181. int _indexGroup;
  182. EntityCollection<T1, T2> _buffers;
  183. }
  184. public GroupsIterator GetEnumerator() { return new GroupsIterator(_db, _groups); }
  185. readonly EntitiesDB _db;
  186. readonly LocalFasterReadOnlyList<ExclusiveGroupStruct> _groups;
  187. public ref struct RefCurrent
  188. {
  189. public RefCurrent(in EntityCollection<T1, T2> buffers, ExclusiveGroupStruct group)
  190. {
  191. _buffers = buffers;
  192. _group = group;
  193. }
  194. public void Deconstruct(out EntityCollection<T1, T2> buffers, out ExclusiveGroupStruct group)
  195. {
  196. buffers = _buffers;
  197. group = _group;
  198. }
  199. public readonly EntityCollection<T1, T2> _buffers;
  200. public readonly ExclusiveGroupStruct _group;
  201. }
  202. }
  203. public readonly ref struct GroupsEnumerable<T1> where T1 : struct, IEntityComponent
  204. {
  205. public GroupsEnumerable(EntitiesDB db, in LocalFasterReadOnlyList<ExclusiveGroupStruct> groups)
  206. {
  207. _db = db;
  208. _groups = groups;
  209. }
  210. public ref struct GroupsIterator
  211. {
  212. public GroupsIterator(EntitiesDB db, in LocalFasterReadOnlyList<ExclusiveGroupStruct> groups) : this()
  213. {
  214. _db = db;
  215. _groups = groups;
  216. _indexGroup = -1;
  217. }
  218. public bool MoveNext()
  219. {
  220. //attention, the while is necessary to skip empty groups
  221. while (++_indexGroup < _groups.count)
  222. {
  223. var entityCollection = _db.QueryEntities<T1>(_groups[_indexGroup]);
  224. if (entityCollection.count == 0)
  225. continue;
  226. _buffer = entityCollection;
  227. break;
  228. }
  229. var moveNext = _indexGroup < _groups.count;
  230. if (moveNext == false)
  231. Reset();
  232. return moveNext;
  233. }
  234. public void Reset() { _indexGroup = -1; }
  235. public RefCurrent Current => new RefCurrent(_buffer, _groups[_indexGroup]);
  236. public bool isValid => _indexGroup != -1;
  237. readonly EntitiesDB _db;
  238. readonly LocalFasterReadOnlyList<ExclusiveGroupStruct> _groups;
  239. int _indexGroup;
  240. EntityCollection<T1> _buffer;
  241. }
  242. public GroupsIterator GetEnumerator() { return new GroupsIterator(_db, _groups); }
  243. readonly EntitiesDB _db;
  244. readonly LocalFasterReadOnlyList<ExclusiveGroupStruct> _groups;
  245. public readonly ref struct RefCurrent
  246. {
  247. public RefCurrent(in EntityCollection<T1> buffers, in ExclusiveGroupStruct group)
  248. {
  249. _buffers = buffers;
  250. _group = group;
  251. }
  252. public void Deconstruct(out EntityCollection<T1> buffers, out ExclusiveGroupStruct group)
  253. {
  254. buffers = _buffers;
  255. group = _group;
  256. }
  257. public void Deconstruct(out EntityCollection<T1> buffers)
  258. {
  259. buffers = _buffers;
  260. }
  261. public readonly EntityCollection<T1> _buffers;
  262. public readonly ExclusiveGroupStruct _group;
  263. }
  264. }
  265. }