module Roby::TaskStateHelper
The TaskStateHelper
allows to add a statemachine to a Roby::Task
and allows the tracking of events within the 'running' state
Public Instance Methods
import_events_to_roby(machine)
click to toggle source
# File lib/roby/coordination/task_state_machine.rb, line 285 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| if !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()
click to toggle source
The default namespace that is added to statemachine methods, e.g. when action for transitions are defined
# File lib/roby/coordination/task_state_machine.rb, line 185 def namespace @namespace ||= nil end
namespace=(name)
click to toggle source
# File lib/roby/coordination/task_state_machine.rb, line 189 def namespace=(name) @namespace=name end
refine_running_state(*args, &block)
click to toggle source
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
# File lib/roby/coordination/task_state_machine.rb, line 241 def refine_running_state (*args, &block) if args.last.kind_of?(Hash) options = args.pop end options = Kernel.validate_options(options || Hash.new, namespace: nil) if options.has_key?(:namespace) self.namespace=options[: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()
click to toggle source
The state machine model that is running on all tasks of this task model
# File lib/roby/coordination/task_state_machine.rb, line 202 def state_machine if @state_machine then @state_machine elsif superclass.respond_to?(:state_machine) superclass.state_machine end end