Class: Roby::Coordination::TaskScript
Overview
Implementation of a task script
The model-level accessors and API is described in Models::Script
Constant Summary
Constants included from Script
Instance Attribute Summary collapse
-
#definition_block ⇒ Object
readonly
Returns the value of attribute definition_block.
Attributes included from Script
#current_instruction, #instructions
Attributes inherited from Base
#arguments, #instances, #parent
Instance Method Summary collapse
- #bind(task) ⇒ Object
-
#emit(event) ⇒ Object
Emit the given event.
- #execute(task = nil, &block) ⇒ Object
- #method_missing(m, *args, &block) ⇒ Object
- #parse(&block) ⇒ Object
-
#poll(&block) ⇒ Object
Executes the provided block once per execution cycle.
-
#poll_until(event, &block) ⇒ Object
Execute the provided block once per execution cycle, until the given event is emitted.
-
#resolve_event(event) ⇒ Object
Resolve the given event object into a Coordination::Event and a Coordination::Models::Event.
- #resolve_instructions ⇒ Object
-
#resolve_task(task) ⇒ Object
Resolve the given event object into a Coordination::Task and a Coordination::Models::Task.
- #respond_to_missing?(m, include_private) ⇒ Boolean
-
#sleep(seconds) ⇒ Object
Sleep for a given number of seconds.
-
#start(task, explicit_start: false, **dependency_options) ⇒ Object
Start the given task at that point in the script, and wait for it to emit its start event.
-
#start_task(task, explicit_start: false) ⇒ Object
Used by Script.
- #task ⇒ Object deprecated Deprecated.
-
#timeout(seconds, options = {}, &block) ⇒ Object
Execute the script instructions given as block.
-
#timeout_start(seconds, options = {}) ⇒ Object
Start a timeout operation.
-
#timeout_stop(timeout) ⇒ Object
Stop a timeout operation.
-
#transition! ⇒ Object
Quit a #poll block.
-
#wait(event, options = {}) ⇒ Object
Wait for an event to be emitted.
- #wait_any(event, options = {}) ⇒ Object deprecated Deprecated.
-
#wait_until ⇒ Object
Waits until the given block returns true.
Methods included from Models::Script
add, call, instructions, terminal, terminal?
Methods included from Script
#dependency_options_for, #finished?, #jump_to, #prepare, #step
Methods inherited from Base
#attach_fault_response_tables_to, #bind_coordination_task_to_instance, #initialize, #instance_for, #model, #plan, #root_task
Constructor Details
This class inherits a constructor from Roby::Coordination::Base
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(m, *args, &block) ⇒ Object
249 250 251 252 253 254 255 |
# File 'lib/roby/coordination/task_script.rb', line 249 def method_missing(m, *args, &block) if m =~ /_(?:event|child)$/ instance_for(model.root).send(m, *args, &block) else super end end |
Instance Attribute Details
#definition_block ⇒ Object (readonly)
Returns the value of attribute definition_block.
15 16 17 |
# File 'lib/roby/coordination/task_script.rb', line 15 def definition_block @definition_block end |
Instance Method Details
#bind(task) ⇒ Object
29 30 31 32 33 34 35 |
# File 'lib/roby/coordination/task_script.rb', line 29 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(event) ⇒ Object
Emit the given event
172 173 174 175 176 |
# File 'lib/roby/coordination/task_script.rb', line 172 def emit(event) event, model_event = resolve_event(event) model.emit(model_event) event end |
#execute(task) ⇒ Object #execute({ ... }) ⇒ Object
117 118 119 120 121 122 123 124 125 126 |
# File 'lib/roby/coordination/task_script.rb', line 117 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 |
#parse(&block) ⇒ Object
24 25 26 27 |
# File 'lib/roby/coordination/task_script.rb', line 24 def parse(&block) @definition_block = block instance_eval(&block) end |
#poll(&block) ⇒ Object
Executes the provided block once per execution cycle
Call #transition! to quit the block
181 182 183 |
# File 'lib/roby/coordination/task_script.rb', line 181 def poll(&block) poll_until(poll_transition_event, &block) end |
#poll_until(event, &block) ⇒ Object
Execute the provided block once per execution cycle, until the given event is emitted
187 188 189 190 191 192 193 |
# File 'lib/roby/coordination/task_script.rb', line 187 def poll_until(event, &block) raise ArgumentError, "poll_until requires a block" unless block event, model_event = resolve_event(event) model.instructions << Script::Models::PollUntil.new(model_event, block) event end |
#resolve_event(event) ⇒ Object
Resolve the given event object into a Coordination::Event and a Coordination::Models::Event
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/roby/coordination/task_script.rb', line 81 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 unless event raise ArgumentError, "#{model.root} has no event called #{symbol}" end end _, model_task = resolve_task(event.task) model_event = model_task.find_event(event.symbol) script_event = instance_for(model_event) [script_event, model_event] end |
#resolve_instructions ⇒ Object
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/roby/coordination/task_script.rb', line 37 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. end end end |
#resolve_task(task) ⇒ Object
Resolve the given event object into a Coordination::Task and a Coordination::Models::Task
65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/roby/coordination/task_script.rb', line 65 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 [script_task, model_task] end |
#respond_to_missing?(m, include_private) ⇒ Boolean
241 242 243 244 245 246 247 |
# File 'lib/roby/coordination/task_script.rb', line 241 def respond_to_missing?(m, include_private) if m =~ /_(?:event|child)$/ instance_for(model.root).respond_to?(m) else super end end |
#sleep(seconds) ⇒ Object
Sleep for a given number of seconds
166 167 168 169 |
# File 'lib/roby/coordination/task_script.rb', line 166 def sleep(seconds) task = start(Tasks::Timeout.new(delay: seconds), explicit_start: true) wait task.stop_event end |
#start(task, explicit_start: false, **dependency_options) ⇒ Object
Start the given task at that point in the script, and wait for it to emit its start event
105 106 107 108 109 |
# File 'lib/roby/coordination/task_script.rb', line 105 def start(task, explicit_start: false, **) task, model_task = resolve_task(task) model.start(model_task, explicit_start: explicit_start, **) task end |
#start_task(task, explicit_start: false) ⇒ Object
Used by Script
234 235 236 237 238 239 |
# File 'lib/roby/coordination/task_script.rb', line 234 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 |
#task ⇒ Object
Use #root_task instead
20 21 22 |
# File 'lib/roby/coordination/task_script.rb', line 20 def task root_task end |
#timeout(seconds, options = {}, &block) ⇒ Object
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)
209 210 211 212 213 |
# File 'lib/roby/coordination/task_script.rb', line 209 def timeout(seconds, = {}, &block) timeout = timeout_start(seconds, ) parse(&block) timeout_stop(timeout) end |
#timeout_start(seconds, options = {}) ⇒ Object
Start a timeout operation. Usually not used directly
218 219 220 221 222 223 224 |
# File 'lib/roby/coordination/task_script.rb', line 218 def timeout_start(seconds, = {}) , = Kernel. , emit: nil if event = [:emit] _, model_event = resolve_event(event) end model.timeout_start(seconds, .merge(emit: model_event)) end |
#timeout_stop(timeout) ⇒ Object
Stop a timeout operation. Usually not used directly
229 230 231 |
# File 'lib/roby/coordination/task_script.rb', line 229 def timeout_stop(timeout) model.timeout_stop(timeout) end |
#transition! ⇒ Object
Quit a #poll block
196 197 198 |
# File 'lib/roby/coordination/task_script.rb', line 196 def transition! root_task.poll_transition_event.emit end |
#wait(event, options = {}) ⇒ Object
Wait for an event to be emitted
142 143 144 145 146 |
# File 'lib/roby/coordination/task_script.rb', line 142 def wait(event, = {}) event, model_event = resolve_event(event) model.wait(model_event, **) event end |
#wait_any(event, options = {}) ⇒ Object
Use wait(event after: Time.at(0)) instead
158 159 160 |
# File 'lib/roby/coordination/task_script.rb', line 158 def wait_any(event, = {}) wait(event, .merge(after: Time.at(0))) end |
#wait_until ⇒ Object
Waits until the given block returns true
149 150 151 152 153 |
# File 'lib/roby/coordination/task_script.rb', line 149 def wait_until poll do transition! if yield end end |