Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Persistence #38

Closed
wbreeze opened this issue Jun 19, 2015 · 3 comments
Closed

Persistence #38

wbreeze opened this issue Jun 19, 2015 · 3 comments

Comments

@wbreeze
Copy link

wbreeze commented Jun 19, 2015

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.

fm = FiniteMachine.define do
  initial :red
fm = FiniteMachine.define do
  events {
    event :start, :none   => :green

In practice, I'm defining a "standalone" along the lines of,

class Engine < FiniteMachine::Definition
  initial :neutral

What I'd like is to define the initial state in the initializer for that class, something like:

class Engine < FiniteMachine::Definition
     def initialize(car, state)
       initial state
       target car
     end

However that does not work. Should it? I get :none as the current state after initialization. Still reading the code.

@wbreeze
Copy link
Author

wbreeze commented Jun 23, 2015

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}"

@wbreeze wbreeze changed the title Persistance Persistence Jun 23, 2015
@wbreeze
Copy link
Author

wbreeze commented Jun 24, 2015

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}"

@wbreeze
Copy link
Author

wbreeze commented Jun 25, 2015

@wbreeze wbreeze closed this as completed Jun 25, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant