.. _stdlib_coroutine: ========== Coroutines ========== This module provides core functionality for working with coroutines in the application. Coroutines can be used to perform asynchronous tasks. To use this module, include the following line in your project file:: require engine.async.coroutine // or require engine.core Here is an example of how to use coroutines:: [async] def await_mouse_press() : void { // Coroutine that waits for a mouse button press while (!mouse_button_pressed(MouseButton Left)) { await_next_frame() // Skip frame } } [async] def smooth_move(node : NodeId; from, to : float3; time : float) : void { // Coroutine that moves a node from one position to another over a given time var t = 0f while (t < time) { // Smoothly move the node from one position to another node.localPosition = lerp(from, to, float3(t / time)) await_next_frame() t += get_delta_time() } node.localPosition = to } [async] def start_game() : void { // Step 1 - wait for mouse press await(await_mouse_press()) // Step 2 - move the cube // 'cube' is a NodeId created earlier start_coroutine(cube, smooth_move(cube, float3(0, 0, 0), float3(0, 0, 1), 1.)) } def on_initialize() : void { start_coroutine(start_game()) } .. note:: `return false` can be used inside a coroutine to finish it early. Use `yield false` to yield coroutine execution without completing it. .. warning:: Be aware that coroutines can't be hot reloaded. If you change the coroutine code, you need to restart the application to apply the changes. +++++++++ Functions +++++++++ * :ref:`start_coroutine (var f: iterator\) ` * :ref:`start_coroutine (node: NodeId; var f: iterator\) ` * :ref:`stop_coroutines (node: NodeId) : bool ` * :ref:`stop_coroutines () : bool ` * :ref:`is_coroutine_running () : bool ` * :ref:`is_coroutine_running (node: NodeId) : bool ` * :ref:`await_next_frame () ` * :ref:`await (var a: iterator\) : bool ` * :ref:`await (var a: iterator\\>) : T ` * :ref:`async_run (var a: iterator\) : auto ` * :ref:`async_run_all (var a: array\\>) : auto ` .. _function-coroutine_start_coroutine_iterator_ls_bool_gr_: .. das:function:: start_coroutine(f: iterator) Starts a coroutine with the provided iterator. :Arguments: * **f** : iterator - the iterator for the coroutine Usage example:: start_coroutine(start_game()) .. _function-coroutine_start_coroutine_NodeId_iterator_ls_bool_gr_: .. das:function:: start_coroutine(node: NodeId; f: iterator) Starts a coroutine associated with a specific scene node. :Arguments: * **node** : :ref:`NodeId ` - the scene node * **f** : iterator - the iterator for the coroutine Usage example:: start_coroutine(myNode, move_node(myNode, 10, 0, 0)) .. _function-coroutine_stop_coroutines_NodeId: .. das:function:: stop_coroutines(node: NodeId) : bool Stops the coroutine associated with the specified scene node. :Arguments: * **node** : :ref:`NodeId ` - the ID of the scene node :Returns: * bool - true if associated coroutine was found and stopped, false otherwise Usage example:: stop_coroutine(myNode) .. _function-coroutine_stop_coroutines: .. das:function:: stop_coroutines() : bool Stops all active and pending coroutines. :Returns: * bool - true if any coroutines were stopped, false otherwise .. _function-coroutine_is_coroutine_running: .. das:function:: is_coroutine_running() : bool Checks if there are any active coroutines. Use ``is_coroutine_running(NodeId())`` to check coroutines unassociated with any scene node. :Returns: * bool - true if there are active coroutines, false otherwise Usage example:: if (!is_coroutine_running()) { print("There are no active coroutines") } .. _function-coroutine_is_coroutine_running_NodeId: .. das:function:: is_coroutine_running(node: NodeId) : bool Checks if there is an active coroutine associated with the specified scene node. :Arguments: * **node** : :ref:`NodeId ` - the scene node :Returns: * bool - true if there is an active coroutine associated with the scene node, false otherwise Usage example:: if (is_coroutine_running(myNode)) { print("There is an active coroutine associated with myNode") } .. _function-async_boost_await_next_frame: .. das:function:: await_next_frame() This function is used to suspend coroutine until next frame. .. _function-async_boost_await_iterator_ls_bool_gr_: .. das:function:: await(a: iterator) : bool This function is used to wait for the result of the async function. :Arguments: * **a** : iterator .. _function-async_boost_await_iterator_ls_variant_ls_res_c_autoT;wait_c_bool_gr__gr_: .. das:function:: await(a: iterator>) : T This function is used to wait for the result of the async function. :Arguments: * **a** : iterator> .. _function-async_boost_async_run_iterator_ls_auto_gr_: .. das:function:: async_run(a: iterator) : auto This function runs async function until it is finished. :Arguments: * **a** : iterator .. _function-async_boost_async_run_all_array_ls_iterator_ls_auto_gr__gr_: .. das:function:: async_run_all(a: array>) : auto This function runs all async function until they are finished (in parallel, starting from the last one). :Arguments: * **a** : array>