41 lines
1 KiB
Python
41 lines
1 KiB
Python
from concurrent.futures import ThreadPoolExecutor
|
|
from dataclasses import dataclass
|
|
from functools import wraps
|
|
from typing import Dict, List, Callable
|
|
|
|
from injectable import injectable, inject
|
|
|
|
|
|
@dataclass
|
|
class Event:
|
|
pass
|
|
|
|
|
|
@injectable(singleton=True)
|
|
class SimpleEventBus:
|
|
def __init__(self):
|
|
self._handlers: Dict[type, List[Callable]] = {}
|
|
self._executor = ThreadPoolExecutor()
|
|
|
|
def publish(self, event: Event) -> None:
|
|
for handler in self._handlers.get(type(event), []):
|
|
# Fire-and-forget execution
|
|
self._executor.submit(handler, event)
|
|
|
|
def subscribe(self, event_type: type, handler: Callable) -> None:
|
|
if event_type not in self._handlers:
|
|
self._handlers[event_type] = []
|
|
self._handlers[event_type].append(handler)
|
|
|
|
@staticmethod
|
|
def on(event: type) -> Callable:
|
|
def outer(func):
|
|
inject(SimpleEventBus).subscribe(event, func)
|
|
|
|
@wraps(func)
|
|
def wrapper(*args, **kwargs):
|
|
return func(*args, **kwargs)
|
|
|
|
return wrapper
|
|
|
|
return outer
|