diff --git a/doc/main/signaltypes.rst b/doc/main/signaltypes.rst index 4e39f40..91e174d 100644 --- a/doc/main/signaltypes.rst +++ b/doc/main/signaltypes.rst @@ -293,25 +293,3 @@ though the *hub* accelerates backward. and other creations, by noting which way the top and front :class:`Side ` of the hub are pointing. The example on the left is the default configuration. - -.. class:: await - -Multitasking -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Pybricks supports cooperative multitasking using the ``async`` and ``await`` -keywords. This allows operations that normally take some time to complete, to -run in parallel with other operations. - -Whenever you see the word ``await`` in the documentation, this means that the -method or function supports multitasking. - -The following example shows how to use multitasking to make a robot drive -forward, then turn and move a gripper at the same time, and then drive -backward. - -.. literalinclude:: - ../../examples/pup/robotics/drivebase_async.py - -If you don't use multitasking, you can ignore the ``await`` keyword and write -programs as usual. diff --git a/doc/main/tools/index.rst b/doc/main/tools/index.rst index 10c890b..d3462af 100644 --- a/doc/main/tools/index.rst +++ b/doc/main/tools/index.rst @@ -55,3 +55,35 @@ Linear algebra tools .. autofunction:: pybricks.tools.vector .. autofunction:: pybricks.tools.cross + +Multitasking +-------------------- + +.. versionadded:: 3.3 + +Pybricks supports cooperative multitasking using the ``async`` and ``await`` +keywords. This allows operations that normally take some time to complete to +run in parallel with other operations. + +.. autofunction:: pybricks.tools.multitask + +.. autofunction:: pybricks.tools.run_task + +The following example shows how to use multitasking to make a robot drive +forward, then turn and move a gripper at the same time, and then drive +backward. + +.. literalinclude:: + ../../../examples/pup/robotics/drivebase_async.py + +.. class:: coroutine + +.. class:: await + +Whenever you see a function or method prefixed by ``await``, this means that +it supports multitasking. When running a coroutine with ``run_task``, all +methods and functions prefixed by ``await`` will act as coroutines. + +If you don't use multitasking, you can ignore the ``await`` keyword and write +programs as usual. Specifically, when ``run_task`` is not used, functions +prefixed by ``await`` will act as normal functions. diff --git a/jedi/tests/test_complete_import.py b/jedi/tests/test_complete_import.py index b77bc11..55eeab5 100644 --- a/jedi/tests/test_complete_import.py +++ b/jedi/tests/test_complete_import.py @@ -159,7 +159,9 @@ def test_from_pybricks_tools_import(): "DataLog", "hub_menu", "Matrix", + "multitask", "read_input_byte", + "run_task", "StopWatch", "vector", "wait", diff --git a/src/pybricks/tools.py b/src/pybricks/tools.py index 8d202ee..2abfdd6 100644 --- a/src/pybricks/tools.py +++ b/src/pybricks/tools.py @@ -5,10 +5,10 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Optional, Sequence, Tuple, overload +from typing import TYPE_CHECKING, Any, Optional, Sequence, Tuple, overload, Coroutine if TYPE_CHECKING: - from ._common import MaybeAwaitable + from ._common import MaybeAwaitable, MaybeAwaitableTuple from .parameters import Number @@ -255,7 +255,40 @@ def hub_menu(*symbols: int | str) -> int | str: """ +def multitask(*coroutines: Coroutine, race=False) -> MaybeAwaitableTuple: + """ + multitask(coroutine1, coroutine2, ...) -> Tuple + + Runs multiple coroutines concurrently. This creates a new coroutine that + can be used like any other, including in another ``multitask`` statement. + + Arguments: + coroutines (coroutine, coroutine, ...): One or more coroutines to run + in parallel. + race (bool): Choose ``False`` to wait for all coroutines to finish. + Choose ``True`` to wait for one coroutine to finish and then + cancel the others, as if it's a "race". + + Returns: + Tuple of the return values of each coroutine. Unfinished coroutines + will have ``None`` as their return value. + """ + + +def run_task(coroutine: Coroutine): + """ + run_task(coroutine) + + Runs a coroutine from start to finish while blocking the rest of the + program. This is used primarily to run the main coroutine of a program. + + Arguments: + coroutine (coroutine): The main coroutine to run. + """ + + # HACK: hide from jedi if TYPE_CHECKING: del Number del MaybeAwaitable + del MaybeAwaitableTuple