made waits structs and added invokelater

This commit is contained in:
Ellpeck 2019-11-20 11:30:28 +01:00
parent a50403686a
commit 2025d6762a
7 changed files with 65 additions and 51 deletions

View file

@ -1,11 +1,11 @@
using System.Collections.Generic; using System.Collections.Generic;
namespace Coroutine { namespace Coroutine {
internal class Coroutine { internal struct Coroutine {
private readonly IEnumerator<Wait> enumerator; private readonly IEnumerator<IWait> enumerator;
public Coroutine(IEnumerator<Wait> enumerator) { public Coroutine(IEnumerator<IWait> enumerator) {
this.enumerator = enumerator; this.enumerator = enumerator;
this.enumerator.MoveNext(); this.enumerator.MoveNext();
} }

View file

@ -7,7 +7,7 @@ namespace Coroutine {
private static readonly List<Coroutine> TickingCoroutines = new List<Coroutine>(); private static readonly List<Coroutine> TickingCoroutines = new List<Coroutine>();
private static readonly List<Coroutine> EventCoroutines = new List<Coroutine>(); private static readonly List<Coroutine> EventCoroutines = new List<Coroutine>();
public static void Start(IEnumerator<Wait> coroutine) { public static void Start(IEnumerator<IWait> coroutine) {
var inst = new Coroutine(coroutine); var inst = new Coroutine(coroutine);
var type = inst.GetCurrentType(); var type = inst.GetCurrentType();
if (type == WaitType.Tick) if (type == WaitType.Tick)
@ -16,6 +16,10 @@ namespace Coroutine {
EventCoroutines.Add(inst); EventCoroutines.Add(inst);
} }
public static void InvokeLater(IWait wait, Action action) {
Start(InvokeLaterImpl(wait, action));
}
public static void Tick(double deltaSeconds) { public static void Tick(double deltaSeconds) {
for (var i = TickingCoroutines.Count - 1; i >= 0; i--) { for (var i = TickingCoroutines.Count - 1; i >= 0; i--) {
var coroutine = TickingCoroutines[i]; var coroutine = TickingCoroutines[i];
@ -40,5 +44,10 @@ namespace Coroutine {
} }
} }
private static IEnumerator<IWait> InvokeLaterImpl(IWait wait, Action action) {
yield return wait;
action();
}
} }
} }

18
Coroutine/IWait.cs Normal file
View file

@ -0,0 +1,18 @@
namespace Coroutine {
public interface IWait {
WaitType GetWaitType();
bool Tick(double deltaSeconds);
bool OnEvent(Event evt);
}
public enum WaitType {
Tick,
Event
}
}

View file

@ -1,24 +0,0 @@
using System;
namespace Coroutine {
public abstract class Wait {
public abstract WaitType GetWaitType();
public virtual bool Tick(double deltaSeconds) {
throw new NotSupportedException();
}
public virtual bool OnEvent(Event evt) {
throw new NotSupportedException();
}
}
public enum WaitType {
Tick,
Event
}
}

View file

@ -1,5 +1,7 @@
using System;
namespace Coroutine { namespace Coroutine {
public class WaitEvent : Wait { public struct WaitEvent : IWait {
private readonly Event evt; private readonly Event evt;
@ -7,11 +9,15 @@ namespace Coroutine {
this.evt = evt; this.evt = evt;
} }
public override WaitType GetWaitType() { public WaitType GetWaitType() {
return WaitType.Event; return WaitType.Event;
} }
public override bool OnEvent(Event evt) { public bool Tick(double deltaSeconds) {
throw new NotSupportedException();
}
public bool OnEvent(Event evt) {
return evt == this.evt; return evt == this.evt;
} }

View file

@ -1,5 +1,7 @@
using System;
namespace Coroutine { namespace Coroutine {
public class WaitSeconds : Wait { public struct WaitSeconds : IWait {
private double seconds; private double seconds;
@ -7,14 +9,18 @@ namespace Coroutine {
this.seconds = seconds; this.seconds = seconds;
} }
public override WaitType GetWaitType() { public WaitType GetWaitType() {
return WaitType.Tick; return WaitType.Tick;
} }
public override bool Tick(double deltaSeconds) { public bool Tick(double deltaSeconds) {
this.seconds -= deltaSeconds; this.seconds -= deltaSeconds;
return this.seconds <= 0; return this.seconds <= 0;
} }
public bool OnEvent(Event evt) {
throw new NotSupportedException();
}
} }
} }

View file

@ -10,10 +10,14 @@ namespace Test {
public static void Main() { public static void Main() {
CoroutineHandler.Start(WaitSeconds()); CoroutineHandler.Start(WaitSeconds());
CoroutineHandler.Start(RaiseTestEvent());
CoroutineHandler.Start(WaitForTestEvent());
CoroutineHandler.Start(PrintEvery5Seconds()); CoroutineHandler.Start(PrintEvery5Seconds());
CoroutineHandler.InvokeLater(new WaitSeconds(10), () => {
Console.WriteLine("Raising test event");
CoroutineHandler.RaiseEvent(TestEvent);
});
CoroutineHandler.InvokeLater(new WaitEvent(TestEvent), () => Console.WriteLine("Test event received"));
var lastTime = DateTime.Now; var lastTime = DateTime.Now;
while (true) { while (true) {
var currTime = DateTime.Now; var currTime = DateTime.Now;
@ -23,28 +27,23 @@ namespace Test {
} }
} }
private static IEnumerator<Wait> WaitSeconds() { private static IEnumerator<IWait> WaitSeconds() {
Console.WriteLine("First thing " + DateTime.Now); Console.WriteLine("First thing " + DateTime.Now);
yield return new WaitSeconds(1); yield return new WaitSeconds(1);
Console.WriteLine("After 1 second " + DateTime.Now); Console.WriteLine("After 1 second " + DateTime.Now);
yield return new WaitSeconds(5); yield return new WaitSeconds(9);
Console.WriteLine("After 5 seconds " + DateTime.Now);
yield return new WaitSeconds(10);
Console.WriteLine("After 10 seconds " + DateTime.Now); Console.WriteLine("After 10 seconds " + DateTime.Now);
} yield return new WaitSeconds(5);
Console.WriteLine("After 5 more seconds " + DateTime.Now);
private static IEnumerator<Wait> RaiseTestEvent() {
yield return new WaitSeconds(10); yield return new WaitSeconds(10);
Console.WriteLine("Raising test event"); Console.WriteLine("After 10 more seconds " + DateTime.Now);
CoroutineHandler.RaiseEvent(TestEvent);
yield return new WaitSeconds(20);
Console.WriteLine("Done");
Environment.Exit(0);
} }
private static IEnumerator<Wait> WaitForTestEvent() { private static IEnumerator<IWait> PrintEvery5Seconds() {
yield return new WaitEvent(TestEvent);
Console.WriteLine("Test event received");
}
private static IEnumerator<Wait> PrintEvery5Seconds() {
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);