mirror of
https://github.com/Ellpeck/Coroutine.git
synced 2024-11-21 21:33:29 +01:00
ensure coroutine handler instance thread safety
This commit is contained in:
parent
f71426321f
commit
1deb8a9d89
1 changed files with 46 additions and 28 deletions
|
@ -16,15 +16,26 @@ namespace Coroutine {
|
||||||
private readonly HashSet<ActiveCoroutine> outstandingEventCoroutines = new HashSet<ActiveCoroutine>();
|
private readonly HashSet<ActiveCoroutine> outstandingEventCoroutines = new HashSet<ActiveCoroutine>();
|
||||||
private readonly HashSet<ActiveCoroutine> outstandingTickingCoroutines = new HashSet<ActiveCoroutine>();
|
private readonly HashSet<ActiveCoroutine> outstandingTickingCoroutines = new HashSet<ActiveCoroutine>();
|
||||||
private readonly Stopwatch stopwatch = new Stopwatch();
|
private readonly Stopwatch stopwatch = new Stopwatch();
|
||||||
|
private readonly object lockObject = new object();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The amount of <see cref="ActiveCoroutine"/> instances that are currently waiting for a tick (waiting for time to pass)
|
/// The amount of <see cref="ActiveCoroutine"/> instances that are currently waiting for a tick (waiting for time to pass)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int TickingCount => this.tickingCoroutines.Count;
|
public int TickingCount {
|
||||||
|
get {
|
||||||
|
lock (this.lockObject)
|
||||||
|
return this.tickingCoroutines.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The amount of <see cref="ActiveCoroutine"/> instances that are currently waiting for an <see cref="Event"/>
|
/// The amount of <see cref="ActiveCoroutine"/> instances that are currently waiting for an <see cref="Event"/>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int EventCount => this.eventCoroutines.Sum(c => c.Value.Count);
|
public int EventCount {
|
||||||
|
get {
|
||||||
|
lock (this.lockObject)
|
||||||
|
return this.eventCoroutines.Sum(c => c.Value.Count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Starts the given coroutine, returning a <see cref="ActiveCoroutine"/> object for management.
|
/// Starts the given coroutine, returning a <see cref="ActiveCoroutine"/> object for management.
|
||||||
|
@ -47,8 +58,10 @@ namespace Coroutine {
|
||||||
/// <returns>An active coroutine object representing this coroutine</returns>
|
/// <returns>An active coroutine object representing this coroutine</returns>
|
||||||
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()) {
|
||||||
|
lock (this.lockObject)
|
||||||
this.GetOutstandingCoroutines(inst.IsWaitingForEvent).Add(inst);
|
this.GetOutstandingCoroutines(inst.IsWaitingForEvent).Add(inst);
|
||||||
|
}
|
||||||
return inst;
|
return inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,6 +83,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) {
|
||||||
|
lock (this.lockObject) {
|
||||||
this.MoveOutstandingCoroutines(false);
|
this.MoveOutstandingCoroutines(false);
|
||||||
this.tickingCoroutines.RemoveAll(c => {
|
this.tickingCoroutines.RemoveAll(c => {
|
||||||
if (c.Tick(deltaSeconds)) {
|
if (c.Tick(deltaSeconds)) {
|
||||||
|
@ -81,6 +95,7 @@ namespace Coroutine {
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Ticks this coroutine handler, causing all time-based <see cref="Wait"/>s to be ticked.
|
/// Ticks this coroutine handler, causing all time-based <see cref="Wait"/>s to be ticked.
|
||||||
|
@ -96,6 +111,7 @@ 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) {
|
||||||
|
lock (this.lockObject) {
|
||||||
this.MoveOutstandingCoroutines(true);
|
this.MoveOutstandingCoroutines(true);
|
||||||
var coroutines = this.GetEventCoroutines(evt, false);
|
var coroutines = this.GetEventCoroutines(evt, false);
|
||||||
if (coroutines != null) {
|
if (coroutines != null) {
|
||||||
|
@ -113,12 +129,14 @@ namespace Coroutine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a list of all currently active <see cref="ActiveCoroutine"/> objects under this handler.
|
/// Returns a list of all currently active <see cref="ActiveCoroutine"/> objects under this handler.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>All active coroutines</returns>
|
/// <returns>All active coroutines</returns>
|
||||||
public IEnumerable<ActiveCoroutine> GetActiveCoroutines() {
|
public IEnumerable<ActiveCoroutine> GetActiveCoroutines() {
|
||||||
|
lock (this.lockObject)
|
||||||
return this.tickingCoroutines.Concat(this.eventCoroutines.Values.SelectMany(c => c));
|
return this.tickingCoroutines.Concat(this.eventCoroutines.Values.SelectMany(c => c));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue