Skip to content

Commit

Permalink
Implement pause logic for coroutine types
Browse files Browse the repository at this point in the history
  • Loading branch information
Inspiaaa committed Sep 5, 2024
1 parent 2771f22 commit e5b1905
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 15 deletions.
4 changes: 2 additions & 2 deletions src/Coroutines/AwaitCoroutine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public AwaitCoroutine(Task<T> task)
this.Task = task;
}

protected override void OnEnter()
protected override void OnStart()
{
// As the CoroutineManager class is not thread safe, ensure that Kill()
// is executed on the main Godot thread.
Expand All @@ -39,7 +39,7 @@ public AwaitCoroutine(Task task)
this.Task = task;
}

protected override void OnEnter()
protected override void OnStart()
{
// As the CoroutineManager class is not thread safe, ensure that Kill()
// is executed on the main Godot thread.
Expand Down
9 changes: 5 additions & 4 deletions src/Coroutines/Coroutine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ public Coroutine(IEnumerator routine)

public Coroutine(Func<Coroutine, IEnumerator> creator)
{
// TODO: Only create the coroutine OnEnter() (e.g. Sequence of Wait and Coroutine)?
this.routine = creator(this);
}

Expand All @@ -30,9 +29,11 @@ protected override void OnEnter()
if (routine == null)
{
Kill();
return;
}
}

protected override void OnStart()
{
EnableUpdates();
}

Expand All @@ -56,9 +57,9 @@ public override void Update()
// coroutine is finished.
if (obj is CoroutineBase childCoroutine)
{
// It's important to pause before starting the child coroutine.
// It's important to disable updates before starting the child coroutine.
// Otherwise, if the child coroutine instantly terminates, which would
// lead to this coroutine resuming, it would pause this coroutine.
// lead to this coroutine resuming updates, it would disable updates to this coroutine.
// That would not be correct.
DisableUpdates();
StartCoroutine(childCoroutine);
Expand Down
6 changes: 4 additions & 2 deletions src/Coroutines/ParallelCoroutine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ protected override void OnEnter()
if (coroutines.Length == 0)
{
Kill();
return;
}

}

protected override void OnStart()
{
foreach (CoroutineBase coroutine in coroutines)
{
StartCoroutine(coroutine);
Expand Down
31 changes: 29 additions & 2 deletions src/Coroutines/RepeatCoroutine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ public class RepeatCoroutine : CoroutineBase

private bool IsInfinite => repeatTimes == -1;

// If the coroutine that is being repeated completes while the game is paused, it is not instantly restarted.
// Instead, it is restarted once the game is resumed, which is indicated by this flag.
private bool isRepeatPending;

public RepeatCoroutine(int repeatTimes, Func<RepeatCoroutine, CoroutineBase> coroutineCreator)
{
this.repeatTimes = repeatTimes;
Expand All @@ -25,9 +29,11 @@ protected override void OnEnter()
if (repeatTimes == 0)
{
Kill();
return;
}
}

protected override void OnStart()
{
Repeat();
}

Expand All @@ -48,6 +54,27 @@ protected override void OnChildStopped(CoroutineBase child)
return;
}

Repeat();
TryRepeat();
}

private void TryRepeat()
{
if (IsRunning)
{
Repeat();
}
else
{
isRepeatPending = true;
}
}

protected override void OnResume()
{
if (isRepeatPending)
{
isRepeatPending = false;
Repeat();
}
}
}
31 changes: 29 additions & 2 deletions src/Coroutines/SequentialCoroutine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ public class SequentialCoroutine : CoroutineBase
{
private readonly CoroutineBase[] coroutines;
private int idx = 0;

// If one of the steps completes while the game is paused, the next step is not instantly run.
// Instead, it is only run once the game is resumed again, which is indicated by this flag.
private bool isSwitchToNextCoroutinePending = false;

public SequentialCoroutine(params CoroutineBase[] coroutines)
{
Expand All @@ -19,9 +23,11 @@ protected override void OnEnter()
if (coroutines.Length == 0)
{
Kill();
return;
}
}

protected override void OnStart()
{
StartCoroutine(coroutines[0]);
}

Expand All @@ -32,11 +38,32 @@ protected override void OnChildStopped(CoroutineBase child)
idx += 1;
if (idx < coroutines.Length)
{
StartCoroutine(coroutines[idx]);
TryStartNextCoroutine();
}
else
{
Kill();
}
}

private void TryStartNextCoroutine()
{
if (IsRunning)
{
StartCoroutine(coroutines[idx]);
}
else
{
isSwitchToNextCoroutinePending = true;
}
}

protected override void OnResume()
{
if (isSwitchToNextCoroutinePending)
{
isSwitchToNextCoroutinePending = false;
StartCoroutine(coroutines[idx]);
}
}
}
2 changes: 1 addition & 1 deletion src/Coroutines/TweenCoroutine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public TweenCoroutine(Func<Tween> createTween)
this.createTween = createTween;
}

protected override void OnEnter()
protected override void OnStart()
{
tween = createTween();

Expand Down
1 change: 1 addition & 0 deletions src/Coroutines/WaitDelayCoroutine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public WaitDelayCoroutine(float delay)

protected override void OnEnter()
{
// TODO: Implement pause logic.
Manager.GetTree().CreateTimer(delay).Timeout += Kill;
}
}
2 changes: 1 addition & 1 deletion src/Coroutines/WaitUntilCoroutine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public WaitUntilCoroutine(Func<Boolean> condition)
this.condition = condition;
}

protected override void OnEnter()
protected override void OnStart()
{
CheckCondition();
if (IsAlive) EnableUpdates();
Expand Down
2 changes: 1 addition & 1 deletion src/Coroutines/WaitWhileCoroutine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public WaitWhileCoroutine(Func<Boolean> condition)
this.condition = condition;
}

protected override void OnEnter()
protected override void OnStart()
{
CheckCondition();
if (IsAlive) EnableUpdates();
Expand Down

0 comments on commit e5b1905

Please sign in to comment.