Source code for simvx.core.coroutines

"""Coroutine helpers: parallel, wait, wait_until, wait_signal, next_frame."""

import time
from collections.abc import Callable
from typing import TYPE_CHECKING

from .descriptors import Coroutine

if TYPE_CHECKING:
    from .descriptors import Signal


[docs] def parallel(*coroutines: Coroutine) -> Coroutine: """Run multiple coroutines simultaneously, finish when all complete.""" active = list(coroutines) while active: finished = [] for co in active: try: next(co) except StopIteration: finished.append(co) for co in finished: active.remove(co) if active: yield
[docs] def wait(seconds: float) -> Coroutine: """Pause a coroutine for given seconds.""" end = time.monotonic() + seconds while time.monotonic() < end: yield
[docs] def wait_until(condition: Callable[[], bool]) -> Coroutine: """Yield until condition() returns True.""" while not condition(): yield
[docs] def wait_signal(signal: Signal) -> Coroutine: """Yield until signal is emitted. Returns signal args.""" received = [None] done = [False] def _on_signal(*args): received[0] = args done[0] = True signal.connect(_on_signal) try: while not done[0]: yield finally: signal.disconnect(_on_signal) return received[0]
[docs] def next_frame() -> Coroutine: """Yield for exactly one frame.""" yield