Last active
March 24, 2021 11:52
-
-
Save margaretdax/7a12a01eacf3739b7b72b635ba80cc5b to your computer and use it in GitHub Desktop.
Tools I used in the development of OX OX OH for fully pausable/resumable "Coroutines" that can be run via Unity Coroutines but is not dependent on Unity at all. The most important thing here is the Run function, which takes a Stack of IEnumerator. The first IEnumerator in the stack passed to run should be whatever you'd normally pass to StartCor…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
public class PausableBehaviour : MonoBehaviour | |
{ | |
private Stack<IEnumerator> stack = new Stack<IEnumerator>(); | |
private Coroutine stackRoutine; | |
private void StartStack() | |
{ | |
if (stack.Count == 0 || stackRoutine != null) return; | |
stackRoutine = StartCoroutine(RoutineUtils.Run(stack, StopStack)); | |
} | |
private void StopStack() | |
{ | |
if (stackRoutine != null) | |
{ | |
StopCoroutine(stackRoutine); | |
} | |
stackRoutine = null; | |
} | |
protected void PushTask(IEnumerator task) | |
{ | |
stack.Push(task); | |
StartStack(); | |
} | |
protected virtual void OnEnable() | |
{ | |
StartStack(); | |
} | |
protected virtual void OnDisable() | |
{ | |
StopStack(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
public static class RoutineUtils | |
{ | |
public static IEnumerator Run(Stack<IEnumerator> stack) | |
{ | |
while(stack.Count > 0) | |
{ | |
bool cont = true; | |
while (cont && stack.Count > 0) | |
{ | |
IEnumerator top = stack.Peek(); | |
if (top.MoveNext()) | |
{ | |
if (top.Current is IEnumerator spawned) | |
{ | |
if(stack.Count > 0) | |
stack.Push(spawned); | |
} | |
else | |
{ | |
cont = false; | |
} | |
} | |
else | |
{ | |
if(stack.Count > 0) | |
stack.Pop(); | |
} | |
} | |
if(stack.Count > 0) | |
yield return null; | |
} | |
} | |
public static IEnumerator Join(List<IEnumerator> iterators) | |
{ | |
List<Stack<IEnumerator>> stacks = new List<Stack<IEnumerator>>(iterators.Count); | |
foreach (IEnumerator it in iterators) | |
{ | |
Stack<IEnumerator> stack = new Stack<IEnumerator>(); | |
stack.Push(it); | |
stacks.Add(stack); | |
} | |
while (stacks.Count > 0) | |
{ | |
for (int i = stacks.Count - 1; i >= 0; i--) | |
{ | |
Stack<IEnumerator> stack = stacks[i]; | |
IEnumerator it = stack.Peek(); | |
if (it.MoveNext()) | |
{ | |
if (it.Current is IEnumerator sub) | |
{ | |
stack.Push(sub); | |
} | |
else if (it.Current is AsyncOperation async) | |
{ | |
stack.Push(WaitAsync(async)); | |
} | |
} | |
else | |
{ | |
stack.Pop(); | |
} | |
if (stack.Count <= 0) | |
{ | |
stacks.RemoveAt(i); | |
} | |
} | |
yield return null; | |
} | |
iterators.Clear(); | |
} | |
public static IEnumerator Join(List<IEnumerator> its, Func<bool> keepAlive) | |
{ | |
IEnumerator joinIterator = Join(its); | |
while (joinIterator.MoveNext() && (keepAlive == null || keepAlive.Invoke())) | |
yield return null; | |
} | |
public static IEnumerator WaitForSeconds(float seconds) | |
{ | |
float timeAcc = Time.deltaTime; | |
while (timeAcc < seconds) | |
{ | |
yield return null; | |
timeAcc += Time.deltaTime; | |
} | |
} | |
public static IEnumerator WaitAsync(AsyncOperation asyncOperation) | |
{ | |
while (!asyncOperation.isDone) | |
yield return null; | |
} | |
public static IEnumerator WaitForFrame(int count = 1) | |
{ | |
for (int i = 0; i < count; i++) | |
{ | |
yield return null; | |
} | |
} | |
public static IEnumerator Chain(IEnumerator one, IEnumerator two) | |
{ | |
yield return one; | |
yield return two; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment