Mirror of Svelto.ECS because we're a fan of it
25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.

547 satır
23KB

  1. using System;
  2. using Svelto.ECS.Internal;
  3. namespace Svelto.ECS
  4. {
  5. public readonly ref struct DoubleEntitiesEnumerator<T1> where T1 : struct, _IInternalEntityComponent
  6. {
  7. public DoubleEntitiesEnumerator(GroupsEnumerable<T1> groupsEnumerable) { _groupsEnumerable = groupsEnumerable; }
  8. public EntityGroupsIterator GetEnumerator() { return new EntityGroupsIterator(_groupsEnumerable); }
  9. readonly GroupsEnumerable<T1> _groupsEnumerable;
  10. public ref struct EntityGroupsIterator
  11. {
  12. public EntityGroupsIterator(GroupsEnumerable<T1> groupsEnumerable) : this()
  13. {
  14. _groupsEnumerableA = groupsEnumerable.GetEnumerator();
  15. _groupsEnumerableA.MoveNext();
  16. _groupsEnumerableB = _groupsEnumerableA;
  17. _indexA = 0;
  18. _indexB = 0;
  19. }
  20. public bool MoveNext()
  21. {
  22. //once GroupEnumerables complete, they reset. If they reset and moveNext doesn't happen, they are invalid
  23. while (_groupsEnumerableA.isValid)
  24. {
  25. var (buffersA, _) = _groupsEnumerableA.Current;
  26. var (buffersB, _) = _groupsEnumerableB.Current;
  27. //current index A must iterate as long as is less than the current A group count
  28. while (_indexA < buffersA.count)
  29. {
  30. //current index B must iterate as long as is less than the current B group count
  31. if (++_indexB < buffersB.count)
  32. {
  33. return true;
  34. }
  35. //if B iteration is over, move to the next group
  36. if (_groupsEnumerableB.MoveNext() == false)
  37. {
  38. //if there is no valid next groups, we reset B and we need to move to the next A element
  39. _groupsEnumerableB = _groupsEnumerableA;
  40. (buffersB, _) = _groupsEnumerableB.Current;
  41. ++_indexA; //next A element
  42. _indexB = _indexA;
  43. }
  44. else
  45. //otherwise the current A will be checked against the new B group. IndexB must be reset
  46. //to work on the new group
  47. {
  48. _indexB = -1;
  49. }
  50. }
  51. //the current group A iteration is done, so we move to the next A group
  52. if (_groupsEnumerableA.MoveNext() == true)
  53. {
  54. //there is a new group, we reset the iteration
  55. _indexA = 0;
  56. _indexB = 0;
  57. _groupsEnumerableB = _groupsEnumerableA;
  58. }
  59. else
  60. return false;
  61. }
  62. return false;
  63. }
  64. public void Reset() { throw new Exception(); }
  65. public ValueRef Current
  66. {
  67. get
  68. {
  69. var valueRef = new ValueRef(_groupsEnumerableA.Current, _indexA, _groupsEnumerableB.Current
  70. , _indexB);
  71. return valueRef;
  72. }
  73. }
  74. public void Dispose() { }
  75. GroupsEnumerable<T1>.GroupsIterator _groupsEnumerableA;
  76. GroupsEnumerable<T1>.GroupsIterator _groupsEnumerableB;
  77. int _indexA;
  78. int _indexB;
  79. }
  80. public readonly ref struct ValueRef
  81. {
  82. readonly GroupsEnumerable<T1>.RefCurrent _current;
  83. readonly int _indexA;
  84. readonly GroupsEnumerable<T1>.RefCurrent _refCurrent;
  85. readonly int _indexB;
  86. public ValueRef
  87. (GroupsEnumerable<T1>.RefCurrent current, int indexA, GroupsEnumerable<T1>.RefCurrent refCurrent
  88. , int indexB)
  89. {
  90. _current = current;
  91. _indexA = indexA;
  92. _refCurrent = refCurrent;
  93. _indexB = indexB;
  94. }
  95. public void Deconstruct
  96. (out EntityCollection<T1> buffers, out int indexA, out EntityCollection<T1> refCurrent, out int indexB)
  97. {
  98. buffers = _current._buffers;
  99. indexA = _indexA;
  100. refCurrent = _refCurrent._buffers;
  101. indexB = _indexB;
  102. }
  103. public void Deconstruct
  104. (out EntityCollection<T1> buffers, out int indexA, out ExclusiveGroupStruct groupA
  105. , out EntityCollection<T1> refCurrent, out int indexB, out ExclusiveGroupStruct groupB)
  106. {
  107. buffers = _current._buffers;
  108. indexA = _indexA;
  109. refCurrent = _refCurrent._buffers;
  110. indexB = _indexB;
  111. groupA = _current._group;
  112. groupB = _refCurrent._group;
  113. }
  114. }
  115. }
  116. public readonly ref struct DoubleIterationEnumerator<T1, T2> where T1 : struct, _IInternalEntityComponent
  117. where T2 : struct, _IInternalEntityComponent
  118. {
  119. public DoubleIterationEnumerator(GroupsEnumerable<T1, T2> groupsEnumerable)
  120. {
  121. _groupsEnumerable = groupsEnumerable;
  122. }
  123. public EntityGroupsIterator GetEnumerator() { return new EntityGroupsIterator(_groupsEnumerable); }
  124. readonly GroupsEnumerable<T1, T2> _groupsEnumerable;
  125. public ref struct EntityGroupsIterator
  126. {
  127. public EntityGroupsIterator(GroupsEnumerable<T1, T2> groupsEnumerable) : this()
  128. {
  129. _groupsEnumerableA = groupsEnumerable.GetEnumerator();
  130. _groupsEnumerableA.MoveNext();
  131. _groupsEnumerableB = _groupsEnumerableA;
  132. _indexA = 0;
  133. _indexB = 0;
  134. }
  135. public bool MoveNext()
  136. {
  137. //once GroupEnumerables complete, they reset. If they reset and moveNext doesn't happen, they are invalid
  138. while (_groupsEnumerableA.isValid)
  139. {
  140. var (buffersA, _) = _groupsEnumerableA.Current;
  141. var (buffersB, _) = _groupsEnumerableB.Current;
  142. //current index A must iterate as long as is less than the current A group count
  143. while (_indexA < buffersA.count)
  144. {
  145. //current index B must iterate as long as is less than the current B group count
  146. if (++_indexB < buffersB.count)
  147. {
  148. return true;
  149. }
  150. //if B iteration is over, move to the next group
  151. if (_groupsEnumerableB.MoveNext() == false)
  152. {
  153. //if there is no valid next groups, we reset B and we need to move to the next A element
  154. _groupsEnumerableB = _groupsEnumerableA;
  155. (buffersB, _) = _groupsEnumerableB.Current;
  156. ++_indexA; //next A element
  157. _indexB = _indexA;
  158. }
  159. else
  160. //otherwise the current A will be checked against the new B group. IndexB must be reset
  161. //to work on the new group
  162. {
  163. _indexB = -1;
  164. }
  165. }
  166. //the current group A iteration is done, so we move to the next A group
  167. if (_groupsEnumerableA.MoveNext() == true)
  168. {
  169. //there is a new group, we reset the iteration
  170. _indexA = 0;
  171. _indexB = 0;
  172. _groupsEnumerableB = _groupsEnumerableA;
  173. }
  174. else
  175. return false;
  176. }
  177. return false;
  178. }
  179. public void Reset() { throw new Exception(); }
  180. public ValueRef Current
  181. {
  182. get
  183. {
  184. var valueRef = new ValueRef(_groupsEnumerableA.Current, _indexA, _groupsEnumerableB.Current
  185. , _indexB);
  186. return valueRef;
  187. }
  188. }
  189. public void Dispose() { }
  190. GroupsEnumerable<T1, T2>.GroupsIterator _groupsEnumerableA;
  191. GroupsEnumerable<T1, T2>.GroupsIterator _groupsEnumerableB;
  192. int _indexA;
  193. int _indexB;
  194. }
  195. public readonly ref struct ValueRef
  196. {
  197. public readonly GroupsEnumerable<T1, T2>.RefCurrent _current;
  198. public readonly int _indexA;
  199. public readonly GroupsEnumerable<T1, T2>.RefCurrent _refCurrent;
  200. public readonly int _indexB;
  201. public ValueRef
  202. (GroupsEnumerable<T1, T2>.RefCurrent current, int indexA, GroupsEnumerable<T1, T2>.RefCurrent refCurrent
  203. , int indexB)
  204. {
  205. _current = current;
  206. _indexA = indexA;
  207. _refCurrent = refCurrent;
  208. _indexB = indexB;
  209. }
  210. public void Deconstruct(out EntityCollection<T1, T2> buffers, out int indexA,
  211. out EntityCollection<T1, T2> refCurrent, out int indexB)
  212. {
  213. buffers = _current._buffers;
  214. indexA = _indexA;
  215. refCurrent = _refCurrent._buffers;
  216. indexB = _indexB;
  217. }
  218. public void Deconstruct
  219. (out EntityCollection<T1, T2> buffers, out int indexA, out ExclusiveGroupStruct groupA
  220. , out EntityCollection<T1, T2> refCurrent, out int indexB, out ExclusiveGroupStruct groupB)
  221. {
  222. buffers = _current._buffers;
  223. indexA = _indexA;
  224. refCurrent = _refCurrent._buffers;
  225. indexB = _indexB;
  226. groupA = _current._group;
  227. groupB = _refCurrent._group;
  228. }
  229. }
  230. }
  231. /// <summary>
  232. /// Special Enumerator to iterate a group of entities against themselves with complexity n*(n+1)/2 (skips already tested couples)
  233. /// </summary>
  234. /// <typeparam name="T1"></typeparam>
  235. /// <typeparam name="T2"></typeparam>
  236. /// <typeparam name="T3"></typeparam>
  237. public readonly ref struct DoubleEntitiesEnumerator<T1, T2, T3> where T1 : struct, _IInternalEntityComponent
  238. where T2 : struct, _IInternalEntityComponent
  239. where T3 : struct, _IInternalEntityComponent
  240. {
  241. public DoubleEntitiesEnumerator(GroupsEnumerable<T1, T2, T3> groupsEnumerable)
  242. {
  243. _groupsEnumerable = groupsEnumerable;
  244. }
  245. public EntityGroupsIterator GetEnumerator() { return new EntityGroupsIterator(_groupsEnumerable); }
  246. readonly GroupsEnumerable<T1, T2, T3> _groupsEnumerable;
  247. public ref struct EntityGroupsIterator
  248. {
  249. public EntityGroupsIterator(GroupsEnumerable<T1, T2, T3> groupsEnumerable) : this()
  250. {
  251. _groupsEnumerableA = groupsEnumerable.GetEnumerator();
  252. _groupsEnumerableA.MoveNext();
  253. _groupsEnumerableB = _groupsEnumerableA;
  254. _indexA = 0;
  255. _indexB = 0;
  256. }
  257. public bool MoveNext()
  258. {
  259. //once GroupEnumerables complete, they reset. If they reset and moveNext doesn't happen, they are invalid
  260. while (_groupsEnumerableA.isValid)
  261. {
  262. var (buffersA, _) = _groupsEnumerableA.Current;
  263. var (buffersB, _) = _groupsEnumerableB.Current;
  264. //current index A must iterate as long as is less than the current A group count
  265. while (_indexA < buffersA.count)
  266. {
  267. //current index B must iterate as long as is less than the current B group count
  268. if (++_indexB < buffersB.count)
  269. {
  270. return true;
  271. }
  272. //if B iteration is over, move to the next group
  273. if (_groupsEnumerableB.MoveNext() == false)
  274. {
  275. //if there is no valid next groups, we reset B and we need to move to the next A element
  276. _groupsEnumerableB = _groupsEnumerableA;
  277. (buffersB, _) = _groupsEnumerableB.Current;
  278. ++_indexA; //next A element
  279. _indexB = _indexA;
  280. }
  281. else
  282. //otherwise the current A will be checked against the new B group. IndexB must be reset
  283. //to work on the new group
  284. {
  285. _indexB = -1;
  286. }
  287. }
  288. //the current group A iteration is done, so we move to the next A group
  289. if (_groupsEnumerableA.MoveNext() == true)
  290. {
  291. //there is a new group, we reset the iteration
  292. _indexA = 0;
  293. _indexB = 0;
  294. _groupsEnumerableB = _groupsEnumerableA;
  295. }
  296. else
  297. return false;
  298. }
  299. return false;
  300. }
  301. public void Reset() { throw new Exception(); }
  302. public ValueRef Current
  303. {
  304. get
  305. {
  306. var valueRef = new ValueRef(_groupsEnumerableA.Current, _indexA, _groupsEnumerableB.Current
  307. , _indexB);
  308. return valueRef;
  309. }
  310. }
  311. public void Dispose() { }
  312. GroupsEnumerable<T1, T2, T3>.GroupsIterator _groupsEnumerableA;
  313. GroupsEnumerable<T1, T2, T3>.GroupsIterator _groupsEnumerableB;
  314. int _indexA;
  315. int _indexB;
  316. }
  317. public readonly ref struct ValueRef
  318. {
  319. readonly GroupsEnumerable<T1, T2, T3>.RefCurrent _current;
  320. readonly int _indexA;
  321. readonly GroupsEnumerable<T1, T2, T3>.RefCurrent _refCurrent;
  322. readonly int _indexB;
  323. public ValueRef
  324. (GroupsEnumerable<T1, T2, T3>.RefCurrent current, int indexA
  325. , GroupsEnumerable<T1, T2, T3>.RefCurrent refCurrent, int indexB)
  326. {
  327. _current = current;
  328. _indexA = indexA;
  329. _refCurrent = refCurrent;
  330. _indexB = indexB;
  331. }
  332. public void Deconstruct
  333. (out EntityCollection<T1, T2, T3> buffers, out int indexA, out EntityCollection<T1, T2, T3> refCurrent
  334. , out int indexB)
  335. {
  336. buffers = _current._buffers;
  337. indexA = _indexA;
  338. refCurrent = _refCurrent._buffers;
  339. indexB = _indexB;
  340. }
  341. public void Deconstruct
  342. (out EntityCollection<T1, T2, T3> buffers, out int indexA, out ExclusiveGroupStruct groupA
  343. , out EntityCollection<T1, T2, T3> refCurrent, out int indexB, out ExclusiveGroupStruct groupB)
  344. {
  345. buffers = _current._buffers;
  346. indexA = _indexA;
  347. refCurrent = _refCurrent._buffers;
  348. indexB = _indexB;
  349. groupA = _current._group;
  350. groupB = _refCurrent._group;
  351. }
  352. }
  353. }
  354. /// <summary>
  355. /// Special Enumerator to iterate a group of entities against themselves with complexity n*(n+1)/2 (skips already tested couples)
  356. /// </summary>
  357. /// <typeparam name="T1"></typeparam>
  358. /// <typeparam name="T2"></typeparam>
  359. /// <typeparam name="T3"></typeparam>
  360. /// <typeparam name="T4"></typeparam>
  361. public readonly ref struct DoubleEntitiesEnumerator<T1, T2, T3, T4> where T1 : struct, _IInternalEntityComponent
  362. where T2 : struct, _IInternalEntityComponent
  363. where T3 : struct, _IInternalEntityComponent
  364. where T4 : struct, _IInternalEntityComponent
  365. {
  366. public DoubleEntitiesEnumerator(GroupsEnumerable<T1, T2, T3, T4> groupsEnumerable)
  367. {
  368. _groupsEnumerable = groupsEnumerable;
  369. }
  370. public EntityGroupsIterator GetEnumerator() { return new EntityGroupsIterator(_groupsEnumerable); }
  371. readonly GroupsEnumerable<T1, T2, T3, T4> _groupsEnumerable;
  372. public ref struct EntityGroupsIterator
  373. {
  374. public EntityGroupsIterator(GroupsEnumerable<T1, T2, T3, T4> groupsEnumerable) : this()
  375. {
  376. _groupsEnumerableA = groupsEnumerable.GetEnumerator();
  377. _groupsEnumerableA.MoveNext();
  378. _groupsEnumerableB = _groupsEnumerableA;
  379. _indexA = 0;
  380. _indexB = 0;
  381. }
  382. public bool MoveNext()
  383. {
  384. //once GroupEnumerables complete, they reset. If they reset and moveNext doesn't happen, they are invalid
  385. while (_groupsEnumerableA.isValid)
  386. {
  387. var (buffersA, _) = _groupsEnumerableA.Current;
  388. var (buffersB, _) = _groupsEnumerableB.Current;
  389. //current index A must iterate as long as is less than the current A group count
  390. while (_indexA < buffersA.count)
  391. {
  392. //current index B must iterate as long as is less than the current B group count
  393. if (++_indexB < buffersB.count)
  394. {
  395. return true;
  396. }
  397. //if B iteration is over, move to the next group
  398. if (_groupsEnumerableB.MoveNext() == false)
  399. {
  400. //if there is no valid next groups, we reset B and we need to move to the next A element
  401. _groupsEnumerableB = _groupsEnumerableA;
  402. (buffersB, _) = _groupsEnumerableB.Current;
  403. ++_indexA; //next A element
  404. _indexB = _indexA;
  405. }
  406. else
  407. //otherwise the current A will be checked against the new B group. IndexB must be reset
  408. //to work on the new group
  409. {
  410. _indexB = -1;
  411. }
  412. }
  413. //the current group A iteration is done, so we move to the next A group
  414. if (_groupsEnumerableA.MoveNext() == true)
  415. {
  416. //there is a new group, we reset the iteration
  417. _indexA = 0;
  418. _indexB = 0;
  419. _groupsEnumerableB = _groupsEnumerableA;
  420. }
  421. else
  422. return false;
  423. }
  424. return false;
  425. }
  426. public void Reset() { throw new Exception(); }
  427. public ValueRef Current
  428. {
  429. get
  430. {
  431. var valueRef = new ValueRef(_groupsEnumerableA.Current, _indexA, _groupsEnumerableB.Current
  432. , _indexB);
  433. return valueRef;
  434. }
  435. }
  436. public void Dispose() { }
  437. GroupsEnumerable<T1, T2, T3, T4>.GroupsIterator _groupsEnumerableA;
  438. GroupsEnumerable<T1, T2, T3, T4>.GroupsIterator _groupsEnumerableB;
  439. int _indexA;
  440. int _indexB;
  441. }
  442. public ref struct ValueRef
  443. {
  444. public readonly GroupsEnumerable<T1, T2, T3, T4>.RefCurrent _current;
  445. public readonly int _indexA;
  446. public readonly GroupsEnumerable<T1, T2, T3, T4>.RefCurrent _refCurrent;
  447. public readonly int _indexB;
  448. public ValueRef
  449. (GroupsEnumerable<T1, T2, T3, T4>.RefCurrent current, int indexA
  450. , GroupsEnumerable<T1, T2, T3, T4>.RefCurrent refCurrent, int indexB)
  451. {
  452. _current = current;
  453. _indexA = indexA;
  454. _refCurrent = refCurrent;
  455. _indexB = indexB;
  456. }
  457. public void Deconstruct
  458. (out EntityCollection<T1, T2, T3, T4> buffers, out int indexA, out EntityCollection<T1, T2, T3, T4> refCurrent
  459. , out int indexB)
  460. {
  461. buffers = _current._buffers;
  462. indexA = _indexA;
  463. refCurrent = _refCurrent._buffers;
  464. indexB = _indexB;
  465. }
  466. public void Deconstruct
  467. (out EntityCollection<T1, T2, T3, T4> buffers, out int indexA, out ExclusiveGroupStruct groupA
  468. , out EntityCollection<T1, T2, T3, T4> refCurrent, out int indexB, out ExclusiveGroupStruct groupB)
  469. {
  470. buffers = _current._buffers;
  471. indexA = _indexA;
  472. refCurrent = _refCurrent._buffers;
  473. indexB = _indexB;
  474. groupA = _current._group;
  475. groupB = _refCurrent._group;
  476. }
  477. }
  478. }
  479. }