Added listen_once to eventbus

This commit is contained in:
Paulus Schoutsen 2013-10-24 00:29:33 +01:00
parent 42c7f33567
commit 00c9d22a58
2 changed files with 26 additions and 5 deletions

View File

@ -10,7 +10,6 @@ import time
import logging
import threading
from collections import defaultdict, namedtuple
from itertools import chain
from datetime import datetime
logging.basicConfig(level=logging.INFO)
@ -122,8 +121,10 @@ class EventBus(object):
""" Fire listeners for event. """
event = Event(self, event_type, event_data)
for listener in chain(self.listeners[ALL_EVENTS],
self.listeners[event.event_type]):
# We do not use itertools.chain() because some listeners might
# choose to remove themselves as a listener while being executed
for listener in self.listeners[ALL_EVENTS] + \
self.listeners[event.event_type]:
try:
listener(event)
@ -141,10 +142,29 @@ class EventBus(object):
"""
self.listeners[event_type].append(listener)
def listen_once(self, event_type, listener):
""" Listen once for event of a specific type.
To listen to all events specify the constant ``ALL_EVENTS``
as event_type.
"""
def onetime_listener(event):
""" Removes listener from eventbus and then fires listener. """
self.remove_listener(event_type, onetime_listener)
listener(event)
self.listen(event_type, onetime_listener)
def remove_listener(self, event_type, listener):
""" Removes a listener of a specific event_type. """
try:
self.listeners[event_type].remove(listener)
if len(self.listeners[event_type]) == 0:
del self.listeners[event_type]
except ValueError:
pass
@ -213,7 +233,7 @@ class Timer(threading.Thread):
self.daemon = True
self.eventbus = eventbus
eventbus.listen(EVENT_START, lambda event: self.start())
eventbus.listen_once(EVENT_START, lambda event: self.start())
def run(self):
""" Start the timer. """

View File

@ -65,7 +65,8 @@ class HTTPInterface(threading.Thread):
self.server.statemachine = statemachine
self.server.api_password = api_password
eventbus.listen(homeassistant.EVENT_START, lambda event: self.start())
eventbus.listen_once(homeassistant.EVENT_START,
lambda event: self.start())
def run(self):
""" Start the HTTP interface. """