Reputation: 15446
I'm working in Unity, and I have a large script. At some point in the script, a coroutine, foo
will be started. I want this coroutine to run another IEnumerator
function, bar
, but I don't want bar
started as a coroutines. Rather, I need foo
to start running, maybe yield a few times, call bar
, wait until bar has finished running, and then continue running. At the moment I'm having to make bar
IEnumerable
to do:
void Start () {
StartCoroutine(foo());
}
IEnumerator foo () {
//Do something up here
foreach (int x in bar()) {
yield return null; //Wait for bar to yield break
}
//Do more stuff down here
yield break;
}
IEnumerable bar () {
for (int x=0; x < 5; x++) {
//Do Something 5 Times
yield return x;
}
yield break;
}
I've been searching, but I can't find the proper way to do this. There will of course be more than 10 such "bar" functions, so I don't want to have to make a for loop every time I want to call one. How can I call the other IEnuerator
functions in this way?
Upvotes: 2
Views: 6652
Reputation: 203842
What you're looking for is something frequently called a yield foreach
. It's a feature that doesn't exist (despite being rather frequently requested). You're pretty much forced to do exactly what you're doing here.
When you're writing an iterator block and you wish to yield each of the items of some other IEnumerable
or IEnumerator
individually you have no choice but to explicitly enumerate the sequence and yield each item. It would be nice if you could write something like yield foreach Bar()
but you can't. Your existing solution is as good as you can get using the current language features.
Upvotes: 2
Reputation: 13224
How about something like this:
class Program
{
public class CoroutineThing
{
public IEnumerator foo()
{
//Do something up here
var nTimesInvoked = 0;
while (bar(nTimesInvoked++))
yield return null; //Wait for bar to yield break
//Do more stuff down here
yield break;
}
bool bar(int nTimesInvoked)
{
if (nTimesInvoked < 5)
{
Console.WriteLine("Bar: {0}", nTimesInvoked);
// Do something;
}
return nTimesInvoked < 4;
}
}
public static void Main(params string[] args)
{
var cor = new CoroutineThing();
var nFoo = 0;
var e = cor.foo();
while (e.MoveNext())
{
nFoo++;
Console.WriteLine("{0} times foo", nFoo);
}
Console.ReadLine();
}
}
Upvotes: 0