Skip to content

Commit

Permalink
fix: timeouts and refresh rate should be accurate
Browse files Browse the repository at this point in the history
Closes #1
  • Loading branch information
aentwist committed Sep 9, 2024
1 parent 37e9bdd commit 0de7e66
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 11 deletions.
20 changes: 16 additions & 4 deletions gamedriver/_tap_img.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import math
import time
import timeit

import cv2 as cv

Expand Down Expand Up @@ -32,11 +34,14 @@ def wait_until_img_visible(
Returns:
Box | None: The match, or None if there is no match within `timeout_s`.
"""
polling_interval_s = settings["refresh_rate_ms"] / 1_000
refresh_rate_s = settings["refresh_rate_ms"] / 1_000
img_bgr = open_img(get_img_path(img)) if isinstance(img, str) else img

box = None
for i in range(math.floor(timeout_s / polling_interval_s)):
t_start = timeit.default_timer()
t_end = t_start
while t_end - t_start < timeout_s:
# t_end is the end of last iteration, i.e. the start of this one
box = locate(
img_bgr,
bounding_box=bounding_box,
Expand All @@ -46,9 +51,16 @@ def wait_until_img_visible(
threshold=threshold,
)
if box:
logger.debug(f"{img} available after {i * polling_interval_s}s")
logger.debug(f"{img} available after {t_end - t_start}s")
break
wait(polling_interval_s)

# Amount of time used so far this loop iteration
t_curr = timeit.default_timer() - t_end
# Time left to use this loop iteration
t_remain = refresh_rate_s - t_curr
if t_remain > 0:
time.sleep(t_remain)
t_end = timeit.default_timer()
else:
logger.debug(f"{img} not available after {timeout_s}s")

Expand Down
27 changes: 20 additions & 7 deletions tests/test_tap_img.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ def locate_campaign_begin():
yield locate


@pytest.fixture
def locate_campaign_begin_delayed():
with patch("gamedriver._tap_img.locate") as locate:
locate.side_effect = [
None,
None,
gd.Box(left=320, top=1602, right=760, bottom=1729),
None,
]
yield locate


@pytest.fixture
def locate_not_found():
with patch("gamedriver._tap_img.locate") as locate:
Expand Down Expand Up @@ -50,18 +62,19 @@ def fast_refresh_settings():
yield settings


def test_wait_until_img_visible(get_screen, get_img_path, fast_refresh_settings):
box = gd.wait_until_img_visible("dispatch-brown")
assert box
assert get_screen.call_count == 3
def test_wait_until_img_visible(
locate_campaign_begin_delayed, get_img_path, fast_refresh_settings
):
assert gd.wait_until_img_visible("dispatch-brown")
assert locate_campaign_begin_delayed.call_count == 3


def test_wait_until_img_visible_timeout(
get_screen, get_img_path, fast_refresh_settings
locate_campaign_begin_delayed, get_img_path, fast_refresh_settings
):
# Refresh rate of 1ms. 2ms / 1ms = 2 calls to get_screen. No match
box = gd.wait_until_img_visible("dispatch-brown", timeout_s=0.002)
assert not box
assert not gd.wait_until_img_visible("dispatch-brown", timeout_s=0.002)
assert locate_campaign_begin_delayed.call_count == 2


@pytest.fixture
Expand Down

0 comments on commit 0de7e66

Please sign in to comment.