Replies: 2 comments
-
Hello @pmi123, you could implement a state history as discussed here and add an from transitions import Machine
import collections
class Model(object):
def __init__(self, history_length):
self.state_history = collections.deque(maxlen=history_length)
@property
def state(self):
return self.state_history[-1]
@state.setter
def state(self, value):
self.state_history.append(value)
def undo(self):
if len(self.state_history) > 1:
# let's assume history is [A, B, C].
# Thus, current state is C and previous state is B.
# Move to previous state B (second last)
self.trigger(f"to_{self.state_history[-2]}")
# The history is now [A, B, C, B].
# Clear history by removing the last two elements.
self.state_history.pop()
self.state_history.pop()
model = Model(5)
machine = Machine(model, states=["A", "B", "C"], ordered_transitions=True, initial="A")
model.next_state() # -> B [A, B]
model.next_state() # -> C [A, B, C]
assert model.is_C()
model.next_state() # -> A [A, B, C, A]
assert model.is_A()
model.undo() # C <- [A, B, C]
model.undo() # B <- [A, B]
assert model.is_B()
model.undo() # A <- [A]
model.undo() # no state change [A]
model.undo() # no state change [A]
assert model.is_A() |
Beta Was this translation helpful? Give feedback.
0 replies
-
Another version that also features redo (with a mode flag): from transitions import Machine
import collections
import enum
class StateMode(enum.Enum):
DEFAULT = 0
UNDO = 1
REDO = 2
class Model(object):
def __init__(self, history_length):
self.state_undo = collections.deque(maxlen=history_length)
self.state_redo = collections.deque(maxlen=history_length)
self.state_mode = StateMode.DEFAULT
@property
def state(self):
return self.state_undo[-1]
@state.setter
def state(self, value):
if self.state_mode == StateMode.UNDO:
self.state_redo.append(self.state_undo.pop())
else:
self.state_undo.append(value)
if self.state_redo and self.state_mode == StateMode.DEFAULT:
self.state_redo.clear()
def undo(self):
if len(self.state_undo) > 1:
self.state_mode = StateMode.UNDO
self.trigger(f"to_{self.state_undo[-1]}")
self.state_mode = StateMode.DEFAULT
return True
return False
def redo(self):
if self.state_redo:
self.state_mode = StateMode.REDO
self.trigger(f"to_{self.state_redo.pop()}")
self.state_mode = StateMode.DEFAULT
return True
return False
model = Model(history_length=5)
machine = Machine(model, states=["A", "B", "C"], ordered_transitions=True, initial="A")
assert model.next_state() # -> B [A, B]
assert model.next_state() # -> C [A, B, C]
assert model.is_C()
assert model.next_state() # -> A [A, B, C, A]
assert model.is_A()
assert model.undo() # C <- [A, B, C]
assert model.undo() # B <- [A, B]
assert model.is_B()
assert model.undo() # A <- [A]
assert not model.undo() # no state change [A]
assert not model.undo() # no state change [A]
assert model.is_A()
assert model.redo()
assert model.redo()
assert model.is_C()
assert model.redo()
assert not model.redo()
assert model.undo()
assert model.is_C()
assert model.to_B()
assert not model.redo()
assert model.undo()
assert model.is_C()
# history is limited to history_length=5 states
# also works with previous version
assert model.next_state()
assert model.next_state()
assert model.next_state()
assert model.next_state()
assert model.next_state()
assert model.next_state()
assert model.next_state()
assert model.next_state()
assert model.next_state()
assert model.undo()
assert model.undo()
assert model.undo()
assert model.undo()
assert not model.undo() |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
I need a transition to take me back to the previous state. Is there such a thing? My use case.
I have a web site with a dashboard (set of buttons in an html snippet) on every page. Each page represents a state in the FSM. However, when I click on a button on the dashboard, it takes me to a new state, test_1, with an associated page test_1.html. I want to have a button on the test_1.html called 'exit', which takes me back to whichever state I came from to get to state test_1.
Thanks!
Beta Was this translation helpful? Give feedback.
All reactions