Skip to content

Commit f873f44

Browse files
committed
Centralize unpacking of SDL_Event union into Event attribute
Add sdl_event to several events which were missing it Haven't decided on timestamp handling yet, this is the most I can do before committing to anything
1 parent ec32d8c commit f873f44

File tree

1 file changed

+55
-17
lines changed

1 file changed

+55
-17
lines changed

tcod/event.py

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
import warnings
8989
from collections.abc import Callable, Iterator, Mapping
9090
from 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

9393
import attrs
9494
import 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)
313326
class 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

Comments
 (0)