Source code for Karana.KUtils.MultibodyTUI.history
"""Contains StateHistroy. A class for keeping track of the TUI state history."""
from typing import TypeVar, Generic
State = TypeVar("State")
[docs]
class StateHistory(Generic[State]):
"""Container for a state object with undo and redo capabilities."""
def __init__(self, init_state: State):
"""Create an instance of StateHistory.
Parameters
----------
init_state: State
The initial state
"""
self._stack = [init_state]
self._redo_stack = []
@property
def state(self) -> State:
"""The current state."""
return self._stack[-1]
@state.setter
def state(self, state: State):
"""Set a new state."""
self.push(state)
[docs]
def push(self, state: State):
"""Set a new state."""
if state == self.state:
return state
self._stack.append(state)
if self._redo_stack:
self._redo_stack = []
@property
def current_state_count(self) -> int:
"""The number of states in the undo stack.
Note that this includes the current state and is always
positive.
"""
return len(self._stack)
@property
def total_state_count(self) -> int:
"""The number of states - past, present, and future.
This is similar to past_state_count but also includes states in
the redo stack.
"""
return len(self._stack) + len(self._redo_stack)
[docs]
def undoStackSize(self) -> int:
"""Return the number of states in the undo stack.
Note that this includes the current state and is always positive
"""
return len(self._stack)
[docs]
def canUndo(self) -> bool:
"""Return whether an undo state is available."""
return len(self._stack) > 1
[docs]
def undo(self):
"""Return to the previous state."""
if not self.canUndo():
return
self._redo_stack.append(self._stack.pop())
[docs]
def canRedo(self) -> bool:
"""Return whether a redo state is available."""
return bool(self._redo_stack)
[docs]
def redo(self):
"""Return to the next state (i.e., undo a previous undo)."""
if not self.canRedo():
return
self._stack.append(self._redo_stack.pop())