roby 0.8.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (644) hide show
  1. checksums.yaml +7 -0
  2. data/.deep-cover.rb +3 -0
  3. data/.gitattributes +1 -0
  4. data/.gitignore +24 -0
  5. data/.simplecov +10 -0
  6. data/.travis.yml +17 -0
  7. data/.yardopts +4 -0
  8. data/Gemfile +15 -0
  9. data/README.md +11 -0
  10. data/Rakefile +47 -177
  11. data/benchmark/{alloc_misc.rb → attic/alloc_misc.rb} +2 -2
  12. data/benchmark/{discovery_latency.rb → attic/discovery_latency.rb} +19 -19
  13. data/benchmark/{garbage_collection.rb → attic/garbage_collection.rb} +9 -9
  14. data/benchmark/{genom.rb → attic/genom.rb} +0 -0
  15. data/benchmark/attic/transactions.rb +62 -0
  16. data/benchmark/plan_basic_operations.rb +28 -0
  17. data/benchmark/relations/graph.rb +63 -0
  18. data/benchmark/ruby/identity.rb +18 -0
  19. data/benchmark/ruby/set_intersect_vs_hash_merge.rb +39 -0
  20. data/benchmark/ruby/yield_vs_block.rb +35 -0
  21. data/benchmark/run +5 -0
  22. data/benchmark/synthetic_plan_modifications_with_transactions.rb +79 -0
  23. data/benchmark/transactions.rb +99 -51
  24. data/bin/roby +38 -197
  25. data/bin/roby-display +14 -0
  26. data/bin/roby-log +3 -176
  27. data/doc/guide/{src → attic}/abstraction/achieve_with.page +1 -1
  28. data/doc/guide/{src → attic}/abstraction/forwarding.page +1 -1
  29. data/doc/guide/{src → attic}/abstraction/hierarchy.page +1 -1
  30. data/doc/guide/{src → attic}/abstraction/index.page +1 -1
  31. data/doc/guide/{src → attic}/abstraction/task_models.page +1 -1
  32. data/doc/guide/{overview.rdoc → attic/cycle/api_overview.rdoc} +6 -1
  33. data/doc/guide/{src → attic}/cycle/cycle-overview.png +0 -0
  34. data/doc/guide/{src → attic}/cycle/cycle-overview.svg +0 -0
  35. data/doc/guide/attic/cycle/error_handling.page +98 -0
  36. data/doc/guide/{src → attic}/cycle/error_instantaneous_repair.png +0 -0
  37. data/doc/guide/{src → attic}/cycle/error_instantaneous_repair.svg +0 -0
  38. data/doc/guide/{src/cycle/error_handling.page → attic/cycle/error_sources.page} +46 -89
  39. data/doc/guide/{src → attic}/cycle/garbage_collection.page +1 -1
  40. data/doc/guide/{src → attic}/cycle/index.page +1 -1
  41. data/doc/guide/{src → attic}/cycle/propagation.page +11 -1
  42. data/doc/guide/{src → attic}/cycle/propagation_diamond.png +0 -0
  43. data/doc/guide/{src → attic}/cycle/propagation_diamond.svg +0 -0
  44. data/doc/guide/attic/plans/building_plans.page +89 -0
  45. data/doc/guide/attic/plans/code.page +192 -0
  46. data/doc/guide/{src/basics → attic/plans}/events.page +3 -4
  47. data/doc/guide/attic/plans/index.page +7 -0
  48. data/doc/guide/{plan_modifications.rdoc → attic/plans/plan_modifications.rdoc} +5 -3
  49. data/doc/guide/{src/basics → attic/plans}/plan_objects.page +2 -1
  50. data/doc/guide/attic/plans/querying_plans.page +5 -0
  51. data/doc/guide/{src/basics → attic/plans}/tasks.page +20 -20
  52. data/doc/guide/config.yaml +7 -4
  53. data/doc/guide/ext/extended_menu.rb +29 -0
  54. data/doc/guide/ext/init.rb +6 -0
  55. data/doc/guide/ext/rdoc_links.rb +7 -6
  56. data/doc/guide/src/advanced_concepts/history.page +5 -0
  57. data/doc/guide/src/advanced_concepts/index.page +11 -0
  58. data/doc/guide/src/advanced_concepts/recognizing_patterns.page +83 -0
  59. data/doc/guide/src/advanced_concepts/scheduling.page +87 -0
  60. data/doc/guide/src/advanced_concepts/transactions.page +5 -0
  61. data/doc/guide/src/advanced_concepts/unreachability.page +42 -0
  62. data/doc/guide/src/base.template +96 -0
  63. data/doc/guide/src/basics_shell_header.txt +5 -7
  64. data/doc/guide/src/building/action_coordination.page +96 -0
  65. data/doc/guide/src/building/actions.page +124 -0
  66. data/doc/guide/src/building/file_layout.page +71 -0
  67. data/doc/guide/src/building/index.page +50 -0
  68. data/doc/guide/src/building/patterns.page +86 -0
  69. data/doc/guide/src/building/patterns_forwarding.png +0 -0
  70. data/doc/guide/src/building/patterns_forwarding.svg +277 -0
  71. data/doc/guide/src/building/runtime.page +95 -0
  72. data/doc/guide/src/building/task_models.page +94 -0
  73. data/doc/guide/src/building/tasks.page +284 -0
  74. data/doc/guide/src/concepts/error_handling.page +100 -0
  75. data/doc/guide/src/concepts/exception_propagation.png +0 -0
  76. data/doc/guide/src/concepts/exception_propagation.svg +445 -0
  77. data/doc/guide/src/concepts/execution.page +85 -0
  78. data/doc/guide/src/concepts/execution.png +0 -0
  79. data/doc/guide/src/concepts/execution.svg +573 -0
  80. data/doc/guide/src/concepts/execution_cycle.png +0 -0
  81. data/doc/guide/src/concepts/garbage_collection.page +57 -0
  82. data/doc/guide/src/concepts/index.page +27 -0
  83. data/doc/guide/src/concepts/plans.page +101 -0
  84. data/doc/guide/src/concepts/policy.page +31 -0
  85. data/doc/guide/src/concepts/reactor.page +61 -0
  86. data/doc/guide/src/concepts/simple_plan_example.png +0 -0
  87. data/doc/guide/src/concepts/simple_plan_example.svg +376 -0
  88. data/doc/guide/src/default.template +9 -74
  89. data/doc/guide/src/event_relations/forward.page +71 -0
  90. data/doc/guide/src/event_relations/index.page +12 -0
  91. data/doc/guide/src/event_relations/scheduling_constraints.page +43 -0
  92. data/doc/guide/src/event_relations/signal.page +55 -0
  93. data/doc/guide/src/event_relations/temporal_constraints.page +77 -0
  94. data/doc/guide/src/htmldoc.metainfo +21 -8
  95. data/doc/guide/src/index.page +8 -3
  96. data/doc/guide/src/{introduction/install.page → installation/index.page} +37 -25
  97. data/doc/guide/src/installation/publications.page +14 -0
  98. data/doc/guide/src/{introduction → installation}/videos.page +14 -7
  99. data/doc/guide/src/interacting/index.page +16 -0
  100. data/doc/guide/src/interacting/run.page +33 -0
  101. data/doc/guide/src/interacting/shell.page +95 -0
  102. data/doc/guide/src/plugins/creating_plugins.page +72 -0
  103. data/doc/guide/src/plugins/index.page +27 -5
  104. data/doc/guide/src/plugins/{fault_tolerance.page → standard_plugins/fault_tolerance.page} +2 -2
  105. data/doc/guide/src/plugins/standard_plugins/index.page +11 -0
  106. data/doc/guide/src/plugins/{subsystems.page → standard_plugins/subsystems.page} +2 -2
  107. data/doc/guide/src/style_screen.css +687 -0
  108. data/doc/guide/src/task_relations/dependency.page +107 -0
  109. data/doc/guide/src/task_relations/executed_by.page +77 -0
  110. data/doc/guide/src/task_relations/index.page +12 -0
  111. data/doc/guide/src/task_relations/new_relations.page +119 -0
  112. data/doc/guide/src/task_relations/planned_by.page +46 -0
  113. data/doc/guide/src/tutorial/app.page +117 -0
  114. data/doc/guide/src/{basics → tutorial}/code_examples.page +6 -5
  115. data/doc/guide/src/{basics → tutorial}/dry.page +15 -15
  116. data/doc/guide/src/{basics → tutorial}/errors.page +43 -68
  117. data/doc/guide/src/tutorial/events.page +195 -0
  118. data/doc/guide/src/{basics → tutorial}/hierarchy.page +53 -52
  119. data/doc/guide/src/tutorial/index.page +13 -0
  120. data/doc/guide/src/tutorial/log_replay/goForward_1.png +0 -0
  121. data/doc/guide/src/tutorial/log_replay/goForward_2.png +0 -0
  122. data/doc/guide/src/tutorial/log_replay/goForward_3.png +0 -0
  123. data/doc/guide/src/{basics → tutorial}/log_replay/goForward_4.png +0 -0
  124. data/doc/guide/src/tutorial/log_replay/goForward_5.png +0 -0
  125. data/doc/guide/src/{basics → tutorial}/log_replay/hierarchy_error_1.png +0 -0
  126. data/doc/guide/src/{basics → tutorial}/log_replay/hierarchy_error_2.png +0 -0
  127. data/doc/guide/src/{basics → tutorial}/log_replay/hierarchy_error_3.png +0 -0
  128. data/doc/guide/src/tutorial/log_replay/moveto_code_error.png +0 -0
  129. data/doc/guide/src/{basics → tutorial}/log_replay/plan_repair_1.png +0 -0
  130. data/doc/guide/src/{basics → tutorial}/log_replay/plan_repair_2.png +0 -0
  131. data/doc/guide/src/{basics → tutorial}/log_replay/plan_repair_3.png +0 -0
  132. data/doc/guide/src/tutorial/log_replay/plan_repair_4.png +0 -0
  133. data/doc/guide/src/tutorial/log_replay/roby_log_main_window.png +0 -0
  134. data/doc/guide/src/{basics → tutorial}/log_replay/roby_log_relation_window.png +0 -0
  135. data/doc/guide/src/{basics → tutorial}/log_replay/roby_replay_event_representation.png +0 -0
  136. data/doc/guide/src/tutorial/relations_display.page +153 -0
  137. data/doc/guide/src/{basics → tutorial}/roby_cycle_overview.png +0 -0
  138. data/doc/guide/src/tutorial/shell.page +121 -0
  139. data/doc/guide/src/{basics → tutorial}/summary.page +1 -1
  140. data/doc/guide/src/tutorial/tasks.page +374 -0
  141. data/lib/roby.rb +102 -47
  142. data/lib/roby/actions.rb +17 -0
  143. data/lib/roby/actions/action.rb +80 -0
  144. data/lib/roby/actions/interface.rb +45 -0
  145. data/lib/roby/actions/library.rb +23 -0
  146. data/lib/roby/actions/models/action.rb +224 -0
  147. data/lib/roby/actions/models/coordination_action.rb +58 -0
  148. data/lib/roby/actions/models/interface.rb +22 -0
  149. data/lib/roby/actions/models/interface_base.rb +294 -0
  150. data/lib/roby/actions/models/library.rb +12 -0
  151. data/lib/roby/actions/models/method_action.rb +90 -0
  152. data/lib/roby/actions/task.rb +114 -0
  153. data/lib/roby/and_generator.rb +125 -0
  154. data/lib/roby/app.rb +2795 -829
  155. data/lib/roby/app/autotest_console_reporter.rb +138 -0
  156. data/lib/roby/app/base.rb +21 -0
  157. data/lib/roby/app/cucumber.rb +2 -0
  158. data/lib/roby/app/cucumber/controller.rb +439 -0
  159. data/lib/roby/app/cucumber/helpers.rb +280 -0
  160. data/lib/roby/app/cucumber/world.rb +32 -0
  161. data/lib/roby/app/debug.rb +136 -0
  162. data/lib/roby/app/gen.rb +2 -0
  163. data/lib/roby/app/rake.rb +178 -38
  164. data/lib/roby/app/robot_config.rb +9 -0
  165. data/lib/roby/app/robot_names.rb +115 -0
  166. data/lib/roby/app/run.rb +3 -2
  167. data/lib/roby/app/scripts.rb +72 -0
  168. data/lib/roby/app/scripts/autotest.rb +173 -0
  169. data/lib/roby/app/scripts/display.rb +2 -0
  170. data/lib/roby/app/scripts/restart.rb +52 -0
  171. data/lib/roby/app/scripts/results.rb +17 -8
  172. data/lib/roby/app/scripts/run.rb +155 -24
  173. data/lib/roby/app/scripts/shell.rb +147 -62
  174. data/lib/roby/app/scripts/test.rb +107 -22
  175. data/lib/roby/app/test_reporter.rb +74 -0
  176. data/lib/roby/app/test_server.rb +159 -0
  177. data/lib/roby/app/vagrant.rb +47 -0
  178. data/lib/roby/backports.rb +16 -0
  179. data/lib/roby/cli/display.rb +190 -0
  180. data/lib/roby/cli/exceptions.rb +17 -0
  181. data/lib/roby/cli/gen/actions/class.rb +5 -0
  182. data/lib/roby/cli/gen/actions/test.rb +6 -0
  183. data/lib/roby/cli/gen/app/.yardopts +6 -0
  184. data/lib/roby/cli/gen/app/README.md +28 -0
  185. data/lib/roby/cli/gen/app/Rakefile +15 -0
  186. data/{app → lib/roby/cli/gen/app}/config/app.yml +29 -39
  187. data/lib/roby/cli/gen/app/models/.gitattributes +1 -0
  188. data/{app → lib/roby/cli/gen/app/scripts}/controllers/.gitattributes +0 -0
  189. data/{app/data/.gitattributes → lib/roby/cli/gen/app/test/.gitignore} +0 -0
  190. data/lib/roby/cli/gen/class/class.rb +6 -0
  191. data/lib/roby/cli/gen/class/test.rb +7 -0
  192. data/lib/roby/cli/gen/helpers.rb +203 -0
  193. data/lib/roby/cli/gen/module/module.rb +5 -0
  194. data/lib/roby/cli/gen/module/test.rb +6 -0
  195. data/lib/roby/cli/gen/roby_app/config/init.rb +17 -0
  196. data/lib/roby/cli/gen/roby_app/config/robots/robot.rb +40 -0
  197. data/lib/roby/cli/gen/task/class.rb +44 -0
  198. data/lib/roby/cli/gen/task/test.rb +6 -0
  199. data/lib/roby/cli/gen_main.rb +120 -0
  200. data/lib/roby/cli/log.rb +276 -0
  201. data/lib/roby/cli/log/flamegraph.html +499 -0
  202. data/lib/roby/cli/log/flamegraph_renderer.rb +88 -0
  203. data/lib/roby/cli/main.rb +153 -0
  204. data/lib/roby/coordination.rb +60 -0
  205. data/lib/roby/coordination/action_script.rb +25 -0
  206. data/lib/roby/coordination/action_state_machine.rb +125 -0
  207. data/lib/roby/coordination/actions.rb +106 -0
  208. data/lib/roby/coordination/base.rb +145 -0
  209. data/lib/roby/coordination/calculus.rb +40 -0
  210. data/lib/roby/coordination/child.rb +28 -0
  211. data/lib/roby/coordination/event.rb +29 -0
  212. data/lib/roby/coordination/fault_handler.rb +25 -0
  213. data/lib/roby/coordination/fault_handling_task.rb +13 -0
  214. data/lib/roby/coordination/fault_response_table.rb +110 -0
  215. data/lib/roby/coordination/models/action_script.rb +64 -0
  216. data/lib/roby/coordination/models/action_state_machine.rb +224 -0
  217. data/lib/roby/coordination/models/actions.rb +191 -0
  218. data/lib/roby/coordination/models/arguments.rb +55 -0
  219. data/lib/roby/coordination/models/base.rb +176 -0
  220. data/lib/roby/coordination/models/capture.rb +86 -0
  221. data/lib/roby/coordination/models/child.rb +35 -0
  222. data/lib/roby/coordination/models/event.rb +41 -0
  223. data/lib/roby/coordination/models/exceptions.rb +42 -0
  224. data/lib/roby/coordination/models/fault_handler.rb +219 -0
  225. data/lib/roby/coordination/models/fault_response_table.rb +77 -0
  226. data/lib/roby/coordination/models/root.rb +22 -0
  227. data/lib/roby/coordination/models/script.rb +283 -0
  228. data/lib/roby/coordination/models/task.rb +184 -0
  229. data/lib/roby/coordination/models/task_from_action.rb +50 -0
  230. data/lib/roby/coordination/models/task_from_as_plan.rb +33 -0
  231. data/lib/roby/coordination/models/task_from_instanciation_object.rb +31 -0
  232. data/lib/roby/coordination/models/task_from_variable.rb +27 -0
  233. data/lib/roby/coordination/models/task_with_dependencies.rb +48 -0
  234. data/lib/roby/coordination/models/variable.rb +32 -0
  235. data/lib/roby/coordination/script.rb +200 -0
  236. data/lib/roby/coordination/script_instruction.rb +12 -0
  237. data/lib/roby/coordination/task.rb +45 -0
  238. data/lib/roby/coordination/task_base.rb +69 -0
  239. data/lib/roby/coordination/task_script.rb +293 -0
  240. data/lib/roby/coordination/task_state_machine.rb +308 -0
  241. data/lib/roby/decision_control.rb +33 -21
  242. data/lib/roby/distributed_object.rb +76 -0
  243. data/lib/roby/droby.rb +17 -0
  244. data/lib/roby/droby/droby_id.rb +6 -0
  245. data/lib/roby/droby/enable.rb +153 -0
  246. data/lib/roby/droby/event_logger.rb +189 -0
  247. data/lib/roby/droby/event_logging.rb +57 -0
  248. data/lib/roby/droby/exceptions.rb +14 -0
  249. data/lib/roby/droby/identifiable.rb +22 -0
  250. data/lib/roby/droby/logfile.rb +141 -0
  251. data/lib/roby/droby/logfile/client.rb +176 -0
  252. data/lib/roby/droby/logfile/file_format.md +97 -0
  253. data/lib/roby/droby/logfile/index.rb +117 -0
  254. data/lib/roby/droby/logfile/reader.rb +139 -0
  255. data/lib/roby/droby/logfile/server.rb +199 -0
  256. data/lib/roby/droby/logfile/writer.rb +114 -0
  257. data/lib/roby/droby/marshal.rb +264 -0
  258. data/lib/roby/droby/marshallable.rb +12 -0
  259. data/lib/roby/droby/null_event_logger.rb +25 -0
  260. data/lib/roby/droby/object_manager.rb +205 -0
  261. data/lib/roby/droby/peer_id.rb +6 -0
  262. data/lib/roby/droby/plan_rebuilder.rb +373 -0
  263. data/lib/roby/droby/rebuilt_plan.rb +160 -0
  264. data/lib/roby/droby/remote_droby_id.rb +6 -0
  265. data/lib/roby/droby/timepoints.rb +205 -0
  266. data/lib/roby/droby/timepoints_ctf.metadata.erb +101 -0
  267. data/lib/roby/droby/timepoints_ctf.rb +125 -0
  268. data/lib/roby/droby/v5.rb +14 -0
  269. data/lib/roby/droby/v5/builtin.rb +120 -0
  270. data/lib/roby/droby/v5/droby_class.rb +45 -0
  271. data/lib/roby/droby/v5/droby_constant.rb +81 -0
  272. data/lib/roby/droby/v5/droby_dump.rb +1026 -0
  273. data/lib/roby/droby/v5/droby_id.rb +44 -0
  274. data/lib/roby/droby/v5/droby_model.rb +82 -0
  275. data/lib/roby/droby/v5/peer_id.rb +10 -0
  276. data/lib/roby/droby/v5/remote_droby_id.rb +42 -0
  277. data/lib/roby/event.rb +79 -957
  278. data/lib/roby/event_constraints.rb +835 -0
  279. data/lib/roby/event_generator.rb +1047 -0
  280. data/lib/roby/event_structure/causal_link.rb +6 -0
  281. data/lib/roby/event_structure/forwarding.rb +6 -0
  282. data/lib/roby/event_structure/precedence.rb +7 -0
  283. data/lib/roby/event_structure/signal.rb +8 -0
  284. data/lib/roby/event_structure/temporal_constraints.rb +640 -0
  285. data/lib/roby/exceptions.rb +446 -152
  286. data/lib/roby/executable_plan.rb +549 -0
  287. data/lib/roby/execution_engine.rb +1997 -950
  288. data/lib/roby/filter_generator.rb +26 -0
  289. data/lib/roby/gui/chronicle_view.rb +225 -0
  290. data/lib/roby/gui/chronicle_widget.rb +925 -0
  291. data/lib/roby/gui/dot_id.rb +11 -0
  292. data/lib/roby/gui/exception_view.rb +44 -0
  293. data/lib/roby/gui/log_display.rb +273 -0
  294. data/lib/roby/gui/model_views.rb +2 -0
  295. data/lib/roby/gui/model_views/action_interface.rb +53 -0
  296. data/lib/roby/gui/model_views/task.rb +47 -0
  297. data/lib/roby/gui/model_views/task.rhtml +41 -0
  298. data/lib/roby/gui/object_info_view.rb +89 -0
  299. data/lib/roby/gui/plan_dot_layout.rb +427 -0
  300. data/lib/roby/gui/plan_rebuilder_widget.rb +357 -0
  301. data/lib/roby/gui/qt4_toMSecsSinceEpoch.rb +8 -0
  302. data/lib/roby/gui/relations_view.rb +278 -0
  303. data/lib/roby/gui/relations_view/relations.ui +139 -0
  304. data/lib/roby/gui/relations_view/relations_canvas.rb +1088 -0
  305. data/lib/roby/gui/relations_view/relations_config.rb +292 -0
  306. data/lib/roby/gui/relations_view/relations_view.ui +53 -0
  307. data/lib/roby/gui/scheduler_view.css +24 -0
  308. data/lib/roby/gui/scheduler_view.rb +46 -0
  309. data/lib/roby/gui/scheduler_view.rhtml +53 -0
  310. data/lib/roby/gui/stepping.rb +93 -0
  311. data/lib/roby/gui/stepping.ui +181 -0
  312. data/lib/roby/gui/styles.rb +81 -0
  313. data/lib/roby/gui/task_display_configuration.rb +42 -0
  314. data/lib/roby/gui/task_state_at.rb +38 -0
  315. data/lib/roby/hooks.rb +26 -0
  316. data/lib/roby/interface.rb +136 -469
  317. data/lib/roby/interface/async.rb +20 -0
  318. data/lib/roby/interface/async/action_monitor.rb +188 -0
  319. data/lib/roby/interface/async/interface.rb +498 -0
  320. data/lib/roby/interface/async/job_monitor.rb +213 -0
  321. data/lib/roby/interface/async/log.rb +238 -0
  322. data/lib/roby/interface/async/new_job_listener.rb +79 -0
  323. data/lib/roby/interface/async/ui_connector.rb +183 -0
  324. data/lib/roby/interface/client.rb +553 -0
  325. data/lib/roby/interface/command.rb +24 -0
  326. data/lib/roby/interface/command_argument.rb +16 -0
  327. data/lib/roby/interface/command_library.rb +92 -0
  328. data/lib/roby/interface/droby_channel.rb +174 -0
  329. data/lib/roby/interface/exceptions.rb +22 -0
  330. data/lib/roby/interface/interface.rb +655 -0
  331. data/lib/roby/interface/job.rb +47 -0
  332. data/lib/roby/interface/rest.rb +10 -0
  333. data/lib/roby/interface/rest/api.rb +29 -0
  334. data/lib/roby/interface/rest/helpers.rb +24 -0
  335. data/lib/roby/interface/rest/server.rb +212 -0
  336. data/lib/roby/interface/server.rb +154 -0
  337. data/lib/roby/interface/shell_client.rb +468 -0
  338. data/lib/roby/interface/shell_subcommand.rb +24 -0
  339. data/lib/roby/interface/subcommand_client.rb +35 -0
  340. data/lib/roby/interface/tcp.rb +168 -0
  341. data/lib/roby/models/arguments.rb +112 -0
  342. data/lib/roby/models/plan_object.rb +83 -0
  343. data/lib/roby/models/task.rb +835 -0
  344. data/lib/roby/models/task_event.rb +62 -0
  345. data/lib/roby/models/task_service.rb +78 -0
  346. data/lib/roby/or_generator.rb +88 -0
  347. data/lib/roby/plan.rb +1751 -864
  348. data/lib/roby/plan_object.rb +611 -0
  349. data/lib/roby/plan_service.rb +200 -0
  350. data/lib/roby/promise.rb +332 -0
  351. data/lib/roby/queries.rb +23 -0
  352. data/lib/roby/queries/and_matcher.rb +32 -0
  353. data/lib/roby/queries/any.rb +27 -0
  354. data/lib/roby/queries/code_error_matcher.rb +58 -0
  355. data/lib/roby/queries/event_generator_matcher.rb +9 -0
  356. data/lib/roby/queries/execution_exception_matcher.rb +165 -0
  357. data/lib/roby/queries/index.rb +165 -0
  358. data/lib/roby/queries/localized_error_matcher.rb +149 -0
  359. data/lib/roby/queries/matcher_base.rb +107 -0
  360. data/lib/roby/queries/none.rb +27 -0
  361. data/lib/roby/queries/not_matcher.rb +30 -0
  362. data/lib/roby/queries/op_matcher.rb +8 -0
  363. data/lib/roby/queries/or_matcher.rb +30 -0
  364. data/lib/roby/queries/plan_object_matcher.rb +363 -0
  365. data/lib/roby/queries/query.rb +188 -0
  366. data/lib/roby/queries/task_event_generator_matcher.rb +86 -0
  367. data/lib/roby/queries/task_matcher.rb +344 -0
  368. data/lib/roby/relations.rb +42 -678
  369. data/lib/roby/relations/bidirectional_directed_adjacency_graph.rb +492 -0
  370. data/lib/roby/relations/directed_relation_support.rb +268 -0
  371. data/lib/roby/relations/event_relation_graph.rb +19 -0
  372. data/lib/roby/relations/fork_merge_visitor.rb +154 -0
  373. data/lib/roby/relations/graph.rb +533 -0
  374. data/lib/roby/relations/models/directed_relation_support.rb +11 -0
  375. data/lib/roby/relations/models/graph.rb +75 -0
  376. data/lib/roby/relations/models/task_relation_graph.rb +18 -0
  377. data/lib/roby/relations/space.rb +380 -0
  378. data/lib/roby/relations/task_relation_graph.rb +20 -0
  379. data/lib/roby/robot.rb +85 -38
  380. data/lib/roby/schedulers/basic.rb +155 -25
  381. data/lib/roby/schedulers/null.rb +20 -0
  382. data/lib/roby/schedulers/reporting.rb +31 -0
  383. data/lib/roby/schedulers/state.rb +129 -0
  384. data/lib/roby/schedulers/temporal.rb +91 -0
  385. data/lib/roby/singletons.rb +87 -0
  386. data/lib/roby/standalone.rb +4 -2
  387. data/lib/roby/standard_errors.rb +405 -82
  388. data/lib/roby/state.rb +6 -3
  389. data/lib/roby/state/conf_model.rb +5 -0
  390. data/lib/roby/state/events.rb +181 -95
  391. data/lib/roby/state/goal_model.rb +77 -0
  392. data/lib/roby/state/open_struct.rb +591 -0
  393. data/lib/roby/state/open_struct_model.rb +68 -0
  394. data/lib/roby/state/pos.rb +45 -45
  395. data/lib/roby/state/shapes.rb +11 -11
  396. data/lib/roby/state/state_model.rb +303 -0
  397. data/lib/roby/state/task.rb +43 -0
  398. data/lib/roby/support.rb +88 -148
  399. data/lib/roby/task.rb +1361 -1750
  400. data/lib/roby/task_arguments.rb +428 -0
  401. data/lib/roby/task_event.rb +127 -0
  402. data/lib/roby/task_event_generator.rb +337 -0
  403. data/lib/roby/task_service.rb +6 -0
  404. data/lib/roby/task_structure/conflicts.rb +104 -0
  405. data/lib/roby/task_structure/dependency.rb +932 -0
  406. data/lib/roby/task_structure/error_handling.rb +118 -0
  407. data/lib/roby/task_structure/executed_by.rb +234 -0
  408. data/lib/roby/task_structure/planned_by.rb +90 -0
  409. data/lib/roby/tasks/aggregator.rb +37 -0
  410. data/lib/roby/tasks/external_process.rb +275 -0
  411. data/lib/roby/tasks/group.rb +27 -0
  412. data/lib/roby/tasks/null.rb +19 -0
  413. data/lib/roby/tasks/parallel.rb +43 -0
  414. data/lib/roby/tasks/sequence.rb +88 -0
  415. data/lib/roby/tasks/simple.rb +21 -0
  416. data/lib/roby/{thread_task.rb → tasks/thread.rb} +50 -24
  417. data/lib/roby/tasks/timeout.rb +17 -0
  418. data/lib/roby/tasks/virtual.rb +55 -0
  419. data/lib/roby/template_plan.rb +7 -0
  420. data/lib/roby/test/aruba_minitest.rb +74 -0
  421. data/lib/roby/test/assertion.rb +16 -0
  422. data/lib/roby/test/assertions.rb +490 -0
  423. data/lib/roby/test/common.rb +368 -591
  424. data/lib/roby/test/dsl.rb +149 -0
  425. data/lib/roby/test/error.rb +18 -0
  426. data/lib/roby/test/event_reporter.rb +83 -0
  427. data/lib/roby/test/execution_expectations.rb +1134 -0
  428. data/lib/roby/test/expect_execution.rb +151 -0
  429. data/lib/roby/test/minitest_helpers.rb +166 -0
  430. data/lib/roby/test/roby_app_helpers.rb +200 -0
  431. data/lib/roby/test/run_planners.rb +155 -0
  432. data/lib/roby/test/self.rb +112 -0
  433. data/lib/roby/test/spec.rb +198 -0
  434. data/lib/roby/test/tasks/empty_task.rb +4 -4
  435. data/lib/roby/test/tasks/goto.rb +28 -27
  436. data/lib/roby/test/teardown_plans.rb +100 -0
  437. data/lib/roby/test/testcase.rb +239 -307
  438. data/lib/roby/test/tools.rb +159 -155
  439. data/lib/roby/test/validate_state_machine.rb +75 -0
  440. data/lib/roby/transaction.rb +1125 -0
  441. data/lib/roby/transaction/event_generator_proxy.rb +63 -0
  442. data/lib/roby/transaction/plan_object_proxy.rb +99 -0
  443. data/lib/roby/transaction/plan_service_proxy.rb +43 -0
  444. data/lib/roby/transaction/proxying.rb +120 -0
  445. data/lib/roby/transaction/task_event_generator_proxy.rb +19 -0
  446. data/lib/roby/transaction/task_proxy.rb +135 -0
  447. data/lib/roby/until_generator.rb +30 -0
  448. data/lib/roby/version.rb +5 -0
  449. data/lib/roby/yard.rb +169 -0
  450. data/lib/yard-roby.rb +1 -0
  451. data/manifest.xml +32 -6
  452. data/roby.gemspec +59 -0
  453. metadata +788 -587
  454. data/Manifest.txt +0 -321
  455. data/NOTES +0 -4
  456. data/README.txt +0 -166
  457. data/TODO.txt +0 -146
  458. data/app/README.txt +0 -24
  459. data/app/Rakefile +0 -8
  460. data/app/config/ROBOT.rb +0 -5
  461. data/app/config/init.rb +0 -33
  462. data/app/config/roby.yml +0 -3
  463. data/app/controllers/ROBOT.rb +0 -2
  464. data/app/planners/ROBOT/main.rb +0 -6
  465. data/app/planners/main.rb +0 -5
  466. data/app/scripts/distributed +0 -3
  467. data/app/scripts/generate/bookmarks +0 -3
  468. data/app/scripts/replay +0 -3
  469. data/app/scripts/results +0 -3
  470. data/app/scripts/run +0 -3
  471. data/app/scripts/server +0 -3
  472. data/app/scripts/shell +0 -3
  473. data/app/scripts/test +0 -3
  474. data/app/tasks/.gitattributes +0 -0
  475. data/app/tasks/ROBOT/.gitattributes +0 -0
  476. data/bin/roby-shell +0 -25
  477. data/doc/guide/src/basics/app.page +0 -139
  478. data/doc/guide/src/basics/index.page +0 -11
  479. data/doc/guide/src/basics/log_replay/goForward_1.png +0 -0
  480. data/doc/guide/src/basics/log_replay/goForward_2.png +0 -0
  481. data/doc/guide/src/basics/log_replay/goForward_3.png +0 -0
  482. data/doc/guide/src/basics/log_replay/goForward_5.png +0 -0
  483. data/doc/guide/src/basics/log_replay/plan_repair_4.png +0 -0
  484. data/doc/guide/src/basics/log_replay/roby_log_main_window.png +0 -0
  485. data/doc/guide/src/basics/relations_display.page +0 -203
  486. data/doc/guide/src/basics/shell.page +0 -102
  487. data/doc/guide/src/default.css +0 -319
  488. data/doc/guide/src/introduction/index.page +0 -29
  489. data/doc/guide/src/introduction/publications.page +0 -14
  490. data/doc/guide/src/relations/dependency.page +0 -89
  491. data/doc/guide/src/relations/index.page +0 -12
  492. data/ext/droby/dump.cc +0 -175
  493. data/ext/droby/extconf.rb +0 -3
  494. data/ext/graph/algorithm.cc +0 -746
  495. data/ext/graph/extconf.rb +0 -7
  496. data/ext/graph/graph.cc +0 -575
  497. data/ext/graph/graph.hh +0 -183
  498. data/ext/graph/iterator_sequence.hh +0 -102
  499. data/ext/graph/undirected_dfs.hh +0 -226
  500. data/ext/graph/undirected_graph.hh +0 -421
  501. data/lib/roby/app/scripts/generate/bookmarks.rb +0 -162
  502. data/lib/roby/app/scripts/replay.rb +0 -31
  503. data/lib/roby/app/scripts/server.rb +0 -18
  504. data/lib/roby/basic_object.rb +0 -151
  505. data/lib/roby/config.rb +0 -14
  506. data/lib/roby/distributed.rb +0 -36
  507. data/lib/roby/distributed/base.rb +0 -448
  508. data/lib/roby/distributed/communication.rb +0 -875
  509. data/lib/roby/distributed/connection_space.rb +0 -616
  510. data/lib/roby/distributed/distributed_object.rb +0 -206
  511. data/lib/roby/distributed/drb.rb +0 -62
  512. data/lib/roby/distributed/notifications.rb +0 -531
  513. data/lib/roby/distributed/peer.rb +0 -555
  514. data/lib/roby/distributed/protocol.rb +0 -529
  515. data/lib/roby/distributed/proxy.rb +0 -343
  516. data/lib/roby/distributed/subscription.rb +0 -311
  517. data/lib/roby/distributed/transaction.rb +0 -498
  518. data/lib/roby/external_process_task.rb +0 -225
  519. data/lib/roby/graph.rb +0 -160
  520. data/lib/roby/log.rb +0 -3
  521. data/lib/roby/log/chronicle.rb +0 -303
  522. data/lib/roby/log/console.rb +0 -74
  523. data/lib/roby/log/data_stream.rb +0 -275
  524. data/lib/roby/log/dot.rb +0 -279
  525. data/lib/roby/log/event_stream.rb +0 -161
  526. data/lib/roby/log/file.rb +0 -396
  527. data/lib/roby/log/gui/basic_display.ui +0 -83
  528. data/lib/roby/log/gui/basic_display_ui.rb +0 -89
  529. data/lib/roby/log/gui/chronicle.rb +0 -26
  530. data/lib/roby/log/gui/chronicle_view.rb +0 -40
  531. data/lib/roby/log/gui/chronicle_view.ui +0 -70
  532. data/lib/roby/log/gui/chronicle_view_ui.rb +0 -90
  533. data/lib/roby/log/gui/data_displays.rb +0 -171
  534. data/lib/roby/log/gui/data_displays.ui +0 -155
  535. data/lib/roby/log/gui/data_displays_ui.rb +0 -146
  536. data/lib/roby/log/gui/notifications.rb +0 -26
  537. data/lib/roby/log/gui/relations.rb +0 -269
  538. data/lib/roby/log/gui/relations.ui +0 -123
  539. data/lib/roby/log/gui/relations_ui.rb +0 -120
  540. data/lib/roby/log/gui/relations_view.rb +0 -185
  541. data/lib/roby/log/gui/relations_view.ui +0 -149
  542. data/lib/roby/log/gui/relations_view_ui.rb +0 -144
  543. data/lib/roby/log/gui/replay.rb +0 -366
  544. data/lib/roby/log/gui/replay_controls.rb +0 -206
  545. data/lib/roby/log/gui/replay_controls.ui +0 -282
  546. data/lib/roby/log/gui/replay_controls_ui.rb +0 -249
  547. data/lib/roby/log/gui/runtime.rb +0 -130
  548. data/lib/roby/log/hooks.rb +0 -186
  549. data/lib/roby/log/logger.rb +0 -203
  550. data/lib/roby/log/notifications.rb +0 -244
  551. data/lib/roby/log/plan_rebuilder.rb +0 -468
  552. data/lib/roby/log/relations.rb +0 -1084
  553. data/lib/roby/log/server.rb +0 -547
  554. data/lib/roby/log/sqlite.rb +0 -47
  555. data/lib/roby/log/timings.rb +0 -233
  556. data/lib/roby/plan-object.rb +0 -371
  557. data/lib/roby/planning.rb +0 -13
  558. data/lib/roby/planning/loops.rb +0 -309
  559. data/lib/roby/planning/model.rb +0 -1012
  560. data/lib/roby/planning/task.rb +0 -180
  561. data/lib/roby/query.rb +0 -655
  562. data/lib/roby/relations/conflicts.rb +0 -67
  563. data/lib/roby/relations/dependency.rb +0 -358
  564. data/lib/roby/relations/ensured.rb +0 -19
  565. data/lib/roby/relations/error_handling.rb +0 -22
  566. data/lib/roby/relations/events.rb +0 -7
  567. data/lib/roby/relations/executed_by.rb +0 -208
  568. data/lib/roby/relations/influence.rb +0 -10
  569. data/lib/roby/relations/planned_by.rb +0 -63
  570. data/lib/roby/state/information.rb +0 -55
  571. data/lib/roby/state/state.rb +0 -367
  572. data/lib/roby/task-operations.rb +0 -186
  573. data/lib/roby/task_index.rb +0 -80
  574. data/lib/roby/test/distributed.rb +0 -230
  575. data/lib/roby/test/tasks/simple_task.rb +0 -23
  576. data/lib/roby/transactions.rb +0 -507
  577. data/lib/roby/transactions/proxy.rb +0 -325
  578. data/plugins/fault_injection/History.txt +0 -4
  579. data/plugins/fault_injection/README.txt +0 -34
  580. data/plugins/fault_injection/Rakefile +0 -12
  581. data/plugins/fault_injection/TODO.txt +0 -0
  582. data/plugins/fault_injection/app.rb +0 -52
  583. data/plugins/fault_injection/fault_injection.rb +0 -89
  584. data/plugins/fault_injection/test/test_fault_injection.rb +0 -78
  585. data/plugins/subsystems/README.txt +0 -37
  586. data/plugins/subsystems/Rakefile +0 -13
  587. data/plugins/subsystems/app.rb +0 -182
  588. data/plugins/subsystems/test/app/README +0 -24
  589. data/plugins/subsystems/test/app/Rakefile +0 -8
  590. data/plugins/subsystems/test/app/config/app.yml +0 -71
  591. data/plugins/subsystems/test/app/config/init.rb +0 -12
  592. data/plugins/subsystems/test/app/config/roby.yml +0 -3
  593. data/plugins/subsystems/test/app/planners/main.rb +0 -20
  594. data/plugins/subsystems/test/app/scripts/distributed +0 -3
  595. data/plugins/subsystems/test/app/scripts/replay +0 -3
  596. data/plugins/subsystems/test/app/scripts/results +0 -3
  597. data/plugins/subsystems/test/app/scripts/run +0 -3
  598. data/plugins/subsystems/test/app/scripts/server +0 -3
  599. data/plugins/subsystems/test/app/scripts/shell +0 -3
  600. data/plugins/subsystems/test/app/scripts/test +0 -3
  601. data/plugins/subsystems/test/app/tasks/services.rb +0 -15
  602. data/plugins/subsystems/test/test_subsystems.rb +0 -78
  603. data/test/distributed/test_communication.rb +0 -195
  604. data/test/distributed/test_connection.rb +0 -284
  605. data/test/distributed/test_execution.rb +0 -378
  606. data/test/distributed/test_mixed_plan.rb +0 -341
  607. data/test/distributed/test_plan_notifications.rb +0 -238
  608. data/test/distributed/test_protocol.rb +0 -525
  609. data/test/distributed/test_query.rb +0 -106
  610. data/test/distributed/test_remote_plan.rb +0 -491
  611. data/test/distributed/test_transaction.rb +0 -466
  612. data/test/mockups/external_process +0 -28
  613. data/test/mockups/tasks.rb +0 -27
  614. data/test/planning/test_loops.rb +0 -432
  615. data/test/planning/test_model.rb +0 -427
  616. data/test/planning/test_task.rb +0 -126
  617. data/test/relations/test_conflicts.rb +0 -42
  618. data/test/relations/test_dependency.rb +0 -324
  619. data/test/relations/test_ensured.rb +0 -38
  620. data/test/relations/test_executed_by.rb +0 -224
  621. data/test/relations/test_planned_by.rb +0 -56
  622. data/test/suite_core.rb +0 -29
  623. data/test/suite_distributed.rb +0 -10
  624. data/test/suite_planning.rb +0 -4
  625. data/test/suite_relations.rb +0 -8
  626. data/test/tasks/test_external_process.rb +0 -126
  627. data/test/tasks/test_thread_task.rb +0 -70
  628. data/test/test_bgl.rb +0 -528
  629. data/test/test_event.rb +0 -969
  630. data/test/test_exceptions.rb +0 -591
  631. data/test/test_execution_engine.rb +0 -987
  632. data/test/test_gui.rb +0 -20
  633. data/test/test_interface.rb +0 -43
  634. data/test/test_log.rb +0 -125
  635. data/test/test_log_server.rb +0 -133
  636. data/test/test_plan.rb +0 -418
  637. data/test/test_query.rb +0 -424
  638. data/test/test_relations.rb +0 -260
  639. data/test/test_state.rb +0 -432
  640. data/test/test_support.rb +0 -16
  641. data/test/test_task.rb +0 -1181
  642. data/test/test_testcase.rb +0 -138
  643. data/test/test_transactions.rb +0 -610
  644. data/test/test_transactions_proxy.rb +0 -216
@@ -1,180 +0,0 @@
1
- module Roby
2
- # An asynchronous planning task using Ruby threads
3
- class PlanningTask < Roby::Task
4
- attr_reader :planner, :transaction
5
-
6
- arguments :planner_model, :method_options, :method_name, :planned_model, :planning_owners
7
-
8
- def planning_method
9
- arguments[:planning_method]
10
- end
11
-
12
- def self.validate_planning_options(options)
13
- options = options.dup
14
- if options[:method_name]
15
- method_name = options[:planning_method] = options[:method_name]
16
- elsif options[:planning_method].respond_to?(:to_str) || options[:planning_method].respond_to?(:to_sym)
17
- method_name = options[:method_name] = options[:planning_method].to_s
18
- end
19
-
20
- if !options[:planner_model]
21
- raise ArgumentError, "missing required argument 'planner_model'"
22
- elsif !options[:planning_method]
23
- raise ArgumentError, "missing required argument 'planning_method'"
24
- elsif !method_name
25
- if options[:planning_method].kind_of?(Roby::Planning::MethodDefinition)
26
- method_name = options[:method_name] = options[:planning_method].name
27
- else
28
- raise ArgumentError, "the planning_method argument is neither a method object nor a name"
29
- end
30
- end
31
- options[:planned_model] ||= nil
32
- options[:planning_owners] ||= nil
33
- options
34
- end
35
-
36
- def self.filter_options(options)
37
- task_options, method_options = Kernel.filter_options options,
38
- :planner_model => nil,
39
- :planning_method => nil,
40
- :method_options => {},
41
- :method_name => nil, # kept for backward compatibility
42
- :planned_model => nil,
43
- :planning_owners => nil
44
-
45
- task_options = validate_planning_options(task_options)
46
- task_options[:method_options] ||= Hash.new
47
- task_options[:method_options].merge! method_options
48
- task_options
49
- end
50
-
51
- def initialize(options)
52
- task_options = PlanningTask.filter_options(options)
53
- super(task_options)
54
- end
55
-
56
- def planned_model
57
- arguments[:planned_model] ||= if method_name
58
- planner_model.model_of(method_name, method_options).returns
59
- else
60
- planning_method.returns
61
- end
62
-
63
- arguments[:planned_model] ||= Roby::Task
64
- end
65
-
66
-
67
- def to_s
68
- "#{super}[#{planning_method}:#{method_options}] -> #{@planned_task || "nil"}"
69
- end
70
-
71
- def planned_task
72
- if success? || result
73
- result
74
- elsif task = planned_tasks.find { true }
75
- task
76
- elsif pending?
77
- task = planned_model.new
78
- task.planned_by self
79
- task.executable = false
80
- task
81
- end
82
- end
83
-
84
- # The thread that is running the planner
85
- attr_reader :thread
86
- # The transaction in which we build the new plan. It gets committed on
87
- # success.
88
- attr_reader :transaction
89
- # The planner result. It is either an exception or a task object
90
- attr_reader :result
91
-
92
- # Starts planning
93
- event :start do |context|
94
- emit :start
95
-
96
- if planning_owners
97
- @transaction = Distributed::Transaction.new(plan)
98
- planning_owners.each do |peer|
99
- transaction.add_owner peer
100
- end
101
- else
102
- @transaction = Transaction.new(plan)
103
- end
104
- @planner = planner_model.new(transaction)
105
-
106
- @thread = Thread.new do
107
- Thread.current.priority = 0
108
- planning_thread(context)
109
- end
110
- end
111
-
112
- def planning_thread(context)
113
- result_task = if planning_method.kind_of?(Roby::Planning::MethodDefinition)
114
- planner.send(:call_planning_methods, Hash.new, method_options.merge(:context => context), planning_method)
115
- else
116
- planner.send(method_name, method_options.merge(:context => context))
117
- end
118
-
119
- # Don't replace the planning task with ourselves if the
120
- # transaction specifies another planning task
121
- if !result_task.planning_task
122
- result_task.planned_by transaction[self]
123
- end
124
-
125
- if placeholder = planned_task
126
- placeholder = transaction[placeholder]
127
- transaction.replace(placeholder, result_task)
128
- placeholder.remove_planning_task transaction[self]
129
- end
130
-
131
- # If the transaction is distributed, and is not proposed to all
132
- # owners, do it
133
- transaction.propose
134
- transaction.commit_transaction do
135
- @result = result_task
136
- end
137
- end
138
-
139
- # Polls for the planning thread end
140
- poll do
141
- if thread.alive?
142
- return
143
- end
144
-
145
- # Check if the transaction has been committed. If it is not the
146
- # case, assume that the thread failed
147
- if transaction.committed?
148
- emit :success
149
- else
150
- error = begin
151
- thread.value
152
- rescue Exception => e
153
- @result = e
154
- end
155
-
156
- transaction.discard_transaction
157
- emit :failed, error
158
- end
159
- end
160
-
161
- # Stops the planning thread
162
- event :stop do |context|
163
- planner.stop
164
- end
165
- on :stop do
166
- @transaction = nil
167
- @planner = nil
168
- @thread = nil
169
- end
170
-
171
- class TransactionProxy < Roby::Transactions::Task
172
- proxy_for PlanningTask
173
- def_delegator :@__getobj__, :planner
174
- def_delegator :@__getobj__, :planning_method
175
- def_delegator :@__getobj__, :method_name
176
- def_delegator :@__getobj__, :method_options
177
- end
178
- end
179
- end
180
-
@@ -1,655 +0,0 @@
1
- module Roby
2
- class Task
3
- # Returns a TaskMatcher object
4
- def self.match(*args)
5
- matcher = TaskMatcher.new
6
- if !args.empty?
7
- matcher.which_fullfills(*args)
8
- end
9
- matcher
10
- end
11
- end
12
-
13
- # This class represents a predicate which can be used to filter tasks. To
14
- # filter plan-related properties, use Query.
15
- #
16
- # A TaskMatcher object is a AND combination of various tests against tasks.
17
- class TaskMatcher
18
- attr_reader :model, :arguments
19
- attr_reader :predicates, :neg_predicates, :owners
20
-
21
- attr_reader :improved_information
22
- attr_reader :needed_information
23
-
24
- # Initializes an empty TaskMatcher object
25
- def initialize
26
- @predicates = ValueSet.new
27
- @neg_predicates = ValueSet.new
28
- @owners = Array.new
29
- @improved_information = ValueSet.new
30
- @needed_information = ValueSet.new
31
- @interruptible = nil
32
- @parents = Hash.new { |h, k| h[k] = Array.new }
33
- @children = Hash.new { |h, k| h[k] = Array.new }
34
- end
35
-
36
- # Shortcut to set both model and argument
37
- def which_fullfills(model, arguments = nil)
38
- with_model(model)
39
- if arguments
40
- with_model_arguments(arguments)
41
- end
42
- self
43
- end
44
-
45
- # Find by model
46
- def with_model(model)
47
- @model = model
48
- self
49
- end
50
-
51
- # Find by arguments defined by the model
52
- def with_model_arguments(arguments)
53
- if !model
54
- raise ArgumentError, "set model first"
55
- end
56
- if model.respond_to?(:to_ary)
57
- valid_arguments = model.inject(Set.new) { |args, m| args | m.arguments.to_set }
58
- else
59
- valid_arguments = model.arguments
60
- end
61
- with_arguments(arguments.slice(*model.arguments))
62
- self
63
- end
64
-
65
- # Find by argument (exact matching)
66
- def with_arguments(arguments)
67
- @arguments ||= Hash.new
68
- self.arguments.merge!(arguments) do |k, old, new|
69
- if old != new
70
- raise ArgumentError, "a constraint has already been set on the #{k} argument"
71
- end
72
- old
73
- end
74
- self
75
- end
76
-
77
- # Find tasks which improves information contained in +info+
78
- def which_improves(*info)
79
- improved_information.merge(info.to_value_set)
80
- self
81
- end
82
-
83
- # Find tasks which need information contained in +info+
84
- def which_needs(*info)
85
- needed_information.merge(info.to_value_set)
86
- self
87
- end
88
-
89
- # Finds by owners. The set of owner is added to any owner already
90
- # added. Do
91
- #
92
- # matcher.owners.clear
93
- #
94
- # to remove all owners
95
- def owned_by(*ids)
96
- @owners |= ids
97
- self
98
- end
99
-
100
- # Finds tasks which we own ourselves.
101
- def self_owned
102
- owned_by(Roby::Distributed)
103
- self
104
- end
105
-
106
- class << self
107
- def declare_class_methods(*names) # :nodoc:
108
- names.each do |name|
109
- raise "no instance method #{name} on TaskMatcher" unless TaskMatcher.method_defined?(name)
110
- TaskMatcher.singleton_class.send(:define_method, name) do |*args|
111
- TaskMatcher.new.send(name, *args)
112
- end
113
- end
114
- end
115
-
116
- # For each name in +names+, define a #name and a #not_name method.
117
- # If the first is called, the matcher will match only tasks whose
118
- # #name? method returns true. If the second is called, the
119
- # opposite will be done.
120
- def match_predicates(*names)
121
- names.each do |name|
122
- class_eval <<-EOD
123
- def #{name}
124
- if neg_predicates.include?(:#{name}?)
125
- raise ArgumentError, "trying to match (#{name}? & !#{name}?)"
126
- end
127
- predicates << :#{name}?
128
- self
129
- end
130
- def not_#{name}
131
- if predicates.include?(:#{name}?)
132
- raise ArgumentError, "trying to match (#{name}? & !#{name}?)"
133
- end
134
- neg_predicates << :#{name}?
135
- self
136
- end
137
- EOD
138
- end
139
- declare_class_methods(*names)
140
- declare_class_methods(*names.map { |n| "not_#{n}" })
141
- end
142
- end
143
- match_predicates :executable, :abstract, :partially_instanciated, :fully_instanciated,
144
- :pending, :running, :finished, :success, :failed, :interruptible, :finishing
145
-
146
- # Helper method for #with_child and #with_parent
147
- def handle_parent_child_arguments(other_query, relation, relation_options) # :nodoc:
148
- if !other_query.kind_of?(TaskMatcher) && !other_query.kind_of?(Task)
149
- if relation.kind_of?(Hash)
150
- arguments = relation
151
- relation = (arguments.delete(:relation) || arguments.delete('relation'))
152
- relation_options = (arguments.delete(:relation_options) || arguments.delete('relation_options'))
153
- else
154
- arguments = Hash.new
155
- end
156
- other_query = TaskMatcher.which_fullfills(other_query, arguments)
157
- end
158
- return relation, [other_query, relation_options]
159
- end
160
-
161
- def with_child(other_query, relation = nil, relation_options = nil)
162
- relation, spec = handle_parent_child_arguments(other_query, relation, relation_options)
163
- @children[relation] << spec
164
- self
165
- end
166
-
167
- def with_parent(other_query, relation = nil, relation_options = nil)
168
- relation, spec = handle_parent_child_arguments(other_query, relation, relation_options)
169
- @parents[relation] << spec
170
- self
171
- end
172
-
173
- # Helper method for handling parent/child matches in #===
174
- def handle_parent_child_match(task, match_spec) # :nodoc:
175
- relation, matchers = *match_spec
176
- return false if !relation && task.relations.empty?
177
- for match_spec in matchers
178
- m, relation_options = *match_spec
179
- if relation
180
- if !yield(relation, m, relation_options)
181
- return false
182
- end
183
- else
184
- result = task.relations.any? do |rel|
185
- yield(rel, m, relation_options)
186
- end
187
- return false if !result
188
- end
189
- end
190
- true
191
- end
192
-
193
- # True if +task+ matches all the criteria defined on this object.
194
- def ===(task)
195
- return unless task.kind_of?(Roby::Task)
196
- if model
197
- return unless task.fullfills?(model)
198
- end
199
- if arguments
200
- return unless task.arguments.slice(*arguments.keys) == arguments
201
- end
202
-
203
- for parent_spec in @parents
204
- result = handle_parent_child_match(task, parent_spec) do |relation, m, relation_options|
205
- task.enum_parent_objects(relation).
206
- any? { |parent| m === parent && (!relation_options || relation_options === parent[task, relation]) }
207
- end
208
- return false if !result
209
- end
210
-
211
- for child_spec in @children
212
- result = handle_parent_child_match(task, child_spec) do |relation, m, relation_options|
213
- task.enum_child_objects(relation).
214
- any? { |child| m === child && (!relation_options || relation_options === task[child, relation]) }
215
- end
216
- return false if !result
217
- end
218
-
219
- for info in improved_information
220
- return false if !task.improves?(info)
221
- end
222
- for info in needed_information
223
- return false if !task.needs?(info)
224
- end
225
- for pred in predicates
226
- return false if !task.send(pred)
227
- end
228
- for pred in neg_predicates
229
- return false if task.send(pred)
230
- end
231
-
232
- return false if !owners.empty? && !(task.owners - owners).empty?
233
- true
234
- end
235
-
236
- # Filters the tasks in +initial_set+ by using the information in
237
- # +task_index+, and returns the result. The resulting set must
238
- # include all tasks in +initial_set+ which match with #===, but can
239
- # include tasks which do not match #===
240
- def filter(initial_set, task_index)
241
- if model
242
- if model.respond_to?(:to_ary)
243
- for m in model
244
- initial_set &= task_index.by_model[m]
245
- end
246
- else
247
- initial_set &= task_index.by_model[model]
248
- end
249
- end
250
-
251
- if !owners.empty?
252
- for o in owners
253
- if candidates = task_index.by_owner[o]
254
- initial_set &= candidates
255
- else
256
- return ValueSet.new
257
- end
258
- end
259
- end
260
-
261
- for pred in (predicates & TaskIndex::STATE_PREDICATES)
262
- initial_set &= task_index.by_state[pred]
263
- end
264
-
265
- for pred in (neg_predicates & TaskIndex::STATE_PREDICATES)
266
- initial_set -= task_index.by_state[pred]
267
- end
268
-
269
- initial_set
270
- end
271
-
272
- # Enumerates all tasks of +plan+ which match this TaskMatcher object
273
- def each(plan, &block)
274
- plan.each_task do |t|
275
- yield(t) if self === t
276
- end
277
- self
278
- end
279
-
280
- # Define singleton classes. For instance, calling TaskMatcher.which_fullfills is equivalent
281
- # to TaskMatcher.new.which_fullfills
282
- declare_class_methods :which_fullfills,
283
- :with_model, :with_arguments,
284
- :which_needs, :which_improves,
285
- :owned_by, :self_owned
286
-
287
- # Returns the negation of this predicate
288
- def negate; NegateTaskMatcher.new(self) end
289
- # Combines this predicate with another using a AND logical operation
290
- def &(other); AndTaskMatcher.new(self, other) end
291
- # Combines this predicate with another using an OR logical operation
292
- def |(other); OrTaskMatcher.new(self, other) end
293
- end
294
-
295
- # A query is a predicate on both the task internal properties, and their
296
- # plan-related properties as well.
297
- class Query < TaskMatcher
298
- # The plan this query acts on
299
- attr_reader :plan
300
- # Search scope for queries on transactions. If equal to :local, the
301
- # query will apply only on the scope of the searched transaction,
302
- # otherwise it applies on a virtual plan that is the result of the
303
- # transaction stack being applied.
304
- #
305
- # The default is :global.
306
- #
307
- # See #local_scope and #global_scope
308
- attr_reader :scope
309
-
310
- # Create a query object on the given plan
311
- def initialize(plan)
312
- @scope = :global
313
- @plan = plan
314
- super()
315
- @plan_predicates = Array.new
316
- @neg_plan_predicates = Array.new
317
- end
318
-
319
- # Changes the scope of this query. See #scope.
320
- def local_scope; @scope = :local end
321
- # Changes the scope of this query. See #scope.
322
- def global_scope; @scope = :global end
323
-
324
- # Changes the plan this query works on
325
- def plan=(new_plan)
326
- reset
327
- @plan = new_plan
328
- end
329
-
330
- # The set of tasks which match in plan. This is a cached value, so use
331
- # #reset to actually recompute this set.
332
- def result_set
333
- @result_set ||= plan.query_result_set(self)
334
- end
335
-
336
- # #result_set is a cached value. Call this method to reinitialize,
337
- # making sure the result set is recomputed next time #result_set is
338
- # called.
339
- def reset
340
- @result_set = nil
341
- self
342
- end
343
-
344
- # The set of predicates of Plan which must return true for #=== to
345
- # return true
346
- attr_reader :plan_predicates
347
- # The set of predicates of Plan which must return false for #=== to
348
- # return true.
349
- attr_reader :neg_plan_predicates
350
-
351
- class << self
352
- # For each name in +names+, define the #name and #not_name methods
353
- # on Query objects. When one of these methods is called on a Query
354
- # object, plan.name?(task) must return true (resp. false) for the
355
- # task to match.
356
- def match_plan_predicates(*names)
357
- names.each do |name|
358
- class_eval <<-EOD
359
- def #{name}
360
- if neg_plan_predicates.include?(:#{name}?)
361
- raise ArgumentError, "trying to match (#{name}? & !#{name}?)"
362
- end
363
- plan_predicates << :#{name}?
364
- self
365
- end
366
- def not_#{name}
367
- if plan_predicates.include?(:#{name}?)
368
- raise ArgumentError, "trying to match (#{name}? & !#{name}?)"
369
- end
370
- neg_plan_predicates << :#{name}?
371
- self
372
- end
373
- EOD
374
- end
375
- end
376
- end
377
- match_plan_predicates :mission, :permanent
378
-
379
- # Returns the set of tasks from the query for which no parent in
380
- # +relation+ can be found in the query itself
381
- def roots(relation)
382
- @result_set = plan.query_roots(result_set, relation)
383
- self
384
- end
385
-
386
- # True if +task+ matches the query. Call #result_set to have the set of
387
- # tasks which match in the given plan.
388
- def ===(task)
389
- return unless super
390
-
391
- for pred in plan_predicates
392
- return unless plan.send(pred, task)
393
- end
394
- for neg_pred in neg_plan_predicates
395
- return if plan.send(neg_pred, task)
396
- end
397
- true
398
- end
399
-
400
- # Iterates on all the tasks in the given plan which match the query
401
- def each(&block)
402
- plan.query_each(result_set, &block)
403
- self
404
- end
405
- include Enumerable
406
- end
407
-
408
- # This task combines multiple task matching predicates through a OR boolean
409
- # operator.
410
- class OrTaskMatcher < TaskMatcher
411
- # Create a new OrTaskMatcher object combining the given predicates.
412
- def initialize(*ops)
413
- @ops = ops
414
- super()
415
- end
416
-
417
- # Filters as much as non-matching tasks as possible out of +task_set+,
418
- # based on the information in +task_index+
419
- def filter(task_set, task_index)
420
- result = ValueSet.new
421
- for child in @ops
422
- result.merge child.filter(task_set, task_index)
423
- end
424
- result
425
- end
426
-
427
- # Add a new predicate to the combination
428
- def <<(op); @ops << op end
429
- # True if the task matches at least one of the underlying predicates
430
- def ===(task)
431
- return unless @ops.any? { |op| op === task }
432
- super
433
- end
434
- end
435
-
436
- # Negate a given task-matching predicate
437
- class NegateTaskMatcher < TaskMatcher
438
- # Create a new TaskMatcher which matches if and only if +op+ does not
439
- def initialize(op)
440
- @op = op
441
- super()
442
- end
443
-
444
- # Filters as much as non-matching tasks as possible out of +task_set+,
445
- # based on the information in +task_index+
446
- def filter(initial_set, task_index)
447
- # WARNING: the value returned by filter is a SUPERSET of the
448
- # possible values for the query. Therefore, the result of
449
- # NegateTaskMatcher#filter is NOT
450
- #
451
- # initial_set - @op.filter(...)
452
- initial_set
453
- end
454
-
455
- # True if the task matches at least one of the underlying predicates
456
- def ===(task)
457
- return if @op === task
458
- super
459
- end
460
- end
461
-
462
- # This task combines multiple task matching predicates through a AND boolean
463
- # operator.
464
- class AndTaskMatcher < TaskMatcher
465
- # Create a new AndTaskMatcher object combining the given predicates.
466
- def initialize(*ops)
467
- @ops = ops
468
- super()
469
- end
470
-
471
- # Filters as much as non-matching tasks as possible out of +task_set+,
472
- # based on the information in +task_index+
473
- def filter(task_set, task_index)
474
- result = task_set
475
- for child in @ops
476
- result &= child.filter(task_set, task_index)
477
- end
478
- result
479
- end
480
-
481
- # Add a new predicate to the combination
482
- def <<(op); @ops << op end
483
- # True if the task matches at least one of the underlying predicates
484
- def ===(task)
485
- return unless @ops.all? { |op| op === task }
486
- super
487
- end
488
- end
489
-
490
- class Plan
491
- # Returns a Query object on this plan
492
- def find_tasks(model = nil, args = nil)
493
- q = Query.new(self)
494
- if model || args
495
- q.which_fullfills(model, args)
496
- end
497
- q
498
- end
499
-
500
- # Starts a local query on this plan
501
- #
502
- # See Query#scope
503
- def find_local_tasks(*args, &block)
504
- query = find_tasks(*args, &block)
505
- query.local_scope
506
- query
507
- end
508
-
509
- # Called by TaskMatcher#result_set and Query#result_set to get the set
510
- # of tasks matching +matcher+
511
- def query_result_set(matcher)
512
- result = ValueSet.new
513
- for task in matcher.filter(known_tasks, task_index)
514
- result << task if matcher === task
515
- end
516
- result
517
- end
518
-
519
- # Called by TaskMatcher#each and Query#each to return the result of
520
- # this query on +self+
521
- def query_each(result_set, &block)
522
- for task in result_set
523
- yield(task)
524
- end
525
- end
526
-
527
- # Given the result set of +query+, returns the subset of tasks which
528
- # have no parent in +query+
529
- def query_roots(result_set, relation)
530
- children = ValueSet.new
531
- found = ValueSet.new
532
- for task in result_set
533
- next if children.include?(task)
534
- task_children = task.generated_subgraph(relation)
535
- found -= task_children
536
- children.merge(task_children)
537
- found << task
538
- end
539
- found
540
- end
541
- end
542
-
543
- class Transaction
544
- # Returns two sets of tasks, [plan, transaction]. The union of the two
545
- # is the component that would be returned by
546
- # +relation.generated_subgraphs(*seeds)+ if the transaction was
547
- # committed
548
- def merged_generated_subgraphs(relation, plan_seeds, transaction_seeds)
549
- plan_set = ValueSet.new
550
- transaction_set = ValueSet.new
551
- plan_seeds = plan_seeds.to_value_set
552
- transaction_seeds = transaction_seeds.to_value_set
553
-
554
- loop do
555
- old_transaction_set = transaction_set.dup
556
- transaction_set.merge(transaction_seeds)
557
- for new_set in relation.generated_subgraphs(transaction_seeds, false)
558
- transaction_set.merge(new_set)
559
- end
560
-
561
- if old_transaction_set.size != transaction_set.size
562
- for o in (transaction_set - old_transaction_set)
563
- if o.respond_to?(:__getobj__)
564
- o.__getobj__.each_child_object(relation) do |child|
565
- plan_seeds << child unless self[child, false]
566
- end
567
- end
568
- end
569
- end
570
- transaction_seeds.clear
571
-
572
- plan_set.merge(plan_seeds)
573
- plan_seeds.each do |seed|
574
- relation.each_dfs(seed, BGL::Graph::TREE) do |_, dest, _, kind|
575
- next if plan_set.include?(dest)
576
- if self[dest, false]
577
- proxy = wrap(dest, false)
578
- unless transaction_set.include?(proxy)
579
- transaction_seeds << proxy
580
- end
581
- relation.prune # transaction branches must be developed inside the transaction
582
- else
583
- plan_set << dest
584
- end
585
- end
586
- end
587
- break if transaction_seeds.empty?
588
-
589
- plan_seeds.clear
590
- end
591
-
592
- [plan_set, transaction_set]
593
- end
594
-
595
- # Returns [plan_set, transaction_set], where the first is the set of
596
- # plan tasks matching +matcher+ and the second the set of transaction
597
- # tasks matching it. The two sets are disjoint.
598
- def query_result_set(matcher)
599
- plan_set = ValueSet.new
600
- if matcher.scope == :global
601
- for task in plan.query_result_set(matcher)
602
- plan_set << task unless self[task, false]
603
- end
604
- end
605
-
606
- transaction_set = super
607
- [plan_set, transaction_set]
608
- end
609
-
610
- # Yields tasks in the result set of +query+. Unlike Query#result_set,
611
- # all the tasks are included in the transaction
612
- def query_each(result_set)
613
- plan_set, trsc_set = result_set
614
- plan_set.each { |task| yield(self[task]) }
615
- trsc_set.each { |task| yield(task) }
616
- end
617
-
618
- # Given the result set of +query+, returns the subset of tasks which
619
- # have no parent in +query+
620
- def query_roots(result_set, relation)
621
- plan_set , trsc_set = *result_set
622
- plan_result , trsc_result = ValueSet.new , ValueSet.new
623
- plan_children , trsc_children = ValueSet.new , ValueSet.new
624
-
625
- for task in plan_set
626
- next if plan_children.include?(task)
627
- task_plan_children, task_trsc_children =
628
- merged_generated_subgraphs(relation, [task], [])
629
-
630
- plan_result -= task_plan_children
631
- trsc_result -= task_trsc_children
632
- plan_children.merge(task_plan_children)
633
- trsc_children.merge(task_trsc_children)
634
-
635
- plan_result << task
636
- end
637
-
638
- for task in trsc_set
639
- next if trsc_children.include?(task)
640
- task_plan_children, task_trsc_children =
641
- merged_generated_subgraphs(relation, [], [task])
642
-
643
- plan_result -= task_plan_children
644
- trsc_result -= task_trsc_children
645
- plan_children.merge(task_plan_children)
646
- trsc_children.merge(task_trsc_children)
647
-
648
- trsc_result << task
649
- end
650
-
651
- [plan_result, trsc_result]
652
- end
653
- end
654
- end
655
-