You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

167 regels
3.4 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. namespace SUISS.Scheduling
  5. {
  6. public class CoTask<TResult, TError> : ICoroutineTask<TResult, TError>, IYieldStatement
  7. {
  8. public CoTask(IEnumerator<IYieldStatement> coroutine)
  9. {
  10. this._routine = this.InternalRoutine(coroutine);
  11. this._error = default(TError);
  12. this._result = default(TResult);
  13. this._running = false;
  14. this._paused = false;
  15. }
  16. public static CoTask<TResult, TError> CreateAndStart(IEnumerator<IYieldStatement> coroutine, IScheduler scheduler)
  17. {
  18. CoTask<TResult, TError> coTask = new CoTask<TResult, TError>(coroutine);
  19. coTask.Start(scheduler);
  20. return coTask;
  21. }
  22. [Obsolete("Use CoReturn.Error(value)")]
  23. public static IYieldStatement Return(TError value)
  24. {
  25. return new CoError<TError>(value);
  26. }
  27. [Obsolete("Use CoReturn.Result(value)")]
  28. public static IYieldStatement Return(TResult value)
  29. {
  30. return new CoResult<TResult>(value);
  31. }
  32. public TResult Result
  33. {
  34. get
  35. {
  36. if (this._running)
  37. {
  38. throw new Exception(string.Format("{0}.Result was read before return value was set!", this));
  39. }
  40. return this._result;
  41. }
  42. }
  43. public TError Error
  44. {
  45. get
  46. {
  47. if (this._running)
  48. {
  49. throw new Exception(string.Format("{0}.Error was read before return error was set!", this));
  50. }
  51. return this._error;
  52. }
  53. }
  54. public bool Running
  55. {
  56. get
  57. {
  58. return this._running;
  59. }
  60. }
  61. public bool IsDone
  62. {
  63. get
  64. {
  65. return !this._running;
  66. }
  67. }
  68. public void Stop()
  69. {
  70. this._running = false;
  71. if (this._onComplete != null)
  72. {
  73. this._onComplete.Stop();
  74. }
  75. }
  76. public void Start(IScheduler scheduler)
  77. {
  78. this._running = true;
  79. this._onComplete = scheduler.StartCoroutine(this._routine);
  80. }
  81. public void Pause()
  82. {
  83. this._paused = true;
  84. }
  85. public void Unpause()
  86. {
  87. this._paused = false;
  88. }
  89. public object UnityYieldable()
  90. {
  91. return this._onComplete.UnityYieldable();
  92. }
  93. public object UnityYieldable(MonoBehaviour runner)
  94. {
  95. return this._onComplete.UnityYieldable(runner);
  96. }
  97. public object SUISSYieldable()
  98. {
  99. return this._onComplete.SUISSYieldable();
  100. }
  101. private IEnumerator<IYieldStatement> InternalRoutine(IEnumerator<IYieldStatement> coroutine)
  102. {
  103. while (this._running)
  104. {
  105. while (this._paused)
  106. {
  107. yield return null;
  108. }
  109. if (!coroutine.MoveNext())
  110. {
  111. this._running = false;
  112. yield break;
  113. }
  114. CoError<TError> coError = coroutine.Current as CoError<TError>;
  115. CoResult<TResult> coResult = coroutine.Current as CoResult<TResult>;
  116. CoReturn coReturn = coroutine.Current as CoReturn;
  117. if (coError != null)
  118. {
  119. this._error = coError.Value;
  120. this._running = false;
  121. yield break;
  122. }
  123. if (coResult != null)
  124. {
  125. this._result = coResult.Value;
  126. this._running = false;
  127. yield break;
  128. }
  129. if (coReturn != null)
  130. {
  131. throw new Exception(string.Format("Type missmatch! {0} returned a wrong value {1} to {2}!", coroutine, coReturn, this));
  132. }
  133. yield return coroutine.Current;
  134. }
  135. yield break;
  136. }
  137. private bool _running;
  138. private bool _paused;
  139. private TError _error;
  140. private TResult _result;
  141. private IEnumerator<IYieldStatement> _routine;
  142. private ICoroutine _onComplete;
  143. }
  144. }