mirror of
https://github.com/Ellpeck/Coroutine.git
synced 2024-11-23 22:08:35 +01:00
fixed some race conditions with nested coroutines
This commit is contained in:
parent
ffdb5ed8f7
commit
6e07a26a6c
2 changed files with 30 additions and 23 deletions
|
@ -124,7 +124,7 @@ namespace Coroutine {
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public int CompareTo(ActiveCoroutine other) {
|
public int CompareTo(ActiveCoroutine other) {
|
||||||
return this.Priority.CompareTo(other.Priority);
|
return other.Priority.CompareTo(this.Priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,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 Stopwatch stopwatch = new Stopwatch();
|
private readonly Stopwatch stopwatch = new Stopwatch();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -45,7 +46,7 @@ namespace Coroutine {
|
||||||
public ActiveCoroutine Start(IEnumerator<Wait> coroutine, string name = "", int priority = 0) {
|
public ActiveCoroutine Start(IEnumerator<Wait> coroutine, string name = "", int priority = 0) {
|
||||||
var inst = new ActiveCoroutine(coroutine, name, priority, this.stopwatch);
|
var inst = new ActiveCoroutine(coroutine, name, priority, this.stopwatch);
|
||||||
if (inst.MoveNext())
|
if (inst.MoveNext())
|
||||||
AddSorted(inst.IsWaitingForEvent() ? this.eventCoroutines : this.tickingCoroutines, inst);
|
this.outstandingCoroutines.Enqueue(inst);
|
||||||
return inst;
|
return inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,15 +68,16 @@ 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) {
|
||||||
for (var i = this.tickingCoroutines.Count - 1; i >= 0; i--) {
|
this.AddOutstandingCoroutines();
|
||||||
var coroutine = this.tickingCoroutines[i];
|
this.tickingCoroutines.RemoveAll(c => {
|
||||||
if (coroutine.Tick(deltaSeconds)) {
|
if (c.Tick(deltaSeconds)) {
|
||||||
this.tickingCoroutines.RemoveAt(i);
|
return true;
|
||||||
} else if (coroutine.IsWaitingForEvent()) {
|
} else if (c.IsWaitingForEvent()) {
|
||||||
this.tickingCoroutines.RemoveAt(i);
|
this.outstandingCoroutines.Enqueue(c);
|
||||||
this.eventCoroutines.Add(coroutine);
|
return true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -83,15 +85,16 @@ 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) {
|
||||||
for (var i = this.eventCoroutines.Count - 1; i >= 0; i--) {
|
this.AddOutstandingCoroutines();
|
||||||
var coroutine = this.eventCoroutines[i];
|
this.eventCoroutines.RemoveAll(c => {
|
||||||
if (coroutine.OnEvent(evt)) {
|
if (c.OnEvent(evt)) {
|
||||||
this.eventCoroutines.RemoveAt(i);
|
return true;
|
||||||
} else if (!coroutine.IsWaitingForEvent()) {
|
} else if (!c.IsWaitingForEvent()) {
|
||||||
this.eventCoroutines.RemoveAt(i);
|
this.outstandingCoroutines.Enqueue(c);
|
||||||
this.tickingCoroutines.Add(coroutine);
|
return true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -102,15 +105,19 @@ namespace Coroutine {
|
||||||
return this.tickingCoroutines.Concat(this.eventCoroutines);
|
return this.tickingCoroutines.Concat(this.eventCoroutines);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void AddOutstandingCoroutines() {
|
||||||
|
while (this.outstandingCoroutines.Count > 0) {
|
||||||
|
var coroutine = this.outstandingCoroutines.Dequeue();
|
||||||
|
var list = coroutine.IsWaitingForEvent() ? this.eventCoroutines : this.tickingCoroutines;
|
||||||
|
var position = list.BinarySearch(coroutine);
|
||||||
|
list.Insert(position < 0 ? ~position : position, coroutine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddSorted(List<ActiveCoroutine> list, ActiveCoroutine coroutine) {
|
|
||||||
var position = list.BinarySearch(coroutine);
|
|
||||||
list.Insert(position < 0 ? ~position : position, coroutine);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue