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 Int ordinal. There are at most two background branches per Run. No Flow.stop(), pause(), resume(), join(), or handle API exists. Main completion waits for the background branches; any branch error 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.
# 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.