Concurrency and execution

Concurrency and execution

A flow runs lines in order. “Blocking” means its next line waits, not that the app freezes. Flow.start() runs another flow alongside it; parallel=True only queues a touch.

Background flows

Flow.start() returns a positive Int once the named flow can receive messages; at most two background flows run together. send() copies messages in order; receive() waits, poll() checks now. Pause keeps messages; stop/completion discards them. running() includes paused flows. Flow.stop(name) stops a background owner; peers continue and its name stays reserved until cleanup ends. Named nested groups share their owner’s messages and stop target; the main flow cannot be stopped this way and has no automatic name. The macro waits for workers: stop endless workers explicitly. Main Pause/Resume affects all flows; global Resume clears individual pauses. Background controls offer Pause/Resume, no Stop button. Invalid/duplicate starts, any flow error, Main Stop or System.stop() stop the whole macro.

# Configure a macro flow named watch_enemy before running
ordinal = Flow.start("watch_enemy", {"task": "status"})
print(ordinal)

Shared state

Keep changeable objects separate per flow. Storage protects each operation, including edits inside collections, but another flow can write between get() and set(). Use one writer to avoid overwriting updates. Screen capture, image reuse and audio settings are shared. Exchange copied messages with Flow.send(), receive() and poll().

Queued touches

parallel=True queues a touch without waiting for completion; delay_before, delay_after still wait outside collect mode. Touch.collect() gathers, Touch.send() sends, and Touch.wait() waits. Different flows’ gestures can cancel each other on the shared screen. Cancelling active gestures requires Android 8 or newer.

# Collect overlapping touches, then wait for completion
Touch.collect()
click((300, 900), hold_ms=1500, parallel=True)
click((780, 900), delay_before=500, parallel=True)
Touch.send()
Touch.wait()

Recognition and UI waits

Region.find* searches for appearance; Region.wait* waits for disappearance. Even one check takes time; repeat rates are 1–60 checks/second. MacroPanel dialogs wait, one at a time. show(mode="floating") continues with one floating panel per run; read controls with values(), remove with close(). OverlayText.off_all() removes only this flow’s overlays; display updates may wait.