[statemachine] properly prevent transition when clearing error
This commit is contained in:
parent
59576e76d8
commit
1c0dc582bd
|
@ -51,7 +51,9 @@ proc schedule*(machine: Machine, event: Event) =
|
|||
proc checkTransitions(machine: Machine) =
|
||||
for transition in machine.transitions:
|
||||
if transition.trigger(machine, machine.state) and
|
||||
(machine.state == nil or machine.state == transition.prevState or transition.prevState of AnyState):
|
||||
(machine.state == nil or
|
||||
machine.state == transition.prevState or
|
||||
transition.prevState of AnyState):
|
||||
machine.schedule(Event.transition(machine.state, transition.nextState))
|
||||
|
||||
proc setValue*[T](prop: TransitionProperty[T], value: T) =
|
||||
|
@ -74,7 +76,7 @@ proc scheduler(machine: Machine) {.async.} =
|
|||
if fut.failed():
|
||||
try:
|
||||
machine.errored.setValue(true) # triggers transitions
|
||||
machine.errored.setValue(false) # clears error without triggering transitions
|
||||
machine.errored.value = false # clears error without triggering transitions
|
||||
machine.lastError = fut.error # stores error in state
|
||||
except AsyncQueueFullError as e:
|
||||
error "Cannot set transition value because queue is full", error = e
|
||||
|
|
|
@ -167,8 +167,7 @@ suite "async state machines":
|
|||
|
||||
test "checks declarative transitions after current state finishes running":
|
||||
machine.start(state4)
|
||||
machine.slotsFilled.setValue(2) # on wrong starting state, so stays on state4
|
||||
await sleepAsync(1.millis)
|
||||
machine.slotsFilled.setValue(2) # no trigger conditions met yet
|
||||
# manually move to State3, where the trigger and the previous state will
|
||||
# be checked
|
||||
machine.schedule(Event.transition(state4, state3))
|
||||
|
@ -182,3 +181,28 @@ suite "async state machines":
|
|||
check eventually machine.state of State5
|
||||
check not machine.errored.value # errored state has been cleared
|
||||
check machine.lastError.msg == "some error"
|
||||
|
||||
test "schedules transitions in order of declaration":
|
||||
var checked = false
|
||||
machine = MyMachine.new(@[
|
||||
Transition.new(
|
||||
state3,
|
||||
state4,
|
||||
proc(m: Machine, s: State): bool =
|
||||
MyMachine(m).slotsFilled.value == 2
|
||||
),
|
||||
Transition.new(
|
||||
state3,
|
||||
state5,
|
||||
proc(m: Machine, s: State): bool =
|
||||
checked = true
|
||||
MyMachine(m).slotsFilled.value == 2
|
||||
)]
|
||||
)
|
||||
machine.slotsFilled = machine.newTransitionProperty(0)
|
||||
machine.start(state3)
|
||||
machine.slotsFilled.setValue(2)
|
||||
check eventually runs == [0, 0, 1, 1, 0]
|
||||
check machine.state of State4
|
||||
check checked
|
||||
#3->5 transition was checked but not run because state had already moved to 4
|
||||
|
|
Loading…
Reference in New Issue