您不能選擇超過 %s 個話題 話題必須以字母或數字為開頭,可包含連接號 ('-') 且最長為 35 個字
 
 
 

139 行
2.7 KiB

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