finite_machine 0.11.2 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +80 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +679 -624
  5. data/lib/finite_machine.rb +35 -45
  6. data/lib/finite_machine/async_call.rb +5 -21
  7. data/lib/finite_machine/callable.rb +4 -4
  8. data/lib/finite_machine/catchable.rb +24 -14
  9. data/lib/finite_machine/choice_merger.rb +20 -20
  10. data/lib/finite_machine/const.rb +16 -0
  11. data/lib/finite_machine/definition.rb +3 -3
  12. data/lib/finite_machine/dsl.rb +98 -151
  13. data/lib/finite_machine/env.rb +4 -2
  14. data/lib/finite_machine/event_definition.rb +7 -15
  15. data/lib/finite_machine/{events_chain.rb → events_map.rb} +40 -53
  16. data/lib/finite_machine/hook_event.rb +60 -61
  17. data/lib/finite_machine/hooks.rb +44 -36
  18. data/lib/finite_machine/listener.rb +2 -2
  19. data/lib/finite_machine/logger.rb +5 -4
  20. data/lib/finite_machine/{event_queue.rb → message_queue.rb} +76 -32
  21. data/lib/finite_machine/observer.rb +71 -34
  22. data/lib/finite_machine/safety.rb +16 -14
  23. data/lib/finite_machine/state_definition.rb +3 -5
  24. data/lib/finite_machine/state_machine.rb +93 -76
  25. data/lib/finite_machine/state_parser.rb +55 -83
  26. data/lib/finite_machine/subscribers.rb +2 -2
  27. data/lib/finite_machine/threadable.rb +3 -1
  28. data/lib/finite_machine/transition.rb +34 -34
  29. data/lib/finite_machine/transition_builder.rb +23 -32
  30. data/lib/finite_machine/transition_event.rb +12 -11
  31. data/lib/finite_machine/two_phase_lock.rb +8 -6
  32. data/lib/finite_machine/undefined_transition.rb +5 -6
  33. data/lib/finite_machine/version.rb +2 -2
  34. metadata +58 -142
  35. data/.gitignore +0 -18
  36. data/.rspec +0 -5
  37. data/.ruby-gemset +0 -1
  38. data/.ruby-version +0 -1
  39. data/.travis.yml +0 -26
  40. data/Gemfile +0 -15
  41. data/Rakefile +0 -8
  42. data/assets/finite_machine_logo.png +0 -0
  43. data/examples/atm.rb +0 -45
  44. data/examples/bug_system.rb +0 -145
  45. data/finite_machine.gemspec +0 -23
  46. data/lib/finite_machine/async_proxy.rb +0 -30
  47. data/spec/integration/system_spec.rb +0 -95
  48. data/spec/spec_helper.rb +0 -33
  49. data/spec/unit/alias_target_spec.rb +0 -108
  50. data/spec/unit/async_events_spec.rb +0 -138
  51. data/spec/unit/callable/call_spec.rb +0 -113
  52. data/spec/unit/callbacks_spec.rb +0 -942
  53. data/spec/unit/can_spec.rb +0 -98
  54. data/spec/unit/choice_spec.rb +0 -331
  55. data/spec/unit/define_spec.rb +0 -55
  56. data/spec/unit/definition_spec.rb +0 -115
  57. data/spec/unit/event_names_spec.rb +0 -19
  58. data/spec/unit/event_queue_spec.rb +0 -52
  59. data/spec/unit/events_chain/add_spec.rb +0 -25
  60. data/spec/unit/events_chain/cancel_transitions_spec.rb +0 -22
  61. data/spec/unit/events_chain/choice_transition_spec.rb +0 -28
  62. data/spec/unit/events_chain/clear_spec.rb +0 -15
  63. data/spec/unit/events_chain/events_spec.rb +0 -18
  64. data/spec/unit/events_chain/inspect_spec.rb +0 -24
  65. data/spec/unit/events_chain/match_transition_spec.rb +0 -37
  66. data/spec/unit/events_chain/move_to_spec.rb +0 -48
  67. data/spec/unit/events_chain/states_for_spec.rb +0 -17
  68. data/spec/unit/events_spec.rb +0 -459
  69. data/spec/unit/handlers_spec.rb +0 -152
  70. data/spec/unit/hook_event/build_spec.rb +0 -15
  71. data/spec/unit/hook_event/eql_spec.rb +0 -36
  72. data/spec/unit/hook_event/infer_default_name_spec.rb +0 -13
  73. data/spec/unit/hook_event/initialize_spec.rb +0 -25
  74. data/spec/unit/hook_event/notify_spec.rb +0 -14
  75. data/spec/unit/hooks/call_spec.rb +0 -24
  76. data/spec/unit/hooks/clear_spec.rb +0 -16
  77. data/spec/unit/hooks/inspect_spec.rb +0 -17
  78. data/spec/unit/hooks/register_spec.rb +0 -22
  79. data/spec/unit/if_unless_spec.rb +0 -353
  80. data/spec/unit/initial_spec.rb +0 -222
  81. data/spec/unit/inspect_spec.rb +0 -17
  82. data/spec/unit/is_spec.rb +0 -55
  83. data/spec/unit/log_transitions_spec.rb +0 -30
  84. data/spec/unit/logger_spec.rb +0 -38
  85. data/spec/unit/respond_to_spec.rb +0 -38
  86. data/spec/unit/state_parser/inspect_spec.rb +0 -25
  87. data/spec/unit/state_parser/parse_spec.rb +0 -59
  88. data/spec/unit/states_spec.rb +0 -34
  89. data/spec/unit/subscribers_spec.rb +0 -42
  90. data/spec/unit/target_spec.rb +0 -225
  91. data/spec/unit/terminated_spec.rb +0 -95
  92. data/spec/unit/transition/check_conditions_spec.rb +0 -54
  93. data/spec/unit/transition/inspect_spec.rb +0 -25
  94. data/spec/unit/transition/matches_spec.rb +0 -23
  95. data/spec/unit/transition/states_spec.rb +0 -31
  96. data/spec/unit/transition/to_state_spec.rb +0 -27
  97. data/spec/unit/trigger_spec.rb +0 -22
  98. data/spec/unit/undefined_transition/eql_spec.rb +0 -17
  99. data/tasks/console.rake +0 -11
  100. data/tasks/coverage.rake +0 -11
  101. data/tasks/spec.rake +0 -29
@@ -1,92 +1,93 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
3
+ require "concurrent/map"
4
+
5
+ require_relative "hook_event"
2
6
 
3
7
  module FiniteMachine
4
8
  # A class reponsible for registering callbacks
5
9
  class Hooks
6
- include Threadable
7
-
8
- attr_threadsafe :collection
10
+ attr_reader :hooks_map
9
11
 
10
- # Initialize a collection of hoooks
12
+ # Initialize a hooks_map of hooks
11
13
  #
12
14
  # @example
13
15
  # Hoosk.new(machine)
14
16
  #
15
17
  # @api public
16
18
  def initialize
17
- @collection = Hash.new do |events_hash, event_type|
18
- events_hash[event_type] = Hash.new do |state_hash, name|
19
+ @hooks_map = Concurrent::Map.new do |events_hash, hook_event|
20
+ events_hash[hook_event] = Concurrent::Map.new do |state_hash, name|
19
21
  state_hash[name] = []
20
22
  end
21
23
  end
22
24
  end
23
25
 
24
- # Register callback
26
+ # Finds all hooks for the event type
25
27
  #
26
- # @param [String] event_type
27
- # @param [String] name
28
- # @param [Proc] callback
28
+ # @param [Symbol] name
29
29
  #
30
30
  # @example
31
- # hooks.register HookEvent::Enter, :green do ... end
31
+ # hooks[HookEvent::Enter][:go] # => [-> { }]
32
32
  #
33
- # @example
34
- # hooks.register HookEvent::Before, :any do ... end
35
- #
36
- # @return [Hash]
33
+ # @return [Array[Transition]]
34
+ # the transitions matching event name
37
35
  #
38
36
  # @api public
39
- def register(event_type, name, callback)
40
- collection[event_type][name] << callback
37
+ def find(name)
38
+ @hooks_map[name]
41
39
  end
40
+ alias [] find
42
41
 
43
- # Unregister callback
42
+ # Register callback
44
43
  #
45
- # @param [String] event_type
44
+ # @param [String] hook_event
46
45
  # @param [String] name
47
46
  # @param [Proc] callback
48
47
  #
49
48
  # @example
50
- # hooks.unregister HookEvent::Enter, :green do ... end
49
+ # hooks.register HookEvent::Enter, :green do ... end
50
+ #
51
+ # @example
52
+ # hooks.register HookEvent::Before, any_state do ... end
51
53
  #
52
54
  # @return [Hash]
53
55
  #
54
56
  # @api public
55
- def unregister(event_type, name, callback)
56
- callbacks = collection[event_type][name]
57
- callbacks.delete(callback)
57
+ def register(hook_event, name, callback)
58
+ @hooks_map[hook_event][name] << callback
58
59
  end
59
60
 
60
- # Return all hooks matching event and state
61
+ # Unregister callback
61
62
  #
62
- # @param [String] event_type
63
- # @param [String] event_state
64
- # @param [Event] event
63
+ # @param [String] hook_event
64
+ # @param [String] name
65
+ # @param [Proc] callback
65
66
  #
66
67
  # @example
67
- # hooks.call(HookEvent::Enter, :green, Event.new)
68
+ # hooks.unregister HookEvent::Enter, :green do ... end
68
69
  #
69
70
  # @return [Hash]
70
71
  #
71
72
  # @api public
72
- def call(event_type, event_state, &block)
73
- collection[event_type][event_state].each(&block)
73
+ def unregister(hook_event, name, callback)
74
+ @hooks_map[hook_event][name].delete(callback)
74
75
  end
75
76
 
76
- # Check if collection has any elements
77
+ # Check if hooks_map has any elements
77
78
  #
78
79
  # @return [Boolean]
79
80
  #
80
81
  # @api public
81
82
  def empty?
82
- collection.empty?
83
+ @hooks_map.empty?
83
84
  end
84
85
 
85
86
  # Remove all callbacks
86
87
  #
87
88
  # @api public
88
89
  def clear
89
- collection.clear
90
+ @hooks_map.clear
90
91
  end
91
92
 
92
93
  # String representation
@@ -95,7 +96,14 @@ module FiniteMachine
95
96
  #
96
97
  # @api public
97
98
  def to_s
98
- self.inspect
99
+ hash = {}
100
+ @hooks_map.each_pair do |hook_event, nested_hash|
101
+ hash[hook_event] = {}
102
+ nested_hash.each_pair do |name, callbacks|
103
+ hash[hook_event][name] = callbacks
104
+ end
105
+ end
106
+ hash.to_s
99
107
  end
100
108
 
101
109
  # String representation
@@ -104,7 +112,7 @@ module FiniteMachine
104
112
  #
105
113
  # @api public
106
114
  def inspect
107
- "<##{self.class}:0x#{object_id.to_s(16)} @collection=#{collection.inspect}>"
115
+ "<##{self.class}:0x#{object_id.to_s(16)} @hooks_map=#{self}>"
108
116
  end
109
117
  end # Hooks
110
118
  end # FiniteMachine
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module FiniteMachine
4
4
  # A generic listener interface
@@ -24,6 +24,6 @@ module FiniteMachine
24
24
  def call(*args)
25
25
  @on_delivery.call(*args) if @on_delivery
26
26
  end
27
- alias_method :handle_delivery, :call
27
+ alias handle_delivery call
28
28
  end # Listener
29
29
  end # FiniteMachine
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  module FiniteMachine
4
4
  module Logger
@@ -21,21 +21,22 @@ module FiniteMachine
21
21
  end
22
22
 
23
23
  def format_error(error)
24
- message = "#{error.class}: #{error.message}\n\t"
24
+ message = ["#{error.class}: #{error.message}\n\t"]
25
25
  if error.backtrace
26
26
  message << "occured at #{error.backtrace.join("\n\t")}"
27
27
  else
28
28
  message << "EMPTY BACKTRACE\n\t"
29
29
  end
30
+ message.join
30
31
  end
31
32
 
32
33
  def report_transition(name, from, to, *args)
33
- message = "Transition: @event=#{name} "
34
+ message = ["Transition: @event=#{name} "]
34
35
  unless args.empty?
35
36
  message << "@with=[#{args.join(',')}] "
36
37
  end
37
38
  message << "#{from} -> #{to}"
38
- info(message)
39
+ info(message.join)
39
40
  end
40
41
  end # Logger
41
42
  end # FiniteMachine
@@ -1,36 +1,55 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- module FiniteMachine
4
- # A class responsible for running asynchronous events
5
- class EventQueue
6
- include Threadable
3
+ require_relative "listener"
4
+ require "thread"
7
5
 
8
- # Initialize an event queue
6
+ module FiniteMachine
7
+ # Allows for storage of asynchronous messages such as events
8
+ # and callbacks.
9
+ #
10
+ # Used internally by {Observer} and {StateMachine}
11
+ #
12
+ # @api private
13
+ class MessageQueue
14
+ # Initialize an event queue in separate thread
9
15
  #
10
16
  # @example
11
- # EventQueue.new
17
+ # MessageQueue.new
12
18
  #
13
19
  # @api public
14
20
  def initialize
21
+ @not_empty = ConditionVariable.new
22
+ @mutex = Mutex.new
15
23
  @queue = Queue.new
16
24
  @dead = false
17
25
  @listeners = []
26
+ @thread = nil
27
+ end
18
28
 
29
+ # Start a new thread with a queue of callback events to run
30
+ #
31
+ # @api private
32
+ def start
33
+ return if running?
34
+
35
+ @mutex.synchronize { spawn_thread }
36
+ end
37
+
38
+ # Spawn new background thread
39
+ #
40
+ # @api private
41
+ def spawn_thread
19
42
  @thread = Thread.new do
43
+ Thread.current.abort_on_exception = true
20
44
  process_events
21
45
  end
22
46
  end
23
47
 
24
- # Retrieve the next event
25
- #
26
- # @return [AsyncCall]
27
- #
28
- # @api private
29
- def next_event
30
- sync_shared { @queue.pop }
48
+ def running?
49
+ !@thread.nil? && alive?
31
50
  end
32
51
 
33
- # Add asynchronous event to the event queue
52
+ # Add asynchronous event to the event queue to process
34
53
  #
35
54
  # @example
36
55
  # event_queue << AsyncCall.build(...)
@@ -41,15 +60,21 @@ module FiniteMachine
41
60
  #
42
61
  # @api public
43
62
  def <<(event)
44
- sync_exclusive { @queue << event }
45
- self
63
+ @mutex.synchronize do
64
+ if @dead
65
+ discard_message(event)
66
+ else
67
+ @queue << event
68
+ @not_empty.signal
69
+ end
70
+ end
46
71
  end
47
72
 
48
73
  # Add listener to the queue to receive messages
49
74
  #
50
75
  # @api public
51
76
  def subscribe(*args, &block)
52
- sync_exclusive do
77
+ @mutex.synchronize do
53
78
  listener = Listener.new(*args)
54
79
  listener.on_delivery(&block)
55
80
  @listeners << listener
@@ -63,7 +88,7 @@ module FiniteMachine
63
88
  #
64
89
  # @api public
65
90
  def empty?
66
- sync_shared { @queue.empty? }
91
+ @mutex.synchronize { @queue.empty? }
67
92
  end
68
93
 
69
94
  # Check if the event queue is alive
@@ -75,7 +100,7 @@ module FiniteMachine
75
100
  #
76
101
  # @api public
77
102
  def alive?
78
- sync_shared { !@dead }
103
+ @mutex.synchronize { !@dead }
79
104
  end
80
105
 
81
106
  # Join the event queue from current thread
@@ -89,6 +114,8 @@ module FiniteMachine
89
114
  #
90
115
  # @api public
91
116
  def join(timeout = nil)
117
+ return unless @thread
118
+
92
119
  timeout.nil? ? @thread.join : @thread.join(timeout)
93
120
  end
94
121
 
@@ -101,16 +128,18 @@ module FiniteMachine
101
128
  #
102
129
  # @api public
103
130
  def shutdown
104
- fail EventQueueDeadError, 'event queue already dead' if @dead
131
+ raise EventQueueDeadError, "event queue already dead" if @dead
105
132
 
106
133
  queue = []
107
- sync_exclusive do
134
+ @mutex.synchronize do
135
+ @dead = true
136
+ @not_empty.broadcast
137
+
108
138
  queue = @queue
109
139
  @queue.clear
110
- @dead = true
111
140
  end
112
141
  while !queue.empty?
113
- Logger.debug "Discarded message: #{queue.pop}"
142
+ discard_message(queue.pop)
114
143
  end
115
144
  true
116
145
  end
@@ -124,20 +153,24 @@ module FiniteMachine
124
153
  #
125
154
  # @api public
126
155
  def size
127
- sync_shared { @queue.size }
156
+ @mutex.synchronize { @queue.size }
157
+ end
158
+
159
+ def inspect
160
+ @mutex.synchronize do
161
+ "#<#{self.class}:#{object_id.to_s(16)} @size=#{size}, @dead=#{@dead}>"
162
+ end
128
163
  end
129
164
 
130
165
  private
131
166
 
132
167
  # Notify consumers about process event
133
168
  #
134
- # @param [FiniteMachine::AsyncCall] event
169
+ # @param [AsyncCall] event
135
170
  #
136
171
  # @api private
137
172
  def notify_listeners(event)
138
- sync_shared do
139
- @listeners.each { |listener| listener.handle_delivery(event) }
140
- end
173
+ @listeners.each { |listener| listener.handle_delivery(event) }
141
174
  end
142
175
 
143
176
  # Process all the events
@@ -147,12 +180,23 @@ module FiniteMachine
147
180
  # @api private
148
181
  def process_events
149
182
  until @dead
150
- event = next_event
151
- notify_listeners(event)
152
- event.dispatch
183
+ @mutex.synchronize do
184
+ while @queue.empty?
185
+ @not_empty.wait(@mutex)
186
+ end
187
+ event = @queue.pop
188
+ break unless event
189
+
190
+ notify_listeners(event)
191
+ event.dispatch
192
+ end
153
193
  end
154
194
  rescue Exception => ex
155
195
  Logger.error "Error while running event: #{Logger.format_error(ex)}"
156
196
  end
197
+
198
+ def discard_message(message)
199
+ Logger.debug "Discarded message: #{message}" if $DEBUG
200
+ end
157
201
  end # EventQueue
158
202
  end # FiniteMachine
@@ -1,26 +1,54 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- require 'finite_machine/hooks'
3
+ require_relative "async_call"
4
+ require_relative "callable"
5
+ require_relative "hook_event"
6
+ require_relative "hooks"
7
+ require_relative "message_queue"
8
+ require_relative "safety"
9
+ require_relative "transition_event"
4
10
 
5
11
  module FiniteMachine
6
12
  # A class responsible for observing state changes
7
- class Observer
8
- include Threadable
13
+ class Observer < GenericDSL
9
14
  include Safety
10
15
 
16
+ # Clean up callback queue
17
+ #
18
+ # @api private
19
+ def self.cleanup_callback_queue
20
+ proc do
21
+ begin
22
+ if callback_queue.alive?
23
+ callback_queue.shutdown
24
+ end
25
+ rescue MessageQueueDeadError
26
+ end
27
+ end
28
+ end
29
+
11
30
  # The current state machine
12
- attr_threadsafe :machine
31
+ attr_reader :machine
13
32
 
14
33
  # The hooks to trigger around the transition lifecycle.
15
- attr_threadsafe :hooks
34
+ attr_reader :hooks
16
35
 
17
36
  # Initialize an Observer
18
37
  #
38
+ # @param [StateMachine] machine
39
+ # reference to the current machine
40
+ #
19
41
  # @api public
20
42
  def initialize(machine)
21
43
  @machine = machine
44
+ @hooks = Hooks.new
45
+
22
46
  @machine.subscribe(self)
23
- @hooks = FiniteMachine::Hooks.new
47
+ ObjectSpace.define_finalizer(self, self.class.cleanup_callback_queue)
48
+ end
49
+
50
+ def callback_queue
51
+ @callback_queue ||= MessageQueue.new
24
52
  end
25
53
 
26
54
  # Evaluate in current context
@@ -43,7 +71,7 @@ module FiniteMachine
43
71
  def on(hook_type, state_or_event_name = nil, async = nil, &callback)
44
72
  sync_exclusive do
45
73
  if state_or_event_name.nil?
46
- state_or_event_name = HookEvent.infer_default_name(hook_type)
74
+ state_or_event_name = HookEvent.any_state_or_event(hook_type)
47
75
  end
48
76
  async = false if async.nil?
49
77
  ensure_valid_callback_name!(hook_type, state_or_event_name)
@@ -118,8 +146,9 @@ module FiniteMachine
118
146
  def emit(event, *data)
119
147
  sync_exclusive do
120
148
  [event.type].each do |hook_type|
121
- [event.name, ANY_STATE, ANY_EVENT].each do |event_name|
122
- hooks.call(hook_type, event_name) do |hook|
149
+ any_state_or_event = HookEvent.any_state_or_event(hook_type)
150
+ [any_state_or_event, event.name].each do |event_name|
151
+ hooks[hook_type][event_name].each do |hook|
123
152
  handle_callback(hook, event, *data)
124
153
  off(hook_type, event_name, &hook) if hook.is_a?(Once)
125
154
  end
@@ -128,26 +157,21 @@ module FiniteMachine
128
157
  end
129
158
  end
130
159
 
131
- private
132
-
133
- # Defer callback execution
160
+ # Cancel the current event
134
161
  #
135
- # @api private
136
- def defer(callable, trans_event, *data)
137
- async_call = AsyncCall.new(machine, callable, trans_event, *data)
138
- machine.event_queue << async_call
139
- end
140
-
141
- # Create callable instance
162
+ # This should be called inside a on_before or on_exit callbacks
163
+ # to prevent event transition.
142
164
  #
143
- # @api private
144
- def create_callable(hook)
145
- callback = proc do |trans_event, *data|
146
- machine.instance_exec(trans_event, *data, &hook)
147
- end
148
- Callable.new(callback)
165
+ # @param [String] msg
166
+ # the message used for failure
167
+ #
168
+ # @api public
169
+ def cancel_event(msg = nil)
170
+ raise CallbackError.new(msg)
149
171
  end
150
172
 
173
+ private
174
+
151
175
  # Handle callback and decide if run synchronously or asynchronously
152
176
  #
153
177
  # @param [Proc] :hook
@@ -160,21 +184,34 @@ module FiniteMachine
160
184
  #
161
185
  # @api private
162
186
  def handle_callback(hook, event, *data)
163
- to = machine.events_chain.move_to(event.event_name, event.from, *data)
164
- trans_event = TransitionEvent.new(event, to)
187
+ to = machine.events_map.move_to(event.event_name, event.from, *data)
188
+ trans_event = TransitionEvent.new(event.event_name, event.from, to)
165
189
  callable = create_callable(hook)
166
190
 
167
191
  if hook.is_a?(Async)
168
192
  defer(callable, trans_event, *data)
169
- result = nil
170
193
  else
171
- result = callable.call(trans_event, *data)
194
+ callable.(trans_event, *data)
172
195
  end
196
+ end
197
+
198
+ # Defer callback execution
199
+ #
200
+ # @api private
201
+ def defer(callable, trans_event, *data)
202
+ async_call = AsyncCall.new(machine, callable, trans_event, *data)
203
+ callback_queue.start unless callback_queue.running?
204
+ callback_queue << async_call
205
+ end
173
206
 
174
- if result == CANCELLED
175
- hooks.clear
176
- machine.events_chain.cancel_transitions(event.event_name)
207
+ # Create callable instance
208
+ #
209
+ # @api private
210
+ def create_callable(hook)
211
+ callback = proc do |trans_event, *data|
212
+ machine.instance_exec(trans_event, *data, &hook)
177
213
  end
214
+ Callable.new(callback)
178
215
  end
179
216
 
180
217
  # Callback names including all states and events
@@ -184,7 +221,7 @@ module FiniteMachine
184
221
  #
185
222
  # @api private
186
223
  def callback_names
187
- machine.states + machine.event_names + [ANY_EVENT, ANY_STATE]
224
+ machine.states + machine.events + [ANY_EVENT, ANY_STATE]
188
225
  end
189
226
 
190
227
  # Forward the message to observer