Controlling Coroutines by Handle

Whenever you call Timing.RunCoroutine(…) a CoroutineHandle object is returned. That object can be used to make one coroutine wait for another using “yield return Timing.WaitUntilDone(handle);”. However, in MEC Pro the CoroutineHandle can do more.

Using Tag or Layer you can set or retrieve the associated graffitti.

CoroutineHandle handle = Timing.RunCoroutine(_TestCoroutine());

string oldTag = handle.Tag;
handle.Tag = "newTag"; 

if(handle.Layer == null) // No layer is assigned
    handle.Layer = gameObject.GetInstanceID();

Note: Layer is a nullable int (int?) so it may require casting into a regular int in your code, and you should check whether the value is null when you query either tags or layers (a null value means that there is no tag or layer assigned.)

Segment can retrieve or change the timing segment that the coroutine is running in.

handle.Segment = Segment.SlowUpdate;

IsRunning, IsPaused, and IsValid
IsRunning returns true until the coroutine terminates, and then it returns false. Paused and/or locked coroutines are considered to be running.

IsPaused returns true if the coroutine is paused or locked.

IsValid returns true if the coroutine handle has ever pointed to a valid coroutine (regardless of whether that coroutine is currently running).

Linking coroutine handles
Handles can be linked to one another using the LinkCoroutine function. This means that the “master” coroutine will send a kill command to the “slave” coroutine when it ends (either from a kill command or just by ending the function). It will also copy any pause or resume commands (but not any calls to WaitForSeconds).

The reason you would want to link coroutines is so you can start two or more coroutines independently but treat the whole group like it’s a single coroutine with the same scope as the master coroutine. A simple example could be if you have a loading progress bar with a coroutine that updates the progress bar’s position. Let’s say that you find that loading can sometimes get stuck and you want to create a second coroutine to watch the progress bar and make the words “sorry for the delay” march around on the screen when it gets stuck. Let’s say there’s also a cancel button which kills your first coroutine and a pause button which pauses it. You could turn your single reference into a list, but that starts getting messy fast. The simple way is to just link the two coroutines in MEC and then you can treat them like a single one. The slave will always be terminated or paused along with the master.

Getting the current coroutine handle
This is a useful convenience that allows you to retrieve your own handle from within a coroutine. You can use your own handle to set up links on the fly, change your own tags, coordinate static lists of different instances of the same coroutine, or all kinds of things.

    private IEnumerator<float> _shout(float time, string text)
        yield return Timing.WaitForSeconds(time);

        CoroutineHandle myHandle = new CoroutineHandle();
        yield return Timing.GetMyHandle(x => myHandle = x);

        Debug.Log(myHandle.Tag + ": " + text);

NOTE: GetMyHandle is a special function that does not cause a one frame delay even though it’s in a yield return statement.