class Roby::Coordination::TaskScript
Implementation of a task script
The model-level accessors and API is described in {Models::Script}
Attributes
Public Instance Methods
# File lib/roby/coordination/task_script.rb, line 27 def bind(task) result_model = self.class.superclass.new_submodel(root: model.root.model) result = result_model.new(task) result.parse(&definition_block) result.prepare result end
Emit the given event
# File lib/roby/coordination/task_script.rb, line 163 def emit(event) event, model_event = resolve_event(event) model.emit(model_event) event end
@overload execute(task)
Deploy and start the given task, and wait for it to finish successfully
@overload execute { … }
Execute the content of the given block once
# File lib/roby/coordination/task_script.rb, line 115 def execute(task = nil, &block) if task task, model_task = resolve_task(task) model.execute(model_task) task else model.instructions << BlockExecute.new(block) nil end end
# File lib/roby/coordination/task_script.rb, line 237 def method_missing(m, *args, &block) if m =~ /_(?:event|child)$/ instance_for(model.root).send(m, *args, &block) else super end end
# File lib/roby/coordination/task_script.rb, line 22 def parse(&block) @definition_block = block instance_eval(&block) end
Executes the provided block once per execution cycle
Call {#transition!} to quit the block
# File lib/roby/coordination/task_script.rb, line 172 def poll(&block) poll_until(poll_transition_event, &block) end
Execute the provided block once per execution cycle, until the given event is emitted
# File lib/roby/coordination/task_script.rb, line 178 def poll_until(event, &block) event, model_event = resolve_event(event) model.instructions << Script::Models::PollUntil.new(model_event, block) event end
Resolve the given event object into a Coordination::Event
and a Coordination::Models::Event
# File lib/roby/coordination/task_script.rb, line 79 def resolve_event(event) if event.respond_to?(:to_sym) symbol = event if root_task event = root_task.find_event(symbol) else event = model.root.find_event(symbol) end if !event raise ArgumentError, "#{model.root} has no event called #{symbol}" end end script_task, model_task = resolve_task(event.task) model_event = model_task.find_event(event.symbol) script_event = instance_for(model_event) return script_event, model_event end
Roby::Coordination::Script#resolve_instructions
# File lib/roby/coordination/task_script.rb, line 35 def resolve_instructions super model.each_task do |model_task| script_task = instance_for(model_task) if script_task.respond_to?(:task) && !script_task.task # Not bound ? Check if the model can be instanciated task = model_task.instanciate(root_task.plan) bind_coordination_task_to_instance(script_task, task, on_replace: :copy) # Protect from scheduling until the start is executed # # #start_task will be called by the Start instruction root_task.start_event.add_causal_link(task.start_event) end end # Now, make the dependencies based on what we do / wait for with # the tasks. Namely, we look at Start (dependency options) and # Wait (success events) instructions.each do |ins| case ins when Coordination::Models::Script::Start task = ins.task.resolve root_task.depends_on task, ins.dependency_options end end end
Resolve the given event object into a Coordination::Task
and a Coordination::Models::Task
# File lib/roby/coordination/task_script.rb, line 63 def resolve_task(task) if root_task && task.kind_of?(Roby::Task) root_task.plan.add(task) model_task = Coordination::Models::Task.new(task.model) script_task = instance_for(model_task) bind_coordination_task_to_instance(script_task, task, on_replace: :copy) else model_task = self.model.task(task) script_task = instance_for(model_task) end return script_task, model_task end
# File lib/roby/coordination/task_script.rb, line 230 def respond_to_missing?(m, include_private) if m =~ /_(?:event|child)$/ instance_for(model.root).respond_to?(m) else super end end
Sleep for a given number of seconds
@param [Float] seconds the number of seconds to stop the script
execution
# File lib/roby/coordination/task_script.rb, line 157 def sleep(seconds) task = start(Tasks::Timeout.new(delay: seconds), explicit_start: true) wait task.stop_event end
Start the given task at that point in the script, and wait for it to emit its start event
@param [Task] task the task that should be started @param [Hash] dependency_options options that should be passed to
TaskStructure::Dependency::Extension#depends_on
# File lib/roby/coordination/task_script.rb, line 103 def start(task, explicit_start: false, **dependency_options) task, model_task = resolve_task(task) model.start(model_task, explicit_start: explicit_start, **dependency_options) task end
Used by Script
# File lib/roby/coordination/task_script.rb, line 223 def start_task(task, explicit_start: false) root_task.start_event.remove_causal_link(task.resolve.start_event) if explicit_start task.resolve.start_event.call end end
@deprecated
Use root_task
instead
# File lib/roby/coordination/task_script.rb, line 18 def task root_task end
Execute the script instructions given as block. If they take more than the specified number of seconds, either generate an error or emit an event (and quit the block)
@param [Hash] options @option options [Event] :event (nil) if set, the given event will
be emitted when the timeout is reached. Otherwise, a Script::TimedOut exception is generated with the script's supporting task as origin
# File lib/roby/coordination/task_script.rb, line 198 def timeout(seconds, options = Hash.new, &block) timeout = timeout_start(seconds, options) parse(&block) timeout_stop(timeout) end
Start a timeout operation. Usually not used directly
@see timeout
# File lib/roby/coordination/task_script.rb, line 207 def timeout_start(seconds, options = Hash.new) options, timeout_options = Kernel.filter_options options, emit: nil if event = options[:emit] script_event, model_event = resolve_event(event) end model.timeout_start(seconds, timeout_options.merge(emit: model_event)) end
Stop a timeout operation. Usually not used directly
@see timeout
# File lib/roby/coordination/task_script.rb, line 218 def timeout_stop(timeout) model.timeout_stop(timeout) end
Quit a {#poll} block
# File lib/roby/coordination/task_script.rb, line 185 def transition! root_task.poll_transition_event.emit end
Wait for an event to be emitted
@param [Hash] options @option options [Time,nil] after (nil) if set, only event
emissions that happened after this value will make the script pass this instruction. The default of nil means "from the point of this instruction on"
@example wait first_child.start_event
Waits until start event has been emitted. Will wait forever if the start event has already been emitted
@example wait first_child.start_event, after: Time.at(0)
Waits for start event to be emitted. Will return immediately if it has already been emitted.
# File lib/roby/coordination/task_script.rb, line 140 def wait(event, options = Hash.new) event, model_event = resolve_event(event) model.wait(model_event, options) event end
@deprecated
Use wait(event after: Time.at(0)) instead
# File lib/roby/coordination/task_script.rb, line 149 def wait_any(event, options = Hash.new) wait(event, options.merge(after: Time.at(0))) end