Update event_bus.py
The EventHandler base class was modified to support the new decoupled __init__ pattern.
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
"""A simple synchronous publish/subscribe event bus."""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from typing import Any, Callable, Dict, List, Optional
|
from typing import Any, Callable, Dict, List, Optional
|
||||||
|
|
||||||
@@ -8,34 +10,33 @@ class EventBus:
|
|||||||
"""A simple synchronous publish/subscribe event bus."""
|
"""A simple synchronous publish/subscribe event bus."""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
# A dictionary to hold listeners for specific string topics
|
|
||||||
self.topics: Dict[str, List[Callable[[Any], None]]] = {}
|
self.topics: Dict[str, List[Callable[[Any], None]]] = {}
|
||||||
|
|
||||||
def subscribe(self, topic: str, listener: Callable[[Any], None]) -> 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:
|
if topic not in self.topics:
|
||||||
self.topics[topic] = []
|
self.topics[topic] = []
|
||||||
self.topics[topic].append(listener)
|
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:
|
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:
|
if data is None:
|
||||||
data = {}
|
data = {}
|
||||||
|
|
||||||
data['__topic'] = topic
|
data['__topic'] = topic
|
||||||
|
|
||||||
listeners = self.topics.get(topic, [])
|
listeners = self.topics.get(topic, [])
|
||||||
|
_LOGGER.debug(f"Publishing event to {len(listeners)} listeners on topic '{topic}'")
|
||||||
for listener in listeners:
|
for listener in listeners:
|
||||||
try:
|
try:
|
||||||
listener(data)
|
listener(data)
|
||||||
except Exception:
|
except Exception:
|
||||||
_LOGGER.exception("Error in event listener for topic %s", topic)
|
_LOGGER.exception("Error in event listener for topic %s", topic)
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
# Client helpers for subscriptions
|
# Client helpers for subscriptions
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
def subscribe(func: Callable) -> Callable:
|
def subscribe(func: Callable) -> Callable:
|
||||||
"""Decorator to mark a method for event bus subscription."""
|
"""Decorator to mark a method for event bus subscription."""
|
||||||
@@ -45,10 +46,13 @@ def subscribe(func: Callable) -> Callable:
|
|||||||
class EventHandler:
|
class EventHandler:
|
||||||
"""
|
"""
|
||||||
A base class for components that subscribe to events.
|
A base class for components that subscribe to events.
|
||||||
|
|
||||||
|
Subclasses must call `self._subscribe_all_methods()` in their __init__.
|
||||||
"""
|
"""
|
||||||
def __init__(self, state: Any):
|
def __init__(self, event_bus: EventBus):
|
||||||
self.state = state
|
self.event_bus = event_bus
|
||||||
self._subscribe_all_methods()
|
# Note: Subclasses must call self._subscribe_all_methods()
|
||||||
|
# after their own __init__ is complete.
|
||||||
|
|
||||||
def _subscribe_all_methods(self):
|
def _subscribe_all_methods(self):
|
||||||
"""Finds and subscribes all methods decorated with @subscribe."""
|
"""Finds and subscribes all methods decorated with @subscribe."""
|
||||||
@@ -57,5 +61,4 @@ class EventHandler:
|
|||||||
|
|
||||||
if hasattr(method, '_event_bus_subscribe'):
|
if hasattr(method, '_event_bus_subscribe'):
|
||||||
# The topic is the name of the method itself.
|
# The topic is the name of the method itself.
|
||||||
self.state.event_bus.subscribe(method_name, method)
|
self.event_bus.subscribe(method_name, method)
|
||||||
_LOGGER.debug(f"Subscribed method '{method_name}' to topic '{method_name}'")
|
|
||||||
|
|||||||
Reference in New Issue
Block a user