# Copyright (C) 2018 Avatao.com Innovative Learning Kft. # All Rights Reserved. See LICENSE file for details. from abc import ABC, abstractmethod from tfw.networking import deserialize_tfw_msg from tfw.networking.event_handlers import ServerConnector class EventHandlerBase(ABC): """ Abstract base class for all Python based EventHandlers. Useful implementation template for other languages. Derived classes must implement the handle_event() method """ def __init__(self, key): self.server_connector = ServerConnector() self.key = key self.subscriptions = set() self.subscribe(self.key) self.subscribe('reset') self.server_connector.register_callback(self.event_handler_callback) def event_handler_callback(self, msg_parts): message = deserialize_tfw_msg(*msg_parts) response = self.dispatch_handling(message) response['key'] = message['key'] if response is None: return self.server_connector.send(response) def dispatch_handling(self, message): if message['key'] != 'reset': return self.handle_event(message) return self.handle_reset(message) @abstractmethod def handle_event(self, message): raise NotImplementedError def handle_reset(self, message): # pylint: disable=unused-argument,no-self-use return None def cleanup(self): pass def subscribe(self, key): if key not in self.subscriptions: self.subscriptions.add(key) self.server_connector.subscribe(key) def unsubscribe(self, key): try: self.subscriptions.remove(key) self.server_connector.unsubscribe(key) except KeyError: pass def unsubscribe_all(self): for sub in self.subscriptions: self.server_connector.unsubscribe(key=sub) self.subscriptions.clear() class TriggeredEventHandler(EventHandlerBase, ABC): # pylint: disable=abstract-method """ Abstract base class for EventHandlers which are only triggered in case TFWServer has successfully triggered an FSM step defined in __init__. """ def __init__(self, key, trigger): super().__init__(key) self.trigger = trigger def dispatch_handling(self, message): if message.get('trigger') == self.trigger: return super().dispatch_handling(message) return None