CONCEPT:

        coroutines

INTRODUCTION:

        Regular LPC functions have a short life span. They must finish,
        before a new event like a player command can be processed.
        Coroutines are a special type of functions, whose execution can
        be suspended and continued at a later time. At each suspension
        point values can be exchanged with another coroutine or the caller.

        Coroutines are passed by reference. When a coroutine finishes
        it decays to the number zero.


DEFINITION:

        Coroutines can be created by calling a function that was declared
        with the async modifier:

            async void fun()
            {
                ...
            }

            coroutine cr = fun();

        Alternatively inline coroutines are created with the inline closure
        syntax:

            coroutine cr = async function void() { ... };

        Normal coroutines can get parameters, inline coroutines cannot.
        (They however can use context variables.)


OPERATIONS:

        These operations can be used from within a coroutine:

        await(coroutine[, value])

            Call another coroutine, pass on the given value and wait for
            this coroutine to finish with a return statement.
            Until then the current coroutine is suspended. Any operation
            on this coroutine will be passed to the called coroutine.
            The result of the await() call is the return value from the
            called coroutine.

        yield([value])

            Suspend execution of the current coroutine and pass the given
            value to the caller. The result of the yield() call is the
            value that will be passed in when the coroutine will be
            continued.

        yield(value, coroutine)

            Suspend execution of the current coroutine and continue the
            given coroutine, thereby passing the value in. The result of
            the yield() call is the value that will be passed in when the
            coroutine will be continued.

        return [value]

            Destroy the current coroutine. If any coroutine is waiting,
            continue its execution. Otherwise return to the caller.


EFUNS:

        call_coroutine(coroutine[, value])

            Call the given coroutine, pass on the given value.

            In contrast to await() and yield() the current execution will
            only be suspended for the call (just like any other function
            call) and be continued when the coroutine suspends execution
            with yield() or finishes execution with return.

            Therefore this efun can also be used from regular functions.

            The result of the efun call is the value of the yield() or
            return call that suspended the execution of the called coroutine.

        this_coroutine()

            Returns the current coroutine. If it's not called from a
            coroutine, the innermost coroutine in the caller stack will
            be returned. Returns 0 if there is no coroutine in the caller
            stack.


EXAMPLE:

        /* Coroutine that sleeps a given amount of time. */
        async void sleep(int sec)
        {
            /* Start a call_out that will wake this coroutine. */
            call_out(#'call_coroutine, sec, this_coroutine());

            /* Suspend and wait. */
            yield();
        }

        /* Use of the sleep() function. */
        async void fun()
        {
            write("Starting...\n");
            await(sleep(10));
            write("Finishing after 10s.\n");
        }


MISCELLANEOUS:

        Support for coroutines is signaled by the macro __LPC_COROUTINES__.

        Only declarative casts to coroutine are possible, there is no
        conversion of any other type to coroutine available (therefore
        there is no to_coroutine() efun).

        Coroutines can not be copied or serialized with save_value().
        Coroutines are bound to their object. If the object is destroyed,
        the coroutines will be as well (and any awaiting coroutines).

        foreach() can be used to call coroutines repeatedly.


HISTORY:

        Coroutines were introduced in LDMud 3.6.5.


SEE ALSO:

	
	async(LPC), await(LPC), yield(LPC), foreach(LPC),
	call_coroutine(E), this_coroutine(E)

UNItopia (mudadm@UNItopia.de)