state_gate 1.2.3 → 2.0.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.
- checksums.yaml +4 -4
- data/lib/state_gate/assertions.rb +246 -0
- data/lib/state_gate/builder/conflict_detection_methods.rb +59 -18
- data/lib/state_gate/builder/dynamic_module_creation_methods.rb +36 -22
- data/lib/state_gate/builder/scope_methods.rb +30 -20
- data/lib/state_gate/builder/state_methods.rb +108 -72
- data/lib/state_gate/builder/transition_methods.rb +54 -34
- data/lib/state_gate/builder/transition_validation_methods.rb +76 -66
- data/lib/state_gate/builder.rb +53 -43
- data/lib/state_gate/engine/configurator.rb +81 -63
- data/lib/state_gate/engine/errator.rb +42 -9
- data/lib/state_gate/engine/fixer.rb +21 -12
- data/lib/state_gate/engine/scoper.rb +12 -4
- data/lib/state_gate/engine/sequencer.rb +18 -5
- data/lib/state_gate/engine/stator.rb +98 -53
- data/lib/state_gate/engine/transitioner.rb +28 -14
- data/lib/state_gate/engine.rb +19 -6
- data/lib/state_gate/type.rb +22 -2
- data/lib/state_gate/version.rb +34 -0
- data/lib/state_gate.rb +88 -61
- metadata +9 -10
|
@@ -12,61 +12,61 @@ module StateGate
|
|
|
12
12
|
#
|
|
13
13
|
# Options include:
|
|
14
14
|
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
15
|
+
# [state]
|
|
16
|
+
# Required name for the new state, supplied as a Symbol. The +state-gate+ requires
|
|
17
|
+
# a minimum of two states to be defined.
|
|
18
18
|
# state :state_name
|
|
19
19
|
#
|
|
20
20
|
#
|
|
21
|
-
#
|
|
21
|
+
# **_:transitions_to_**
|
|
22
22
|
# An optional list of the other state that this state is allowed to change to.
|
|
23
23
|
# state :state_1, transtions_to: [:state_2, :state_3, :state_4]
|
|
24
24
|
# state :state_2, transtions_to: :state_4
|
|
25
25
|
# state :state_3, transtions_to: :any
|
|
26
26
|
# state :state_4
|
|
27
27
|
#
|
|
28
|
-
#
|
|
28
|
+
# **_:human_**
|
|
29
29
|
# An optional String name to used when displaying gthe state in a view. If no
|
|
30
30
|
# name is specified, it will default to +:state.titleized+.
|
|
31
31
|
# state :state_1, transtions_to: [:state_2, :state_3], human: "My State"
|
|
32
32
|
#
|
|
33
33
|
#
|
|
34
|
-
#
|
|
35
|
-
#
|
|
36
|
-
#
|
|
34
|
+
# [default]
|
|
35
|
+
# Optional setting to specify the default state for a new object. The state name
|
|
36
|
+
# is given as a Symbol.
|
|
37
37
|
# default :state_name
|
|
38
38
|
#
|
|
39
39
|
#
|
|
40
|
-
#
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
# prefix :before
|
|
40
|
+
# [prefix]
|
|
41
|
+
# Optional setting to add a given Symbol before each state name when using Class Scopes.
|
|
42
|
+
# This helps to differential between multiple attributes that have similar state names.
|
|
43
|
+
# prefix :before #=> Class.before_active
|
|
44
44
|
#
|
|
45
45
|
#
|
|
46
|
-
#
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
# suffix :after
|
|
46
|
+
# [suffix]
|
|
47
|
+
# Optional setting to add a given Symbol after each state name when using Class Scopes.
|
|
48
|
+
# This helps to differential between multiple attributes that have similar state names.
|
|
49
|
+
# suffix :after #=> Class.active_after
|
|
50
50
|
#
|
|
51
51
|
#
|
|
52
|
-
#
|
|
53
|
-
#
|
|
54
|
-
#
|
|
52
|
+
# [make_sequential]
|
|
53
|
+
# Optional setting to automatically add transitions from each state to both the
|
|
54
|
+
# preceeding and following states.
|
|
55
55
|
# make_sequential
|
|
56
56
|
#
|
|
57
|
-
#
|
|
58
|
-
#
|
|
59
|
-
#
|
|
60
|
-
#
|
|
57
|
+
# **_:one_way_**
|
|
58
|
+
# Option to restrict the generated transitions to one directtion only: from each
|
|
59
|
+
# state to the follow state.
|
|
60
|
+
# make_sequential :one_way
|
|
61
61
|
#
|
|
62
|
-
#
|
|
63
|
-
#
|
|
64
|
-
#
|
|
65
|
-
#
|
|
62
|
+
# **_:loop_**
|
|
63
|
+
# Option to add transitions from the last state to the first and, unless +:one_way+
|
|
64
|
+
# is specified, also from the first state to the last.
|
|
65
|
+
# make_sequential :one_way, :loop
|
|
66
66
|
#
|
|
67
67
|
#
|
|
68
|
-
#
|
|
69
|
-
#
|
|
68
|
+
# [no_scopes]
|
|
69
|
+
# Optional setting to disable the generation of Class Scope helpers methods.
|
|
70
70
|
# no_scopes
|
|
71
71
|
#
|
|
72
72
|
module Configurator
|
|
@@ -81,53 +81,65 @@ module StateGate
|
|
|
81
81
|
# ======================================================================
|
|
82
82
|
|
|
83
83
|
|
|
84
|
+
##
|
|
84
85
|
# Execute the provided configuration.
|
|
85
86
|
#
|
|
87
|
+
# @block config
|
|
88
|
+
# the given configuration
|
|
89
|
+
#
|
|
86
90
|
# ==== actions
|
|
87
91
|
#
|
|
88
|
-
#
|
|
89
|
-
#
|
|
90
|
-
#
|
|
92
|
+
# - create sequence links and transitions
|
|
93
|
+
# - create scope names
|
|
94
|
+
# - remove duplicate transitions for each state
|
|
91
95
|
#
|
|
92
|
-
#
|
|
93
|
-
#
|
|
94
|
-
#
|
|
96
|
+
# - verify there are multiple valid state names
|
|
97
|
+
# - verify all transitions lead to existing states
|
|
98
|
+
# - verify each state, except the default, can be reached from a transition
|
|
95
99
|
#
|
|
96
|
-
def
|
|
97
|
-
|
|
100
|
+
def _parse_configuration(&config)
|
|
101
|
+
_exec_configuration(&config)
|
|
98
102
|
|
|
99
103
|
generate_sequences
|
|
100
104
|
generate_scope_names
|
|
101
105
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
_assert_states_are_valid
|
|
107
|
+
_assert_transitions_exist
|
|
108
|
+
_assert_uniq_transitions
|
|
109
|
+
_assert_any_has_been_expanded
|
|
110
|
+
_assert_all_transitions_are_states
|
|
111
|
+
_assert_all_states_are_reachable
|
|
108
112
|
end
|
|
109
113
|
|
|
110
114
|
|
|
111
115
|
|
|
116
|
+
##
|
|
112
117
|
# Run the configuration commands.
|
|
113
118
|
#
|
|
119
|
+
# @block config
|
|
120
|
+
# the given configuration
|
|
121
|
+
#
|
|
114
122
|
# ==== actions
|
|
115
123
|
#
|
|
116
|
-
#
|
|
117
|
-
#
|
|
118
|
-
#
|
|
124
|
+
# - create sequence links and transitions
|
|
125
|
+
# - create scope names
|
|
126
|
+
# - remove duplicate transitions for each state
|
|
127
|
+
#
|
|
128
|
+
# - verify there are multiple valid state names
|
|
129
|
+
# - verify all transitions lead to existing states
|
|
130
|
+
# - verify each state, except the default, can be reached from a transition
|
|
119
131
|
#
|
|
120
|
-
#
|
|
121
|
-
#
|
|
122
|
-
# + verify each state, except the default, can be reached from a transition
|
|
132
|
+
# @note
|
|
133
|
+
# - gsub both ways to account for ruby 3.4 message change
|
|
123
134
|
#
|
|
124
|
-
def
|
|
135
|
+
def _exec_configuration(&config)
|
|
125
136
|
instance_exec(&config)
|
|
126
137
|
rescue NameError => e
|
|
127
138
|
err_command = e.to_s.gsub('undefined local variable or method `', '')
|
|
139
|
+
.to_s.gsub("undefined local variable or method '", '')
|
|
128
140
|
.split("'")
|
|
129
141
|
.first
|
|
130
|
-
|
|
142
|
+
_cerr :bad_command, cmd: err_command
|
|
131
143
|
end
|
|
132
144
|
|
|
133
145
|
|
|
@@ -136,21 +148,22 @@ module StateGate
|
|
|
136
148
|
# Assertions
|
|
137
149
|
# ======================================================================
|
|
138
150
|
|
|
151
|
+
##
|
|
139
152
|
# Ensure there are enough states and the default is a valid state, setting
|
|
140
153
|
# the default to the first state if required.
|
|
141
154
|
#
|
|
142
|
-
def
|
|
155
|
+
def _assert_states_are_valid
|
|
143
156
|
state_names = @states.keys
|
|
144
157
|
|
|
145
158
|
# are there states
|
|
146
|
-
|
|
159
|
+
_cerr(:states_missing_err) if state_names.blank?
|
|
147
160
|
|
|
148
161
|
# is there more than one state
|
|
149
|
-
|
|
162
|
+
_cerr(:single_state_err) if state_names.one?
|
|
150
163
|
|
|
151
164
|
# set the deafult state if needed, otherwise check it is a valid state
|
|
152
165
|
if @default
|
|
153
|
-
|
|
166
|
+
_cerr(:default_state_err) unless state_names.include?(@default)
|
|
154
167
|
else
|
|
155
168
|
@default = state_names.first
|
|
156
169
|
end
|
|
@@ -158,11 +171,12 @@ module StateGate
|
|
|
158
171
|
|
|
159
172
|
|
|
160
173
|
|
|
174
|
+
##
|
|
161
175
|
# Ensure that transitions have been specified. If not, then add the transitions
|
|
162
176
|
# to allow every stater to transition to another state and flag the engine as
|
|
163
177
|
# transitionless, so we don't add any validation methods.
|
|
164
178
|
#
|
|
165
|
-
def
|
|
179
|
+
def _assert_transitions_exist
|
|
166
180
|
return if @states.map { |_state, opts| opts[:transitions_to] }.uniq.flatten.any?
|
|
167
181
|
|
|
168
182
|
@transitionless = true
|
|
@@ -173,39 +187,42 @@ module StateGate
|
|
|
173
187
|
|
|
174
188
|
|
|
175
189
|
|
|
190
|
+
##
|
|
176
191
|
# Ensure that there is only one of reach transition
|
|
177
192
|
#
|
|
178
|
-
def
|
|
193
|
+
def _assert_uniq_transitions
|
|
179
194
|
@states.each { |_state, opts| opts[:transitions_to].uniq! }
|
|
180
195
|
end
|
|
181
196
|
|
|
182
197
|
|
|
183
198
|
|
|
199
|
+
##
|
|
184
200
|
# Ensure that the :any transition is expanded or raise an exception
|
|
185
201
|
# if it's included with other transitions
|
|
186
|
-
def
|
|
202
|
+
def _assert_any_has_been_expanded
|
|
187
203
|
@states.each do |state_name, opts|
|
|
188
204
|
if opts[:transitions_to] == [:any]
|
|
189
205
|
@states[state_name][:transitions_to] = @states.keys - [state_name]
|
|
190
206
|
|
|
191
207
|
elsif opts[:transitions_to].include?(:any)
|
|
192
|
-
|
|
208
|
+
_cerr(:any_transition_err, state: state_name, kattr: true)
|
|
193
209
|
end
|
|
194
210
|
end
|
|
195
211
|
end
|
|
196
212
|
|
|
197
213
|
|
|
198
214
|
|
|
215
|
+
##
|
|
199
216
|
# Ensure all transitions are to valid states.
|
|
200
217
|
#
|
|
201
218
|
# Replaces transition to :any with a list of all states
|
|
202
219
|
# Raises an exception if :any in included with a list of other transitions
|
|
203
220
|
#
|
|
204
|
-
def
|
|
221
|
+
def _assert_all_transitions_are_states
|
|
205
222
|
@states.each do |state_name, opts|
|
|
206
223
|
opts[:transitions_to].each do |transition|
|
|
207
224
|
unless @states.keys.include?(transition)
|
|
208
|
-
|
|
225
|
+
_cerr(:transition_state_err, state: state_name, transition: transition, kattr: true)
|
|
209
226
|
end
|
|
210
227
|
end
|
|
211
228
|
end
|
|
@@ -213,16 +230,17 @@ module StateGate
|
|
|
213
230
|
|
|
214
231
|
|
|
215
232
|
|
|
233
|
+
##
|
|
216
234
|
# Ensure there is a transition leading to every non-default state.
|
|
217
235
|
#
|
|
218
|
-
def
|
|
236
|
+
def _assert_all_states_are_reachable
|
|
219
237
|
# is there a transition to every state except the default.
|
|
220
238
|
transitions = @states.map { |_state, opts| opts[:transitions_to] }.flatten.uniq
|
|
221
239
|
adrift_states = (@states.keys - transitions - [@default])
|
|
222
240
|
return if adrift_states.blank?
|
|
223
241
|
|
|
224
242
|
states = adrift_states.map { |s| ':' + s.to_s }.to_sentence
|
|
225
|
-
|
|
243
|
+
_cerr(:transitionless_states_err, states: states, kattr: true)
|
|
226
244
|
end
|
|
227
245
|
|
|
228
246
|
end # ConfigurationMethods
|
|
@@ -6,8 +6,8 @@ module StateGate
|
|
|
6
6
|
# = Description
|
|
7
7
|
#
|
|
8
8
|
# Adds error reporting methods to a StateMachine::Engine
|
|
9
|
-
#
|
|
10
|
-
#
|
|
9
|
+
# - all error messages are I18n configured
|
|
10
|
+
# - method names are deliberately short to encourage code readability with
|
|
11
11
|
# if/unless one-liners
|
|
12
12
|
module Errator
|
|
13
13
|
|
|
@@ -15,24 +15,39 @@ module StateGate
|
|
|
15
15
|
# ======================================================================
|
|
16
16
|
private
|
|
17
17
|
|
|
18
|
+
##
|
|
18
19
|
# Format the given value and report an ArgumentError
|
|
19
20
|
#
|
|
20
|
-
|
|
21
|
+
# @param [String]
|
|
22
|
+
# the error message
|
|
23
|
+
#
|
|
24
|
+
# @raise [ArgumentError]
|
|
25
|
+
#
|
|
26
|
+
def _invalid_state_error(val)
|
|
21
27
|
case val
|
|
22
28
|
when NilClass
|
|
23
|
-
|
|
29
|
+
_aerr :invalid_state_err, val: "'nil'", kattr: true
|
|
24
30
|
when Symbol
|
|
25
|
-
|
|
31
|
+
_aerr :invalid_state_err, val: ":#{val}", kattr: true
|
|
26
32
|
else
|
|
27
|
-
|
|
33
|
+
_aerr :invalid_state_err, val: "'#{val&.to_s}'", kattr: true
|
|
28
34
|
end
|
|
29
35
|
end
|
|
30
36
|
|
|
31
37
|
|
|
32
38
|
|
|
39
|
+
##
|
|
33
40
|
# Report a ConfigurationError, including the Klass#attr variable.
|
|
34
41
|
#
|
|
35
|
-
|
|
42
|
+
# @param [Symbol] err
|
|
43
|
+
# the I18n error message key
|
|
44
|
+
#
|
|
45
|
+
# @param [Hash] args
|
|
46
|
+
# arguments to be included in the error
|
|
47
|
+
#
|
|
48
|
+
# @raise [ConfigurationError]
|
|
49
|
+
#
|
|
50
|
+
def _cerr(err, **args)
|
|
36
51
|
args[:kattr] = "#{@klass}##{@attribute}" if args[:kattr] == true
|
|
37
52
|
key = "state_gate.engine.config.#{err}"
|
|
38
53
|
fail ConfigurationError, I18n.t(key, **args)
|
|
@@ -40,9 +55,18 @@ module StateGate
|
|
|
40
55
|
|
|
41
56
|
|
|
42
57
|
|
|
58
|
+
##
|
|
43
59
|
# Report a RuntimeError, including the Klass#attr variable.
|
|
44
60
|
#
|
|
45
|
-
|
|
61
|
+
# @param [Symbol] err
|
|
62
|
+
# the I18n error message key
|
|
63
|
+
#
|
|
64
|
+
# @param [Hash] args
|
|
65
|
+
# arguments to be included in the error
|
|
66
|
+
#
|
|
67
|
+
# @raise [RuntimeError]
|
|
68
|
+
#
|
|
69
|
+
def _rerr(err, **args)
|
|
46
70
|
args[:kattr] = "#{@klass}##{@attribute}" if args[:kattr] == true
|
|
47
71
|
key = "state_gate.engine.#{err}"
|
|
48
72
|
fail I18n.t(key, **args)
|
|
@@ -50,9 +74,18 @@ module StateGate
|
|
|
50
74
|
|
|
51
75
|
|
|
52
76
|
|
|
77
|
+
##
|
|
53
78
|
# Report an ArgumentError, including the Klass#attr variable.
|
|
54
79
|
#
|
|
55
|
-
|
|
80
|
+
# @param [Symbol] err
|
|
81
|
+
# the I18n error message key
|
|
82
|
+
#
|
|
83
|
+
# @param [Hash] args
|
|
84
|
+
# arguments to be included in the error
|
|
85
|
+
#
|
|
86
|
+
# @raise [ArgumentError]
|
|
87
|
+
#
|
|
88
|
+
def _aerr(err, **args)
|
|
56
89
|
args[:kattr] = "#{@klass}##{@attribute}" if args[:kattr] == true
|
|
57
90
|
key = "state_gate.engine.#{err}"
|
|
58
91
|
fail ArgumentError, I18n.t(key, **args)
|
|
@@ -13,15 +13,19 @@ module StateGate
|
|
|
13
13
|
# Configuration Methods
|
|
14
14
|
# ======================================================================
|
|
15
15
|
|
|
16
|
+
##
|
|
16
17
|
# A phrase to add before state names when using Class Scopes.
|
|
17
18
|
# This helps differential attributes that have similar state names.
|
|
18
|
-
# (Symbol | optional)
|
|
19
19
|
#
|
|
20
|
-
#
|
|
20
|
+
# @param [Symbol] val
|
|
21
|
+
# the prefix to use
|
|
22
|
+
#
|
|
23
|
+
# @example
|
|
24
|
+
# prefix :before #=> Class.before_active
|
|
21
25
|
#
|
|
22
26
|
def prefix(val = nil)
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
_cerr(:prefix_type_err, kattr: true) unless val.is_a?(Symbol)
|
|
28
|
+
_cerr(:prefix_multiple_err, kattr: true) if @prefix
|
|
25
29
|
@prefix = "#{val.to_s.downcase}_"
|
|
26
30
|
end # prefix
|
|
27
31
|
|
|
@@ -29,13 +33,16 @@ module StateGate
|
|
|
29
33
|
|
|
30
34
|
# A phrase to add before state names when using Class Scopes.
|
|
31
35
|
# This helps differential attributes that have similar state names.
|
|
32
|
-
# (Symbol | optional)
|
|
33
36
|
#
|
|
34
|
-
#
|
|
37
|
+
# @param [Symbol] val
|
|
38
|
+
# the suffix to use
|
|
39
|
+
#
|
|
40
|
+
# @example
|
|
41
|
+
# suffix :after #=> Class.active_after
|
|
35
42
|
#
|
|
36
43
|
def suffix(val = nil)
|
|
37
|
-
|
|
38
|
-
|
|
44
|
+
_cerr(:suffix_type_err, kattr: true) unless val.is_a?(Symbol)
|
|
45
|
+
_cerr(:suffix_multiple_err, kattr: true) if @suffix
|
|
39
46
|
@suffix = "_#{val.to_s.downcase}"
|
|
40
47
|
end # suffix
|
|
41
48
|
|
|
@@ -49,8 +56,9 @@ module StateGate
|
|
|
49
56
|
# Returns the defined prefix for the state_gate, or an empty string if no
|
|
50
57
|
# prefix has been defined.
|
|
51
58
|
#
|
|
52
|
-
#
|
|
53
|
-
# .state_prefix
|
|
59
|
+
# @example
|
|
60
|
+
# .state_prefix #=> 'my_prefix'
|
|
61
|
+
# .state_prefix #=> ''
|
|
54
62
|
#
|
|
55
63
|
def state_prefix
|
|
56
64
|
@prefix
|
|
@@ -62,8 +70,9 @@ module StateGate
|
|
|
62
70
|
# Returns the defined suffix for the state_gate, or an empty string if no
|
|
63
71
|
# suffix has been defined.
|
|
64
72
|
#
|
|
65
|
-
#
|
|
66
|
-
# .state_suffix
|
|
73
|
+
# @example
|
|
74
|
+
# .state_suffix #=> 'my_suffix'
|
|
75
|
+
# .state_suffix #=> ''
|
|
67
76
|
#
|
|
68
77
|
def state_suffix
|
|
69
78
|
@suffix
|
|
@@ -13,8 +13,10 @@ module StateGate
|
|
|
13
13
|
# Configuration Methods
|
|
14
14
|
# ======================================================================
|
|
15
15
|
|
|
16
|
+
##
|
|
16
17
|
# Disables the generation of Class Scope helpers methods
|
|
17
18
|
#
|
|
19
|
+
# @example
|
|
18
20
|
# no_scopes
|
|
19
21
|
#
|
|
20
22
|
def no_scopes
|
|
@@ -23,6 +25,7 @@ module StateGate
|
|
|
23
25
|
|
|
24
26
|
|
|
25
27
|
|
|
28
|
+
##
|
|
26
29
|
# Generate the scope name to use for each state.
|
|
27
30
|
#
|
|
28
31
|
def generate_scope_names
|
|
@@ -40,7 +43,8 @@ module StateGate
|
|
|
40
43
|
##
|
|
41
44
|
# Returns TRUE if scope methods should be added to the model, otherwise FALSE.
|
|
42
45
|
#
|
|
43
|
-
#
|
|
46
|
+
# @example
|
|
47
|
+
# .include_scopes? #=> true
|
|
44
48
|
#
|
|
45
49
|
def include_scopes?
|
|
46
50
|
!!@scopes
|
|
@@ -52,9 +56,13 @@ module StateGate
|
|
|
52
56
|
# Returns the scope name for the given state. Scope names are generated by
|
|
53
57
|
# concatenating the prefix, state name and suffix
|
|
54
58
|
#
|
|
55
|
-
#
|
|
56
|
-
#
|
|
57
|
-
#
|
|
59
|
+
# @param [Symbol] state_name
|
|
60
|
+
# the state to generate the scope_name for
|
|
61
|
+
#
|
|
62
|
+
# Example
|
|
63
|
+
# .scope_name_for_state(:active) #=> 'active'
|
|
64
|
+
# .scope_name_for_state(:pending) #=> 'pending_status'
|
|
65
|
+
# .scope_name_for_state(:archived) #=> 'with_archived_status'
|
|
58
66
|
#
|
|
59
67
|
def scope_name_for_state(state_name = nil)
|
|
60
68
|
state = assert_valid_state!(state_name)
|
|
@@ -15,16 +15,23 @@ module StateGate
|
|
|
15
15
|
# Configuration Methods
|
|
16
16
|
# ======================================================================
|
|
17
17
|
|
|
18
|
+
##
|
|
18
19
|
# Automatically add transitions from each state to the preceeding and following states.
|
|
19
20
|
# make_sequential
|
|
20
21
|
#
|
|
21
|
-
# [
|
|
22
|
+
# @param [Array[Symbol]] args
|
|
23
|
+
# the optional configuration arguments
|
|
24
|
+
#
|
|
25
|
+
# @option args [Symbol] :one_way
|
|
22
26
|
# Only adds tranitions from each state to the follow state. (optional)
|
|
23
|
-
# make_sequential :one_way
|
|
24
27
|
#
|
|
25
|
-
# [:loop
|
|
28
|
+
# @option args [Symbol] :loop
|
|
26
29
|
# Adds transitions from the last state to the first and from the first to the last
|
|
27
30
|
# (unless also :one_way) (optional)
|
|
31
|
+
#
|
|
32
|
+
# @example
|
|
33
|
+
# make_sequential :one_way
|
|
34
|
+
# make_sequential :loop
|
|
28
35
|
# make_sequential :one_way, :loop
|
|
29
36
|
#
|
|
30
37
|
def make_sequential(*args)
|
|
@@ -35,6 +42,7 @@ module StateGate
|
|
|
35
42
|
|
|
36
43
|
|
|
37
44
|
|
|
45
|
+
##
|
|
38
46
|
# Add sequence hooks if sequential requested.
|
|
39
47
|
#
|
|
40
48
|
def generate_sequences
|
|
@@ -47,6 +55,7 @@ module StateGate
|
|
|
47
55
|
|
|
48
56
|
|
|
49
57
|
|
|
58
|
+
##
|
|
50
59
|
# Add the previous sequential state
|
|
51
60
|
#
|
|
52
61
|
def add_previous_sequential_state
|
|
@@ -64,6 +73,7 @@ module StateGate
|
|
|
64
73
|
|
|
65
74
|
|
|
66
75
|
|
|
76
|
+
##
|
|
67
77
|
# Add the next sequential state
|
|
68
78
|
#
|
|
69
79
|
def add_next_sequential_state
|
|
@@ -79,6 +89,7 @@ module StateGate
|
|
|
79
89
|
|
|
80
90
|
|
|
81
91
|
|
|
92
|
+
##
|
|
82
93
|
# Add the first and last transitions to complete the sequential loop.
|
|
83
94
|
#
|
|
84
95
|
def loop_sequence
|
|
@@ -103,9 +114,11 @@ module StateGate
|
|
|
103
114
|
# ======================================================================
|
|
104
115
|
|
|
105
116
|
##
|
|
106
|
-
# return
|
|
117
|
+
# @return [Boolean]
|
|
118
|
+
# true if the state_gate is sequential, otherwise false.
|
|
107
119
|
#
|
|
108
|
-
#
|
|
120
|
+
# @example
|
|
121
|
+
# .sequential? #=> TRUE
|
|
109
122
|
#
|
|
110
123
|
def sequential?
|
|
111
124
|
!!@sequential
|