OpenSpace/openspace/runtime/event_bus.py
2026-07-17 11:43:42 +08:00

38 lines
1.2 KiB
Python

from __future__ import annotations
import inspect
from collections.abc import Callable
from typing import Any
RuntimeEventSink = Callable[[str, dict[str, Any]], Any]
class RuntimeEventBus:
"""Fan out runtime events without owning transport-specific behavior."""
def __init__(self, dispatcher: RuntimeEventSink | None = None) -> None:
self._dispatcher = dispatcher
self._sinks: list[RuntimeEventSink] = []
def register_sink(self, sink: RuntimeEventSink) -> None:
self._sinks.append(sink)
def unregister_sink(self, sink: RuntimeEventSink) -> None:
if sink in self._sinks:
self._sinks.remove(sink)
async def emit(self, event_type: str, data: dict[str, Any]) -> None:
if self._dispatcher is not None:
await self._call_sink(self._dispatcher, event_type, data)
for sink in list(self._sinks):
await self._call_sink(sink, event_type, data)
async def _call_sink(
self,
sink: RuntimeEventSink,
event_type: str,
data: dict[str, Any],
) -> None:
result = sink(event_type, dict(data))
if inspect.isawaitable(result):
await result