Where.cs 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818
  1. using Cysharp.Threading.Tasks.Internal;
  2. using System;
  3. using System.Threading;
  4. namespace Cysharp.Threading.Tasks.Linq
  5. {
  6. public static partial class UniTaskAsyncEnumerable
  7. {
  8. public static IUniTaskAsyncEnumerable<TSource> Where<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Boolean> predicate)
  9. {
  10. Error.ThrowArgumentNullException(source, nameof(source));
  11. Error.ThrowArgumentNullException(predicate, nameof(predicate));
  12. return new Where<TSource>(source, predicate);
  13. }
  14. public static IUniTaskAsyncEnumerable<TSource> Where<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Int32, Boolean> predicate)
  15. {
  16. Error.ThrowArgumentNullException(source, nameof(source));
  17. Error.ThrowArgumentNullException(predicate, nameof(predicate));
  18. return new WhereInt<TSource>(source, predicate);
  19. }
  20. public static IUniTaskAsyncEnumerable<TSource> WhereAwait<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<Boolean>> predicate)
  21. {
  22. Error.ThrowArgumentNullException(source, nameof(source));
  23. Error.ThrowArgumentNullException(predicate, nameof(predicate));
  24. return new WhereAwait<TSource>(source, predicate);
  25. }
  26. public static IUniTaskAsyncEnumerable<TSource> WhereAwait<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Int32, UniTask<Boolean>> predicate)
  27. {
  28. Error.ThrowArgumentNullException(source, nameof(source));
  29. Error.ThrowArgumentNullException(predicate, nameof(predicate));
  30. return new WhereIntAwait<TSource>(source, predicate);
  31. }
  32. public static IUniTaskAsyncEnumerable<TSource> WhereAwaitWithCancellation<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<Boolean>> predicate)
  33. {
  34. Error.ThrowArgumentNullException(source, nameof(source));
  35. Error.ThrowArgumentNullException(predicate, nameof(predicate));
  36. return new WhereAwaitWithCancellation<TSource>(source, predicate);
  37. }
  38. public static IUniTaskAsyncEnumerable<TSource> WhereAwaitWithCancellation<TSource>(this IUniTaskAsyncEnumerable<TSource> source, Func<TSource, Int32, CancellationToken, UniTask<Boolean>> predicate)
  39. {
  40. Error.ThrowArgumentNullException(source, nameof(source));
  41. Error.ThrowArgumentNullException(predicate, nameof(predicate));
  42. return new WhereIntAwaitWithCancellation<TSource>(source, predicate);
  43. }
  44. }
  45. internal sealed class Where<TSource> : IUniTaskAsyncEnumerable<TSource>
  46. {
  47. readonly IUniTaskAsyncEnumerable<TSource> source;
  48. readonly Func<TSource, bool> predicate;
  49. public Where(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, bool> predicate)
  50. {
  51. this.source = source;
  52. this.predicate = predicate;
  53. }
  54. public IUniTaskAsyncEnumerator<TSource> GetAsyncEnumerator(CancellationToken cancellationToken = default)
  55. {
  56. return new _Where(source, predicate, cancellationToken);
  57. }
  58. sealed class _Where : MoveNextSource, IUniTaskAsyncEnumerator<TSource>
  59. {
  60. readonly IUniTaskAsyncEnumerable<TSource> source;
  61. readonly Func<TSource, bool> predicate;
  62. readonly CancellationToken cancellationToken;
  63. int state = -1;
  64. IUniTaskAsyncEnumerator<TSource> enumerator;
  65. UniTask<bool>.Awaiter awaiter;
  66. Action moveNextAction;
  67. public _Where(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, bool> predicate, CancellationToken cancellationToken)
  68. {
  69. this.source = source;
  70. this.predicate = predicate;
  71. this.cancellationToken = cancellationToken;
  72. this.moveNextAction = MoveNext;
  73. TaskTracker.TrackActiveTask(this, 3);
  74. }
  75. public TSource Current { get; private set; }
  76. public UniTask<bool> MoveNextAsync()
  77. {
  78. if (state == -2) return default;
  79. completionSource.Reset();
  80. MoveNext();
  81. return new UniTask<bool>(this, completionSource.Version);
  82. }
  83. void MoveNext()
  84. {
  85. REPEAT:
  86. try
  87. {
  88. switch (state)
  89. {
  90. case -1: // init
  91. enumerator = source.GetAsyncEnumerator(cancellationToken);
  92. goto case 0;
  93. case 0:
  94. awaiter = enumerator.MoveNextAsync().GetAwaiter();
  95. if (awaiter.IsCompleted)
  96. {
  97. goto case 1;
  98. }
  99. else
  100. {
  101. state = 1;
  102. awaiter.UnsafeOnCompleted(moveNextAction);
  103. return;
  104. }
  105. case 1:
  106. if (awaiter.GetResult())
  107. {
  108. Current = enumerator.Current;
  109. if (predicate(Current))
  110. {
  111. goto CONTINUE;
  112. }
  113. else
  114. {
  115. state = 0;
  116. goto REPEAT;
  117. }
  118. }
  119. else
  120. {
  121. goto DONE;
  122. }
  123. default:
  124. goto DONE;
  125. }
  126. }
  127. catch (Exception ex)
  128. {
  129. state = -2;
  130. completionSource.TrySetException(ex);
  131. return;
  132. }
  133. DONE:
  134. state = -2;
  135. completionSource.TrySetResult(false);
  136. return;
  137. CONTINUE:
  138. state = 0;
  139. completionSource.TrySetResult(true);
  140. return;
  141. }
  142. public UniTask DisposeAsync()
  143. {
  144. TaskTracker.RemoveTracking(this);
  145. return enumerator.DisposeAsync();
  146. }
  147. }
  148. }
  149. internal sealed class WhereInt<TSource> : IUniTaskAsyncEnumerable<TSource>
  150. {
  151. readonly IUniTaskAsyncEnumerable<TSource> source;
  152. readonly Func<TSource, int, bool> predicate;
  153. public WhereInt(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, int, bool> predicate)
  154. {
  155. this.source = source;
  156. this.predicate = predicate;
  157. }
  158. public IUniTaskAsyncEnumerator<TSource> GetAsyncEnumerator(CancellationToken cancellationToken = default)
  159. {
  160. return new _Where(source, predicate, cancellationToken);
  161. }
  162. sealed class _Where : MoveNextSource, IUniTaskAsyncEnumerator<TSource>
  163. {
  164. readonly IUniTaskAsyncEnumerable<TSource> source;
  165. readonly Func<TSource, int, bool> predicate;
  166. readonly CancellationToken cancellationToken;
  167. int state = -1;
  168. IUniTaskAsyncEnumerator<TSource> enumerator;
  169. UniTask<bool>.Awaiter awaiter;
  170. Action moveNextAction;
  171. int index;
  172. public _Where(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, int, bool> predicate, CancellationToken cancellationToken)
  173. {
  174. this.source = source;
  175. this.predicate = predicate;
  176. this.cancellationToken = cancellationToken;
  177. this.moveNextAction = MoveNext;
  178. TaskTracker.TrackActiveTask(this, 3);
  179. }
  180. public TSource Current { get; private set; }
  181. public UniTask<bool> MoveNextAsync()
  182. {
  183. if (state == -2) return default;
  184. completionSource.Reset();
  185. MoveNext();
  186. return new UniTask<bool>(this, completionSource.Version);
  187. }
  188. void MoveNext()
  189. {
  190. REPEAT:
  191. try
  192. {
  193. switch (state)
  194. {
  195. case -1: // init
  196. enumerator = source.GetAsyncEnumerator(cancellationToken);
  197. goto case 0;
  198. case 0:
  199. awaiter = enumerator.MoveNextAsync().GetAwaiter();
  200. if (awaiter.IsCompleted)
  201. {
  202. goto case 1;
  203. }
  204. else
  205. {
  206. state = 1;
  207. awaiter.UnsafeOnCompleted(moveNextAction);
  208. return;
  209. }
  210. case 1:
  211. if (awaiter.GetResult())
  212. {
  213. Current = enumerator.Current;
  214. if (predicate(Current, checked(index++)))
  215. {
  216. goto CONTINUE;
  217. }
  218. else
  219. {
  220. state = 0;
  221. goto REPEAT;
  222. }
  223. }
  224. else
  225. {
  226. goto DONE;
  227. }
  228. default:
  229. goto DONE;
  230. }
  231. }
  232. catch (Exception ex)
  233. {
  234. state = -2;
  235. completionSource.TrySetException(ex);
  236. return;
  237. }
  238. DONE:
  239. state = -2;
  240. completionSource.TrySetResult(false);
  241. return;
  242. CONTINUE:
  243. state = 0;
  244. completionSource.TrySetResult(true);
  245. return;
  246. }
  247. public UniTask DisposeAsync()
  248. {
  249. TaskTracker.RemoveTracking(this);
  250. return enumerator.DisposeAsync();
  251. }
  252. }
  253. }
  254. internal sealed class WhereAwait<TSource> : IUniTaskAsyncEnumerable<TSource>
  255. {
  256. readonly IUniTaskAsyncEnumerable<TSource> source;
  257. readonly Func<TSource, UniTask<bool>> predicate;
  258. public WhereAwait(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<bool>> predicate)
  259. {
  260. this.source = source;
  261. this.predicate = predicate;
  262. }
  263. public IUniTaskAsyncEnumerator<TSource> GetAsyncEnumerator(CancellationToken cancellationToken = default)
  264. {
  265. return new _WhereAwait(source, predicate, cancellationToken);
  266. }
  267. sealed class _WhereAwait : MoveNextSource, IUniTaskAsyncEnumerator<TSource>
  268. {
  269. readonly IUniTaskAsyncEnumerable<TSource> source;
  270. readonly Func<TSource, UniTask<bool>> predicate;
  271. readonly CancellationToken cancellationToken;
  272. int state = -1;
  273. IUniTaskAsyncEnumerator<TSource> enumerator;
  274. UniTask<bool>.Awaiter awaiter;
  275. UniTask<bool>.Awaiter awaiter2;
  276. Action moveNextAction;
  277. public _WhereAwait(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, UniTask<bool>> predicate, CancellationToken cancellationToken)
  278. {
  279. this.source = source;
  280. this.predicate = predicate;
  281. this.cancellationToken = cancellationToken;
  282. this.moveNextAction = MoveNext;
  283. TaskTracker.TrackActiveTask(this, 3);
  284. }
  285. public TSource Current { get; private set; }
  286. public UniTask<bool> MoveNextAsync()
  287. {
  288. if (state == -2) return default;
  289. completionSource.Reset();
  290. MoveNext();
  291. return new UniTask<bool>(this, completionSource.Version);
  292. }
  293. void MoveNext()
  294. {
  295. REPEAT:
  296. try
  297. {
  298. switch (state)
  299. {
  300. case -1: // init
  301. enumerator = source.GetAsyncEnumerator(cancellationToken);
  302. goto case 0;
  303. case 0:
  304. awaiter = enumerator.MoveNextAsync().GetAwaiter();
  305. if (awaiter.IsCompleted)
  306. {
  307. goto case 1;
  308. }
  309. else
  310. {
  311. state = 1;
  312. awaiter.UnsafeOnCompleted(moveNextAction);
  313. return;
  314. }
  315. case 1:
  316. if (awaiter.GetResult())
  317. {
  318. Current = enumerator.Current;
  319. awaiter2 = predicate(Current).GetAwaiter();
  320. if (awaiter2.IsCompleted)
  321. {
  322. goto case 2;
  323. }
  324. else
  325. {
  326. state = 2;
  327. awaiter2.UnsafeOnCompleted(moveNextAction);
  328. return;
  329. }
  330. }
  331. else
  332. {
  333. goto DONE;
  334. }
  335. case 2:
  336. if (awaiter2.GetResult())
  337. {
  338. goto CONTINUE;
  339. }
  340. else
  341. {
  342. state = 0;
  343. goto REPEAT;
  344. }
  345. default:
  346. goto DONE;
  347. }
  348. }
  349. catch (Exception ex)
  350. {
  351. state = -2;
  352. completionSource.TrySetException(ex);
  353. return;
  354. }
  355. DONE:
  356. state = -2;
  357. completionSource.TrySetResult(false);
  358. return;
  359. CONTINUE:
  360. state = 0;
  361. completionSource.TrySetResult(true);
  362. return;
  363. }
  364. public UniTask DisposeAsync()
  365. {
  366. TaskTracker.RemoveTracking(this);
  367. return enumerator.DisposeAsync();
  368. }
  369. }
  370. }
  371. internal sealed class WhereIntAwait<TSource> : IUniTaskAsyncEnumerable<TSource>
  372. {
  373. readonly IUniTaskAsyncEnumerable<TSource> source;
  374. readonly Func<TSource, int, UniTask<bool>> predicate;
  375. public WhereIntAwait(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, int, UniTask<bool>> predicate)
  376. {
  377. this.source = source;
  378. this.predicate = predicate;
  379. }
  380. public IUniTaskAsyncEnumerator<TSource> GetAsyncEnumerator(CancellationToken cancellationToken = default)
  381. {
  382. return new _WhereAwait(source, predicate, cancellationToken);
  383. }
  384. sealed class _WhereAwait : MoveNextSource, IUniTaskAsyncEnumerator<TSource>
  385. {
  386. readonly IUniTaskAsyncEnumerable<TSource> source;
  387. readonly Func<TSource, int, UniTask<bool>> predicate;
  388. readonly CancellationToken cancellationToken;
  389. int state = -1;
  390. IUniTaskAsyncEnumerator<TSource> enumerator;
  391. UniTask<bool>.Awaiter awaiter;
  392. UniTask<bool>.Awaiter awaiter2;
  393. Action moveNextAction;
  394. int index;
  395. public _WhereAwait(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, int, UniTask<bool>> predicate, CancellationToken cancellationToken)
  396. {
  397. this.source = source;
  398. this.predicate = predicate;
  399. this.cancellationToken = cancellationToken;
  400. this.moveNextAction = MoveNext;
  401. TaskTracker.TrackActiveTask(this, 3);
  402. }
  403. public TSource Current { get; private set; }
  404. public UniTask<bool> MoveNextAsync()
  405. {
  406. if (state == -2) return default;
  407. completionSource.Reset();
  408. MoveNext();
  409. return new UniTask<bool>(this, completionSource.Version);
  410. }
  411. void MoveNext()
  412. {
  413. REPEAT:
  414. try
  415. {
  416. switch (state)
  417. {
  418. case -1: // init
  419. enumerator = source.GetAsyncEnumerator(cancellationToken);
  420. goto case 0;
  421. case 0:
  422. awaiter = enumerator.MoveNextAsync().GetAwaiter();
  423. if (awaiter.IsCompleted)
  424. {
  425. goto case 1;
  426. }
  427. else
  428. {
  429. state = 1;
  430. awaiter.UnsafeOnCompleted(moveNextAction);
  431. return;
  432. }
  433. case 1:
  434. if (awaiter.GetResult())
  435. {
  436. Current = enumerator.Current;
  437. awaiter2 = predicate(Current, checked(index++)).GetAwaiter();
  438. if (awaiter2.IsCompleted)
  439. {
  440. goto case 2;
  441. }
  442. else
  443. {
  444. state = 2;
  445. awaiter2.UnsafeOnCompleted(moveNextAction);
  446. return;
  447. }
  448. }
  449. else
  450. {
  451. goto DONE;
  452. }
  453. case 2:
  454. if (awaiter2.GetResult())
  455. {
  456. goto CONTINUE;
  457. }
  458. else
  459. {
  460. state = 0;
  461. goto REPEAT;
  462. }
  463. default:
  464. goto DONE;
  465. }
  466. }
  467. catch (Exception ex)
  468. {
  469. state = -2;
  470. completionSource.TrySetException(ex);
  471. return;
  472. }
  473. DONE:
  474. state = -2;
  475. completionSource.TrySetResult(false);
  476. return;
  477. CONTINUE:
  478. state = 0;
  479. completionSource.TrySetResult(true);
  480. return;
  481. }
  482. public UniTask DisposeAsync()
  483. {
  484. TaskTracker.RemoveTracking(this);
  485. return enumerator.DisposeAsync();
  486. }
  487. }
  488. }
  489. internal sealed class WhereAwaitWithCancellation<TSource> : IUniTaskAsyncEnumerable<TSource>
  490. {
  491. readonly IUniTaskAsyncEnumerable<TSource> source;
  492. readonly Func<TSource, CancellationToken, UniTask<bool>> predicate;
  493. public WhereAwaitWithCancellation(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<bool>> predicate)
  494. {
  495. this.source = source;
  496. this.predicate = predicate;
  497. }
  498. public IUniTaskAsyncEnumerator<TSource> GetAsyncEnumerator(CancellationToken cancellationToken = default)
  499. {
  500. return new _WhereAwaitWithCancellation(source, predicate, cancellationToken);
  501. }
  502. sealed class _WhereAwaitWithCancellation : MoveNextSource, IUniTaskAsyncEnumerator<TSource>
  503. {
  504. readonly IUniTaskAsyncEnumerable<TSource> source;
  505. readonly Func<TSource, CancellationToken, UniTask<bool>> predicate;
  506. readonly CancellationToken cancellationToken;
  507. int state = -1;
  508. IUniTaskAsyncEnumerator<TSource> enumerator;
  509. UniTask<bool>.Awaiter awaiter;
  510. UniTask<bool>.Awaiter awaiter2;
  511. Action moveNextAction;
  512. public _WhereAwaitWithCancellation(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, UniTask<bool>> predicate, CancellationToken cancellationToken)
  513. {
  514. this.source = source;
  515. this.predicate = predicate;
  516. this.cancellationToken = cancellationToken;
  517. this.moveNextAction = MoveNext;
  518. TaskTracker.TrackActiveTask(this, 3);
  519. }
  520. public TSource Current { get; private set; }
  521. public UniTask<bool> MoveNextAsync()
  522. {
  523. if (state == -2) return default;
  524. completionSource.Reset();
  525. MoveNext();
  526. return new UniTask<bool>(this, completionSource.Version);
  527. }
  528. void MoveNext()
  529. {
  530. REPEAT:
  531. try
  532. {
  533. switch (state)
  534. {
  535. case -1: // init
  536. enumerator = source.GetAsyncEnumerator(cancellationToken);
  537. goto case 0;
  538. case 0:
  539. awaiter = enumerator.MoveNextAsync().GetAwaiter();
  540. if (awaiter.IsCompleted)
  541. {
  542. goto case 1;
  543. }
  544. else
  545. {
  546. state = 1;
  547. awaiter.UnsafeOnCompleted(moveNextAction);
  548. return;
  549. }
  550. case 1:
  551. if (awaiter.GetResult())
  552. {
  553. Current = enumerator.Current;
  554. awaiter2 = predicate(Current, cancellationToken).GetAwaiter();
  555. if (awaiter2.IsCompleted)
  556. {
  557. goto case 2;
  558. }
  559. else
  560. {
  561. state = 2;
  562. awaiter2.UnsafeOnCompleted(moveNextAction);
  563. return;
  564. }
  565. }
  566. else
  567. {
  568. goto DONE;
  569. }
  570. case 2:
  571. if (awaiter2.GetResult())
  572. {
  573. goto CONTINUE;
  574. }
  575. else
  576. {
  577. state = 0;
  578. goto REPEAT;
  579. }
  580. default:
  581. goto DONE;
  582. }
  583. }
  584. catch (Exception ex)
  585. {
  586. state = -2;
  587. completionSource.TrySetException(ex);
  588. return;
  589. }
  590. DONE:
  591. state = -2;
  592. completionSource.TrySetResult(false);
  593. return;
  594. CONTINUE:
  595. state = 0;
  596. completionSource.TrySetResult(true);
  597. return;
  598. }
  599. public UniTask DisposeAsync()
  600. {
  601. TaskTracker.RemoveTracking(this);
  602. return enumerator.DisposeAsync();
  603. }
  604. }
  605. }
  606. internal sealed class WhereIntAwaitWithCancellation<TSource> : IUniTaskAsyncEnumerable<TSource>
  607. {
  608. readonly IUniTaskAsyncEnumerable<TSource> source;
  609. readonly Func<TSource, int, CancellationToken, UniTask<bool>> predicate;
  610. public WhereIntAwaitWithCancellation(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, int, CancellationToken, UniTask<bool>> predicate)
  611. {
  612. this.source = source;
  613. this.predicate = predicate;
  614. }
  615. public IUniTaskAsyncEnumerator<TSource> GetAsyncEnumerator(CancellationToken cancellationToken = default)
  616. {
  617. return new _WhereAwaitWithCancellation(source, predicate, cancellationToken);
  618. }
  619. sealed class _WhereAwaitWithCancellation : MoveNextSource, IUniTaskAsyncEnumerator<TSource>
  620. {
  621. readonly IUniTaskAsyncEnumerable<TSource> source;
  622. readonly Func<TSource, int, CancellationToken, UniTask<bool>> predicate;
  623. readonly CancellationToken cancellationToken;
  624. int state = -1;
  625. IUniTaskAsyncEnumerator<TSource> enumerator;
  626. UniTask<bool>.Awaiter awaiter;
  627. UniTask<bool>.Awaiter awaiter2;
  628. Action moveNextAction;
  629. int index;
  630. public _WhereAwaitWithCancellation(IUniTaskAsyncEnumerable<TSource> source, Func<TSource, int, CancellationToken, UniTask<bool>> predicate, CancellationToken cancellationToken)
  631. {
  632. this.source = source;
  633. this.predicate = predicate;
  634. this.cancellationToken = cancellationToken;
  635. this.moveNextAction = MoveNext;
  636. TaskTracker.TrackActiveTask(this, 3);
  637. }
  638. public TSource Current { get; private set; }
  639. public UniTask<bool> MoveNextAsync()
  640. {
  641. if (state == -2) return default;
  642. completionSource.Reset();
  643. MoveNext();
  644. return new UniTask<bool>(this, completionSource.Version);
  645. }
  646. void MoveNext()
  647. {
  648. REPEAT:
  649. try
  650. {
  651. switch (state)
  652. {
  653. case -1: // init
  654. enumerator = source.GetAsyncEnumerator(cancellationToken);
  655. goto case 0;
  656. case 0:
  657. awaiter = enumerator.MoveNextAsync().GetAwaiter();
  658. if (awaiter.IsCompleted)
  659. {
  660. goto case 1;
  661. }
  662. else
  663. {
  664. state = 1;
  665. awaiter.UnsafeOnCompleted(moveNextAction);
  666. return;
  667. }
  668. case 1:
  669. if (awaiter.GetResult())
  670. {
  671. Current = enumerator.Current;
  672. awaiter2 = predicate(Current, checked(index++), cancellationToken).GetAwaiter();
  673. if (awaiter2.IsCompleted)
  674. {
  675. goto case 2;
  676. }
  677. else
  678. {
  679. state = 2;
  680. awaiter2.UnsafeOnCompleted(moveNextAction);
  681. return;
  682. }
  683. }
  684. else
  685. {
  686. goto DONE;
  687. }
  688. case 2:
  689. if (awaiter2.GetResult())
  690. {
  691. goto CONTINUE;
  692. }
  693. else
  694. {
  695. state = 0;
  696. goto REPEAT;
  697. }
  698. default:
  699. goto DONE;
  700. }
  701. }
  702. catch (Exception ex)
  703. {
  704. state = -2;
  705. completionSource.TrySetException(ex);
  706. return;
  707. }
  708. DONE:
  709. state = -2;
  710. completionSource.TrySetResult(false);
  711. return;
  712. CONTINUE:
  713. state = 0;
  714. completionSource.TrySetResult(true);
  715. return;
  716. }
  717. public UniTask DisposeAsync()
  718. {
  719. TaskTracker.RemoveTracking(this);
  720. return enumerator.DisposeAsync();
  721. }
  722. }
  723. }
  724. }