module Statesman::Machine::ClassMethods
Attributes
initial_state[R]
Public Instance Methods
after_guard_failure(options = {}, &block)
click to toggle source
# File lib/statesman/machine.rb, line 95 def after_guard_failure(options = {}, &block) add_callback(callback_type: :after_guard_failure, callback_class: Callback, from: options[:from], to: options[:to], &block) end
after_transition(options = { after_commit: false }, &block)
click to toggle source
# File lib/statesman/machine.rb, line 83 def after_transition(options = { after_commit: false }, &block) callback_type = options[:after_commit] ? :after_commit : :after add_callback(callback_type: callback_type, callback_class: Callback, from: options[:from], to: options[:to], &block) end
after_transition_failure(options = {}, &block)
click to toggle source
# File lib/statesman/machine.rb, line 90 def after_transition_failure(options = {}, &block) add_callback(callback_type: :after_transition_failure, callback_class: Callback, from: options[:from], to: options[:to], &block) end
before_transition(options = {}, &block)
click to toggle source
# File lib/statesman/machine.rb, line 73 def before_transition(options = {}, &block) add_callback(callback_type: :before, callback_class: Callback, from: options[:from], to: options[:to], &block) end
callbacks()
click to toggle source
# File lib/statesman/machine.rb, line 49 def callbacks @callbacks ||= { before: [], after: [], after_transition_failure: [], after_guard_failure: [], after_commit: [], guards: [], } end
guard_transition(options = {}, &block)
click to toggle source
# File lib/statesman/machine.rb, line 78 def guard_transition(options = {}, &block) add_callback(callback_type: :guards, callback_class: Guard, from: options[:from], to: options[:to], &block) end
state(name, options = { initial: false })
click to toggle source
# File lib/statesman/machine.rb, line 36 def state(name, options = { initial: false }) name = name.to_s if options[:initial] validate_initial_state(name) @initial_state = name end states << name end
states()
click to toggle source
# File lib/statesman/machine.rb, line 32 def states @states ||= [] end
successors()
click to toggle source
# File lib/statesman/machine.rb, line 45 def successors @successors ||= {} end
transition(from: nil, to: nil)
click to toggle source
# File lib/statesman/machine.rb, line 60 def transition(from: nil, to: nil) from = to_s_or_nil(from) to = array_to_s_or_nil(to) raise InvalidStateError, "No to states provided." if to.empty? successors[from] ||= [] ([from] + to).each { |state| validate_state(state) } successors[from] += to end
validate_callback_condition(options = { from: nil, to: nil })
click to toggle source
# File lib/statesman/machine.rb, line 100 def validate_callback_condition(options = { from: nil, to: nil }) from = to_s_or_nil(options[:from]) to = array_to_s_or_nil(options[:to]) ([from] + to).compact.each { |state| validate_state(state) } return if from.nil? && to.empty? validate_not_from_terminal_state(from) to.each { |state| validate_not_to_initial_state(state) } return if from.nil? || to.empty? to.each { |state| validate_from_and_to_state(from, state) } end
validate_from_and_to_state(from, to)
click to toggle source
Check that the transition is valid when 'from' and 'to' are given
# File lib/statesman/machine.rb, line 132 def validate_from_and_to_state(from, to) unless successors.fetch(from, []).include?(to) raise InvalidTransitionError, "Cannot transition from '#{from}' to '#{to}'" end end
validate_not_from_terminal_state(from)
click to toggle source
Check that the 'from' state is not terminal
# File lib/statesman/machine.rb, line 116 def validate_not_from_terminal_state(from) unless from.nil? || successors.key?(from) raise InvalidTransitionError, "Cannot transition away from terminal state '#{from}'" end end
validate_not_to_initial_state(to)
click to toggle source
Check that the 'to' state is not initial
# File lib/statesman/machine.rb, line 124 def validate_not_to_initial_state(to) unless to.nil? || successors.values.flatten.include?(to) raise InvalidTransitionError, "Cannot transition to initial state '#{to}'" end end
Private Instance Methods
add_callback(callback_type: nil, callback_class: nil, from: nil, to: nil, &block)
click to toggle source
# File lib/statesman/machine.rb, line 141 def add_callback(callback_type: nil, callback_class: nil, from: nil, to: nil, &block) validate_callback_type_and_class(callback_type, callback_class) from = to_s_or_nil(from) to = array_to_s_or_nil(to) validate_callback_condition(from: from, to: to) callbacks[callback_type] << callback_class.new(from: from, to: to, callback: block) end
array_to_s_or_nil(input)
click to toggle source
# File lib/statesman/machine.rb, line 176 def array_to_s_or_nil(input) Array(input).map { |item| to_s_or_nil(item) } end
to_s_or_nil(input)
click to toggle source
# File lib/statesman/machine.rb, line 172 def to_s_or_nil(input) input.nil? ? input : input.to_s end
validate_callback_type_and_class(callback_type, callback_class)
click to toggle source
# File lib/statesman/machine.rb, line 154 def validate_callback_type_and_class(callback_type, callback_class) raise ArgumentError, "missing keyword: callback_type" if callback_type.nil? raise ArgumentError, "missing keyword: callback_class" if callback_class.nil? end
validate_initial_state(state)
click to toggle source
# File lib/statesman/machine.rb, line 165 def validate_initial_state(state) unless initial_state.nil? raise InvalidStateError, "Cannot set initial state to '#{state}', " \ "already defined as #{initial_state}." end end
validate_state(state)
click to toggle source
# File lib/statesman/machine.rb, line 159 def validate_state(state) unless states.include?(state.to_s) raise InvalidStateError, "Invalid state '#{state}'" end end