Concurrency and execution
Concurrency and execution
A normal call executes in the current flow and may wait for capture, processing, gestures, UI dispatch, or user input. parallel on a touch and Flow.start are different mechanisms. Blocking describes a wait in the calling flow, not a freeze of the Android UI.
Background flows
Flow.start(name, params=None) starts an isolated branch and returns its positive Int ordinal, with its message queue already registered. There are at most two background branches per Run. Flow.send copies safe payloads into FIFO queues; receive waits on the current branch and poll checks immediately. Pause preserves messages; stop or completion discards them. Flow.running includes paused invocations. Flow.stop requests only a background branch cancellation; main and peers continue, and cleanup is asynchronous. Named foreground groups share their owning branch queue and stop targets that owner; main cannot be stopped. No synthesized main name exists. Main completion waits for live workers, so explicitly stop long-lived workers. A name stays reserved through cleanup. Dock Pause/Resume behavior is unchanged and has no branch Stop button. Main Pause/Resume affects every branch and global Resume clears local pause flags. Invalid/duplicate starts, branch errors, Main Stop and System.stop() stop the whole Run.
# Configure a macro flow named watch_enemy before running
ordinal = Flow.start("watch_enemy", {"task": "status"})
print(ordinal)Queued touches
parallel=True queues a touch; outside collect mode delay_before and delay_after still wait in the caller. Touch.collect() gathers touches for Touch.send(), and Touch.wait() waits for completion. Gestures share Android’s input channel; they do not become independent devices. Cancellation of active gestures requires Android 8 or newer. Touch gestures from different branches can cancel each other.
# 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-pass recognition takes processing time. Polling rate is limited to 1–60 Hz. Interactive MacroPanel prompts serialize and wait for the user. OverlayText is owned by its flow; off_all() only releases overlays from that flow, while UI work goes through Android Main.