I'm new to pygame and tried to write my own Event Manager because I couldn't find a solution I was satisfied with. So I wrote my own inspired by the observer pattern:
from typing import Callable
from pygame.event import Event
EventHandler = Callable[[Event], None]
_managers = dict()
class EventManager:
def __init__(self, name):
self.name = name
self.handlers: dict[int, list[EventHandler]] = dict()
def notify(self, event: Event, selector=lambda event: event.type):
eventType = selector(event)
if eventType not in self.handlers:
return
for handler in self.handlers[eventType]:
handler(event)
def register(self, eventType: int, handler: EventHandler):
print(f"{self.name} registered {eventType}")
if eventType not in self.handlers:
self.handlers[eventType] = [handler]
else:
self.handlers[eventType].append(handler)
def deregister(self, eventType: int, handler: EventHandler):
if not self._is_registered(eventType, handler):
return
self.handlers[eventType].remove(handler)
def _is_registered(self, eventType, handler):
return eventType in self.handlers and handler in self.handlers[eventType]
@staticmethod
def get(id: str):
if id not in _managers:
_managers[id] = EventManager(id)
return _managers[id]
generalEventManager = EventManager.get("General Events")
keyEventManager = EventManager.get("Key Events")
it's used like this:
class Foo:
_running = True
def register_events(self):
generalEventManager.register(pygame.QUIT, lambda _: self.on_quit())
generalEventManager.register(pygame.KEYDOWN, lambda event: self.on_key_down(event))
# register key events with
# keyEventManager.register(pygame.K_RETURN, lambda _: self.on_k_return())
# ...
def on_key_down(self, event: Event):
keyEventManager.notify(event, selector=lambda event: event.key)
def on_quit(self):
self._running = False
def on_cleanup(self):
pygame.quit()
def on_execute(self):
while self._running:
for event in pygame.event.get():
self.on_event(event)
self.on_cleanup()
Is this pythonian? Are there better solutions in pygame? Are there generic python library solutions that I didn't find?