def test_clear(): import asynckivy as ak e1 = ak.Event() e2 = ak.Event() async def _task(): nonlocal task_state task_state = 'A' await e1.wait() task_state = 'B' await e2.wait() task_state = 'C' await e1.wait() task_state = 'D' task_state = None ak.start(_task()) assert task_state == 'A' e1.set() assert task_state == 'B' e1.clear() e2.set() assert task_state == 'C' e1.set() assert task_state == 'D'
def test_reset_argument_while_resuming_awaited_coroutines(): import asynckivy as ak e = ak.Event() async def task1(e): assert await e.wait() == 'A' e.clear() e.set('B') nonlocal done1 done1 = True async def task2(e): assert await e.wait() == 'A' assert await e.wait() == 'B' nonlocal done2 done2 = True done1 = False done2 = False ak.start(task1(e)) ak.start(task2(e)) assert not done1 assert not done2 e.set('A') assert done1 assert done2
def test_gather(): import asynckivy as ak from asynckivy._core import gather events = [ak.Event() for __ in range(3)] async def _test(): tasks = await gather( (event.wait() for event in events), n=2, ) assert tasks[0].done assert not tasks[1].done assert tasks[2].done nonlocal done done = True done = False ak.start(_test()) assert not done events[0].set() assert not done events[0].set() assert not done events[2].set() assert done
async def _test(): tasks = await ak.or_( *(do_nothing() for __ in range(n_do_nothing)), *(ak.Event().wait() for __ in range(3 - n_do_nothing)), ) for task in tasks[:n_do_nothing]: assert task.done for task in tasks[n_do_nothing:]: assert not task.done nonlocal done done = True
async def run_in_executer(func, executer): event = asynckivy.Event() future = executer.submit(_wrapper, func, event) try: ret, exc = await event.wait() except GeneratorExit: future.cancel() raise assert future.done() if exc is not None: raise exc return ret
def test_set_before_task_starts(): import asynckivy as ak e = ak.Event() e.set() async def _task(): await e.wait() nonlocal done done = True done = False ak.start(_task()) assert done
async def run_in_thread(func, *, daemon=False): event = asynckivy.Event() Thread( name='asynckivy.run_in_thread', target=_wrapper, daemon=daemon, args=( func, event, ), ).start() ret, exc = await event.wait() if exc is not None: raise exc return ret
def test_pass_argument(): import asynckivy as ak e = ak.Event() async def task(e): assert await e.wait() == 'A' nonlocal done done = True done = False ak.start(task(e)) assert not done e.set('A') assert done done = False ak.start(task(e)) assert done
def test_normal(self): import asynckivy as ak events = [ak.Event() for __ in range(3)] async def _test(): tasks = await ak.or_(*(event.wait() for event in events)) assert not tasks[0].done assert tasks[1].done assert not tasks[2].done nonlocal done done = True done = False ak.start(_test()) assert not done events[1].set() assert done
def test_cancel_before_getting_excuted(kivy_clock): import time import asynckivy as ak flag = ak.Event() async def job(executer): await ak.run_in_executer(flag.set, executer) with ThreadPoolExecutor(max_workers=1) as executer: executer.submit(time.sleep, .1) task = ak.start(job(executer)) time.sleep(.02) assert not task.done assert not flag.is_set() kivy_clock.tick() task.cancel() assert task.cancelled assert not flag.is_set() time.sleep(.2) assert not flag.is_set()
async def flip_all(self, cards, event): """ Given an idle event, flip a list of cards all at once and wait until all finish. Once done, activate the event so that the caller can safely continue execution. ------------------------------------------------------------------------------ This is the concurrent version of flip_one(), animations play simultaneously. Each card is tracked by a unique child event to eliminate possible race conditions. """ child_events = [] # start asynchronous calls for card in cards: child_event = ak.Event() child_events.append(child_event) ak.start(self.flip_one(card, child_event)) # wait until all events join for child_event in child_events: await child_event.wait() event.set( ) # all animations complete, notify the caller who is waiting for the event
def test_multiple_tasks(): import asynckivy as ak e = ak.Event() async def _task1(): await e.wait() nonlocal task1_done task1_done = True async def _task2(): await e.wait() nonlocal task2_done task2_done = True task1_done = False task2_done = False ak.start(_task1()) ak.start(_task2()) assert not task1_done assert not task2_done e.set() assert task1_done assert task2_done
async def click(self, touch): # disable mouse clicks until the function returns self.mouse_disabled = True # determine which card is clicked on row = -1 col = -1 clicked_card = None for x, y in self.walk_cards(): card = self.cards[x, y] if card.collide_point(touch.x, touch.y): row = x col = y clicked_card = card break # mouse click outside the board, do nothing if clicked_card is None: self.mouse_disabled = False return # clicked card is already exposed, do nothing if clicked_card.index > 0: self.mouse_disabled = False return # otherwise, flip it and update board status else: self.flips += 1 # the 1st card is clicked on if self.state == 0: event = ak.Event() coroutine = self.flip_one(clicked_card, event) ak.start(coroutine) await event.wait() print('1st card flipped') self.last_clicked = self.cards[ row, col] # after flip, the card back no longer exists self.state = 1 # the 2nd card is clicked on else: event = ak.Event() coroutine = self.flip_one(clicked_card, event) ak.start(coroutine) await event.wait() print('2nd card flipped') # if matched, reset the board to state 0, check win conditions if self.last_clicked.index == self.cards[row, col].index: self.last_clicked = None self.state = 0 is_win = True for x, y in self.walk_cards(): if self.cards[x, y].index == 0: is_win = False break if is_win: self.congratulate() self.reset(self.theme) # if mismatched, flip both cards back after 2 seconds, then reset to state 0 else: await safe_sleep(0.5) event = ak.Event() cards = [self.last_clicked, self.cards[row, col]] coroutine = self.flip_all(cards, event) ak.start(coroutine) await event.wait() print('both cards are hidden') self.last_clicked = None self.state = 0 self.mouse_disabled = False