Source code for statechart.runtime

# -*- coding: utf-8 -*-
#
# Copyright (c) 2016, Leigh McKenzie
# All rights reserved.
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

import logging


[docs]class StateRuntimeData: """ Holds the runtime specific data for a state in the statechart. """ def __init__(self): self._logger = logging.getLogger(self.__class__.__name__) self.current_state = None self.state_set = list()
[docs]class Metadata: """ Describes runtime specific data of the statechart. The main data is the currently active state. For every active state a StateRuntimeData object is created which stores specific data for the state. This object is allocated only when the state is active, otherwise it is deleted. """ def __init__(self): self._logger = logging.getLogger(self.__class__.__name__) self.active_states = {} self.event = None self.transition = None self._history_states = {}
[docs] def activate(self, state): """ Activates a state for this Metadata. If the state is not already active, it will be added and a new StateRuntimeData created. Args: state (State): State to activate. """ if not (state in self.active_states): self.active_states[state] = StateRuntimeData() data = self.active_states[state] data.current_state = None if state.context: if state.context not in self.active_states: raise RuntimeError('Parent state not activated') data = self.active_states[state.context] data.current_state = state
[docs] def deactivate(self, state): """ Deactivates the state and frees the allocated resources. Args: state (State): State to dactivate. """ if state in self.active_states: data = self.active_states[state] data.current_state = None data = None del self.active_states[state]
[docs] def get_history_state(self, history_state): """ Get the last active state when the history state context was deactivated. Args: history_state (HistoryState): History state to lookup Returns: The most recent state remembered by the specified history state. """ return self._history_states[history_state]
[docs] def has_history_info(self, history_state): """ Check if the active state runtime has history info to restore. Args: history_state (HistoryState): History state to lookup. Returns: True if the history state has info of a state to be restored. """ status = False if history_state in self._history_states: status = True return status
[docs] def is_active(self, state): """ Checks whether the given state is active or not. Args: state (State): State to check. Returns: True if the state is active. """ status = False if state in self.active_states: status = True return status
[docs] def reset(self): """Resets the metadata object for reuse.""" self.active_states.clear() self._history_states.clear()
[docs] def store_history_info(self, history_state, actual_state): """" Store history for history state when leaving context. Args: history_state (HistoryState): History state to store. When this state's context is reactivated, the history state can be restored in order to recall the actual state to recall. actual_state: (State): State to recall. """ self._history_states[history_state] = actual_state