From f3cecca1f8a4bae3d2abbd6fd28ed4022c9838d3 Mon Sep 17 00:00:00 2001 From: YoursFunny Date: Mon, 6 Jul 2026 20:22:57 +0800 Subject: [PATCH] feat: add timeout support to loop method for enhanced state management --- module/base/base.py | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/module/base/base.py b/module/base/base.py index 7d47c34..9106a1b 100644 --- a/module/base/base.py +++ b/module/base/base.py @@ -69,28 +69,50 @@ class ModuleBase: pool = ThreadPoolExecutor(1) return pool - def loop(self, skip_first=True): + def loop(self, skip_first=True, timeout=None): """ A syntactic sugar to start a state loop Args: skip_first (bool): Usually to be True to reuse the previous screenshot + timeout (int | float | Timer): Seconds of timeout or a Timer object Yields: np.ndarray: screenshot Examples: + # state machine that handle clicking until destination for _ in self.loop(): if self.appear(...): break if self.appear_then_click(...): continue + + Examples: + # state machine with timeout + for _ in self.loop(timeout=2): + if self.appear(...): + logger.info('Wait success') + break + else: + logger.warning('Wait timeout') """ + if timeout is not None: + if isinstance(timeout, Timer): + timeout.reset() + else: + timeout = Timer.from_seconds(timeout).start() + while 1: + if timeout is not None: + if timeout.reached(): + return + if skip_first: skip_first = False else: self.device.screenshot() + try: yield self.device.image except AttributeError: @@ -425,7 +447,6 @@ class ModuleBase: def interval_is_reached(self, button, interval=5): return self.get_interval_timer(button, interval=interval, renew=True).reached() - _image_file = '' @property