allow querying finish states of coroutines

This commit is contained in:
Ellpeck 2020-02-28 22:27:38 +01:00
parent 0642b84085
commit d6ad4e1f2c
3 changed files with 23 additions and 18 deletions

View file

@ -1,34 +1,35 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Coroutine { namespace Coroutine {
internal struct Coroutine { public class ActiveCoroutine {
private readonly IEnumerator<IWait> enumerator; private readonly IEnumerator<IWait> enumerator;
public bool IsFinished { get; private set; }
public Coroutine(IEnumerator<IWait> enumerator) { internal ActiveCoroutine(IEnumerator<IWait> enumerator) {
this.enumerator = enumerator; this.enumerator = enumerator;
this.enumerator.MoveNext(); this.enumerator.MoveNext();
} }
public bool Tick(double deltaSeconds) { internal bool Tick(double deltaSeconds) {
var curr = this.enumerator.Current; var curr = this.enumerator.Current;
if (curr != null && curr.Tick(deltaSeconds)) { if (curr != null && curr.Tick(deltaSeconds)) {
if (!this.enumerator.MoveNext()) if (!this.enumerator.MoveNext())
return true; this.IsFinished = true;
} }
return false; return this.IsFinished;
} }
public bool OnEvent(Event evt) { internal bool OnEvent(Event evt) {
var curr = this.enumerator.Current; var curr = this.enumerator.Current;
if (curr != null && curr.OnEvent(evt)) { if (curr != null && curr.OnEvent(evt)) {
if (!this.enumerator.MoveNext()) if (!this.enumerator.MoveNext())
return true; this.IsFinished = true;
} }
return false; return this.IsFinished;
} }
public WaitType GetCurrentType() { internal WaitType GetCurrentType() {
return this.enumerator.Current.GetWaitType(); return this.enumerator.Current.GetWaitType();
} }

View file

@ -4,16 +4,17 @@ using System.Collections.Generic;
namespace Coroutine { namespace Coroutine {
public static class CoroutineHandler { public static class CoroutineHandler {
private static readonly List<Coroutine> TickingCoroutines = new List<Coroutine>(); private static readonly List<ActiveCoroutine> TickingCoroutines = new List<ActiveCoroutine>();
private static readonly List<Coroutine> EventCoroutines = new List<Coroutine>(); private static readonly List<ActiveCoroutine> EventCoroutines = new List<ActiveCoroutine>();
public static void Start(IEnumerator<IWait> coroutine) { public static ActiveCoroutine Start(IEnumerator<IWait> coroutine) {
var inst = new Coroutine(coroutine); var inst = new ActiveCoroutine(coroutine);
var type = inst.GetCurrentType(); var type = inst.GetCurrentType();
if (type == WaitType.Tick) if (type == WaitType.Tick)
TickingCoroutines.Add(inst); TickingCoroutines.Add(inst);
else if (type == WaitType.Event) else if (type == WaitType.Event)
EventCoroutines.Add(inst); EventCoroutines.Add(inst);
return inst;
} }
public static void InvokeLater(IWait wait, Action action) { public static void InvokeLater(IWait wait, Action action) {

View file

@ -9,8 +9,8 @@ namespace Test {
private static readonly Event TestEvent = new Event(); private static readonly Event TestEvent = new Event();
public static void Main() { public static void Main() {
CoroutineHandler.Start(WaitSeconds()); var seconds = CoroutineHandler.Start(WaitSeconds());
CoroutineHandler.Start(PrintEvery5Seconds()); CoroutineHandler.Start(PrintEvery10Seconds(seconds));
CoroutineHandler.InvokeLater(new WaitSeconds(10), () => { CoroutineHandler.InvokeLater(new WaitSeconds(10), () => {
Console.WriteLine("Raising test event"); Console.WriteLine("Raising test event");
@ -39,14 +39,17 @@ namespace Test {
Console.WriteLine("After 10 more seconds " + DateTime.Now); Console.WriteLine("After 10 more seconds " + DateTime.Now);
yield return new WaitSeconds(20); yield return new WaitSeconds(20);
Console.WriteLine("Done"); Console.WriteLine("First coroutine done");
Environment.Exit(0);
} }
private static IEnumerator<IWait> PrintEvery5Seconds() { private static IEnumerator<IWait> PrintEvery10Seconds(ActiveCoroutine first) {
while (true) { while (true) {
yield return new WaitSeconds(10); yield return new WaitSeconds(10);
Console.WriteLine("The time is " + DateTime.Now); Console.WriteLine("The time is " + DateTime.Now);
if (first.IsFinished) {
Console.WriteLine("By the way, the first coroutine has finished!");
Environment.Exit(0);
}
} }
} }