Module: Statesman::Machine::ClassMethods

Defined in:
lib/statesman/machine.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#initial_stateObject (readonly)

Returns the value of attribute initial_state.



29
30
31
# File 'lib/statesman/machine.rb', line 29

def initial_state
  @initial_state
end

Instance Method Details

#after_transition(options = { from: nil, to: nil, after_commit: false }, &block) ⇒ Object



96
97
98
99
100
101
102
103
# File 'lib/statesman/machine.rb', line 96

def after_transition(options = { from: nil, to: nil,
                                 after_commit: false }, &block)
  callback_type = options[:after_commit] ? :after_commit : :after

  add_callback(
    options.merge(callback_class: Callback, callback_type: callback_type),
    &block)
end

#before_transition(options = { from: nil, to: nil }, &block) ⇒ Object



84
85
86
87
88
# File 'lib/statesman/machine.rb', line 84

def before_transition(options = { from: nil, to: nil }, &block)
  add_callback(
    options.merge(callback_class: Callback, callback_type: :before),
    &block)
end

#callbacksObject



56
57
58
59
60
61
62
63
# File 'lib/statesman/machine.rb', line 56

def callbacks
  @callbacks ||= {
    before:       [],
    after:        [],
    after_commit: [],
    guards:       []
  }
end

#event(name, &block) ⇒ Object



48
49
50
# File 'lib/statesman/machine.rb', line 48

def event(name, &block)
  EventTransitions.new(self, name, &block)
end

#eventsObject



35
36
37
# File 'lib/statesman/machine.rb', line 35

def events
  @events ||= {}
end

#guard_transition(options = { from: nil, to: nil }, &block) ⇒ Object



90
91
92
93
94
# File 'lib/statesman/machine.rb', line 90

def guard_transition(options = { from: nil, to: nil }, &block)
  add_callback(
    options.merge(callback_class: Guard, callback_type: :guards),
    &block)
end

#state(name, options = { initial: false }) ⇒ Object



39
40
41
42
43
44
45
46
# File 'lib/statesman/machine.rb', line 39

def state(name, options = { initial: false })
  name = name.to_s
  if options[:initial]
    validate_initial_state(name)
    @initial_state = name
  end
  states << name
end

#statesObject



31
32
33
# File 'lib/statesman/machine.rb', line 31

def states
  @states ||= []
end

#successorsObject



52
53
54
# File 'lib/statesman/machine.rb', line 52

def successors
  @successors ||= {}
end

#transition(options = { from: nil, to: nil }, event = nil) ⇒ Object

Raises:



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/statesman/machine.rb', line 65

def transition(options = { from: nil, to: nil }, event = nil)
  from = to_s_or_nil(options[:from])
  to = array_to_s_or_nil(options[:to])

  raise InvalidStateError, "No to states provided." if to.empty?

  successors[from] ||= []

  ([from] + to).each { |state| validate_state(state) }

  successors[from] += to

  if event
    events[event] ||= {}
    events[event][from] ||= []
    events[event][from]  += to
  end
end

#validate_callback_condition(options = { from: nil, to: nil }) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/statesman/machine.rb', line 105

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) ⇒ Object

Check that the transition is valid when ‘from’ and ‘to’ are given



137
138
139
140
141
142
# File 'lib/statesman/machine.rb', line 137

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) ⇒ Object

Check that the ‘from’ state is not terminal



121
122
123
124
125
126
# File 'lib/statesman/machine.rb', line 121

def validate_not_from_terminal_state(from)
  unless from.nil? || successors.keys.include?(from)
    raise InvalidTransitionError,
          "Cannot transition away from terminal state '#{from}'"
  end
end

#validate_not_to_initial_state(to) ⇒ Object

Check that the ‘to’ state is not initial



129
130
131
132
133
134
# File 'lib/statesman/machine.rb', line 129

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