|
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using SUISS.Core;
- using SUISS.Core.Utilities;
- using UnityEngine;
-
- namespace SUISS.Scheduling
- {
- public class Scheduler : SingletonMonobehaviour<Scheduler>, IComparer<IEnumerator>
- {
- private SortedDictionary<IEnumerator, IEnumerator> Routines
- {
- get
- {
- if (this._routines == null)
- {
- this._routines = new SortedDictionary<IEnumerator, IEnumerator>(this);
- }
- return this._routines;
- }
- }
-
- private void Update()
- {
- foreach (IEnumerator enumerator2 in new List<IEnumerator>(this.Routines.Keys))
- {
- object obj = enumerator2.Current;
- if (obj != null)
- {
- if (obj is double)
- {
- if (Scheduler.TimeLeft(enumerator2) > 0.0)
- {
- break;
- }
- }
- else if (obj is AsyncOperation && !((AsyncOperation)obj).isDone)
- {
- continue;
- }
- }
- this.Execute(enumerator2);
- }
- }
-
- public int Compare(IEnumerator xEnum, IEnumerator yEnum)
- {
- object obj = xEnum.Current;
- object obj2 = yEnum.Current;
- if (obj == null || obj2 == null)
- {
- if (obj != null)
- {
- return 1;
- }
- if (obj2 != null)
- {
- return -1;
- }
- }
- else if (obj is double || obj2 is double)
- {
- if (!(obj is double))
- {
- return -1;
- }
- if (!(obj2 is double))
- {
- return 1;
- }
- double num = (double)obj;
- double num2 = (double)obj2;
- if (num < num2)
- {
- return -1;
- }
- if (num > num2)
- {
- return 1;
- }
- }
- if (!this._uniqueIdentifiers.ContainsKey(xEnum))
- {
- this._uniqueIdentifiers[xEnum] = this._nextUniqueIdentifier++;
- }
- if (!this._uniqueIdentifiers.ContainsKey(yEnum))
- {
- this._uniqueIdentifiers[yEnum] = this._nextUniqueIdentifier++;
- }
- return this._uniqueIdentifiers[xEnum] - this._uniqueIdentifiers[yEnum];
- }
-
- public void StartRoutine(IEnumerator routine, GameObject go)
- {
- if (go != null)
- {
- this._gameObjects.Add(routine, go);
- this._debugInfo.Add(routine, string.Format("{0}: {1}", this.FullName(go), SUISS.Core.Utilities.StackTraceUtility.ExtractStackTrace()));
- }
- this.StartRoutine(routine);
- }
-
- private string FullName(GameObject go)
- {
- string text = string.Empty;
- Transform transform = go.transform;
- while (transform != null)
- {
- if (text.Length == 0)
- {
- text = transform.name;
- }
- else
- {
- text = string.Format("{0}/{1}", transform.name, text);
- }
- transform = transform.parent;
- }
- return text;
- }
-
- public void StartRoutine(IEnumerator routine)
- {
- if (this.Routines.ContainsKey(routine))
- {
- throw new SchedulerException("You are calling StartRoutine on a routine that was already started.");
- }
- this.Routines.Add(routine, routine);
- this.Execute(routine);
- }
-
- public bool IsRunning(IEnumerator routine)
- {
- return this.Routines.ContainsKey(routine);
- }
-
- public void StopRoutine(IEnumerator routine)
- {
- bool leaf = this.Routines.Remove(routine);
- this.CleanupRoutine(routine, leaf, false);
- }
-
- [Obsolete("You are calling MonoBehaviour.StartCoroutine while you meant to use Scheduler.StartRoutine instead.", true)]
- public new void StartCoroutine(IEnumerator routine)
- {
- throw new InvalidOperationException("You are calling MonoBehaviour.StartCoroutine while you meant to use Scheduler.StartRoutine instead.");
- }
-
- [Obsolete("You are calling MonoBehaviour.StopCoroutine while you meant to use Scheduler.StopRoutine instead.", true)]
- public new void StopCoroutine(IEnumerator routine)
- {
- throw new InvalidOperationException("You are calling MonoBehaviour.StopCoroutine while you meant to use Scheduler.StopRoutine instead.");
- }
-
- public void ExecuteNextFrame(GameObject go, Action action)
- {
- this.StartRoutine(Scheduler.NextFrame(action), go);
- }
-
- public void ExecuteNextFrame(Action action)
- {
- this.StartRoutine(Scheduler.NextFrame(action));
- }
-
- public IEnumerator ExecuteDelayed(Action action, float delaySeconds)
- {
- IEnumerator result;
- this.StartRoutine(result = Scheduler.Delayed(action, delaySeconds));
- return result;
- }
-
- [Obsolete("This is nasty! Just keep track of your routines, and clean them up yourself.", false)]
- public void DestroyedGameObject(GameObject go)
- {
- IEnumerator enumerator;
- do
- {
- enumerator = null;
- foreach (KeyValuePair<IEnumerator, GameObject> keyValuePair in this._gameObjects)
- {
- if (object.ReferenceEquals(keyValuePair.Value, go))
- {
- enumerator = keyValuePair.Key;
- break;
- }
- }
- if (enumerator != null)
- {
- this.StopRoutine(enumerator);
- }
- }
- while (enumerator != null);
- }
-
- private void Execute(IEnumerator routine)
- {
- this.Routines.Remove(routine);
- GameObject gameObject = null;
- bool flag = false;
- if (this._gameObjects.TryGetValue(routine, out gameObject))
- {
- if (gameObject != null)
- {
- flag = routine.MoveNext();
- }
- else
- {
- string arg = "unknown";
- try
- {
- arg = gameObject.name;
- }
- catch
- {
- }
- string arg2 = string.Empty;
- if (this._debugInfo.ContainsKey(routine))
- {
- arg2 = "\n" + this._debugInfo[routine];
- }
- UnityEngine.Debug.LogError(string.Format("Routine was still running on gameObject ({0}) that has been destroyed.{1}", arg, arg2));
- }
- }
- else
- {
- flag = routine.MoveNext();
- }
- if (flag)
- {
- object obj = routine.Current;
- if (obj is IEnumerator)
- {
- IEnumerator enumerator = (IEnumerator)obj;
- if (!this._parents.ContainsKey(enumerator))
- {
- this._parents[enumerator] = new List<IEnumerator>();
- }
- this._parents[enumerator].Add(routine);
- bool flag2 = this.IsRunning(enumerator);
- if (!flag2)
- {
- foreach (List<IEnumerator> list in this._parents.Values)
- {
- if (list.Contains(enumerator))
- {
- flag2 = true;
- break;
- }
- }
- }
- if (!flag2)
- {
- this.Routines.Add(enumerator, enumerator);
- if (gameObject != null)
- {
- this._gameObjects.Add(enumerator, gameObject);
- this._debugInfo.Add(enumerator, string.Format("{0}: {1}", this.FullName(gameObject), SUISS.Core.Utilities.StackTraceUtility.ExtractStackTrace()));
- }
- this.Execute(enumerator);
- }
- else if (this._parents[enumerator].Count < 2)
- {
- UnityEngine.Debug.LogWarning("Child routine was already running, but it had no parent routines!");
- }
- }
- else
- {
- if (this.Routines.ContainsKey(routine))
- {
- UnityEngine.Debug.LogWarning(string.Format("Routine {0} with Current {1} is already in Routines as {2} with current {3}", new object[]
- {
- routine,
- routine.Current,
- this.Routines[routine],
- this.Routines[routine].Current
- }));
- }
- this.Routines.Add(routine, routine);
- }
- }
- else
- {
- this.CleanupRoutine(routine, true, true);
- }
- }
-
- private void CleanupRoutine(IEnumerator routine, bool leaf, bool executeParents)
- {
- this._gameObjects.Remove(routine);
- this._debugInfo.Remove(routine);
- this._uniqueIdentifiers.Remove(routine);
- if (leaf)
- {
- if (this._parents.ContainsKey(routine))
- {
- List<IEnumerator> list = this._parents[routine];
- this._parents.Remove(routine);
- foreach (IEnumerator enumerator2 in list)
- {
- this.Routines.Add(enumerator2, enumerator2);
- }
- if (executeParents)
- {
- foreach (IEnumerator routine2 in list)
- {
- this.Execute(routine2);
- }
- }
- }
- }
- else
- {
- IEnumerator enumerator4 = null;
- bool flag = false;
- foreach (IEnumerator enumerator6 in this._parents.Keys)
- {
- if (this._parents[enumerator6].Contains(routine))
- {
- enumerator4 = enumerator6;
- if (this._parents[enumerator6].Count > 1)
- {
- this._parents[enumerator6].Remove(routine);
- }
- else
- {
- flag = true;
- }
- break;
- }
- }
- if (enumerator4 == null)
- {
- UnityEngine.Debug.LogWarning("Unable to find routine in _parents");
- }
- else if (flag)
- {
- this._parents.Remove(enumerator4);
- bool leaf2 = this.Routines.Remove(enumerator4);
- this.CleanupRoutine(enumerator4, leaf2, false);
- }
- else
- {
- this.CleanupRoutine(routine, true, executeParents);
- }
- }
- }
-
- public static IEnumerator NextFrame(Action action)
- {
- if (action != null)
- {
- yield return null;
- action();
- }
- yield break;
- }
-
- public static IEnumerator Delayed(Action action, float delaySeconds)
- {
- if (action != null)
- {
- yield return Timing.time + (double)delaySeconds;
- action();
- }
- yield break;
- }
-
- public static double TimeLeft(IEnumerator routine)
- {
- object obj = routine.Current;
- if (obj == null)
- {
- return 1E-06;
- }
- if (obj is double)
- {
- return (double)obj - Timing.time;
- }
- UnityEngine.Debug.LogWarning(string.Format("TimeLeft requested on routine of which current (type {0}) is not a double", obj.GetType()));
- return 0.0;
- }
-
- private Dictionary<IEnumerator, int> _uniqueIdentifiers = new Dictionary<IEnumerator, int>();
-
- private int _nextUniqueIdentifier;
-
- private SortedDictionary<IEnumerator, IEnumerator> _routines;
-
- private Dictionary<IEnumerator, List<IEnumerator>> _parents = new Dictionary<IEnumerator, List<IEnumerator>>();
-
- private Dictionary<IEnumerator, GameObject> _gameObjects = new Dictionary<IEnumerator, GameObject>();
-
- private Dictionary<IEnumerator, string> _debugInfo = new Dictionary<IEnumerator, string>();
- }
- }
|