UnityAsyncExtensions.Jobs.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #if ENABLE_MANAGED_JOBS
  2. #pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
  3. using System;
  4. using System.Threading;
  5. using Unity.Jobs;
  6. using UnityEngine;
  7. namespace Cysharp.Threading.Tasks
  8. {
  9. public static partial class UnityAsyncExtensions
  10. {
  11. public static async UniTask WaitAsync(this JobHandle jobHandle, PlayerLoopTiming waitTiming, CancellationToken cancellationToken = default)
  12. {
  13. await UniTask.Yield(waitTiming);
  14. jobHandle.Complete();
  15. cancellationToken.ThrowIfCancellationRequested(); // call cancel after Complete.
  16. }
  17. public static UniTask.Awaiter GetAwaiter(this JobHandle jobHandle)
  18. {
  19. var handler = JobHandlePromise.Create(jobHandle, out var token);
  20. {
  21. PlayerLoopHelper.AddAction(PlayerLoopTiming.EarlyUpdate, handler);
  22. PlayerLoopHelper.AddAction(PlayerLoopTiming.PreUpdate, handler);
  23. PlayerLoopHelper.AddAction(PlayerLoopTiming.Update, handler);
  24. PlayerLoopHelper.AddAction(PlayerLoopTiming.PreLateUpdate, handler);
  25. PlayerLoopHelper.AddAction(PlayerLoopTiming.PostLateUpdate, handler);
  26. }
  27. return new UniTask(handler, token).GetAwaiter();
  28. }
  29. // can not pass CancellationToken because can't handle JobHandle's Complete and NativeArray.Dispose.
  30. public static UniTask ToUniTask(this JobHandle jobHandle, PlayerLoopTiming waitTiming)
  31. {
  32. var handler = JobHandlePromise.Create(jobHandle, out var token);
  33. {
  34. PlayerLoopHelper.AddAction(waitTiming, handler);
  35. }
  36. return new UniTask(handler, token);
  37. }
  38. sealed class JobHandlePromise : IUniTaskSource, IPlayerLoopItem
  39. {
  40. JobHandle jobHandle;
  41. UniTaskCompletionSourceCore<AsyncUnit> core;
  42. // Cancellation is not supported.
  43. public static JobHandlePromise Create(JobHandle jobHandle, out short token)
  44. {
  45. // not use pool.
  46. var result = new JobHandlePromise();
  47. result.jobHandle = jobHandle;
  48. TaskTracker.TrackActiveTask(result, 3);
  49. token = result.core.Version;
  50. return result;
  51. }
  52. public void GetResult(short token)
  53. {
  54. TaskTracker.RemoveTracking(this);
  55. core.GetResult(token);
  56. }
  57. public UniTaskStatus GetStatus(short token)
  58. {
  59. return core.GetStatus(token);
  60. }
  61. public UniTaskStatus UnsafeGetStatus()
  62. {
  63. return core.UnsafeGetStatus();
  64. }
  65. public void OnCompleted(Action<object> continuation, object state, short token)
  66. {
  67. core.OnCompleted(continuation, state, token);
  68. }
  69. public bool MoveNext()
  70. {
  71. if (jobHandle.IsCompleted | PlayerLoopHelper.IsEditorApplicationQuitting)
  72. {
  73. jobHandle.Complete();
  74. core.TrySetResult(AsyncUnit.Default);
  75. return false;
  76. }
  77. return true;
  78. }
  79. }
  80. }
  81. }
  82. #endif