Skip to content

Commit 12a4e10

Browse files
authored
Merge pull request #3 from AAulicino/develop
1.1.0
2 parents 4c5fcf8 + 098a1ad commit 12a4e10

32 files changed

+979
-55
lines changed

CHANGELOG.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [1.1.0] - 2022-06-16
8+
### Added
9+
- Nested coroutine calls support.
10+
711
## [1.0.0] - 2022-06-13
812
### Added
9-
- Initial release
13+
- Initial release.
1014

11-
[0.1.0]: https://github.com/olivierlacan/keep-a-changelog/releases/tag/v1.0.0
15+
[1.1.0]: https://github.com/AAulicino/Unity-Coroutines-for-NSubstitute/compare/1.0.0...1.1.0
16+
[1.0.0]: https://github.com/AAulicino/Unity-Coroutines-for-NSubstitute/releases/tag/1.0.0

Editor/Substitutes/CoroutineCall/IStartCoroutineCall.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ namespace CoroutineSubstitute.Substitutes.Call
55
public interface IStartCoroutineCall : IEnumerator
66
{
77
int Id { get; }
8+
void SetNestedCoroutine (IStartCoroutineCall call);
89
}
910
}

Editor/Substitutes/CoroutineCall/IStartCoroutineCallFactory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@ namespace CoroutineSubstitute.Substitutes.Call
44
{
55
public interface IStartCoroutineCallFactory
66
{
7-
IStartCoroutineCall Create (int id, IEnumerator enumerator);
7+
IStartCoroutineCall Create (IEnumerator enumerator);
88
}
99
}
Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,73 @@
1+
using System;
12
using System.Collections;
3+
using CoroutineSubstitute.Utils;
4+
using UnityEngine;
25

36
namespace CoroutineSubstitute.Substitutes.Call
47
{
58
public class StartCoroutineCall : IStartCoroutineCall, IEnumerator
69
{
7-
readonly IEnumerator enumerator;
8-
910
public int Id { get; }
10-
public object Current => enumerator.Current;
11+
public object Current => nestedCoroutine ?? nestedCall?.Current ?? enumerator.Current;
12+
13+
readonly IEnumerator enumerator;
14+
readonly IStartCoroutineCallFactory callFactory;
15+
IStartCoroutineCall nestedCall;
16+
Coroutine nestedCoroutine;
1117

12-
public StartCoroutineCall (int id, IEnumerator enumerator)
18+
public StartCoroutineCall (
19+
int id,
20+
IEnumerator enumerator,
21+
IStartCoroutineCallFactory callFactory
22+
)
1323
{
1424
Id = id;
1525
this.enumerator = enumerator;
26+
this.callFactory = callFactory;
27+
}
28+
29+
public bool MoveNext ()
30+
{
31+
if (nestedCall != null)
32+
{
33+
if (nestedCall.MoveNext())
34+
return true;
35+
nestedCall = null;
36+
}
37+
38+
if (enumerator.MoveNext())
39+
{
40+
if (Current is IEnumerator enumerator)
41+
nestedCall = callFactory.Create(enumerator);
42+
else if (Current is Coroutine coroutine)
43+
nestedCoroutine = coroutine;
44+
return true;
45+
}
46+
return false;
47+
}
48+
49+
public void SetNestedCoroutine (IStartCoroutineCall call)
50+
{
51+
if (nestedCall?.Current is Coroutine coroutine && coroutine.GetId() == call.Id)
52+
{
53+
nestedCall.SetNestedCoroutine(call);
54+
return;
55+
}
56+
57+
if (nestedCoroutine == null)
58+
throw new InvalidOperationException("Nested coroutine is not set");
59+
60+
if (nestedCoroutine.GetId() != call.Id)
61+
{
62+
throw new InvalidOperationException(
63+
$"Received Coroutine={call.Id}, expected Coroutine={nestedCoroutine.GetId()}"
64+
);
65+
}
66+
67+
nestedCall = call;
68+
nestedCoroutine = null;
1669
}
1770

18-
public bool MoveNext () => enumerator.MoveNext();
1971
public void Reset () => enumerator.Reset();
2072
}
2173
}

Editor/Substitutes/CoroutineCall/StartCoroutineCallFactory.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ namespace CoroutineSubstitute.Substitutes.Call
44
{
55
public class StartCoroutineCallFactory : IStartCoroutineCallFactory
66
{
7-
public IStartCoroutineCall Create (int id, IEnumerator enumerator)
7+
int id;
8+
9+
public IStartCoroutineCall Create (IEnumerator enumerator)
810
{
9-
return new StartCoroutineCall(id, enumerator);
11+
return new StartCoroutineCall(id++, enumerator, this);
1012
}
1113
}
1214
}

Editor/Substitutes/CoroutineRunnerSubstitute.cs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections;
33
using System.Collections.Generic;
4+
using System.Linq;
45
using CoroutineSubstitute.Substitutes.Call;
56
using CoroutineSubstitute.Utils;
67
using UnityEngine;
@@ -29,7 +30,7 @@ public virtual Coroutine StartCoroutine (IEnumerator enumerator)
2930
if (enumerator is null)
3031
throw new ArgumentNullException(nameof(enumerator));
3132

32-
IStartCoroutineCall call = callFactory.Create(activeCoroutines.Count, enumerator);
33+
IStartCoroutineCall call = callFactory.Create(enumerator);
3334
activeCoroutines.Add(call.Id, call);
3435
return CoroutineFactory.Create(call.Id);
3536
}
@@ -50,8 +51,27 @@ public virtual void StopCoroutine (Coroutine routine)
5051
public virtual bool MoveNext ()
5152
{
5253
bool anySucceeded = false;
53-
foreach (IStartCoroutineCall call in activeCoroutines.Values)
54-
anySucceeded |= call.MoveNext();
54+
HashSet<int> callsToRemove = new HashSet<int>();
55+
56+
foreach (IStartCoroutineCall call in activeCoroutines.Values.ToArray())
57+
{
58+
bool result = call.MoveNext();
59+
60+
if (callsToRemove.Contains(call.Id))
61+
continue;
62+
63+
if (call.Current is Coroutine coroutine)
64+
{
65+
int coroutineId = coroutine.GetId();
66+
call.SetNestedCoroutine(activeCoroutines[coroutineId]);
67+
callsToRemove.Add(coroutineId);
68+
}
69+
anySucceeded |= result;
70+
}
71+
72+
foreach (int id in callsToRemove)
73+
activeCoroutines.Remove(id);
74+
5575
return anySucceeded;
5676
}
5777

Tests/Editor/Samples/Counter/Counter.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ public class Counter
77
{
88
public int Current { get; private set; }
99

10+
public bool KeepRunning { get; set; } = true;
11+
1012
readonly ICoroutineRunner runner;
1113
Coroutine coroutine;
1214

@@ -28,7 +30,7 @@ public void Stop ()
2830

2931
IEnumerator CounterRoutine ()
3032
{
31-
while (true)
33+
while (KeepRunning)
3234
{
3335
Current++;
3436
yield return null;

Tests/Editor/Samples/Counter/CounterTests.cs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public void Setup ()
2121
}
2222
}
2323

24-
class StartCounter : BaseSubstitutionTests
24+
class Start : BaseSubstitutionTests
2525
{
2626
[Test]
2727
public void Calls_StartCoroutine ()
@@ -67,9 +67,21 @@ public void Three_MoveNext_Increments_To_Three ()
6767

6868
Assert.AreEqual(3, Counter.Current);
6969
}
70+
71+
[Test]
72+
public void Stops_When_Routine_Completed ()
73+
{
74+
Counter.Start();
75+
Runner.MoveNext();
76+
77+
Counter.KeepRunning = false;
78+
Runner.MoveNext();
79+
80+
Assert.AreEqual(1, Counter.Current);
81+
}
7082
}
7183

72-
class StopCounter : BaseSubstitutionTests
84+
class Stop : BaseSubstitutionTests
7385
{
7486
[Test]
7587
public void Calls_StopCoroutine ()

0 commit comments

Comments
 (0)