diff --git a/Coroutine/ActiveCoroutine.cs b/Coroutine/ActiveCoroutine.cs
index e6067c8..ef33d41 100644
--- a/Coroutine/ActiveCoroutine.cs
+++ b/Coroutine/ActiveCoroutine.cs
@@ -7,7 +7,7 @@ namespace Coroutine {
/// A reference to a currently running coroutine.
/// This is returned by .
///
- public class ActiveCoroutine {
+ public class ActiveCoroutine : IComparable {
private readonly IEnumerator enumerator;
private readonly Stopwatch stopwatch;
@@ -52,11 +52,17 @@ namespace Coroutine {
/// When not specified on startup of this coroutine, the name defaults to an empty string.
///
public readonly string Name;
+ ///
+ /// The priority of this coroutine. The higher the priority, the earlier it is advanced compared to other coroutines that advance around the same time.
+ /// When not specified at startup of this coroutine, the priority defaults to 0.
+ ///
+ public readonly int Priority;
- internal ActiveCoroutine(IEnumerator enumerator, string name, Stopwatch stopwatch) {
+ internal ActiveCoroutine(IEnumerator enumerator, string name, int priority, Stopwatch stopwatch) {
this.enumerator = enumerator;
- this.stopwatch = stopwatch;
this.Name = name;
+ this.Priority = priority;
+ this.stopwatch = stopwatch;
}
///
@@ -93,8 +99,7 @@ namespace Coroutine {
var result = this.enumerator.MoveNext();
this.stopwatch.Stop();
this.TotalMoveNextTime += this.stopwatch.Elapsed;
- if (this.stopwatch.Elapsed > this.MaxMoveNextTime)
- {
+ if (this.stopwatch.Elapsed > this.MaxMoveNextTime) {
this.MaxMoveNextTime = this.stopwatch.Elapsed;
}
this.MoveNextCount++;
@@ -118,5 +123,10 @@ namespace Coroutine {
/// The coroutine that finished
public delegate void FinishCallback(ActiveCoroutine coroutine);
+ ///
+ public int CompareTo(ActiveCoroutine other) {
+ return other.Priority.CompareTo(this.Priority);
+ }
+
}
}
\ No newline at end of file
diff --git a/Coroutine/CoroutineHandler.cs b/Coroutine/CoroutineHandler.cs
index cd3238b..a5673f1 100644
--- a/Coroutine/CoroutineHandler.cs
+++ b/Coroutine/CoroutineHandler.cs
@@ -15,19 +15,19 @@ namespace Coroutine {
///
public static int EventCount => Instance.EventCount;
- ///
- public static ActiveCoroutine Start(IEnumerable coroutine, string name = "") {
- return Instance.Start(coroutine, name);
+ ///
+ public static ActiveCoroutine Start(IEnumerable coroutine, string name = "", int priority = 0) {
+ return Instance.Start(coroutine, name, priority);
}
- ///
- public static ActiveCoroutine Start(IEnumerator coroutine, string name = "") {
- return Instance.Start(coroutine, name);
+ ///
+ public static ActiveCoroutine Start(IEnumerator coroutine, string name = "", int priority = 0) {
+ return Instance.Start(coroutine, name, priority);
}
///
- public static ActiveCoroutine InvokeLater(Wait wait, Action action) {
- return Instance.InvokeLater(wait, action);
+ public static ActiveCoroutine InvokeLater(Wait wait, Action action, string name = "", int priority = 0) {
+ return Instance.InvokeLater(wait, action, name, priority);
}
///
diff --git a/Coroutine/CoroutineHandlerInstance.cs b/Coroutine/CoroutineHandlerInstance.cs
index 35fc62f..8b8fe46 100644
--- a/Coroutine/CoroutineHandlerInstance.cs
+++ b/Coroutine/CoroutineHandlerInstance.cs
@@ -28,27 +28,24 @@ namespace Coroutine {
/// Note that this calls to get the enumerator.
///
/// The coroutine to start
- /// The name that this coroutine should have. Defaults to an empty string.
+ /// The that this coroutine should have. Defaults to an empty string.
+ /// The that this coroutine should have. The higher the priority, the earlier it is advanced. Defaults to 0.
/// An active coroutine object representing this coroutine
- public ActiveCoroutine Start(IEnumerable coroutine, string name = "") {
- return this.Start(coroutine.GetEnumerator(), name);
+ public ActiveCoroutine Start(IEnumerable coroutine, string name = "", int priority = 0) {
+ return this.Start(coroutine.GetEnumerator(), name, priority);
}
///
/// Starts the given coroutine, returning a object for management.
///
/// The coroutine to start
- /// The name that this coroutine should have. Defaults to an empty string.
+ /// The that this coroutine should have. Defaults to an empty string.
+ /// The that this coroutine should have. The higher the priority, the earlier it is advanced compared to other coroutines that advance around the same time. Defaults to 0.
/// An active coroutine object representing this coroutine
- public ActiveCoroutine Start(IEnumerator coroutine, string name = "") {
- var inst = new ActiveCoroutine(coroutine, name, this.stopwatch);
- if (inst.MoveNext()) {
- if (inst.IsWaitingForEvent()) {
- this.eventCoroutines.Add(inst);
- } else {
- this.tickingCoroutines.Add(inst);
- }
- }
+ public ActiveCoroutine Start(IEnumerator coroutine, string name = "", int priority = 0) {
+ var inst = new ActiveCoroutine(coroutine, name, priority, this.stopwatch);
+ if (inst.MoveNext())
+ AddSorted(inst.IsWaitingForEvent() ? this.eventCoroutines : this.tickingCoroutines, inst);
return inst;
}
@@ -58,9 +55,11 @@ namespace Coroutine {
///
/// The wait to wait for
/// The action to execute after waiting
+ /// The that the underlying coroutine should have. Defaults to an empty string.
+ /// The that the underlying coroutine should have. The higher the priority, the earlier it is advanced compared to other coroutines that advance around the same time. Defaults to 0.
/// An active coroutine object representing this coroutine
- public ActiveCoroutine InvokeLater(Wait wait, Action action) {
- return this.Start(InvokeLaterImpl(wait, action));
+ public ActiveCoroutine InvokeLater(Wait wait, Action action, string name = "", int priority = 0) {
+ return this.Start(InvokeLaterImpl(wait, action), name, priority);
}
///
@@ -68,15 +67,15 @@ namespace Coroutine {
///
/// The amount of seconds that have passed since the last time this method was invoked
public void Tick(double deltaSeconds) {
- for (var i = this.tickingCoroutines.Count - 1; i >= 0; i--) {
- var coroutine = this.tickingCoroutines[i];
- if (coroutine.Tick(deltaSeconds)) {
- this.tickingCoroutines.RemoveAt(i);
- } else if (coroutine.IsWaitingForEvent()) {
- this.tickingCoroutines.RemoveAt(i);
- this.eventCoroutines.Add(coroutine);
+ this.tickingCoroutines.RemoveAll(c => {
+ if (c.Tick(deltaSeconds)) {
+ return true;
+ } else if (c.IsWaitingForEvent()) {
+ AddSorted(this.eventCoroutines, c);
+ return true;
}
- }
+ return false;
+ });
}
///
@@ -84,15 +83,15 @@ namespace Coroutine {
///
/// The event to raise
public void RaiseEvent(Event evt) {
- for (var i = this.eventCoroutines.Count - 1; i >= 0; i--) {
- var coroutine = this.eventCoroutines[i];
- if (coroutine.OnEvent(evt)) {
- this.eventCoroutines.RemoveAt(i);
- } else if (!coroutine.IsWaitingForEvent()) {
- this.eventCoroutines.RemoveAt(i);
- this.tickingCoroutines.Add(coroutine);
+ this.eventCoroutines.RemoveAll(c => {
+ if (c.OnEvent(evt)) {
+ return true;
+ } else if (!c.IsWaitingForEvent()) {
+ AddSorted(this.tickingCoroutines, c);
+ return true;
}
- }
+ return false;
+ });
}
///
@@ -108,5 +107,10 @@ namespace Coroutine {
action();
}
+ private static void AddSorted(List list, ActiveCoroutine coroutine) {
+ var position = list.BinarySearch(coroutine);
+ list.Insert(position < 0 ? ~position : position, coroutine);
+ }
+
}
}
\ No newline at end of file
diff --git a/Test/Example.cs b/Test/Example.cs
index 380d908..cd774f0 100644
--- a/Test/Example.cs
+++ b/Test/Example.cs
@@ -20,6 +20,9 @@ namespace Test {
});
CoroutineHandler.InvokeLater(new Wait(TestEvent), () => Console.WriteLine("Test event received"));
+ CoroutineHandler.InvokeLater(new Wait(TestEvent), () => Console.WriteLine("I am invoked after 'Test event received'"), priority: -5);
+ CoroutineHandler.InvokeLater(new Wait(TestEvent), () => Console.WriteLine("I am invoked before 'Test event received'"), priority: 2);
+
var lastTime = DateTime.Now;
while (true) {
var currTime = DateTime.Now;
@@ -51,9 +54,9 @@ namespace Test {
if (first.IsFinished) {
Console.WriteLine("By the way, the first coroutine has finished!");
Console.WriteLine($"{first.Name} data: {first.MoveNextCount} moves, " +
- $"{first.TotalMoveNextTime.TotalMilliseconds} total time, " +
- $"{first.AverageMoveNextTime.TotalMilliseconds} average, " +
- $"{first.MaxMoveNextTime.TotalMilliseconds} maximum");
+ $"{first.TotalMoveNextTime.TotalMilliseconds} total time, " +
+ $"{first.AverageMoveNextTime.TotalMilliseconds} average, " +
+ $"{first.MaxMoveNextTime.TotalMilliseconds} maximum");
Environment.Exit(0);
}
}