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