Skip to content

Commit 7c4ecf3

Browse files
sezanzebshawarden
andauthored
Optional wait randomness (#986)
Added an optional argument to wait to the amount of time wait can vary between between the 2 specific values. 2nd 'max_time' argument is ignored if value is less than 1st 'time' argument. Co-authored-by: Samuel Hawarden <[email protected]> Co-authored-by: Samuel Hawarden <[email protected]>
1 parent 5f3d981 commit 7c4ecf3

File tree

2 files changed

+61
-3
lines changed

2 files changed

+61
-3
lines changed

inputremapper/injection/macros/macro.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import copy
4141
import math
4242
import re
43+
import random
4344
from typing import List, Callable, Awaitable, Tuple, Optional, Union, Any
4445

4546
from evdev.ecodes import (
@@ -468,12 +469,19 @@ async def task(handler: Callable):
468469

469470
self.tasks.append(task)
470471

471-
def add_wait(self, time: Union[int, float]):
472+
def add_wait(self, time: Union[str, float, int], max_time=None):
472473
"""Wait time in milliseconds."""
473-
time = self._type_check(time, [int, float], "wait", 1)
474+
time = self._type_check(time, [float, int], "wait", 1)
475+
max_time = self._type_check(max_time, [float, int, None], "wait", 2)
474476

475477
async def task(_):
476-
await asyncio.sleep(self._resolve(time, [int, float]) / 1000)
478+
resolved_time = self._resolve(time, [float, int])
479+
resolved_max_time = self._resolve(max_time, [float, int])
480+
481+
if resolved_max_time is not None and resolved_max_time > resolved_time:
482+
resolved_time = random.uniform(resolved_time, resolved_max_time)
483+
484+
await asyncio.sleep(resolved_time / 1000)
477485

478486
self.tasks.append(task)
479487

tests/unit/test_macros.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,6 +1344,56 @@ def set_foo(value):
13441344
)
13451345

13461346

1347+
@test_setup
1348+
class TestWait(MacroTestBase):
1349+
async def assert_time_randomized(
1350+
self,
1351+
macro: Macro,
1352+
min_: float,
1353+
max_: float,
1354+
):
1355+
for _ in range(100):
1356+
start = time.time()
1357+
await macro.run(self.handler)
1358+
time_taken = time.time() - start
1359+
1360+
# Any of the runs should be within the defined range, to prove that they
1361+
# are indeed random.
1362+
if min_ < time_taken < max_:
1363+
return
1364+
1365+
raise AssertionError("`wait` was not randomized")
1366+
1367+
async def test_wait_1_core(self):
1368+
mapping = DummyMapping()
1369+
mapping.macro_key_sleep_ms = 0
1370+
macro = parse("repeat(5, wait(50))", self.context, mapping, True)
1371+
1372+
start = time.time()
1373+
await macro.run(self.handler)
1374+
time_per_iteration = (time.time() - start) / 5
1375+
1376+
self.assertLess(abs(time_per_iteration - 0.05), 0.005)
1377+
1378+
async def test_wait_2_ranged(self):
1379+
mapping = DummyMapping()
1380+
mapping.macro_key_sleep_ms = 0
1381+
macro = parse("wait(1, 100)", self.context, mapping, True)
1382+
await self.assert_time_randomized(macro, 0.02, 0.08)
1383+
1384+
async def test_wait_3_ranged_single_get(self):
1385+
mapping = DummyMapping()
1386+
mapping.macro_key_sleep_ms = 0
1387+
macro = parse("set(a, 100).wait(1, $a)", self.context, mapping, True)
1388+
await self.assert_time_randomized(macro, 0.02, 0.08)
1389+
1390+
async def test_wait_4_ranged_double_get(self):
1391+
mapping = DummyMapping()
1392+
mapping.macro_key_sleep_ms = 0
1393+
macro = parse("set(a, 1).set(b, 100).wait($a, $b)", self.context, mapping, True)
1394+
await self.assert_time_randomized(macro, 0.02, 0.08)
1395+
1396+
13471397
@test_setup
13481398
class TestIfSingle(MacroTestBase):
13491399
async def test_if_single(self):

0 commit comments

Comments
 (0)