您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

100 行
3.4 KiB

  1. using System.Threading;
  2. namespace Cysharp.Threading.Tasks.Linq
  3. {
  4. public static partial class UniTaskAsyncEnumerable
  5. {
  6. public static IUniTaskAsyncEnumerable<AsyncUnit> EveryUpdate(PlayerLoopTiming updateTiming = PlayerLoopTiming.Update, bool cancelImmediately = false)
  7. {
  8. return new EveryUpdate(updateTiming, cancelImmediately);
  9. }
  10. }
  11. internal class EveryUpdate : IUniTaskAsyncEnumerable<AsyncUnit>
  12. {
  13. readonly PlayerLoopTiming updateTiming;
  14. readonly bool cancelImmediately;
  15. public EveryUpdate(PlayerLoopTiming updateTiming, bool cancelImmediately)
  16. {
  17. this.updateTiming = updateTiming;
  18. this.cancelImmediately = cancelImmediately;
  19. }
  20. public IUniTaskAsyncEnumerator<AsyncUnit> GetAsyncEnumerator(CancellationToken cancellationToken = default)
  21. {
  22. return new _EveryUpdate(updateTiming, cancellationToken, cancelImmediately);
  23. }
  24. class _EveryUpdate : MoveNextSource, IUniTaskAsyncEnumerator<AsyncUnit>, IPlayerLoopItem
  25. {
  26. readonly PlayerLoopTiming updateTiming;
  27. readonly CancellationToken cancellationToken;
  28. readonly CancellationTokenRegistration cancellationTokenRegistration;
  29. bool disposed;
  30. public _EveryUpdate(PlayerLoopTiming updateTiming, CancellationToken cancellationToken, bool cancelImmediately)
  31. {
  32. this.updateTiming = updateTiming;
  33. this.cancellationToken = cancellationToken;
  34. if (cancelImmediately && cancellationToken.CanBeCanceled)
  35. {
  36. cancellationTokenRegistration = cancellationToken.RegisterWithoutCaptureExecutionContext(state =>
  37. {
  38. var source = (_EveryUpdate)state;
  39. source.completionSource.TrySetCanceled(source.cancellationToken);
  40. }, this);
  41. }
  42. TaskTracker.TrackActiveTask(this, 2);
  43. PlayerLoopHelper.AddAction(updateTiming, this);
  44. }
  45. public AsyncUnit Current => default;
  46. public UniTask<bool> MoveNextAsync()
  47. {
  48. if (disposed) return CompletedTasks.False;
  49. completionSource.Reset();
  50. if (cancellationToken.IsCancellationRequested)
  51. {
  52. completionSource.TrySetCanceled(cancellationToken);
  53. }
  54. return new UniTask<bool>(this, completionSource.Version);
  55. }
  56. public UniTask DisposeAsync()
  57. {
  58. if (!disposed)
  59. {
  60. cancellationTokenRegistration.Dispose();
  61. disposed = true;
  62. TaskTracker.RemoveTracking(this);
  63. }
  64. return default;
  65. }
  66. public bool MoveNext()
  67. {
  68. if (cancellationToken.IsCancellationRequested)
  69. {
  70. completionSource.TrySetCanceled(cancellationToken);
  71. return false;
  72. }
  73. if (disposed)
  74. {
  75. completionSource.TrySetResult(false);
  76. return false;
  77. }
  78. completionSource.TrySetResult(true);
  79. return true;
  80. }
  81. }
  82. }
  83. }