|
-
- from .events import Events
- from .nodes import Node
- from .time import Time
- from .display import Display
-
- class StateMachineError(Exception):
- pass
-
-
- # This is the main, active state (Node).
- _ACTIVE_STATE = None
-
- # In some cases, the previous state isn't totally shut down, but temporarily put on hold.
- # Only the _render() call will be made on hold states.
- _HOLD_STATE = None
-
- # List of all states registered into the State Manager.
- _STATE_LIST = []
-
- _TIME = Time()
-
-
- class StateMachine:
- def __init__(self):
- pass
-
- def has_node(self, name):
- """
- Returns true if a Node with the given name has been registered in the State List.
- NOTE: This is only going to check the root Node's name, not any other node in the node tree.
- """
- global _STATE_LIST
- for n in _STATE_LIST:
- if n.name == name:
- return True
- return False
-
- def register_node(self, node):
- """
-
- """
- if not isinstance(node, Node):
- raise TypeError("Expected a Node instance.")
- # Check if given the root Node. If not, get the root Node.
- if node.parent != None:
- node = node.root
- if self.has_node(node.name):
- raise StateMachineError("State machine already registered node named '{}'. Names must be unique.".format(node.name))
- global _STATE_LIST
- _STATE_LIST.append(node)
-
- def activate_node(self, name, hold_previous=False):
- """
-
- """
- global _ACTIVE_STATE, _TIME
- if self.has_node(name):
- if _ACTIVE_STATE is not None:
- if _ACTIVE_STATE.name == name:
- return
- self._releaseActive(hold_previous)
- self._setActive(name)
- if _ACTIVE_STATE is not None:
- _TIME.reset()
-
-
- def _relaseActive(self, hold_previous):
- global _ACTIVE_STATE, _HOLD_STATE
- a = _ACTIVE_STATE
- a._pause()
- if _HOLD_STATE is not None:
- _ACTIVE_STATE = _HOLD_STATE
- _HOLD_STATE = None
- _ACTIVE_STATE._start()
- else:
- _ACTIVE_STATE = None
-
- if hold_previous == True:
- _HOLD_STATE = a
- else:
- a._close()
-
- def _setActive(self, name):
- global _ACTIVE_STATE, _STATE_LIST
- for n in _STATE_LIST:
- if n.name == name:
- _ACTIVE_STATE = n
- break
- if _ACTIVE_STATE is not None:
- _ACTIVE_STATE._init()
- _ACTIVE_STATE._start()
- elif _HOLD_STATE is not None:
- # If we failed to find an Active state, then we need to drop any hold state as well...
- # Keep things as clean as possible
- _HOLD_STATE._close()
- _HOLD_STATE = None
-
- def close(self):
- global _ACTIVE_STATE, _HOLD_STATE, _STATE_LIST
- if _HOLD_STATE is not None:
- _HOLD_STATE._close()
- _HOLD_STATE = None
- if _ACTIVE_STATE is not None:
- _ACTIVE_STATE._pause()
- _ACTIVE_STATE._close()
- _ACTIVE_STATE = None
- _STATE_LIST = []
-
- def update(self):
- global _ACTIVE_STATE, _TIME
- if _ACTIVE_STATE is not None:
- _ACTIVE_STATE._update(_TIME.delta)
-
- def render(self):
- global _ACTIVE_STATE, _HOLD_STATE
- dsurf = Display.surface
- if dsurf is not None:
- Display.clear()
-
- # If there's a hold state, render that first.
- if _HOLD_STATE is not None:
- _HOLD_STATE._render(dsurf)
- # Render the active state next so it overdraws the hold state.
- if _ACTIVE_STATE is not None:
- _ACTIVE_STATE._render(dsurf)
-
- Display.flip()
-
-
-
-
|