# 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.subscribe(self.key, 'reset') self.server_connector.register_callback(self.event_handler_callback) def event_handler_callback(self, msg_parts): """ Callback that is invoked when receiving a message. Dispatches messages to handler methods and sends a response back in case the handler returned something. This is subscribed in __init__(). """ message = deserialize_tfw_msg(*msg_parts) response = self.dispatch_handling(message) if response: response['key'] = message['key'] self.server_connector.send(response) def dispatch_handling(self, message): """ Used to dispatch messages to their specific handlers. """ if message['key'] != 'reset': return self.handle_event(message) return self.handle_reset(message) @abstractmethod def handle_event(self, message): """ Abstract method that implements the handling of messages. :param message: the message received """ raise NotImplementedError def handle_reset(self, message): # pylint: disable=unused-argument,no-self-use """ Usually 'reset' events receive some sort of special treatment. :param message: the message received """ return None def subscribe(self, *keys): """ Subscribe this EventHandler to receive events for given keys. Note that you can subscribe to the same key several times in which case you will need to unsubscribe multiple times in order to stop receiving events. :param keys: list of keys to subscribe to """ for key in keys: self.server_connector.subscribe(key) def unsubscribe(self, *keys): """ Unsubscribe this eventhandler from the given keys. :param keys: list of keys to unsubscribe from """ for key in keys: self.server_connector.unsubscribe(key) def cleanup(self): """ Perform cleanup actions such as releasing database connections and stuff like that. """ pass 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