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.

327 lines
9.0KB

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. namespace Svelto.ECS
  5. {
  6. public struct EntityCollection<T>
  7. {
  8. public EntityCollection(T[] array, uint count)
  9. {
  10. _array = array;
  11. _count = count;
  12. }
  13. public EntityIterator GetEnumerator()
  14. {
  15. return new EntityIterator(_array, _count);
  16. }
  17. readonly T[] _array;
  18. readonly uint _count;
  19. public struct EntityIterator : IEnumerator<T>
  20. {
  21. public EntityIterator(T[] array, uint count) : this()
  22. {
  23. _array = array;
  24. _count = count;
  25. _index = -1;
  26. }
  27. public bool MoveNext()
  28. {
  29. return ++_index < _count;
  30. }
  31. public void Reset()
  32. {
  33. _index = -1;
  34. }
  35. public ref T Current => ref _array[_index];
  36. T IEnumerator<T>.Current => throw new NotImplementedException();
  37. object IEnumerator.Current => throw new NotImplementedException();
  38. public void Dispose() {}
  39. readonly T[] _array;
  40. readonly uint _count;
  41. int _index;
  42. }
  43. }
  44. public struct EntityCollection<T1, T2>
  45. {
  46. public EntityCollection(in (T1[], T2[]) array, uint count)
  47. {
  48. _array = array;
  49. _count = count;
  50. }
  51. public EntityIterator GetEnumerator()
  52. {
  53. return new EntityIterator(_array, _count);
  54. }
  55. readonly (T1[], T2[]) _array;
  56. readonly uint _count;
  57. public struct EntityIterator : IEnumerator<ValueRef<T1, T2>>
  58. {
  59. public EntityIterator((T1[], T2[]) array, uint count) : this()
  60. {
  61. _array = array;
  62. _count = count;
  63. _index = -1;
  64. }
  65. public bool MoveNext()
  66. {
  67. return ++_index < _count;
  68. }
  69. public void Reset()
  70. {
  71. _index = -1;
  72. }
  73. public ValueRef<T1, T2> Current => new ValueRef<T1, T2>(_array, (uint) _index);
  74. ValueRef<T1, T2> IEnumerator<ValueRef<T1, T2>>. Current => throw new NotImplementedException();
  75. object IEnumerator.Current => throw new NotImplementedException();
  76. public void Dispose() {}
  77. readonly (T1[], T2[]) _array;
  78. readonly uint _count;
  79. int _index;
  80. }
  81. }
  82. public struct EntityCollection<T1, T2, T3>
  83. {
  84. public EntityCollection(in (T1[], T2[], T3[]) array, uint count)
  85. {
  86. _array = array;
  87. _count = count;
  88. }
  89. public EntityIterator GetEnumerator()
  90. {
  91. return new EntityIterator(_array, _count);
  92. }
  93. readonly (T1[], T2[], T3[]) _array;
  94. readonly uint _count;
  95. public struct EntityIterator : IEnumerator<ValueRef<T1, T2, T3>>
  96. {
  97. public EntityIterator((T1[], T2[], T3[]) array, uint count) : this()
  98. {
  99. _array = array;
  100. _count = count;
  101. _index = -1;
  102. }
  103. public bool MoveNext()
  104. {
  105. return ++_index < _count;
  106. }
  107. public void Reset()
  108. {
  109. _index = -1;
  110. }
  111. public ValueRef<T1, T2, T3> Current => new ValueRef<T1, T2, T3>(_array, (uint) _index);
  112. ValueRef<T1, T2, T3> IEnumerator<ValueRef<T1, T2, T3>>.Current => throw new NotImplementedException();
  113. object IEnumerator. Current => throw new NotImplementedException();
  114. public void Dispose() {}
  115. readonly (T1[], T2[], T3[]) _array;
  116. readonly uint _count;
  117. int _index;
  118. }
  119. }
  120. public struct EntityCollections<T> where T : struct, IEntityStruct
  121. {
  122. public EntityCollections(IEntitiesDB db, ExclusiveGroup[] groups) : this()
  123. {
  124. _db = db;
  125. _groups = groups;
  126. }
  127. public EntityGroupsIterator GetEnumerator()
  128. {
  129. return new EntityGroupsIterator(_db, _groups);
  130. }
  131. readonly IEntitiesDB _db;
  132. readonly ExclusiveGroup[] _groups;
  133. public struct EntityGroupsIterator : IEnumerator<T>
  134. {
  135. public EntityGroupsIterator(IEntitiesDB db, ExclusiveGroup[] groups) : this()
  136. {
  137. _db = db;
  138. _groups = groups;
  139. _indexGroup = -1;
  140. _index = -1;
  141. }
  142. public bool MoveNext()
  143. {
  144. while (_index + 1 >= _count && ++_indexGroup < _groups.Length)
  145. {
  146. _index = -1;
  147. _array = _db.QueryEntities<T>(_groups[_indexGroup], out _count);
  148. }
  149. return ++_index < _count;
  150. }
  151. public void Reset()
  152. {
  153. _index = -1;
  154. _indexGroup = -1;
  155. _count = 0;
  156. }
  157. public ref T Current => ref _array[_index];
  158. T IEnumerator<T>.Current => throw new NotImplementedException();
  159. object IEnumerator.Current => throw new NotImplementedException();
  160. public void Dispose() {}
  161. readonly IEntitiesDB _db;
  162. readonly ExclusiveGroup[] _groups;
  163. T[] _array;
  164. uint _count;
  165. int _index;
  166. int _indexGroup;
  167. }
  168. }
  169. public struct EntityCollections<T1, T2> where T1 : struct, IEntityStruct where T2 : struct, IEntityStruct
  170. {
  171. public EntityCollections(IEntitiesDB db, ExclusiveGroup[] groups) : this()
  172. {
  173. _db = db;
  174. _groups = groups;
  175. }
  176. public EntityGroupsIterator GetEnumerator()
  177. {
  178. return new EntityGroupsIterator(_db, _groups);
  179. }
  180. readonly IEntitiesDB _db;
  181. readonly ExclusiveGroup[] _groups;
  182. public struct EntityGroupsIterator : IEnumerator<ValueRef<T1, T2>>
  183. {
  184. public EntityGroupsIterator(IEntitiesDB db, ExclusiveGroup[] groups) : this()
  185. {
  186. _db = db;
  187. _groups = groups;
  188. _indexGroup = -1;
  189. _index = -1;
  190. }
  191. public bool MoveNext()
  192. {
  193. while (_index + 1 >= _count && ++_indexGroup < _groups.Length)
  194. {
  195. _index = -1;
  196. var array1 = _db.QueryEntities<T1>(_groups[_indexGroup], out _count);
  197. var array2 = _db.QueryEntities<T2>(_groups[_indexGroup], out var count1);
  198. _array = (array1, array2);
  199. #if DEBUG && !PROFILER
  200. if (_count != count1)
  201. throw new ECSException("number of entities in group doesn't match");
  202. #endif
  203. }
  204. return ++_index < _count;
  205. }
  206. public void Reset()
  207. {
  208. _index = -1;
  209. _indexGroup = -1;
  210. var array1 = _db.QueryEntities<T1>(_groups[0], out _count);
  211. var array2 = _db.QueryEntities<T2>(_groups[0], out var count1);
  212. _array = (array1, array2);
  213. #if DEBUG && !PROFILER
  214. if (_count != count1)
  215. throw new ECSException("number of entities in group doesn't match");
  216. #endif
  217. }
  218. public ValueRef<T1, T2> Current
  219. {
  220. get
  221. {
  222. var valueRef = new ValueRef<T1, T2>(_array, (uint) _index);
  223. return valueRef;
  224. }
  225. }
  226. ValueRef<T1, T2> IEnumerator<ValueRef<T1, T2>>.Current => throw new NotImplementedException();
  227. object IEnumerator.Current => throw new NotImplementedException();
  228. public void Dispose() {}
  229. readonly IEntitiesDB _db;
  230. readonly ExclusiveGroup[] _groups;
  231. uint _count;
  232. int _index;
  233. int _indexGroup;
  234. (T1[], T2[]) _array;
  235. }
  236. }
  237. public struct ValueRef<T1, T2>
  238. {
  239. readonly (T1[], T2[]) array;
  240. readonly uint index;
  241. public ValueRef(in (T1[], T2[]) entity1, uint i)
  242. {
  243. array = entity1;
  244. index = i;
  245. }
  246. public ref T1 entityStructA => ref array.Item1[index];
  247. public ref T2 entityStructB => ref array.Item2[index];
  248. }
  249. public struct ValueRef<T1, T2, T3>
  250. {
  251. readonly (T1[], T2[], T3[]) array;
  252. readonly uint index;
  253. public ValueRef(in (T1[], T2[], T3[]) entity1, uint i)
  254. {
  255. array = entity1;
  256. index = i;
  257. }
  258. public ref T1 entityStructA => ref array.Item1[index];
  259. public ref T2 entityStructB => ref array.Item2[index];
  260. public ref T3 entityStructC => ref array.Item3[index];
  261. }
  262. }