McRogueFace/games/unwritten/core/inputstack.py

46 lines
1.4 KiB
Python
Raw Normal View History

"""UNWRITTEN - modal input dispatch. Owner: Agent A.
One InputStack per scene owns scene.on_key and dispatches to a stack of
handlers, top-most first. A handler is fn(key, state) -> bool; returning True
consumes the event (lower handlers do not see it). Overworld pushes its
movement handler; a DialogueBox / menu pushes itself while open and pops on
close, freezing everything beneath it.
"""
class InputStack:
def __init__(self, scene):
self.scene = scene
self.stack = [] # list of (name, handler)
scene.on_key = self._dispatch
def push(self, handler, name=""):
self.stack.append((name, handler))
def pop(self, name=""):
"""Pop the top handler, or the top-most handler matching name."""
if name:
for i in range(len(self.stack) - 1, -1, -1):
if self.stack[i][0] == name:
return self.stack.pop(i)
return None
if self.stack:
return self.stack.pop()
return None
def replace(self, handler, name=""):
"""Replace the top handler with a new one."""
self.pop()
self.push(handler, name)
def clear(self):
self.stack = []
def has(self, name):
return any(n == name for n, _ in self.stack)
def _dispatch(self, key, state):
for i in range(len(self.stack) - 1, -1, -1):
handler = self.stack[i][1]
if handler(key, state):
return