ValueTaskMotionConfiguredSource.cs 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. using System;
  2. using System.Threading;
  3. using System.Threading.Tasks.Sources;
  4. using LitMotion.Collections;
  5. namespace LitMotion
  6. {
  7. internal sealed class ValueTaskMotionConfiguredSource : MotionConfiguredSourceBase, IValueTaskSource, ILinkedPoolNode<ValueTaskMotionConfiguredSource>
  8. {
  9. static LinkedPool<ValueTaskMotionConfiguredSource> pool;
  10. ValueTaskMotionConfiguredSource nextNode;
  11. public ref ValueTaskMotionConfiguredSource NextNode => ref nextNode;
  12. ManualResetValueTaskSourceCore<object> core;
  13. static ValueTaskMotionConfiguredSource FromCanceled(out short token)
  14. {
  15. if (canceledSource == null)
  16. {
  17. canceledSource = new();
  18. }
  19. canceledSource.core.Reset();
  20. canceledSource.core.SetException(new OperationCanceledException());
  21. token = canceledSource.Version;
  22. return canceledSource;
  23. }
  24. static ValueTaskMotionConfiguredSource canceledSource;
  25. ValueTaskMotionConfiguredSource() : base() { }
  26. public static IValueTaskSource Create(MotionHandle motionHandle, CancelBehaviour cancelBehaviour, CancellationToken cancellationToken, out short token)
  27. {
  28. if (cancellationToken.IsCancellationRequested)
  29. {
  30. OnCanceledTokenReceived(motionHandle, cancelBehaviour);
  31. return FromCanceled(out token);
  32. }
  33. if (!pool.TryPop(out var result))
  34. {
  35. result = new ValueTaskMotionConfiguredSource();
  36. }
  37. result.Initialize(motionHandle, cancelBehaviour, cancellationToken);
  38. token = result.core.Version;
  39. return result;
  40. }
  41. public short Version => core.Version;
  42. public void GetResult(short token)
  43. {
  44. try
  45. {
  46. core.GetResult(token);
  47. }
  48. finally
  49. {
  50. TryReturn();
  51. }
  52. }
  53. public ValueTaskSourceStatus GetStatus(short token)
  54. {
  55. return core.GetStatus(token);
  56. }
  57. public void OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags)
  58. {
  59. core.OnCompleted(continuation, state, token, flags);
  60. }
  61. bool TryReturn()
  62. {
  63. core.Reset();
  64. DisposeRegistration();
  65. RestoreOriginalCallback();
  66. ResetFields();
  67. return pool.TryPush(this);
  68. }
  69. protected override void SetTaskCanceled(CancellationToken cancellationToken)
  70. {
  71. core.SetException(new OperationCanceledException());
  72. }
  73. protected override void SetTaskCompleted()
  74. {
  75. core.SetResult(null);
  76. }
  77. }
  78. }