|
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- namespace SUISS.Scheduling
- {
- public class UnityScheduler : IScheduler
- {
- [Obsolete("Use default constructor.")]
- public UnityScheduler(MonoBehaviour runner)
- {
- this._executorName = string.Format("__ScheduleExecutor{0}", UnityEngine.Random.Range(1000, 9999));
- this._executor = runner;
- }
-
- public UnityScheduler()
- {
- this._executorName = string.Format("__ScheduleExecutor{0}", UnityEngine.Random.Range(1000, 9999));
- this.CreateScheduleExecutor();
- }
-
- public ICoroutine StartCoroutine(IEnumerator<IYieldStatement> routine)
- {
- if (this._executor == null)
- {
- this.CreateScheduleExecutor();
- }
- if (!(this._executor != null))
- {
- UnityEngine.Debug.LogError(string.Format("The schedule executor backing this scheduler is null! Can't start {0}", routine));
- return null;
- }
- if (this._runningRoutines.Contains(routine))
- {
- throw new SchedulerException(string.Format("You are calling StartRoutine on a routine '{0}' that was already started.", routine));
- }
- this._runningRoutines.Add(routine);
- return new UnityScheduler.CoroutineWapper(routine, this);
- }
-
- private MonoBehaviour Executor
- {
- get
- {
- if (this._executor == null)
- {
- UnityEngine.Debug.LogError(string.Format("{0} is going to create a second GameObject to run coroutines! (Is the app quitting?) Any coroutines running before this may not have been completed! I hope you never see this error! :(", this));
- this.CreateScheduleExecutor();
- }
- return this._executor;
- }
- }
-
- private bool IsSupportedYieldable(object yieldable)
- {
- return yieldable == null || yieldable is AsyncOperation || yieldable is YieldInstruction;
- }
-
- private void CreateScheduleExecutor()
- {
- if (this._executor == null)
- {
- GameObject gameObject = GameObject.Find(this._executorName);
- if (gameObject == null)
- {
- gameObject = new GameObject();
- gameObject.name = this._executorName;
- UnityEngine.Object.DontDestroyOnLoad(gameObject);
- }
- this._executor = gameObject.GetComponent<MonoBehaviour>();
- if (this._executor == null)
- {
- this._executor = gameObject.AddComponent<UnityScheduler.UnitySchedulerMonoBehaviour>();
- }
- }
- }
-
- private void StopCoroutine(IEnumerator routine)
- {
- this._runningRoutines.Remove(routine);
- }
-
- private HashSet<IEnumerator> _runningRoutines = new HashSet<IEnumerator>();
-
- private MonoBehaviour _executor;
-
- private string _executorName;
-
- private class CoroutineWapper : ICoroutine, IYieldStatement
- {
- public CoroutineWapper(IEnumerator routine, UnityScheduler scheduler)
- {
- this._scheduler = scheduler;
- this._executor = this._scheduler.Executor;
- this._innerRoutine = routine;
- if (this._executor != null)
- {
- this._isRunning = true;
- this._coroutine = this._executor.StartCoroutine(this.Routine(routine));
- }
- }
-
- public void Stop()
- {
- if (this._isRunning && this._executor != null)
- {
- this._executor.StopCoroutine(this._coroutine);
- this._scheduler.StopCoroutine(this._innerRoutine);
- this._isRunning = false;
- }
- }
-
- public bool IsRunning
- {
- get
- {
- return this._isRunning && this._executor != null;
- }
- }
-
- public object UnityYieldable()
- {
- return this._coroutine;
- }
-
- public object UnityYieldable(MonoBehaviour runner)
- {
- return this._coroutine;
- }
-
- public object SUISSYieldable()
- {
- UnityEngine.Debug.LogError(string.Format("Coroutines started using the Unity scheduler should not be mixed with the SUISS Scheduler. {0}", this._innerRoutine));
- return null;
- }
-
- private IEnumerator Routine(IEnumerator routine)
- {
- while (routine.MoveNext())
- {
- object yielded = routine.Current;
- if (yielded == null)
- {
- yield return null;
- }
- else
- {
- if (yielded is IYieldStatement)
- {
- yielded = ((IYieldStatement)yielded).UnityYieldable(this._executor);
- }
- if (!this._scheduler.IsSupportedYieldable(yielded))
- {
- UnityEngine.Debug.LogWarning(string.Format("The coroutine '{0}' yielded '{1}' which is not supported by '{2}'!", this._innerRoutine, yielded ?? "null", this._scheduler));
- }
- yield return yielded;
- }
- }
- this._scheduler.StopCoroutine(this._innerRoutine);
- this._isRunning = false;
- yield break;
- }
-
- private Coroutine _coroutine;
-
- private bool _isRunning;
-
- private IEnumerator _innerRoutine;
-
- private UnityScheduler _scheduler;
-
- private MonoBehaviour _executor;
- }
-
- private class UnitySchedulerMonoBehaviour : MonoBehaviour
- {
- }
- }
- }
|