-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
222050b
commit 5432a99
Showing
3 changed files
with
78 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,103 @@ | ||
import types | ||
from collections.abc import Awaitable | ||
from collections.abc import Awaitable, Callable | ||
from functools import partial | ||
|
||
from asyncgui import _current_task, _sleep_forever | ||
from pygame.event import Event | ||
|
||
from .constants import DEFAULT_PRIORITY | ||
from ._priority_dispatcher import PriorityDispatcher | ||
|
||
|
||
def _resume_task(task_step, filter, event: Event): | ||
r = filter(event) | ||
if r: | ||
task_step(event) | ||
return r | ||
|
||
|
||
@types.coroutine | ||
def sdl_event(dispatcher: PriorityDispatcher, *, priority=DEFAULT_PRIORITY, filter=lambda event: True) -> Awaitable[Event]: | ||
def sdl_event(dispatcher, *, priority=DEFAULT_PRIORITY, filter=lambda event: True) -> Awaitable[Event]: | ||
''' | ||
Waits for a SDL event to occur | ||
Waits for a SDL event to occur. | ||
.. code-block:: | ||
e = await sdl_event(dispatcher) | ||
print(f"A {pygame.event.event_name(e.type)} event occurred.") | ||
You usually want to wait for an event of specific type(s). | ||
You probably want to wait for an event of specific type(s). | ||
.. code-block:: | ||
e = await sdl_event(dispatcher, filter=lambda e: e.type == pygame.FINGERDOWN) | ||
print("A FINGERDOWN event occurred") | ||
''' | ||
task = (yield _current_task)[0][0] | ||
|
||
def _callback(event): | ||
r = filter(event) | ||
if r: | ||
task._step(event) | ||
return r | ||
|
||
sub = dispatcher.add_subscriber(_callback, priority) | ||
sub = dispatcher.add_subscriber(partial(_resume_task, task._step, filter), priority) | ||
try: | ||
return (yield _sleep_forever)[0][0] | ||
finally: | ||
sub.cancel() | ||
|
||
|
||
class sdl_event_repeatedly: | ||
''' | ||
Returns an async context manager that provides an efficient way to repeat waiting for a SDL event to occur. | ||
.. code-block:: | ||
async with sdl_event_repeatedly(dispatcher) as sdl_event: | ||
while True: | ||
e = await sdl_event() | ||
print(f"A {pygame.event.event_name(e.type)} event occurred.") | ||
This API is designed to handle SDL events that may frequently occur, such as ``MOUSEMOTION`` or ``FINGERMOTION``: | ||
.. code-block:: | ||
def filter(event, allowed_list=(MOUSEMOTION, MOUSEBUTTONUP)): | ||
return event.type in allowed_list | ||
async with sdl_event_repeatedly(dispatcher, filter=filter) as sdl_event: | ||
while True: | ||
e = await sdl_event() | ||
if e.type == MOUSEBUTTONUP: | ||
break | ||
print(f"The mouse cursor is now at ({e.x}, {e.y}).") | ||
**Restriction** | ||
You are not allowed to perform any kind of async operations inside the with-block except ``await sdl_event()``. | ||
.. code-block:: | ||
async with sdl_event_repeatedly(dispatcher) as sdl_event: | ||
await sdl_event() # OK | ||
await something_else # NOT ALLOWED | ||
async with async_context_manager: # NOT ALLOWED | ||
... | ||
async for __ in async_iterator: # NOT ALLOWED | ||
... | ||
''' | ||
|
||
def __init__(self, dispatcher, *, filter=lambda event: True, priority=DEFAULT_PRIORITY): | ||
self._dispatcher = dispatcher | ||
self._filter = filter | ||
self._priority = priority | ||
|
||
@staticmethod | ||
@types.coroutine | ||
def _wait_for_an_event_to_occur(_sleep_forever=_sleep_forever) -> Awaitable[Event]: | ||
return (yield _sleep_forever)[0][0] | ||
|
||
@types.coroutine | ||
def __aenter__(self) -> Awaitable[Callable[[], Awaitable[Event]]]: | ||
task = (yield _current_task)[0][0] | ||
self._subscriber = self._dispatcher.add_subscriber( | ||
partial(_resume_task, task._step, self._filter), | ||
self._priority, | ||
) | ||
return self._wait_for_an_event_to_occur | ||
|
||
async def __aexit__(self, *args): | ||
self._subscriber.cancel() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters