added another test-case

also, provided a fix.
This commit is contained in:
Zaafar 2021-03-19 18:37:17 -04:00
parent 7bff370663
commit 3998cd92d7
2 changed files with 77 additions and 9 deletions

View file

@ -13,6 +13,7 @@ namespace Coroutine {
private readonly List<ActiveCoroutine> tickingCoroutines = new List<ActiveCoroutine>(); private readonly List<ActiveCoroutine> tickingCoroutines = new List<ActiveCoroutine>();
private readonly List<ActiveCoroutine> eventCoroutines = new List<ActiveCoroutine>(); private readonly List<ActiveCoroutine> eventCoroutines = new List<ActiveCoroutine>();
private readonly Queue<ActiveCoroutine> outstandingCoroutines = new Queue<ActiveCoroutine>(); private readonly Queue<ActiveCoroutine> outstandingCoroutines = new Queue<ActiveCoroutine>();
private readonly Dictionary<int, byte> deletedCoroutinesIndexes = new Dictionary<int, byte>();
private readonly Stopwatch stopwatch = new Stopwatch(); private readonly Stopwatch stopwatch = new Stopwatch();
/// <summary> /// <summary>
@ -68,6 +69,7 @@ namespace Coroutine {
/// </summary> /// </summary>
/// <param name="deltaSeconds">The amount of seconds that have passed since the last time this method was invoked</param> /// <param name="deltaSeconds">The amount of seconds that have passed since the last time this method was invoked</param>
public void Tick(double deltaSeconds) { public void Tick(double deltaSeconds) {
this.RemoveDeletedCoroutines();
this.AddOutstandingCoroutines(); this.AddOutstandingCoroutines();
this.tickingCoroutines.RemoveAll(c => { this.tickingCoroutines.RemoveAll(c => {
if (c.Tick(deltaSeconds)) { if (c.Tick(deltaSeconds)) {
@ -85,16 +87,15 @@ namespace Coroutine {
/// </summary> /// </summary>
/// <param name="evt">The event to raise</param> /// <param name="evt">The event to raise</param>
public void RaiseEvent(Event evt) { public void RaiseEvent(Event evt) {
this.AddOutstandingCoroutines(); for (int i = 0; i < this.eventCoroutines.Count; i++) {
this.eventCoroutines.RemoveAll(c => { var eventCoroutine = this.eventCoroutines[i];
if (c.OnEvent(evt)) { if (eventCoroutine.OnEvent(evt)) {
return true; this.deletedCoroutinesIndexes[i] = 1;
} else if (!c.IsWaitingForEvent()) { } else if (!eventCoroutine.IsWaitingForEvent()) {
this.outstandingCoroutines.Enqueue(c); this.outstandingCoroutines.Enqueue(eventCoroutine);
return true; this.deletedCoroutinesIndexes[i] = 1;
}
} }
return false;
});
} }
/// <summary> /// <summary>
@ -114,6 +115,15 @@ namespace Coroutine {
} }
} }
private void RemoveDeletedCoroutines() {
int counter = 0;
this.eventCoroutines.RemoveAll(c => {
return this.deletedCoroutinesIndexes.ContainsKey(counter++);
});
this.deletedCoroutinesIndexes.Clear();
}
private static IEnumerator<Wait> InvokeLaterImpl(Wait wait, Action action) { private static IEnumerator<Wait> InvokeLaterImpl(Wait wait, Action action) {
yield return wait; yield return wait;
action(); action();

View file

@ -18,8 +18,10 @@ namespace Tests {
var cr = CoroutineHandler.Start(OnEventTriggered()); var cr = CoroutineHandler.Start(OnEventTriggered());
Assert.AreEqual(1, counter, "instruction before yield is not executed."); Assert.AreEqual(1, counter, "instruction before yield is not executed.");
CoroutineHandler.Tick(1);
CoroutineHandler.RaiseEvent(myEvent); CoroutineHandler.RaiseEvent(myEvent);
Assert.AreEqual(2, counter, "instruction after yield is not executed."); Assert.AreEqual(2, counter, "instruction after yield is not executed.");
CoroutineHandler.Tick(1);
CoroutineHandler.RaiseEvent(myEvent); CoroutineHandler.RaiseEvent(myEvent);
Assert.AreEqual(2, counter, "instruction after yield is not executed."); Assert.AreEqual(2, counter, "instruction after yield is not executed.");
@ -46,6 +48,7 @@ namespace Tests {
} }
var cr = CoroutineHandler.Start(OnEventTriggeredInfinite()); var cr = CoroutineHandler.Start(OnEventTriggeredInfinite());
CoroutineHandler.Tick(1);
cr.OnFinished += SetCounterToUnreachableValue; cr.OnFinished += SetCounterToUnreachableValue;
for (var i = 0; i < 50; i++) for (var i = 0; i < 50; i++)
CoroutineHandler.RaiseEvent(myOtherEvent); CoroutineHandler.RaiseEvent(myOtherEvent);
@ -80,6 +83,7 @@ namespace Tests {
} }
var cr = CoroutineHandler.Start(OnEvent()); var cr = CoroutineHandler.Start(OnEvent());
CoroutineHandler.Tick(1);
cr.OnFinished += SetCounterToUnreachableValue; cr.OnFinished += SetCounterToUnreachableValue;
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++)
CoroutineHandler.RaiseEvent(myEvent); CoroutineHandler.RaiseEvent(myEvent);
@ -136,21 +140,25 @@ namespace Tests {
Assert.AreEqual(0, counterGrandParent, "Grand Parent counter is invalid at event 0."); Assert.AreEqual(0, counterGrandParent, "Grand Parent counter is invalid at event 0.");
Assert.AreEqual(0, counterParent, "Parent counter is invalid at event 0."); Assert.AreEqual(0, counterParent, "Parent counter is invalid at event 0.");
Assert.AreEqual(0, counterChild, "Child counter is invalid at event 0."); Assert.AreEqual(0, counterChild, "Child counter is invalid at event 0.");
CoroutineHandler.Tick(1);
CoroutineHandler.RaiseEvent(myEvent); CoroutineHandler.RaiseEvent(myEvent);
Assert.AreEqual(1, counterAlwaysRunning, "Always running counter is invalid at event 1."); Assert.AreEqual(1, counterAlwaysRunning, "Always running counter is invalid at event 1.");
Assert.AreEqual(1, counterGrandParent, "Grand Parent counter is invalid at event 1."); Assert.AreEqual(1, counterGrandParent, "Grand Parent counter is invalid at event 1.");
Assert.AreEqual(0, counterParent, "Parent counter is invalid at event 1."); Assert.AreEqual(0, counterParent, "Parent counter is invalid at event 1.");
Assert.AreEqual(0, counterChild, "Child counter is invalid at event 1."); Assert.AreEqual(0, counterChild, "Child counter is invalid at event 1.");
CoroutineHandler.Tick(1);
CoroutineHandler.RaiseEvent(myEvent); CoroutineHandler.RaiseEvent(myEvent);
Assert.AreEqual(2, counterAlwaysRunning, "Always running counter is invalid at event 2."); Assert.AreEqual(2, counterAlwaysRunning, "Always running counter is invalid at event 2.");
Assert.AreEqual(1, counterGrandParent, "Grand Parent counter is invalid at event 2."); Assert.AreEqual(1, counterGrandParent, "Grand Parent counter is invalid at event 2.");
Assert.AreEqual(1, counterParent, "Parent counter is invalid at event 2."); Assert.AreEqual(1, counterParent, "Parent counter is invalid at event 2.");
Assert.AreEqual(0, counterChild, "Child counter is invalid at event 2."); Assert.AreEqual(0, counterChild, "Child counter is invalid at event 2.");
CoroutineHandler.Tick(1);
CoroutineHandler.RaiseEvent(myEvent); CoroutineHandler.RaiseEvent(myEvent);
Assert.AreEqual(3, counterAlwaysRunning, "Always running counter is invalid at event 3."); Assert.AreEqual(3, counterAlwaysRunning, "Always running counter is invalid at event 3.");
Assert.AreEqual(1, counterGrandParent, "Grand Parent counter is invalid at event 3."); Assert.AreEqual(1, counterGrandParent, "Grand Parent counter is invalid at event 3.");
Assert.AreEqual(1, counterParent, "Parent counter is invalid at event 3."); Assert.AreEqual(1, counterParent, "Parent counter is invalid at event 3.");
Assert.AreEqual(1, counterChild, "Child counter is invalid at event 3."); Assert.AreEqual(1, counterChild, "Child counter is invalid at event 3.");
CoroutineHandler.Tick(1);
CoroutineHandler.RaiseEvent(myEvent); CoroutineHandler.RaiseEvent(myEvent);
Assert.AreEqual(4, counterAlwaysRunning, "Always running counter is invalid at event 4."); Assert.AreEqual(4, counterAlwaysRunning, "Always running counter is invalid at event 4.");
Assert.AreEqual(1, counterGrandParent, "Grand Parent counter is invalid at event 4."); Assert.AreEqual(1, counterGrandParent, "Grand Parent counter is invalid at event 4.");
@ -158,6 +166,54 @@ namespace Tests {
Assert.AreEqual(1, counterChild, "Child counter is invalid at event 4."); Assert.AreEqual(1, counterChild, "Child counter is invalid at event 4.");
} }
[Test]
public void TestNestedRaiseEvent() {
var event1 = new Event();
var event2 = new Event();
var event3 = new Event();
var CoroutineCreated = new Event();
int counterCoroutineA = 0;
int counter = 0;
CoroutineHandler.Start(OnCoroutineCreatedInfinite());
CoroutineHandler.Start(OnEvent1());
CoroutineHandler.Tick(1);
CoroutineHandler.RaiseEvent(event1);
CoroutineHandler.Tick(1);
CoroutineHandler.RaiseEvent(event2);
CoroutineHandler.Tick(1);
CoroutineHandler.RaiseEvent(event3);
Assert.AreEqual(3, counter);
Assert.AreEqual(2, counterCoroutineA);
IEnumerator<Wait> OnCoroutineCreatedInfinite() {
while (true)
{
yield return new Wait(CoroutineCreated);
counterCoroutineA++;
}
}
IEnumerator<Wait> OnEvent1() {
yield return new Wait(event1);
counter++;
CoroutineHandler.Start(OnEvent2());
CoroutineHandler.RaiseEvent(CoroutineCreated);
}
IEnumerator<Wait> OnEvent2() {
yield return new Wait(event2);
counter++;
CoroutineHandler.Start(OnEvent3());
CoroutineHandler.RaiseEvent(CoroutineCreated);
}
IEnumerator<Wait> OnEvent3() {
yield return new Wait(event3);
counter++;
}
}
[Test] [Test]
public void TestPriority() { public void TestPriority() {
var myEvent = new Event(); var myEvent = new Event();
@ -207,6 +263,7 @@ namespace Tests {
CoroutineHandler.Start(ShouldExecuteAfter()); CoroutineHandler.Start(ShouldExecuteAfter());
CoroutineHandler.Start(ShouldExecuteBefore0(), priority: highPriority); CoroutineHandler.Start(ShouldExecuteBefore0(), priority: highPriority);
CoroutineHandler.Start(ShouldExecuteFinally(), priority: -1); CoroutineHandler.Start(ShouldExecuteFinally(), priority: -1);
CoroutineHandler.Tick(1);
CoroutineHandler.RaiseEvent(myEvent); CoroutineHandler.RaiseEvent(myEvent);
Assert.AreEqual(1, counterShouldExecuteAfter, $"ShouldExecuteAfter counter {counterShouldExecuteAfter} is invalid."); Assert.AreEqual(1, counterShouldExecuteAfter, $"ShouldExecuteAfter counter {counterShouldExecuteAfter} is invalid.");
Assert.AreEqual(1, counterShouldExecuteFinally, $"ShouldExecuteFinally counter {counterShouldExecuteFinally} is invalid."); Assert.AreEqual(1, counterShouldExecuteFinally, $"ShouldExecuteFinally counter {counterShouldExecuteFinally} is invalid.");
@ -229,6 +286,7 @@ namespace Tests {
}); });
Assert.AreEqual(0, counter, "Incorrect counter value after 5 seconds."); Assert.AreEqual(0, counter, "Incorrect counter value after 5 seconds.");
CoroutineHandler.Tick(1);
CoroutineHandler.RaiseEvent(myEvent); CoroutineHandler.RaiseEvent(myEvent);
Assert.AreEqual(3, counter, "Incorrect counter value after 10 seconds."); Assert.AreEqual(3, counter, "Incorrect counter value after 10 seconds.");
Assert.AreEqual(true, cr.IsFinished, "Incorrect IsFinished value."); Assert.AreEqual(true, cr.IsFinished, "Incorrect IsFinished value.");