using System; using System.Collections.Generic; using UnityEngine; namespace SUISS.Scheduling { public class CoTask : ICoroutineTask, IYieldStatement { public CoTask(IEnumerator coroutine) { this._routine = this.InternalRoutine(coroutine); this._error = default(TError); this._result = default(TResult); this._running = false; this._paused = false; } public static CoTask CreateAndStart(IEnumerator coroutine, IScheduler scheduler) { CoTask coTask = new CoTask(coroutine); coTask.Start(scheduler); return coTask; } [Obsolete("Use CoReturn.Error(value)")] public static IYieldStatement Return(TError value) { return new CoError(value); } [Obsolete("Use CoReturn.Result(value)")] public static IYieldStatement Return(TResult value) { return new CoResult(value); } public TResult Result { get { if (this._running) { throw new Exception(string.Format("{0}.Result was read before return value was set!", this)); } return this._result; } } public TError Error { get { if (this._running) { throw new Exception(string.Format("{0}.Error was read before return error was set!", this)); } return this._error; } } public bool Running { get { return this._running; } } public bool IsDone { get { return !this._running; } } public void Stop() { this._running = false; if (this._onComplete != null) { this._onComplete.Stop(); } } public void Start(IScheduler scheduler) { this._running = true; this._onComplete = scheduler.StartCoroutine(this._routine); } public void Pause() { this._paused = true; } public void Unpause() { this._paused = false; } public object UnityYieldable() { return this._onComplete.UnityYieldable(); } public object UnityYieldable(MonoBehaviour runner) { return this._onComplete.UnityYieldable(runner); } public object SUISSYieldable() { return this._onComplete.SUISSYieldable(); } private IEnumerator InternalRoutine(IEnumerator coroutine) { while (this._running) { while (this._paused) { yield return null; } if (!coroutine.MoveNext()) { this._running = false; yield break; } CoError coError = coroutine.Current as CoError; CoResult coResult = coroutine.Current as CoResult; CoReturn coReturn = coroutine.Current as CoReturn; if (coError != null) { this._error = coError.Value; this._running = false; yield break; } if (coResult != null) { this._result = coResult.Value; this._running = false; yield break; } if (coReturn != null) { throw new Exception(string.Format("Type missmatch! {0} returned a wrong value {1} to {2}!", coroutine, coReturn, this)); } yield return coroutine.Current; } yield break; } private bool _running; private bool _paused; private TError _error; private TResult _result; private IEnumerator _routine; private ICoroutine _onComplete; } }