class StateJacket::StateMachine

Attributes

state[R]
transition_system[R]
triggers[R]

Public Class Methods

new(transition_system, state:) click to toggle source
# File lib/state_jacket/state_machine.rb, line 5
def initialize(transition_system, state:)
  transition_system.lock
  raise ArgumentError.new("illegal state") unless transition_system.is_state?(state)
  @transition_system = transition_system
  @state = state.to_s
  @triggers = {}
end

Public Instance Methods

can_trigger?(event) click to toggle source
# File lib/state_jacket/state_machine.rb, line 60
def can_trigger?(event)
  return false unless is_locked?
  !!transition_for(event)
end
events() click to toggle source
# File lib/state_jacket/state_machine.rb, line 17
def events
  triggers.keys
end
is_event?(event) click to toggle source
# File lib/state_jacket/state_machine.rb, line 56
def is_event?(event)
  triggers.has_key? event.to_s
end
is_locked?() click to toggle source
# File lib/state_jacket/state_machine.rb, line 52
def is_locked?
  !!@locked
end
lock() click to toggle source
# File lib/state_jacket/state_machine.rb, line 44
def lock
  return true if is_locked?
  triggers.freeze
  triggers.values.map(&:freeze)
  triggers.values.freeze
  @locked = true
end
on(event, transitions={}) click to toggle source
# File lib/state_jacket/state_machine.rb, line 21
def on(event, transitions={})
  raise "events cannot be added after locking" if is_locked?
  raise ArgumentError.new("event has already been added") if is_event?(event)
  transitions.each do |from, to|
    raise ArgumentError.new("illegal transition") unless transition_system.can_transition?(from => to)
    triggers[event.to_s] ||= []
    triggers[event.to_s] << { from.to_s => to.to_s }
    triggers[event.to_s].uniq!
  end
end
to_h() click to toggle source
# File lib/state_jacket/state_machine.rb, line 13
def to_h
  triggers.dup
end
trigger(event) { |from, to| ... } click to toggle source
# File lib/state_jacket/state_machine.rb, line 32
def trigger(event)
  raise "must be locked before triggering events" unless is_locked?
  raise ArgumentError.new("event not defined") unless is_event?(event)
  transition = transition_for(event)
  return nil unless transition
  from = @state
  to = transition.values.first
  raise "current state doesn't match transition state" unless from == transition.keys.first
  yield from, to if block_given?
  @state = to
end

Private Instance Methods

transition_for(event) click to toggle source
# File lib/state_jacket/state_machine.rb, line 69
def transition_for(event)
  triggers[event.to_s].find { |entry| entry.keys.first == state }
end