using System; using System.Collections.Generic; using System.Linq; namespace Barotrauma { enum CoroutineStatus { Running, Success, Failure } class CoroutineHandle { public readonly IEnumerator Coroutine; public readonly string Name; public CoroutineHandle(IEnumerator coroutine, string name = "") { Coroutine = coroutine; Name = string.IsNullOrWhiteSpace(name) ? coroutine.ToString() : name; } } // Keeps track of all running coroutines, and runs them till the end. static class CoroutineManager { static readonly List Coroutines = new List(); public static float UnscaledDeltaTime, DeltaTime; public static CoroutineHandle StartCoroutine(IEnumerable func, string name = "") { var handle = new CoroutineHandle(func.GetEnumerator(), name); Coroutines.Add(handle); return handle; } public static bool IsCoroutineRunning(string name) { return Coroutines.Any(c => c.Name == name); } public static bool IsCoroutineRunning(CoroutineHandle handle) { return Coroutines.Contains(handle); } public static void StopCoroutines(string name) { Coroutines.RemoveAll(c => c.Name == name); } public static void StopCoroutines(CoroutineHandle handle) { Coroutines.RemoveAll(c => c == handle); } // Updating just means stepping through all the coroutines public static void Update(float unscaledDeltaTime, float deltaTime) { UnscaledDeltaTime = unscaledDeltaTime; DeltaTime = deltaTime; for (int i = Coroutines.Count-1; i>=0; i--) { if (Coroutines[i].Coroutine.Current != null) { WaitForSeconds wfs = Coroutines[i].Coroutine.Current as WaitForSeconds; if (wfs != null) { if (!wfs.CheckFinished(unscaledDeltaTime)) continue; } else { switch ((CoroutineStatus)Coroutines[i].Coroutine.Current) { case CoroutineStatus.Success: Coroutines.RemoveAt(i); continue; case CoroutineStatus.Failure: DebugConsole.ThrowError("Coroutine ''" + Coroutines[i]+ "'' has failed"); break; } } } //try //{ Coroutines[i].Coroutine.MoveNext(); //} //catch (Exception e) //{ // DebugConsole.ThrowError("Coroutine " + Coroutines[i].Name + " threw an exception: " + e.Message); //#if DEBUG // throw e; //#endif // Coroutines.RemoveAt(i); // } } } } class WaitForSeconds { float timer; public WaitForSeconds(float time) { timer = time; } public bool CheckFinished(float deltaTime) { timer -= deltaTime; return timer<=0.0f; } } }