Update event_bus.py

The EventHandler base class was modified to support the new decoupled __init__ pattern.
This commit is contained in:
imonlinux
2025-11-17 21:50:53 -08:00
committed by GitHub
parent f39df8a40a
commit b62d07be7d
+15 -12
View File
@@ -1,3 +1,5 @@
"""A simple synchronous publish/subscribe event bus."""
import logging
from typing import Any, Callable, Dict, List, Optional
@@ -8,34 +10,33 @@ class EventBus:
"""A simple synchronous publish/subscribe event bus."""
def __init__(self):
# A dictionary to hold listeners for specific string topics
self.topics: Dict[str, List[Callable[[Any], None]]] = {}
def subscribe(self, topic: str, listener: Callable[[Any], None]) -> None:
"""
Subscribes a listener to a topic.
"""
"""Subscribes a listener to a topic."""
if topic not in self.topics:
self.topics[topic] = []
self.topics[topic].append(listener)
_LOGGER.debug(f"Subscribed listener to topic '{topic}'")
def publish(self, topic: str, data: Optional[Dict[str, Any]] = None) -> None:
"""
Publishes an event to all subscribed listeners.
"""
"""Publishes an event to all subscribed listeners."""
if data is None:
data = {}
data['__topic'] = topic
listeners = self.topics.get(topic, [])
_LOGGER.debug(f"Publishing event to {len(listeners)} listeners on topic '{topic}'")
for listener in listeners:
try:
listener(data)
except Exception:
_LOGGER.exception("Error in event listener for topic %s", topic)
# -----------------------------------------------------------------------------
# Client helpers for subscriptions
# -----------------------------------------------------------------------------
def subscribe(func: Callable) -> Callable:
"""Decorator to mark a method for event bus subscription."""
@@ -45,10 +46,13 @@ def subscribe(func: Callable) -> Callable:
class EventHandler:
"""
A base class for components that subscribe to events.
Subclasses must call `self._subscribe_all_methods()` in their __init__.
"""
def __init__(self, state: Any):
self.state = state
self._subscribe_all_methods()
def __init__(self, event_bus: EventBus):
self.event_bus = event_bus
# Note: Subclasses must call self._subscribe_all_methods()
# after their own __init__ is complete.
def _subscribe_all_methods(self):
"""Finds and subscribes all methods decorated with @subscribe."""
@@ -57,5 +61,4 @@ class EventHandler:
if hasattr(method, '_event_bus_subscribe'):
# The topic is the name of the method itself.
self.state.event_bus.subscribe(method_name, method)
_LOGGER.debug(f"Subscribed method '{method_name}' to topic '{method_name}'")
self.event_bus.subscribe(method_name, method)