| 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) |