Closed wbreeze closed 9 years ago
Found the restore!
method and the section in the doc about persisting state with ActiveRecord.
The constructor for the class inheriting from FiniteMachine::Definition,
for example, Engine
class Engine < FiniteMachine::Definition
returns a class FiniteMachine::StateMachine
when called new
on it. The new
takes any number of arguments, and any initialize
method of the class is never called.
Here is output from the program that follows:
GSM class is FiniteMachine::StateMachine
GSM current state is red
.gems/gems/finite_machine-0.10.1/lib/finite_machine/state_machine.rb:259:in `valid_state?': inappropriate current state 'red' (FiniteMachine::InvalidStateError)
require 'finite_machine'
class GenericStateMachine < FiniteMachine::Definition
initial :red
def initialize(light)
puts "INITIALIZER WITH #{light}"
super
restore! light.state
target light
end
events {
event :start, :red => :green
event :stop, :green => :red
}
callbacks {
on_enter { |event| target.state = event.to }
}
end
class Light
attr_accessor :state
def initialize
state = 'green'
end
def to_s
"Light in state #{state}"
end
end
light = Light.new
gsm = GenericStateMachine.new(light)
puts "GSM class is #{gsm.class.to_s}"
puts "GSM current state is #{gsm.current}"
gsm.stop
puts "GSM state after stop is #{gsm.current}"
puts "Light state after stop is #{light.state}"
What works better is to make a state machine factory, that uses the DSL via FiniteMachine.define
https://en.wikipedia.org/wiki/Factory_(object-oriented_programming)
Here is output from the program that follows:
CREATING MACHINE with Light in state green
GSM class is FiniteMachine::StateMachine
GSM current state is green
GSM state after stop is red
Light state after stop is red
require 'finite_machine'
class LightMachineFactory
def self.create_machine(light)
FiniteMachine.define do
puts "CREATING MACHINE with #{light}"
initial light.state
target light
events {
event :start, :red => :green
event :stop, :green => :red
}
callbacks {
on_enter { |event| target.state = event.to }
}
end
end
end
class Light
attr_accessor :state
def initialize
@state = 'green'
end
def to_s
"Light in state #{state}"
end
def state
@state.to_sym
end
end
light = Light.new
gsm = LightMachineFactory.create_machine(light)
puts "GSM class is #{gsm.class.to_s}"
puts "GSM current state is #{gsm.current}"
gsm.stop
puts "GSM state after stop is #{gsm.current}"
puts "Light state after stop is #{light.state}"
Reposted at stackoverflow as http://stackoverflow.com/questions/31040725/peter-murach-finite-machine-restore-persisted-state
Pardon me for making this an issue. It's really a question.
I'm having trouble persisting the state. More specifically, I'd like to instantiate the state machine with the prior saved state.
All I've been able to find is the DSL that lets me define an initial state, or define an event that transitions to an initial state. Both require me to define the initial state at coding time.
In practice, I'm defining a "standalone" along the lines of,
What I'd like is to define the initial state in the initializer for that class, something like:
However that does not work. Should it? I get
:none
as the current state after initialization. Still reading the code.