Kaynağa Gözat

Added gbe.statemachine which utilizes Nodes as a 'scene'.

master
Bryan Miller 6 yıl önce
ebeveyn
işleme
b99ecc1fb4
2 değiştirilmiş dosya ile 134 ekleme ve 0 silme
  1. +1
    -0
      game/gbe/__init__.py
  2. +133
    -0
      game/gbe/statemachine.py

+ 1
- 0
game/gbe/__init__.py Dosyayı Görüntüle

@@ -9,3 +9,4 @@ from . import display
from . import events
from . import nodes
from . import resource
from . import statemachine

+ 133
- 0
game/gbe/statemachine.py Dosyayı Görüntüle

@@ -0,0 +1,133 @@

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()






Yükleniyor…
İptal
Kaydet