state_machines 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +0 -2
- data/README.md +25 -0
- data/Rakefile +10 -1
- data/lib/state_machines/branch.rb +0 -4
- data/lib/state_machines/core.rb +23 -5
- data/lib/state_machines/error.rb +81 -2
- data/lib/state_machines/event.rb +2 -20
- data/lib/state_machines/event_collection.rb +25 -27
- data/lib/state_machines/extensions.rb +34 -34
- data/lib/state_machines/integrations.rb +98 -90
- data/lib/state_machines/integrations/base.rb +11 -60
- data/lib/state_machines/matcher.rb +0 -2
- data/lib/state_machines/node_collection.rb +0 -2
- data/lib/state_machines/path_collection.rb +0 -2
- data/lib/state_machines/state.rb +0 -3
- data/lib/state_machines/state_collection.rb +17 -19
- data/lib/state_machines/state_context.rb +1 -6
- data/lib/state_machines/transition.rb +0 -56
- data/lib/state_machines/version.rb +1 -1
- data/spec/spec_helper.rb +1 -0
- data/spec/state_machines/assertions_spec.rb +31 -0
- data/spec/state_machines/branch_spec.rb +827 -0
- data/spec/state_machines/callbacks_spec.rb +706 -0
- data/spec/state_machines/errors_spec.rb +1 -0
- data/spec/state_machines/event_collection_spec.rb +401 -0
- data/spec/state_machines/event_spec.rb +1140 -0
- data/spec/{helpers → state_machines}/helper_spec.rb +0 -0
- data/spec/state_machines/integration_base_spec.rb +12 -0
- data/spec/state_machines/integration_spec.rb +132 -0
- data/spec/state_machines/invalid_event_spec.rb +19 -0
- data/spec/state_machines/invalid_parallel_transition_spec.rb +18 -0
- data/spec/state_machines/invalid_transition_spec.rb +114 -0
- data/spec/state_machines/machine_collection_spec.rb +606 -0
- data/spec/{machine_spec.rb → state_machines/machine_spec.rb} +11 -2
- data/spec/{matcher_helpers_spec.rb → state_machines/matcher_helpers_spec.rb} +0 -0
- data/spec/{matcher_spec.rb → state_machines/matcher_spec.rb} +0 -0
- data/spec/{node_collection_spec.rb → state_machines/node_collection_spec.rb} +0 -0
- data/spec/{path_collection_spec.rb → state_machines/path_collection_spec.rb} +0 -0
- data/spec/{path_spec.rb → state_machines/path_spec.rb} +0 -0
- data/spec/{state_collection_spec.rb → state_machines/state_collection_spec.rb} +0 -0
- data/spec/{state_context_spec.rb → state_machines/state_context_spec.rb} +0 -0
- data/spec/{state_machine_spec.rb → state_machines/state_machine_spec.rb} +0 -0
- data/spec/{state_spec.rb → state_machines/state_spec.rb} +0 -0
- data/spec/{transition_collection_spec.rb → state_machines/transition_collection_spec.rb} +0 -0
- data/spec/{transition_spec.rb → state_machines/transition_spec.rb} +0 -0
- data/spec/support/migration_helpers.rb +9 -0
- data/state_machines.gemspec +3 -1
- metadata +68 -45
- data/lib/state_machines/yard.rb +0 -8
- data/spec/errors/default_spec.rb +0 -14
- data/spec/errors/with_message_spec.rb +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3eee931d0f563b659a9e786dc0eea93ed9f9f537
|
4
|
+
data.tar.gz: f53da4d08eecd750e4b416f5926e31b49be341f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c1fde9ad6a6b0fb3a3f066a87f7f80c90d78c9f7d633f92f67ff0f3104bc01d16bddf4485f1b24ab3dc35bd14e6e348b8bc3ee8f45cce9edc89ef771869b9229
|
7
|
+
data.tar.gz: 9f07e5b0c0d579557d0a4648b909922a85f45653366ed37e738a3176d52e4ef5ed586471395ea1ca1fcf22109a2d3dda0139e7676f9199666348c108904cabdc
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
[![Build Status](https://travis-ci.org/seuros/state_machines.svg?branch=master)](https://travis-ci.org/seuros/state_machines)
|
2
|
+
[![Code Climate](https://codeclimate.com/github/seuros/state_machines.png)](https://codeclimate.com/github/seuros/state_machines)
|
1
3
|
# State Machines
|
2
4
|
|
3
5
|
State Machines adds support for creating state machines for attributes on any Ruby class.
|
@@ -20,6 +22,29 @@ Or install it yourself as:
|
|
20
22
|
|
21
23
|
TODO: Write usage instructions here
|
22
24
|
|
25
|
+
## Dependencies
|
26
|
+
|
27
|
+
Ruby versions officially supported and tested:
|
28
|
+
|
29
|
+
* Ruby (MRI) 1.9.3+
|
30
|
+
* JRuby (1.9)
|
31
|
+
* Rubinius
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
For graphing state machine:
|
36
|
+
|
37
|
+
* [state_machines-graphviz](http://github.com/seuros/state_machines-graphviz)
|
38
|
+
|
39
|
+
For documenting state machines:
|
40
|
+
|
41
|
+
* [state_machines-yard](http://github.com/seuros/state_machines-yard)
|
42
|
+
|
43
|
+
|
44
|
+
## TODO
|
45
|
+
|
46
|
+
Add matchers/assertions for rspec and minitest
|
47
|
+
|
23
48
|
## Contributing
|
24
49
|
|
25
50
|
1. Fork it ( https://github.com/seuros/state_machines/fork )
|
data/Rakefile
CHANGED
@@ -1,7 +1,3 @@
|
|
1
|
-
require 'state_machines/matcher'
|
2
|
-
require 'state_machines/eval_helpers'
|
3
|
-
require 'state_machines/assertions'
|
4
|
-
|
5
1
|
module StateMachines
|
6
2
|
# Represents a set of requirements that must be met in order for a transition
|
7
3
|
# or callback to occur. Branches verify that the event, from state, and to
|
data/lib/state_machines/core.rb
CHANGED
@@ -3,23 +3,41 @@
|
|
3
3
|
# * StateMachines::MacroMethods which adds the state_machine DSL to your class
|
4
4
|
# * A set of initializers for setting state_machine defaults based on the current
|
5
5
|
# running environment (such as within Rails)
|
6
|
-
require 'state_machines/error'
|
7
6
|
require 'state_machines/assertions'
|
7
|
+
require 'state_machines/error'
|
8
8
|
|
9
|
-
require 'state_machines/machine_collection'
|
10
9
|
require 'state_machines/extensions'
|
11
10
|
|
12
|
-
require 'state_machines/integrations/base'
|
13
11
|
require 'state_machines/integrations'
|
12
|
+
require 'state_machines/integrations/base'
|
13
|
+
|
14
|
+
require 'state_machines/eval_helpers'
|
15
|
+
|
16
|
+
require 'singleton'
|
17
|
+
require 'state_machines/matcher'
|
18
|
+
require 'state_machines/matcher_helpers'
|
19
|
+
|
20
|
+
require 'state_machines/transition'
|
21
|
+
require 'state_machines/transition_collection'
|
22
|
+
|
23
|
+
require 'state_machines/branch'
|
14
24
|
|
15
25
|
require 'state_machines/helper_module'
|
16
26
|
require 'state_machines/state'
|
17
|
-
require 'state_machines/event'
|
18
27
|
require 'state_machines/callback'
|
19
28
|
require 'state_machines/node_collection'
|
29
|
+
|
30
|
+
require 'state_machines/state_context'
|
31
|
+
require 'state_machines/state'
|
20
32
|
require 'state_machines/state_collection'
|
33
|
+
|
34
|
+
require 'state_machines/event'
|
21
35
|
require 'state_machines/event_collection'
|
36
|
+
|
37
|
+
require 'state_machines/path'
|
22
38
|
require 'state_machines/path_collection'
|
23
|
-
|
39
|
+
|
24
40
|
require 'state_machines/machine'
|
41
|
+
require 'state_machines/machine_collection'
|
42
|
+
|
25
43
|
require 'state_machines/macro_methods'
|
data/lib/state_machines/error.rb
CHANGED
@@ -3,11 +3,90 @@ module StateMachines
|
|
3
3
|
class Error < StandardError
|
4
4
|
# The object that failed
|
5
5
|
attr_reader :object
|
6
|
-
|
6
|
+
|
7
7
|
def initialize(object, message = nil) #:nodoc:
|
8
8
|
@object = object
|
9
|
-
|
9
|
+
|
10
10
|
super(message)
|
11
11
|
end
|
12
12
|
end
|
13
|
+
|
14
|
+
# An invalid integration was specified
|
15
|
+
class IntegrationNotFound < Error
|
16
|
+
def initialize(name)
|
17
|
+
super(nil, "#{name.inspect} is an invalid integration")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# An invalid integration was registered
|
22
|
+
class IntegrationError < StandardError
|
23
|
+
end
|
24
|
+
|
25
|
+
# An invalid event was specified
|
26
|
+
class InvalidEvent < Error
|
27
|
+
# The event that was attempted to be run
|
28
|
+
attr_reader :event
|
29
|
+
|
30
|
+
def initialize(object, event_name) #:nodoc:
|
31
|
+
@event = event_name
|
32
|
+
|
33
|
+
super(object, "#{event.inspect} is an unknown state machine event")
|
34
|
+
end
|
35
|
+
end
|
36
|
+
# An invalid transition was attempted
|
37
|
+
class InvalidTransition < Error
|
38
|
+
# The machine attempting to be transitioned
|
39
|
+
attr_reader :machine
|
40
|
+
|
41
|
+
# The current state value for the machine
|
42
|
+
attr_reader :from
|
43
|
+
|
44
|
+
def initialize(object, machine, event) #:nodoc:
|
45
|
+
@machine = machine
|
46
|
+
@from_state = machine.states.match!(object)
|
47
|
+
@from = machine.read(object, :state)
|
48
|
+
@event = machine.events.fetch(event)
|
49
|
+
errors = machine.errors_for(object)
|
50
|
+
|
51
|
+
message = "Cannot transition #{machine.name} via :#{self.event} from #{from_name.inspect}"
|
52
|
+
message << " (Reason(s): #{errors})" unless errors.empty?
|
53
|
+
super(object, message)
|
54
|
+
end
|
55
|
+
|
56
|
+
# The event that triggered the failed transition
|
57
|
+
def event
|
58
|
+
@event.name
|
59
|
+
end
|
60
|
+
|
61
|
+
# The fully-qualified name of the event that triggered the failed transition
|
62
|
+
def qualified_event
|
63
|
+
@event.qualified_name
|
64
|
+
end
|
65
|
+
|
66
|
+
# The name for the current state
|
67
|
+
def from_name
|
68
|
+
@from_state.name
|
69
|
+
end
|
70
|
+
|
71
|
+
# The fully-qualified name for the current state
|
72
|
+
def qualified_from_name
|
73
|
+
@from_state.qualified_name
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# A set of transition failed to run in parallel
|
78
|
+
class InvalidParallelTransition < Error
|
79
|
+
# The set of events that failed the transition(s)
|
80
|
+
attr_reader :events
|
81
|
+
|
82
|
+
def initialize(object, events) #:nodoc:
|
83
|
+
@events = events
|
84
|
+
|
85
|
+
super(object, "Cannot run events in parallel: #{events * ', '}")
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# A method was called in an invalid state context
|
90
|
+
class InvalidContext < Error
|
91
|
+
end
|
13
92
|
end
|
data/lib/state_machines/event.rb
CHANGED
@@ -1,22 +1,4 @@
|
|
1
|
-
require 'state_machines/transition'
|
2
|
-
require 'state_machines/branch'
|
3
|
-
require 'state_machines/assertions'
|
4
|
-
require 'state_machines/matcher_helpers'
|
5
|
-
require 'state_machines/error'
|
6
|
-
|
7
1
|
module StateMachines
|
8
|
-
# An invalid event was specified
|
9
|
-
class InvalidEvent < Error
|
10
|
-
# The event that was attempted to be run
|
11
|
-
attr_reader :event
|
12
|
-
|
13
|
-
def initialize(object, event_name) #:nodoc:
|
14
|
-
@event = event_name
|
15
|
-
|
16
|
-
super(object, "#{event.inspect} is an unknown state machine event")
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
2
|
# An event defines an action that transitions an attribute from one state to
|
21
3
|
# another. The state that an attribute is transitioned to depends on the
|
22
4
|
# branches configured for the event.
|
@@ -58,8 +40,8 @@ module StateMachines
|
|
58
40
|
reset
|
59
41
|
|
60
42
|
# Output a warning if another event has a conflicting qualified name
|
61
|
-
if conflict = machine.owner_class.state_machines.detect { |
|
62
|
-
|
43
|
+
if conflict = machine.owner_class.state_machines.detect { |_other_name, other_machine| other_machine != @machine && other_machine.events[qualified_name, :qualified_name] }
|
44
|
+
_name, other_machine = conflict
|
63
45
|
warn "Event #{qualified_name.inspect} for #{machine.name.inspect} is already defined in #{other_machine.name.inspect}"
|
64
46
|
else
|
65
47
|
add_actions
|
@@ -1,12 +1,10 @@
|
|
1
|
-
require 'state_machines/node_collection'
|
2
|
-
|
3
1
|
module StateMachines
|
4
2
|
# Represents a collection of events in a state machine
|
5
3
|
class EventCollection < NodeCollection
|
6
4
|
def initialize(machine) #:nodoc:
|
7
5
|
super(machine, :index => [:name, :qualified_name])
|
8
6
|
end
|
9
|
-
|
7
|
+
|
10
8
|
# Gets the list of events that can be fired on the given object.
|
11
9
|
#
|
12
10
|
# Valid requirement options:
|
@@ -41,9 +39,9 @@ module StateMachines
|
|
41
39
|
# vehicle.state = 'idling'
|
42
40
|
# events.valid_for(vehicle) # => [#<StateMachines::Event name=:park transitions=[:idling => :parked]>]
|
43
41
|
def valid_for(object, requirements = {})
|
44
|
-
match(requirements).select {|event| event.can_fire?(object, requirements)}
|
42
|
+
match(requirements).select { |event| event.can_fire?(object, requirements) }
|
45
43
|
end
|
46
|
-
|
44
|
+
|
47
45
|
# Gets the list of transitions that can be run on the given object.
|
48
46
|
#
|
49
47
|
# Valid requirement options:
|
@@ -81,9 +79,9 @@ module StateMachines
|
|
81
79
|
# # Search for explicit transitions regardless of the current state
|
82
80
|
# events.transitions_for(vehicle, :from => :parked) # => [#<StateMachines::Transition attribute=:state event=:ignite from="parked" from_name=:parked to="idling" to_name=:idling>]
|
83
81
|
def transitions_for(object, requirements = {})
|
84
|
-
match(requirements).map {|event| event.transition_for(object, requirements)}.compact
|
82
|
+
match(requirements).map { |event| event.transition_for(object, requirements) }.compact
|
85
83
|
end
|
86
|
-
|
84
|
+
|
87
85
|
# Gets the transition that should be performed for the event stored in the
|
88
86
|
# given object's event attribute. This also takes an additional parameter
|
89
87
|
# for automatically invalidating the object if the event or transition are
|
@@ -115,27 +113,27 @@ module StateMachines
|
|
115
113
|
# events.attribute_transition_for(vehicle) # => #<StateMachines::Transition attribute=:state event=:ignite from="parked" from_name=:parked to="idling" to_name=:idling>
|
116
114
|
def attribute_transition_for(object, invalidate = false)
|
117
115
|
return unless machine.action
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
116
|
+
|
117
|
+
# TODO, simplify
|
118
|
+
machine.read(object, :event_transition) || if event_name = machine.read(object, :event)
|
119
|
+
if event = self[event_name.to_sym, :name]
|
120
|
+
event.transition_for(object) || begin
|
121
|
+
# No valid transition: invalidate
|
122
|
+
machine.invalidate(object, :event, :invalid_event, [[:state, machine.states.match!(object).human_name(object.class)]]) if invalidate
|
123
|
+
false
|
124
|
+
end
|
125
|
+
else
|
126
|
+
# Event is unknown: invalidate
|
127
|
+
machine.invalidate(object, :event, :invalid) if invalidate
|
128
|
+
false
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
134
132
|
end
|
135
|
-
|
133
|
+
|
136
134
|
private
|
137
|
-
|
138
|
-
|
139
|
-
|
135
|
+
def match(requirements) #:nodoc:
|
136
|
+
requirements && requirements[:on] ? [fetch(requirements.delete(:on))] : self
|
137
|
+
end
|
140
138
|
end
|
141
139
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
module StateMachines
|
3
2
|
module ClassMethods
|
4
3
|
def self.extended(base) #:nodoc:
|
@@ -6,20 +5,20 @@ module StateMachines
|
|
6
5
|
@state_machines = MachineCollection.new
|
7
6
|
end
|
8
7
|
end
|
9
|
-
|
8
|
+
|
10
9
|
# Gets the current list of state machines defined for this class. This
|
11
10
|
# class-level attribute acts like an inheritable attribute. The attribute
|
12
11
|
# is available to each subclass, each having a copy of its superclass's
|
13
12
|
# attribute.
|
14
|
-
#
|
13
|
+
#
|
15
14
|
# The hash of state machines maps <tt>:attribute</tt> => +machine+, e.g.
|
16
|
-
#
|
15
|
+
#
|
17
16
|
# Vehicle.state_machines # => {:state => #<StateMachines::Machine:0xb6f6e4a4 ...>}
|
18
17
|
def state_machines
|
19
18
|
@state_machines ||= superclass.state_machines.dup
|
20
19
|
end
|
21
20
|
end
|
22
|
-
|
21
|
+
|
23
22
|
module InstanceMethods
|
24
23
|
# Runs one or more events in parallel. All events will run through the
|
25
24
|
# following steps:
|
@@ -27,7 +26,7 @@ module StateMachines
|
|
27
26
|
# * Persist state
|
28
27
|
# * Invoke action
|
29
28
|
# * After callbacks
|
30
|
-
#
|
29
|
+
#
|
31
30
|
# For example, if two events (for state machines A and B) are run in
|
32
31
|
# parallel, the order in which steps are run is:
|
33
32
|
# * A - Before transition callbacks
|
@@ -38,62 +37,62 @@ module StateMachines
|
|
38
37
|
# * B - Invoke action (only if different than A's action)
|
39
38
|
# * A - After transition callbacks
|
40
39
|
# * B - After transition callbacks
|
41
|
-
#
|
40
|
+
#
|
42
41
|
# *Note* that multiple events on the same state machine / attribute cannot
|
43
42
|
# be run in parallel. If this is attempted, an ArgumentError will be
|
44
43
|
# raised.
|
45
|
-
#
|
44
|
+
#
|
46
45
|
# == Halting callbacks
|
47
|
-
#
|
46
|
+
#
|
48
47
|
# When running multiple events in parallel, special consideration should
|
49
48
|
# be taken with regard to how halting within callbacks affects the flow.
|
50
|
-
#
|
49
|
+
#
|
51
50
|
# For *before* callbacks, any <tt>:halt</tt> error that's thrown will
|
52
51
|
# immediately cancel the perform for all transitions. As a result, it's
|
53
52
|
# possible for one event's transition to affect the continuation of
|
54
53
|
# another.
|
55
|
-
#
|
54
|
+
#
|
56
55
|
# On the other hand, any <tt>:halt</tt> error that's thrown within an
|
57
56
|
# *after* callback with only affect that event's transition. Other
|
58
57
|
# transitions will continue to run their own callbacks.
|
59
|
-
#
|
58
|
+
#
|
60
59
|
# == Example
|
61
|
-
#
|
60
|
+
#
|
62
61
|
# class Vehicle
|
63
62
|
# state_machine :initial => :parked do
|
64
63
|
# event :ignite do
|
65
64
|
# transition :parked => :idling
|
66
65
|
# end
|
67
|
-
#
|
66
|
+
#
|
68
67
|
# event :park do
|
69
68
|
# transition :idling => :parked
|
70
69
|
# end
|
71
70
|
# end
|
72
|
-
#
|
71
|
+
#
|
73
72
|
# state_machine :alarm_state, :namespace => 'alarm', :initial => :on do
|
74
73
|
# event :enable do
|
75
74
|
# transition all => :active
|
76
75
|
# end
|
77
|
-
#
|
76
|
+
#
|
78
77
|
# event :disable do
|
79
78
|
# transition all => :off
|
80
79
|
# end
|
81
80
|
# end
|
82
81
|
# end
|
83
|
-
#
|
82
|
+
#
|
84
83
|
# vehicle = Vehicle.new # => #<Vehicle:0xb7c02850 @state="parked", @alarm_state="active">
|
85
84
|
# vehicle.state # => "parked"
|
86
85
|
# vehicle.alarm_state # => "active"
|
87
|
-
#
|
86
|
+
#
|
88
87
|
# vehicle.fire_events(:ignite, :disable_alarm) # => true
|
89
88
|
# vehicle.state # => "idling"
|
90
89
|
# vehicle.alarm_state # => "off"
|
91
|
-
#
|
90
|
+
#
|
92
91
|
# # If any event fails, the entire event chain fails
|
93
92
|
# vehicle.fire_events(:ignite, :enable_alarm) # => false
|
94
93
|
# vehicle.state # => "idling"
|
95
94
|
# vehicle.alarm_state # => "off"
|
96
|
-
#
|
95
|
+
#
|
97
96
|
# # Exception raised on invalid event
|
98
97
|
# vehicle.fire_events(:park, :invalid) # => StateMachines::InvalidEvent: :invalid is an unknown event
|
99
98
|
# vehicle.state # => "idling"
|
@@ -101,48 +100,49 @@ module StateMachines
|
|
101
100
|
def fire_events(*events)
|
102
101
|
self.class.state_machines.fire_events(self, *events)
|
103
102
|
end
|
104
|
-
|
103
|
+
|
105
104
|
# Run one or more events in parallel. If any event fails to run, then
|
106
105
|
# a StateMachines::InvalidTransition exception will be raised.
|
107
|
-
#
|
106
|
+
#
|
108
107
|
# See StateMachines::InstanceMethods#fire_events for more information.
|
109
|
-
#
|
108
|
+
#
|
110
109
|
# == Example
|
111
|
-
#
|
110
|
+
#
|
112
111
|
# class Vehicle
|
113
112
|
# state_machine :initial => :parked do
|
114
113
|
# event :ignite do
|
115
114
|
# transition :parked => :idling
|
116
115
|
# end
|
117
|
-
#
|
116
|
+
#
|
118
117
|
# event :park do
|
119
118
|
# transition :idling => :parked
|
120
119
|
# end
|
121
120
|
# end
|
122
|
-
#
|
121
|
+
#
|
123
122
|
# state_machine :alarm_state, :namespace => 'alarm', :initial => :active do
|
124
123
|
# event :enable do
|
125
124
|
# transition all => :active
|
126
125
|
# end
|
127
|
-
#
|
126
|
+
#
|
128
127
|
# event :disable do
|
129
128
|
# transition all => :off
|
130
129
|
# end
|
131
130
|
# end
|
132
131
|
# end
|
133
|
-
#
|
132
|
+
#
|
134
133
|
# vehicle = Vehicle.new # => #<Vehicle:0xb7c02850 @state="parked", @alarm_state="active">
|
135
134
|
# vehicle.fire_events(:ignite, :disable_alarm) # => true
|
136
|
-
#
|
135
|
+
#
|
137
136
|
# vehicle.fire_events!(:ignite, :disable_alarm) # => StateMachines::InvalidTranstion: Cannot run events in parallel: ignite, disable_alarm
|
138
137
|
def fire_events!(*events)
|
139
138
|
run_action = [true, false].include?(events.last) ? events.pop : true
|
140
|
-
fire_events(*(events + [run_action])) ||
|
139
|
+
fire_events(*(events + [run_action])) || fail(StateMachines::InvalidParallelTransition.new(self, events))
|
141
140
|
end
|
142
|
-
|
141
|
+
|
143
142
|
protected
|
144
|
-
|
145
|
-
|
146
|
-
|
143
|
+
|
144
|
+
def initialize_state_machines(options = {}, &block) #:nodoc:
|
145
|
+
self.class.state_machines.initialize_states(self, options, &block)
|
146
|
+
end
|
147
147
|
end
|
148
148
|
end
|