class DataMapper::Is::StateMachine::Data::Machine

This Machine class represents one state machine.

A model (i.e. a DataMapper resource) can have more than one Machine.

Attributes

column[RW]

The property of the DM resource that will hold this Machine’s state.

TODO: change :column to :property

current_state_name[RW]

The current value of this Machine’s state

This is the “primary control” of this Machine’s state. All other methods key off the value of @current_state_name.

events[RW]
initial[RW]

The initial value of this Machine’s state

states[RW]

Public Class Methods

new(column, initial) click to toggle source
# File lib/dm-is-state_machine/is/data/machine.rb, line 30
def initialize(column, initial)
  @column, @initial   = column, initial
  @events, @states    = [], []
  @current_state_name = initial
end

Public Instance Methods

current_state() click to toggle source

Return the current state

@api public

# File lib/dm-is-state_machine/is/data/machine.rb, line 64
def current_state
  find_state(@current_state_name)
  # TODO: add caching, i.e. with `@current_state ||= ...`
end
find_event(event_name) click to toggle source

Find event whose name is event_name

@api semipublic

# File lib/dm-is-state_machine/is/data/machine.rb, line 72
def find_event(event_name)
  @events.find { |event| event.name.to_s == event_name.to_s }
  # TODO: use a data structure that prevents duplicates
end
find_state(state_name) click to toggle source

Find state whose name is event_name

@api semipublic

# File lib/dm-is-state_machine/is/data/machine.rb, line 80
def find_state(state_name)
  @states.find { |state| state.name.to_s == state_name.to_s }
  # TODO: use a data structure that prevents duplicates
end
fire_event(event_name, resource) click to toggle source

Fire (activate) the event with name event_name

@api public

# File lib/dm-is-state_machine/is/data/machine.rb, line 39
def fire_event(event_name, resource)
  unless event = find_event(event_name)
    raise InvalidEvent, "Could not find event (#{event_name.inspect})"
  end
  transition = event.transitions.find do |t|
     t[:from].to_s == @current_state_name.to_s
  end
  unless transition
    raise InvalidEvent, "Event (#{event_name.inspect}) does not" +
    "exist for current state (#{@current_state_name.inspect})"
  end

  # == Run :exit hook (if present) ==
  resource.run_hook_if_present current_state.options[:exit]

  # == Change the current_state ==
  @current_state_name = transition[:to]

  # == Run :enter hook (if present) ==
  resource.run_hook_if_present current_state.options[:enter]
end