Module: Roby::TaskStateHelper
- Included in:
- Task
- Defined in:
- lib/roby/coordination/task_state_machine.rb
Overview
The TaskStateHelper allows to add a statemachine to a Roby::Task and allows the tracking of events within the ‘running’ state
Defined Under Namespace
Classes: Proxy
Instance Method Summary collapse
- #import_events_to_roby(machine) ⇒ Object
-
#namespace ⇒ Object
The default namespace that is added to statemachine methods, e.g.
- #namespace=(name) ⇒ Object
-
#refine_running_state(*args, &block) ⇒ Object
Refine the running state of the Roby::Task using a state machine description.
-
#state_machine ⇒ Object
The state machine model that is running on all tasks of this task model.
Instance Method Details
#import_events_to_roby(machine) ⇒ Object
286 287 288 289 290 291 292 293 294 295 296 297 298 |
# File 'lib/roby/coordination/task_state_machine.rb', line 286 def import_events_to_roby(machine) # Roby requires the self to be the subclassed Roby::Task # Thus embed import into refine_running_state and using eval here machine.events.each do |e| unless has_event?(e.name) event e.name, controlable: true end # when event is called transition the state_machine on(e.name) do |event| state_machine.send("#{e.name.to_sym}!") end end end |
#namespace ⇒ Object
The default namespace that is added to statemachine methods, e.g. when action for transitions are defined
186 187 188 |
# File 'lib/roby/coordination/task_state_machine.rb', line 186 def namespace @namespace ||= nil end |
#namespace=(name) ⇒ Object
190 191 192 |
# File 'lib/roby/coordination/task_state_machine.rb', line 190 def namespace=(name) @namespace = name end |
#refine_running_state(*args, &block) ⇒ Object
Refine the running state of the Roby::Task using a state machine description. The initial state of the machine is set to ‘running’ by default.
Example:
refine_running_state do
on :pause do
transition [:running] => paused
end
on :resume do
transition [:paused] => :running
end
state :paused do
def poll(task)
sleep 4
task.emit :resume
end
end
end
Events are translated into roby events and the statemachine in hooked into the on(:yourevent) {|context| … } You can add additional event handlers as ususal using on(:yourevent) .. syntax
The current status (substate of the running state) can be retrieved via
yourtask.state_machine.status
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 |
# File 'lib/roby/coordination/task_state_machine.rb', line 242 def refine_running_state(*args, &block) if args.last.kind_of?(Hash) = args.pop end = Kernel.( || {}, namespace: nil) if .has_key?(:namespace) self.namespace = [:namespace] end # Check if a model of a class ancestor already exists # If a parent_model exists, prepare the proxy class accordingly # The proxy allows us to use the state_machine library even # with instances if parent_model = self.superclass.state_machine proxy_model = Class.new(parent_model.owner_class) else proxy_model = Class.new(Proxy) end # Create the state machine instance that will serve as base model # for instances of the Roby::Task (or its subclasses) this machine # is associated with The namespace allows to pre/postfix # automatically generated functions, such as for sending events: # <task>.state_machine.pause_<namespace>! or querying the status # <task>.state_machine.<namespace>_paused? Note cannot use :state # instead of :status here for yet unknown reason Changing the # attribute :status also changes other method definitions, due to # meta programming approach of the underlying library, e.g. # status_transitions(from: ..., to: ...) if self.namespace machine = StateMachine::Machine.find_or_create(proxy_model, :status, initial: :running, namespace: self.namespace) else machine = StateMachine::Machine.find_or_create(proxy_model, :status, initial: :running) end machine_loader = StateMachineDefinitionContext.new(self, machine) machine_loader.instance_eval(&block) @state_machine = machine import_events_to_roby(machine) end |
#state_machine ⇒ Object
The state machine model that is running on all tasks of this task model
203 204 205 206 207 208 |
# File 'lib/roby/coordination/task_state_machine.rb', line 203 def state_machine if @state_machine then @state_machine elsif superclass.respond_to?(:state_machine) superclass.state_machine end end |