Skip to content

Simplify c-side of events sub-module. (Part 2) #3045

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 41 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
93828b9
Just rename "event.c" to "_event.c".
gresm Jun 17, 2024
dbf8c26
Merge branch 'pygame-community:main' into events_as_types_python
gresm Jun 18, 2024
a604caa
Just rename "event.c" to "_event.c".
gresm Jun 17, 2024
ce045d3
Merge branch 'events-in-python' of https://github.com/gresm/pygame-ce…
gresm Jul 16, 2024
3009fe1
Move custom_type() to python.
gresm Jul 16, 2024
549805e
Bugfix
gresm Jul 16, 2024
f333b6e
Move event_name() to python.
gresm Jul 16, 2024
8485bdd
Update _NAMES_MAPPING
gresm Jul 17, 2024
1b10fd9
Moving Event() to python, likely not working yet.
gresm Jul 18, 2024
0c5c9fb
Moving Event() to python - bugfix.
gresm Jul 18, 2024
27194e3
Moving Event() to python - bugfix 2.
gresm Jul 19, 2024
097ad6a
Moving Event() to python - bugfix 3.
gresm Jul 19, 2024
931cf5e
Moving Event() to python - bugfix 4.
gresm Jul 19, 2024
d80bf00
Merge branch 'main' into events-in-python
gresm Jul 19, 2024
db570be
Moving Event() to python - bugfix 5.
gresm Jul 19, 2024
06b8a14
Add documentation.
gresm Jul 19, 2024
ea11552
Merge branch 'pygame-community:main' into events-in-python
gresm Aug 8, 2024
38084e8
Input buffer.
gresm Aug 8, 2024
6fd93ba
Mark what to do.
gresm Aug 9, 2024
cba8374
Dopump export.
gresm Aug 10, 2024
0e21061
Allowed_set/allowed_get.
gresm Aug 10, 2024
2e9eabb
Move set_allowed, set_blocked, get_blocked to python.
gresm Aug 14, 2024
8a2253a
Bugfix.
gresm Aug 16, 2024
900a4b6
Add docstrings.
gresm Aug 21, 2024
fed5617
Remove _pgEventDictProxy and use a naive multiple Py_INCREF-s approac…
gresm Aug 26, 2024
e8e9a42
Merge branch 'main' into events-in-python-2
gresm Aug 26, 2024
8680024
Fix formatting for docs and bugfixes.
gresm Aug 26, 2024
9c539c6
Buffered INCREFs and DECREFs for timers.
gresm Aug 26, 2024
246a305
Fix 2 old memory leaks and remove negative decref bug.
gresm Aug 28, 2024
01e30c7
Merge branch 'main' of https://github.com/pygame-community/pygame-ce …
gresm Aug 28, 2024
ba48bcc
Fix a typing issue.
gresm Aug 28, 2024
3cb18db
Improve documentation.
gresm Aug 28, 2024
46f17c4
Move get() to python.
gresm Sep 11, 2024
4b7124e
Merge branch 'main' of https://github.com/pygame-community/pygame-ce …
gresm Sep 11, 2024
55220a4
Format
gresm Sep 23, 2024
0e4df38
Merge branch 'main' of https://github.com/pygame-community/pygame-ce …
gresm Sep 23, 2024
8a62db9
Move peek() to python.
gresm Sep 24, 2024
5d6bdc7
Merge remote-tracking branch 'origin' into events-in-python-2
gresm Sep 24, 2024
a62e529
Run updated pre-commit.
gresm Sep 24, 2024
987bf9a
Merge branch 'main' of https://github.com/pygame-community/pygame-ce …
gresm Sep 25, 2024
9e10e91
Merge branch 'main' of https://github.com/pygame-community/pygame-ce …
gresm Oct 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion buildconfig/Setup.Android.SDL2.in
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ base src_c/base.c $(SDL) $(DEBUG)
color src_c/color.c $(SDL) $(DEBUG)
constants src_c/constants.c $(SDL) $(DEBUG)
display src_c/display.c $(SDL) $(DEBUG)
event src_c/event.c $(SDL) $(DEBUG)
_event src_c/_event.c $(SDL) $(DEBUG)
key src_c/key.c $(SDL) $(DEBUG)
mouse src_c/mouse.c $(SDL) $(DEBUG)
rect src_c/rect.c src_c/pgcompat_rect.c $(SDL) $(DEBUG)
Expand Down
2 changes: 1 addition & 1 deletion buildconfig/Setup.Emscripten.SDL2.in
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ controller src_c/void.c
controller_old src_c/void.c
display src_c/void.c
draw src_c/void.c
event src_c/void.c
_event src_c/void.c
font src_c/void.c
gfxdraw src_c/void.c
joystick src_c/void.c
Expand Down
2 changes: 1 addition & 1 deletion buildconfig/Setup.SDL2.in
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ base src_c/base.c $(SDL) $(DEBUG)
color src_c/color.c $(SDL) $(DEBUG)
constants src_c/constants.c $(SDL) $(DEBUG)
display src_c/display.c $(SDL) $(DEBUG)
event src_c/event.c $(SDL) $(DEBUG)
_event src_c/_event.c $(SDL) $(DEBUG)
key src_c/key.c $(SDL) $(DEBUG)
mouse src_c/mouse.c $(SDL) $(DEBUG)
rect src_c/rect.c src_c/pgcompat_rect.c $(SDL) $(DEBUG)
Expand Down
21 changes: 21 additions & 0 deletions buildconfig/stubs/pygame/_event.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from __future__ import annotations

from .typing import SequenceLike, EventLike

_EventTypes = int | SequenceLike[int]

def pump(dopump: bool, /) -> None: ...
def _get(type: int, /) -> EventLike | None: ...
def _peek(type: int, /) -> bool: ...
def _proxify_event_type(type: int, /) -> int: ...
def video_check() -> None: ...
def poll() -> EventLike: ...
def wait(timeout: int = 0) -> EventLike: ...
def set_grab(grab: bool, /) -> None: ...
def get_grab() -> bool: ...
def allowed_get(type: int, /) -> bool: ...
def allowed_set(type: int, val: bool, /) -> None: ...
def post(event: EventLike, /) -> bool: ...
def register_event_class(cls: type[EventLike]) -> None: ...
def _internal_mod_init() -> None: ...
def _internal_mod_quit() -> None: ...
44 changes: 19 additions & 25 deletions buildconfig/stubs/pygame/event.pyi
Original file line number Diff line number Diff line change
@@ -1,27 +1,19 @@
from typing import (
Any,
Dict,
List,
Optional,
Union,
final,
)
from typing import Any, Union, Optional, Dict

from pygame.typing import SequenceLike
from pygame.typing import SequenceLike, EventLike

@final
class Event:
type: int
dict: Dict[str, Any]
__dict__: Dict[str, Any]
__hash__: None # type: ignore

class Event(EventLike):
def __init__(
self, type: int, dict: Dict[str, Any] = ..., **kwargs: Any
self, type: int, dict: Optional[Dict[str, Any]] = None, **kwargs: Any
) -> None: ...
def __new__(cls, *args: Any, **kwargs: Any) -> "Event": ...
def __getattribute__(self, name: str) -> Any: ...
def __setattr__(self, name: str, value: Any) -> None: ...
def __delattr__(self, name: str) -> None: ...
def __int__(self) -> int: ...
def __bool__(self) -> bool: ...
def __eq__(self, other: Any) -> bool: ...

_EventTypes = Union[int, SequenceLike[int]]

Expand All @@ -30,18 +22,20 @@ def get(
eventtype: Optional[_EventTypes] = None,
pump: Any = True,
exclude: Optional[_EventTypes] = None,
) -> List[Event]: ...
def poll() -> Event: ...
def wait(timeout: int = 0) -> Event: ...
def peek(eventtype: Optional[_EventTypes] = None, pump: Any = True) -> bool: ...
) -> list[EventLike]: ...
def poll() -> EventLike: ...
def wait(timeout: int = 0) -> EventLike: ...
def peek(eventtype: Optional[_EventTypes] = None, pump: Any = True) -> Union[bool, EventLike]: ...
def clear(eventtype: Optional[_EventTypes] = None, pump: Any = True) -> None: ...
def event_name(type: int, /) -> str: ...
def set_blocked(type: Optional[_EventTypes], /) -> None: ...
def set_allowed(type: Optional[_EventTypes], /) -> None: ...
def get_blocked(type: _EventTypes, /) -> bool: ...
def event_name(type: int) -> str: ...
def set_blocked(type: Optional[_EventTypes], *args: int) -> None: ...
def set_allowed(type: Optional[_EventTypes], *args: int) -> None: ...
def get_blocked(type: _EventTypes, *args: int) -> bool: ...
def set_grab(grab: bool, /) -> None: ...
def get_grab() -> bool: ...
def post(event: Event, /) -> bool: ...
def post(event: EventLike, /) -> bool: ...
def custom_type() -> int: ...
def init() -> None: ...
def quit() -> None: ...

EventType = Event
33 changes: 29 additions & 4 deletions buildconfig/stubs/pygame/typing.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,18 @@ __all__ = [

import sys
from abc import abstractmethod
from typing import IO, Callable, Tuple, Union, TypeVar, Protocol
from typing import (
IO,
Callable,
Tuple,
Dict,
Union,
Optional,
TypeVar,
Protocol,
Any,
Iterable,
)

from pygame.color import Color
from pygame.rect import Rect, FRect
Expand All @@ -40,13 +51,14 @@ _T_co = TypeVar("_T_co", covariant=True)

class SequenceLike(Protocol[_T_co]):
"""
Variant of the standard `Sequence` ABC that only requires `__getitem__` and `__len__`.
Variant of the standard `Sequence` ABC that only requires `__getitem__`.
"""

@abstractmethod
def __getitem__(self, index: int, /) -> _T_co: ...
@abstractmethod
def __len__(self) -> int: ...


IterableLike = Union[SequenceLike[_T_co], Iterable[_T_co]]


# Modify typehints when it is possible to annotate sizes
Expand All @@ -72,6 +84,16 @@ RectLike = Union[
]


class EventLike(Protocol):
def __init__(self, type: int, /, **kwargs: Any) -> None: ...
def __new__(cls, *args: Any, **kwargs: Any) -> "EventLike": ...

@property
def type(self) -> int: ...
@property
def dict(self) -> Dict[str, Any]: ...


# cleanup namespace
del (
sys,
Expand All @@ -82,7 +104,10 @@ del (
IO,
Callable,
Tuple,
Dict,
Union,
Optional,
TypeVar,
Protocol,
Any,
)
56 changes: 31 additions & 25 deletions docs/reST/c_api/event.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,42 @@ The extension module :py:mod:`pygame.event`.

Header file: src_c/include/pygame.h

.. c:function:: PyObject* pgEvent_GetType(void)

.. c:type:: pgEventObject
Return a python class that is currently set to be the event class

The :py:class:`pygame.event.EventType` object C struct.

.. c:member:: int type

The event type code.

.. c:type:: pgEvent_Type

The pygame event object type :py:class:`pygame.event.EventType`.
If the class is not known at the time (called before ``pygame._event.register_event_class``)
this function will return NULL and set the error.

.. c:function:: int pgEvent_Check(PyObject *x)

Return true if *x* is a pygame event instance

Will return false if *x* is a subclass of event.
This is a macro. No check is made that *x* is not ``NULL``.
Will return -1 if python error is set while checking.
No check is made that *x* is not ``NULL``.

.. c:function:: PyObject* pgEvent_New(SDL_Event *event)

Return a new pygame event instance for the SDL *event*.
If *event* is ``NULL`` then create an empty event object.
On failure raise a Python exception and return ``NULL``.

.. note::
This is a destructive operation, so don't use passed SDL_Event afterwards.

.. c:function:: PyObject* pgEvent_FromTypeAndDict(int e_type, PyObject *dict)

Instantiates a new Event object created from the given event type and a dict.

On error returns NULL and sets python exception.

.. c:function:: int pgEvent_GetEventType(PyObject *)

Returns an event type extracted from the python object.

On error this retuns -1.

.. c:function:: char* pgEvent_GetKeyDownInfo(void)

Return an array of bools (using char) of length SDL_NUM_SCANCODES
Expand All @@ -59,23 +69,19 @@ Header file: src_c/include/pygame.h
Return an array of bools (using char) of length 5
with the most recent button releases.

.. c:function:: int pg_post_event(Uint32 type, PyObject *dict)
.. c:function:: int pg_post_event(Uint32 type, PyObject *obj)

Posts a pygame event that is an ``SDL_USEREVENT`` on the SDL side. This
function takes a python dict, which can be NULL too.
This function does not need GIL to be held if dict is NULL, but needs GIL
function takes a python dict or Event instance, which can be NULL too.
This function does not need GIL to be held if obj is NULL, but needs GIL
otherwise. Just like the SDL ``SDL_PushEvent`` function, returns 1 on
success, 0 if the event was not posted due to it being blocked, and -1 on
failure.

.. c:function:: int pg_post_event_dictproxy(Uint32 type, pgEventDictProxy *dict_proxy)

Posts a pygame event that is an ``SDL_USEREVENT`` on the SDL side, can also
optionally take a dictproxy instance. Using this dictproxy API is especially
useful when multiple events that need to be posted share the same dict
attribute, like in the case of event timers. This way, the number of python
increfs and decrefs are reduced, and callers of this function don't need to
hold GIL for every event posted, the GIL only needs to be held during the
creation of the dictproxy instance, and when it is freed.
Just like the SDL ``SDL_PushEvent`` function, returns 1 on success, 0 if the
event was not posted due to it being blocked, and -1 on failure.
.. ## pg_post_event ##

.. c:function:: int pg_post_event_steal(Uint32 type, PyObject *obj)

Nearly the same as :c:func:`pg_post_event`, but with two differences.
1) This doesn't need GIL held at all when called.
2) This steals the reference to obj, instead of borrowing it.
10 changes: 8 additions & 2 deletions docs/reST/ref/event.rst
Original file line number Diff line number Diff line change
Expand Up @@ -317,15 +317,21 @@ On Android, the following events can be generated
.. function:: peek

| :sl:`test if event types are waiting on the queue`
| :sg:`peek(eventtype=None) -> bool`
| :sg:`peek(eventtype=None, pump=True) -> bool`
| :sg:`peek() -> Event instance`
| :sg:`peek(eventtype) -> bool`
| :sg:`peek(eventtype, pump=True) -> bool`

Returns ``True`` if there are any events of the given type waiting on the
queue. If a sequence of event types is passed, this will return ``True`` if
any of those events are on the queue.

If ``pump`` is ``True`` (the default), then :func:`pygame.event.pump()` will be called.

If ``eventtype`` is unspecified, or ``None``, then this function will return the top-most event instead.

.. note::
There is no guarantee that the event got with :func:`pygame.event.get()` immediately after calling this function will be the same.

.. versionchangedold:: 1.9.5 Added ``pump`` argument

.. ## pygame.event.peek ##
Expand Down
14 changes: 14 additions & 0 deletions docs/reST/ref/typing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,18 @@ type aliases for proper typehint annotations.
* Any object with a ``.rect`` attribute which is a ``RectLike`` or a function
returning a ``RectLike``

.. data:: EventLike

A protocol representing an event that is undestood by pygame-ce.

* ``pygame.Event(type, dict, arg=val)``
* A python class that implements EventLike protocol:

::

class MyEvent:
def __init__(self, type: int, **kwargs):
self.type = type
self.dict = kwargs

.. ## pygame.typing ##
Loading
Loading