Module: Roby::Test::RunPlanners
Overview
Module that implement the #run_planners functionality
It is already included in Roby’s own test classes, you do not need to use this module directly. Simply use #run_planners
Defined Under Namespace
Classes: ActionPlanningHandler, PlanningHandler
Constant Summary collapse
- @@roby_planner_handlers =
[]
Class Method Summary collapse
-
.deregister_planning_handler(handler) ⇒ Object
Remove a planning handler added with roby_plan_with.
-
.planner_handler_for(task) ⇒ PlanningHandler
private
Find the handler that should be used by #roby_run_planner to plan a given task.
-
.roby_plan_with(matcher, handler) ⇒ Object
Declare what #roby_run_planner should use to develop a given task during a test.
-
.setup_planning_handlers(test, plan, root_tasks, recursive: true) ⇒ Object
private
Helper that sets up the planning handlers for #run_planners.
Instance Method Summary collapse
-
#run_planners(root_tasks, recursive: true) ⇒ Object
Run the planners that are required by a task or subplan.
Class Method Details
.deregister_planning_handler(handler) ⇒ Object
Remove a planning handler added with roby_plan_with
184 185 186 |
# File 'lib/roby/test/run_planners.rb', line 184 def self.deregister_planning_handler(handler) @@roby_planner_handlers.delete_if { |_, h| h == handler } end |
.planner_handler_for(task) ⇒ PlanningHandler
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Find the handler that should be used by #roby_run_planner to plan a given task.
161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/roby/test/run_planners.rb', line 161 def self.planner_handler_for(task) _, handler_class = @@roby_planner_handlers.find do |matcher, _handler| matcher === task end unless handler_class raise ArgumentError, "no planning handler found for #{task}" end handler_class end |
.roby_plan_with(matcher, handler) ⇒ Object
Declare what #roby_run_planner should use to develop a given task during a test
The latest handler registered wins
179 180 181 |
# File 'lib/roby/test/run_planners.rb', line 179 def self.roby_plan_with(matcher, handler) @@roby_planner_handlers.unshift [matcher, handler] end |
.setup_planning_handlers(test, plan, root_tasks, recursive: true) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Helper that sets up the planning handlers for #run_planners
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/roby/test/run_planners.rb', line 13 def self.setup_planning_handlers(test, plan, root_tasks, recursive: true) root_tasks = root_tasks.map do |root_task| if root_task.respond_to?(:as_plan) root_task = root_task.as_plan plan.add(root_task) end root_task end if recursive tasks = root_tasks.each_with_object(root_tasks.to_set) do |task, s| s.merge( plan.task_relation_graph_for(Roby::TaskStructure::Dependency) .enum_for(:depth_first_visit, task).to_set ) end else tasks = root_tasks.to_set end by_handler = tasks .find_all { |t| t.abstract? && t.planning_task } .find_all { |t| !t.planning_task.failed? } .group_by { |t| RunPlanners.planner_handler_for(t) } .map { |h_class, h_tasks| [h_class.new(test), h_tasks] } return root_tasks.map(&:as_service), [] if by_handler.empty? placeholder_tasks = {} by_handler.each do |handler, handler_tasks| handler_tasks.each do |t| placeholder_tasks[t] ||= t.as_service end handler.start(handler_tasks) end services = root_tasks.map { |t| placeholder_tasks[t] ||= t.as_service } [services, by_handler] end |
Instance Method Details
#run_planners(root_tasks, recursive: true) ⇒ Object
Run the planners that are required by a task or subplan
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/roby/test/run_planners.rb', line 64 def run_planners(root_tasks, recursive: true) was_array = root_tasks.respond_to?(:to_ary) root_tasks = Array(root_tasks) if (not_a_task = root_tasks.find { |t| !t.respond_to?(:as_plan) }) raise ArgumentError, "#{not_a_task} is not a Roby task and cannot "\ "be converted to one" end unless execution_engine.in_propagation_context? services = nil expect_execution do services = run_planners(root_tasks, recursive: recursive) end.to_run result_tasks = services.map(&:to_task) return was_array ? result_tasks : result_tasks.first end root_task_services, by_handler = RunPlanners.setup_planning_handlers( self, plan, root_tasks, recursive: recursive ) if by_handler.empty? return was_array ? root_task_services : root_task_services.first end add_expectations do all_handlers_finished = false achieve(description: "expected all planning handlers to finish") do # by_handler == nil is used to indicate that an execute # block is pending if all_handlers_finished all_handlers_finished = false if recursive by_handler = nil execute do new_roots = root_task_services.map(&:to_task) root_task_services, by_handler = RunPlanners.setup_planning_handlers( self, plan, new_roots, recursive: true ) end else by_handler = [] end elsif by_handler && !by_handler.empty? execute do all_handlers_finished = by_handler.all? { |handler, _| handler.finished? } end end # by_handler == nil is used to indicate that an execute # block is pending by_handler&.empty? end end was_array ? root_task_services : root_task_services.first end |