8888import warnings
8989from collections .abc import Callable , Iterator , Mapping
9090from math import floor
91- from typing import TYPE_CHECKING , Any , Final , Generic , Literal , NamedTuple , TypeAlias , TypeVar , overload
91+ from typing import TYPE_CHECKING , Any , Final , Generic , Literal , NamedTuple , TypeAlias , TypedDict , TypeVar , overload
9292
9393import attrs
9494import numpy as np
@@ -309,11 +309,24 @@ def __repr__(self) -> str:
309309 return "|" .join (f"{ self .__class__ .__name__ } .{ self .__class__ (bit ).name } " for bit in self .__class__ if bit & self )
310310
311311
312+ class _CommonSDLEventAttributes (TypedDict ):
313+ """Common keywords for Event subclasses."""
314+
315+ sdl_event : _C_SDL_Event
316+
317+
318+ def _unpack_sdl_event (sdl_event : _C_SDL_Event ) -> _CommonSDLEventAttributes :
319+ """Unpack an SDL_Event union into common attributes, such as timestamp."""
320+ return {
321+ "sdl_event" : sdl_event ,
322+ }
323+
324+
312325@attrs .define (slots = True , kw_only = True )
313326class Event :
314327 """The base event class."""
315328
316- sdl_event : _C_SDL_Event = attrs .field (default = None , eq = False , kw_only = True , repr = False )
329+ sdl_event : _C_SDL_Event = attrs .field (default = None , eq = False , repr = False )
317330 """When available, this holds a python-cffi 'SDL_Event*' pointer. All sub-classes have this attribute."""
318331
319332 @property
@@ -349,7 +362,7 @@ class Quit(Event):
349362
350363 @classmethod
351364 def _from_sdl_event (cls , sdl_event : _C_SDL_Event ) -> Self :
352- return cls (sdl_event = sdl_event )
365+ return cls (** _unpack_sdl_event ( sdl_event ) )
353366
354367
355368@attrs .define (slots = True , kw_only = True )
@@ -383,7 +396,7 @@ def _from_sdl_event(cls, sdl_event: _C_SDL_Event) -> Self:
383396 sym = KeySym (keysym .key ),
384397 mod = Modifier (keysym .mod ),
385398 repeat = bool (sdl_event .key .repeat ),
386- sdl_event = sdl_event ,
399+ ** _unpack_sdl_event ( sdl_event ) ,
387400 )
388401
389402
@@ -521,14 +534,28 @@ def _from_sdl_event(cls, sdl_event: _C_SDL_Event) -> Self:
521534 pixel_motion = Point (float (motion .xrel ), float (motion .yrel ))
522535 subtile = _pixel_to_tile (pixel )
523536 if subtile is None :
524- self = cls (position = pixel , motion = pixel_motion , tile = None , tile_motion = None , state = state )
537+ self = cls (
538+ position = pixel ,
539+ motion = pixel_motion ,
540+ tile = None ,
541+ tile_motion = None ,
542+ state = state ,
543+ ** _unpack_sdl_event (sdl_event ),
544+ )
525545 else :
526546 tile = Point (floor (subtile [0 ]), floor (subtile [1 ]))
527547 prev_pixel = (pixel [0 ] - pixel_motion [0 ], pixel [1 ] - pixel_motion [1 ])
528548 prev_subtile = _pixel_to_tile (prev_pixel ) or (0 , 0 )
529549 prev_tile = floor (prev_subtile [0 ]), floor (prev_subtile [1 ])
530550 tile_motion = Point (tile [0 ] - prev_tile [0 ], tile [1 ] - prev_tile [1 ])
531- self = cls (position = pixel , motion = pixel_motion , tile = tile , tile_motion = tile_motion , state = state )
551+ self = cls (
552+ position = pixel ,
553+ motion = pixel_motion ,
554+ tile = tile ,
555+ tile_motion = tile_motion ,
556+ state = state ,
557+ ** _unpack_sdl_event (sdl_event ),
558+ )
532559 self .sdl_event = sdl_event
533560 return self
534561
@@ -564,7 +591,7 @@ def _from_sdl_event(cls, sdl_event: _C_SDL_Event) -> Self:
564591 tile : Point [int ] | None = None
565592 else :
566593 tile = Point (floor (subtile [0 ]), floor (subtile [1 ]))
567- self = cls (position = pixel , tile = tile , button = MouseButton (button .button ))
594+ self = cls (position = pixel , tile = tile , button = MouseButton (button .button ), ** _unpack_sdl_event ( sdl_event ) )
568595 self .sdl_event = sdl_event
569596 return self
570597
@@ -602,7 +629,7 @@ class MouseWheel(Event):
602629 @classmethod
603630 def _from_sdl_event (cls , sdl_event : _C_SDL_Event ) -> Self :
604631 wheel = sdl_event .wheel
605- return cls (x = int (wheel .x ), y = int (wheel .y ), flipped = bool (wheel .direction ), sdl_event = sdl_event )
632+ return cls (x = int (wheel .x ), y = int (wheel .y ), flipped = bool (wheel .direction ), ** _unpack_sdl_event ( sdl_event ) )
606633
607634
608635@attrs .define (slots = True , kw_only = True )
@@ -620,7 +647,7 @@ class TextInput(Event):
620647
621648 @classmethod
622649 def _from_sdl_event (cls , sdl_event : _C_SDL_Event ) -> Self :
623- return cls (text = str (ffi .string (sdl_event .text .text , 32 ), encoding = "utf8" ), sdl_event = sdl_event )
650+ return cls (text = str (ffi .string (sdl_event .text .text , 32 ), encoding = "utf8" ), ** _unpack_sdl_event ( sdl_event ) )
624651
625652
626653@attrs .define (slots = True , kw_only = True )
@@ -655,7 +682,9 @@ def _from_sdl_event(cls, sdl_event: _C_SDL_Event) -> WindowEvent | Undefined:
655682 event_type : Final = _WINDOW_TYPES_FROM_ENUM [sdl_event .type ]
656683 self : WindowEvent
657684 if sdl_event .type == lib .SDL_EVENT_WINDOW_MOVED :
658- self = WindowMoved (x = int (sdl_event .window .data1 ), y = int (sdl_event .window .data2 ), sdl_event = sdl_event )
685+ self = WindowMoved (
686+ x = int (sdl_event .window .data1 ), y = int (sdl_event .window .data2 ), ** _unpack_sdl_event (sdl_event )
687+ )
659688 elif sdl_event .type in (
660689 lib .SDL_EVENT_WINDOW_RESIZED ,
661690 lib .SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED ,
@@ -664,12 +693,12 @@ def _from_sdl_event(cls, sdl_event: _C_SDL_Event) -> WindowEvent | Undefined:
664693 type = event_type , # type: ignore[arg-type] # Currently NOT validated
665694 width = int (sdl_event .window .data1 ),
666695 height = int (sdl_event .window .data2 ),
667- sdl_event = sdl_event ,
696+ ** _unpack_sdl_event ( sdl_event ) ,
668697 )
669698 else :
670699 self = cls (
671700 type = event_type , # type: ignore[arg-type] # Currently NOT validated
672- sdl_event = sdl_event ,
701+ ** _unpack_sdl_event ( sdl_event ) ,
673702 )
674703 return self
675704
@@ -764,7 +793,12 @@ class JoystickAxis(JoystickEvent):
764793
765794 @classmethod
766795 def _from_sdl_event (cls , sdl_event : _C_SDL_Event ) -> Self :
767- return cls (which = int (sdl_event .jaxis .which ), axis = int (sdl_event .jaxis .axis ), value = int (sdl_event .jaxis .value ))
796+ return cls (
797+ which = int (sdl_event .jaxis .which ),
798+ axis = int (sdl_event .jaxis .axis ),
799+ value = int (sdl_event .jaxis .value ),
800+ ** _unpack_sdl_event (sdl_event ),
801+ )
768802
769803
770804@attrs .define (slots = True , kw_only = True )
@@ -793,6 +827,7 @@ def _from_sdl_event(cls, sdl_event: _C_SDL_Event) -> Self:
793827 ball = int (sdl_event .jball .ball ),
794828 dx = int (sdl_event .jball .xrel ),
795829 dy = int (sdl_event .jball .yrel ),
830+ ** _unpack_sdl_event (sdl_event ),
796831 )
797832
798833
@@ -816,7 +851,7 @@ class JoystickHat(JoystickEvent):
816851 @classmethod
817852 def _from_sdl_event (cls , sdl_event : _C_SDL_Event ) -> Self :
818853 x , y = _HAT_DIRECTIONS [sdl_event .jhat .hat ]
819- return cls (which = int (sdl_event .jhat .which ), x = x , y = y )
854+ return cls (which = int (sdl_event .jhat .which ), x = x , y = y , ** _unpack_sdl_event ( sdl_event ) )
820855
821856
822857@attrs .define (slots = True , kw_only = True )
@@ -856,6 +891,7 @@ def _from_sdl_event(cls, sdl_event: _C_SDL_Event) -> Self:
856891 which = int (sdl_event .jbutton .which ),
857892 button = int (sdl_event .jbutton .button ),
858893 pressed = bool (sdl_event .jbutton .down ),
894+ ** _unpack_sdl_event (sdl_event ),
859895 )
860896
861897
@@ -889,7 +925,7 @@ def _from_sdl_event(cls, sdl_event: _C_SDL_Event) -> Self:
889925 lib .SDL_EVENT_JOYSTICK_ADDED : "JOYDEVICEADDED" ,
890926 lib .SDL_EVENT_JOYSTICK_REMOVED : "JOYDEVICEREMOVED" ,
891927 }
892- return cls (type = types [sdl_event .type ], which = int (sdl_event .jdevice .which ))
928+ return cls (type = types [sdl_event .type ], which = int (sdl_event .jdevice .which ), ** _unpack_sdl_event ( sdl_event ) )
893929
894930
895931@attrs .define (slots = True , kw_only = True )
@@ -932,6 +968,7 @@ def _from_sdl_event(cls, sdl_event: _C_SDL_Event) -> Self:
932968 which = int (sdl_event .gaxis .which ),
933969 axis = tcod .sdl .joystick .ControllerAxis (sdl_event .gaxis .axis ),
934970 value = int (sdl_event .gaxis .value ),
971+ ** _unpack_sdl_event (sdl_event ),
935972 )
936973
937974
@@ -963,6 +1000,7 @@ def _from_sdl_event(cls, sdl_event: _C_SDL_Event) -> Self:
9631000 which = int (sdl_event .gbutton .which ),
9641001 button = tcod .sdl .joystick .ControllerButton (sdl_event .gbutton .button ),
9651002 pressed = bool (sdl_event .gbutton .down ),
1003+ ** _unpack_sdl_event (sdl_event ),
9661004 )
9671005
9681006
@@ -982,7 +1020,7 @@ def _from_sdl_event(cls, sdl_event: _C_SDL_Event) -> Self:
9821020 lib .SDL_EVENT_GAMEPAD_REMOVED : "CONTROLLERDEVICEREMOVED" ,
9831021 lib .SDL_EVENT_GAMEPAD_REMAPPED : "CONTROLLERDEVICEREMAPPED" ,
9841022 }
985- return cls (type = types [sdl_event .type ], which = int (sdl_event .gdevice .which ))
1023+ return cls (type = types [sdl_event .type ], which = int (sdl_event .gdevice .which ), ** _unpack_sdl_event ( sdl_event ) )
9861024
9871025
9881026@functools .cache
@@ -1000,7 +1038,7 @@ class Undefined(Event):
10001038
10011039 @classmethod
10021040 def _from_sdl_event (cls , sdl_event : _C_SDL_Event ) -> Self :
1003- return cls (sdl_event = sdl_event )
1041+ return cls (** _unpack_sdl_event ( sdl_event ) )
10041042
10051043 def __repr__ (self ) -> str :
10061044 """Return debug info for this undefined event, including the SDL event name."""
0 commit comments