What does it mean for a coroutine to be "terminated externally"?


#1

There is language in some coroutines (like in the AIController class) that specifically state:

// This coroutine never finishes by itself and can only be terminated externally.

I checked the primer, and I did not find any instances of the language ‘terminate’ or ‘externally’ nearby mentions of coroutines, so my assumption is that ‘terminated externally’ means ‘this coroutine waits for a particular message from UE4’s runtime that signals its own termination’, instead of there existing a language feature that enables the programmer the ability to terminate a coroutine.

Does such a language feature exist? If so, how does it work?

More generally, I noticed the kill switch “abort_coroutines_on_this”, but I’m wondering if SK provides more granular control.

Some kind of API like:
active_coroutines(object) -> Returns a list of references to active coroutines operating on object
abort_coroutine(object, acr[x]) -> aborts active coroutine x on object.
stop_coroutine(object, acr[x]) -> stalls active coroutine x on object.
stopped_coroutines(object) -> Returns a list of references to stopped coroutines operating on object
start_coroutine(object, scr[x]) -> starts a stopped coroutine x on object.

I’m not suggesting a feature request. I just want to know if this kind of handling of coroutines exists in SK, and how to achieve it.

I know SK allows us to bind coroutines as return objects. But the documentation states the new object is only bound after the coroutine has completed, so I stopped investigating that approach.

To be clear, this is more a SK language question than a “I have a particular need to accomplish in UE4 with SK.” one.


#2

The basics for starting a coroutine that you later want to abort by hand is to use InvokedCoroutine. The branch command returns an InvokeCoroutine.

I’ll often use this as a state machine. It works like this.

  1. Define the data member in your class
    InvokedCoroutine !@state_co

  2. Initialize the data in ! with a InvokedCoroutine, think of this kind of like a placeholder for InvokeCoroutine!null
    @state_co : branch _wait(-1)

  3. Store whatever InvokedCoroutine you are interested in aborting later
    @state_co : branch _flee

  4. Abort the InvokedCoroutine if it is valid
    @state_co.abort when @state_co.valid?

You might imagine doing #4 before #3 when changing states.


#3

Thanks! Very helpful.

Is “terminate externally” synonymous with “abort” here?


#4

Yes. It just means it will keep on running until some language or engine mechanism stops it.

@error454’s answer talks about how to manage coroutines at a more sophisticated level using InvokedCoroutine objects. An even easier mechanism is to use the race command. It will abort any of its subordinate coroutines that were not the first to complete.

The concurrency commands branch, race and sync are described briefly here:

You can also manage coroutines with Mind objects, though again this is fairly sophisticated and overkill for most situations. See Mind objects and the Master Mind in the SkookumScript online docs.

These are powerful features of SkookumScript which are in need of additional documentation. If you need more help or tips just ask on the forum. :madsci: