mirror of
https://github.com/Ellpeck/Coroutine.git
synced 2024-11-24 06:18:33 +01:00
Merge pull request #10 from zaafar/master
Stop RaiseEvent from adding/deleting Coroutines
This commit is contained in:
commit
47ffd9b79a
2 changed files with 84 additions and 10 deletions
|
@ -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> eventcoroutinesIndexesToDelete = 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.removeEventCoroutines();
|
||||||
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 (var 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.eventcoroutinesIndexesToDelete[i] = 1;
|
||||||
} else if (!c.IsWaitingForEvent()) {
|
} else if (!eventCoroutine.IsWaitingForEvent()) {
|
||||||
this.outstandingCoroutines.Enqueue(c);
|
this.outstandingCoroutines.Enqueue(eventCoroutine);
|
||||||
return true;
|
this.eventcoroutinesIndexesToDelete[i] = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -114,6 +115,15 @@ namespace Coroutine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void removeEventCoroutines() {
|
||||||
|
int counter = 0;
|
||||||
|
this.eventCoroutines.RemoveAll(c => {
|
||||||
|
return this.eventcoroutinesIndexesToDelete.ContainsKey(counter++);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.eventcoroutinesIndexesToDelete.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();
|
||||||
|
|
|
@ -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);
|
||||||
|
@ -88,6 +92,8 @@ namespace Tests {
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestNestedCoroutine() {
|
public void TestNestedCoroutine() {
|
||||||
|
var onChildCreated = new Event();
|
||||||
|
var onParentCreated = new Event();
|
||||||
var myEvent = new Event();
|
var myEvent = new Event();
|
||||||
var counterAlwaysRunning = 0;
|
var counterAlwaysRunning = 0;
|
||||||
|
|
||||||
|
@ -120,8 +126,12 @@ namespace Tests {
|
||||||
counterGrandParent++;
|
counterGrandParent++;
|
||||||
// Nested corotuine starting.
|
// Nested corotuine starting.
|
||||||
var p = CoroutineHandler.Start(Parent());
|
var p = CoroutineHandler.Start(Parent());
|
||||||
|
CoroutineHandler.RaiseEvent(onParentCreated);
|
||||||
// Nested corotuine starting in OnFinished.
|
// Nested corotuine starting in OnFinished.
|
||||||
p.OnFinished += ac => CoroutineHandler.Start(Child());
|
p.OnFinished += ac => {
|
||||||
|
CoroutineHandler.Start(Child());
|
||||||
|
CoroutineHandler.RaiseEvent(onChildCreated);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
CoroutineHandler.Start(AlwaysRunning());
|
CoroutineHandler.Start(AlwaysRunning());
|
||||||
|
@ -130,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.");
|
||||||
|
@ -152,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();
|
||||||
|
@ -201,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.");
|
||||||
|
@ -223,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.");
|
||||||
|
|
Loading…
Reference in a new issue