Skip to content

Commit 5a44f99

Browse files
committed
Add pixel wait for
1 parent 1457e19 commit 5a44f99

1 file changed

Lines changed: 77 additions & 7 deletions

File tree

src/tapper/helper/img.py

Lines changed: 77 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,19 +67,22 @@ def wait_for(
6767
This is blocking until timeout, obviously.
6868
6969
:param image: see SearchableImage
70-
:param timeout: How long to search for.
70+
:param timeout: If this many seconds elapsed, return None.
7171
:param interval: Time between searches. Note that search can take significant time as well,
7272
and actual frequency may be lower than you expect because of this.
7373
:param precision: see `find` param.
7474
:return: Coordinates X and Y of top-left of the found image relative to the bounding box (if any).
7575
"""
7676
finish_time = time.perf_counter() + timeout
7777
normalized = _normalize(image) # type: ignore
78-
while time.perf_counter() < finish_time:
78+
while True:
7979
if found := _find_in_image(normalized, precision=precision): # type: ignore
8080
return found
81+
if time.perf_counter() < finish_time:
82+
return None
8183
time.sleep(interval)
82-
return None
84+
if time.perf_counter() < finish_time:
85+
return None
8386

8487

8588
def wait_for_one_of(
@@ -119,12 +122,15 @@ def wait_for_one_of(
119122
"""
120123
finish_time = time.perf_counter() + timeout
121124
normalized = [_normalize(image) for image in images] # type: ignore
122-
while time.perf_counter() < finish_time:
125+
while True:
123126
for i in range(len(normalized)):
124127
if _find_in_image(normalized[i], precision=precision): # type: ignore
125128
return images[i]
129+
if time.perf_counter() < finish_time:
130+
return None
126131
time.sleep(interval)
127-
return None
132+
if time.perf_counter() < finish_time:
133+
return None
128134

129135

130136
def snip(
@@ -198,7 +204,7 @@ def pixel_info(
198204
:return: callable toggle, to be set into a Tap.
199205
"""
200206
return lambda: callback(
201-
get_pixel_color(tapper.mouse.get_pos(), outer), tapper.mouse.get_pos()
207+
pixel_get_color(tapper.mouse.get_pos(), outer), tapper.mouse.get_pos()
202208
)
203209

204210

@@ -222,7 +228,7 @@ def pixel_str(
222228
return lambda: callback(_pixel_str(tapper.mouse.get_pos(), outer))
223229

224230

225-
def get_pixel_color(
231+
def pixel_get_color(
226232
coords: tuple[int, int], outer: str | ndarray | None = None
227233
) -> tuple[int, int, int]:
228234
"""
@@ -257,3 +263,67 @@ def pixel_find(
257263
:return: Coordinates X and Y of the first pixel that matches, or None if no match.
258264
"""
259265
return _pixel_find(color, bbox_or_coords, _normalize(outer)[0], variation)
266+
267+
268+
def pixel_wait_for(
269+
color: tuple[int, int, int],
270+
bbox_or_coords: tuple[int, int, int, int] | tuple[int, int] | None = None,
271+
timeout: int | float = 5,
272+
interval: float = 0.1,
273+
variation: int = 0,
274+
) -> tuple[int, int] | None:
275+
"""
276+
Regularly search the screen or region of the screen for a pixel,
277+
returning coordinates when it appears, or None if timeout.
278+
This is blocking until timeout, obviously.
279+
280+
:param color: see pixel_find
281+
:param bbox_or_coords: see pixel_find
282+
:param timeout: If this many seconds elapsed, return None.
283+
:param interval: Time between searches.
284+
:param variation: see pixel_find
285+
:return: Coordinates of the pixel if found, else None.
286+
"""
287+
finish_time = time.perf_counter() + timeout
288+
while True:
289+
if found := pixel_find(color, bbox_or_coords, variation=variation):
290+
return found
291+
if time.perf_counter() < finish_time:
292+
return None
293+
time.sleep(interval)
294+
if time.perf_counter() < finish_time:
295+
return None
296+
297+
298+
def pixel_wait_for_one_of(
299+
colors_coords: list[
300+
tuple[tuple[int, int, int], tuple[int, int, int, int] | tuple[int, int] | None]
301+
],
302+
timeout: int | float = 5,
303+
interval: float = 0.1,
304+
variation: int = 0,
305+
) -> tuple[
306+
tuple[int, int, int], tuple[int, int, int, int] | tuple[int, int] | None
307+
] | None:
308+
"""
309+
Regularly search the screen or region of the screen for pixels,
310+
returning first that appears, or None if timeout.
311+
This is blocking until timeout, obviously.
312+
313+
:param colors_coords: list of tuples(color, coords) - for color and coords see pixel_find.
314+
Each pixel may have own coords/bbox to be searched in. Coords None will search entire screen.
315+
:param timeout: see pixel_wait_for
316+
:param interval: see pixel_wait_for
317+
:param variation: see pixel_find
318+
:return: tuple(color, coords) that was found, else None.
319+
"""
320+
finish_time = time.perf_counter() + timeout
321+
while True:
322+
for _, col_coo in enumerate(colors_coords):
323+
if pixel_find(*col_coo, variation=variation):
324+
return col_coo
325+
if time.perf_counter() < finish_time:
326+
return None
327+
time.sleep(interval)
328+
if time.perf_counter() < finish_time:
329+
return None

0 commit comments

Comments
 (0)