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
@@ -0,0 +1,549 @@
1
+ module Roby
2
+ # A plan that can be used for execution
3
+ #
4
+ # While {Plan} maintains the plan data structure itself, this class provides
5
+ # excution-related services such as exceptions and GC-related methods
6
+ class ExecutablePlan < Plan
7
+ extend Logger::Hierarchy
8
+ extend Logger::Forward
9
+
10
+ # The ExecutionEngine object which handles this plan. The role of this
11
+ # object is to provide the event propagation, error propagation and
12
+ # garbage collection mechanisms for the execution.
13
+ #
14
+ # @return [ExecutionEngine]
15
+ attr_accessor :execution_engine
16
+
17
+ # The ConnectionSpace object which handles this plan. The role of this
18
+ # object is to sharing with other Roby plan managers
19
+ attr_accessor :connection_space
20
+
21
+ # @deprecated use {#execution_engine} instead
22
+ def engine
23
+ Roby.warn_deprecated "Plan#engine is deprecated, use #execution_engine instead"
24
+ execution_engine
25
+ end
26
+
27
+ # The DecisionControl object which is associated with this plan. This
28
+ # object's role is to handle the conflicts that can occur during event
29
+ # propagation.
30
+ def control; execution_engine.control end
31
+
32
+ # A set of tasks which are useful (and as such would not been garbage
33
+ # collected), but we want to GC anyway
34
+ #
35
+ # @return [Set<Roby::Task>]
36
+ attr_reader :force_gc
37
+
38
+ # The list of plan-wide exception handlers
39
+ #
40
+ # @return [Array<(#===, #call)>]
41
+ attr_reader :exception_handlers
42
+
43
+ def initialize(event_logger: DRoby::NullEventLogger.new)
44
+ super(graph_observer: self, event_logger: event_logger)
45
+
46
+ @execution_engine = ExecutionEngine.new(self)
47
+ @force_gc = Set.new
48
+ @exception_handlers = Array.new
49
+ on_exception LocalizedError do |plan, error|
50
+ plan.default_localized_error_handling(error)
51
+ end
52
+ end
53
+
54
+ # @api private
55
+ #
56
+ # Put the given task in quarantine. In practice, it means that all the
57
+ # event relations of that task's events are removed, as well as its
58
+ # children. Then, the task is marked as quarantined with
59
+ # {Task#quarantined?} and the engine will not attempt to garbage-collect
60
+ # it anymore
61
+ #
62
+ # This is used as a last resort, when the task cannot be stopped/GCed by
63
+ # normal means.
64
+ def quarantine_task(task)
65
+ log(:quarantined_task, droby_id, task)
66
+
67
+ task.quarantined!
68
+ task.clear_relations(remove_internal: false, remove_strong: false)
69
+ self
70
+ end
71
+
72
+ # Check that this is an executable plan
73
+ #
74
+ # This always returns true for {ExecutablePlan}
75
+ def executable?; true end
76
+
77
+ def refresh_relations
78
+ super
79
+ execution_engine.refresh_relations
80
+ end
81
+
82
+ def event_logger=(logger)
83
+ super
84
+ log :register_executable_plan, droby_id
85
+ end
86
+
87
+ # @api private
88
+ #
89
+ # Default toplevel error handling for {LocalizedError}
90
+ #
91
+ # It activates fault handlers, and adds {MissionFailedError} /
92
+ # {PermanentTaskError}
93
+ def default_localized_error_handling(error)
94
+ matching_handlers = Array.new
95
+ active_fault_response_tables.each do |table|
96
+ table.find_all_matching_handlers(error).each do |handler|
97
+ matching_handlers << [table, handler]
98
+ end
99
+ end
100
+ handlers = matching_handlers.sort_by { |_, handler| handler.priority }
101
+
102
+ while !handlers.empty?
103
+ table, handler = handlers.shift
104
+ if handler
105
+ begin
106
+ handler.activate(error, table.arguments)
107
+ return
108
+ rescue Exception => e
109
+ Robot.warn "ignored exception handler #{handler} because of exception"
110
+ Roby.log_exception_with_backtrace(e, Robot, :warn)
111
+ end
112
+ end
113
+ end
114
+
115
+ pass_exception
116
+ end
117
+
118
+ def generate_induced_errors(error_phase_results)
119
+ error_phase_results.each_fatal_error do |execution_exception, tasks|
120
+ # MissionFailedError and PermanentTaskError are not propagated,
121
+ # so tasks == [origin] and we should not re-add an error
122
+ if execution_exception.exception.kind_of?(MissionFailedError) ||
123
+ execution_exception.exception.kind_of?(PermanentTaskError)
124
+ next
125
+ end
126
+
127
+ tasks.each do |t|
128
+ if mission_task?(t)
129
+ add_error(MissionFailedError.new(t, execution_exception.exception), propagate_through: [])
130
+ elsif permanent_task?(t)
131
+ add_error(PermanentTaskError.new(t, execution_exception.exception), propagate_through: [])
132
+ end
133
+ end
134
+ end
135
+ end
136
+
137
+ # Calls the given block in the execution thread of this plan's engine.
138
+ # If there is no engine attached to this plan, yields immediately
139
+ #
140
+ # See ExecutionEngine#execute
141
+ def execute(&block)
142
+ execution_engine.execute(&block)
143
+ end
144
+
145
+ # @api private
146
+ #
147
+ # Hook called when a task is finalized
148
+ def finalized_task(task)
149
+ execution_engine.finalized_task(task)
150
+ super
151
+ end
152
+
153
+ # @api private
154
+ #
155
+ # Hook called when an event is finalized
156
+ def finalized_event(event)
157
+ execution_engine.finalized_event(event)
158
+ super
159
+ end
160
+
161
+ # @api private
162
+ #
163
+ # Hook called before an edge gets added to this plan
164
+ #
165
+ # If an exception is raised, the edge will not be added
166
+ #
167
+ # @param [Object] parent the child object
168
+ # @param [Object] child the child object
169
+ # @param [Array<Class<Relations::Graph>>] relations the graphs in which an edge
170
+ # has been added
171
+ # @param [Object] info the associated edge info that applies to
172
+ # relations.first
173
+ def adding_edge(parent, child, relations, info)
174
+ if !parent.read_write? || !child.read_write?
175
+ raise OwnershipError, "cannot remove a relation between two objects we don't own"
176
+ elsif parent.garbage?
177
+ raise ReusingGarbage, "attempting to reuse #{parent} which is marked as garbage"
178
+ elsif child.garbage?
179
+ raise ReusingGarbage, "attempting to reuse #{child} which is marked as garbage"
180
+ end
181
+
182
+ if last_dag = relations.find_all(&:dag?).last
183
+ if child.relation_graph_for(last_dag).reachable?(child, parent)
184
+ raise Relations::CycleFoundError, "adding an edge from #{parent} to #{child} would create a cycle in #{last_dag}"
185
+ end
186
+ end
187
+
188
+ relations.each do |rel|
189
+ if name = rel.child_name
190
+ parent.send("adding_#{rel.child_name}", child, info)
191
+ child.send("adding_#{rel.child_name}_parent", parent, info)
192
+ end
193
+ end
194
+
195
+ for trsc in transactions
196
+ next unless trsc.proxying?
197
+ if (parent_proxy = trsc[parent, create: false]) && (child_proxy = trsc[child, create: false])
198
+ trsc.adding_plan_relation(parent_proxy, child_proxy, relations, info)
199
+ end
200
+ end
201
+ end
202
+
203
+ # @api private
204
+ #
205
+ # Hook called after a new edge has been added in this plan
206
+ #
207
+ # @param [Object] parent the child object
208
+ # @param [Object] child the child object
209
+ # @param [Array<Class<Relations::Graph>>] relations the graphs in which an edge
210
+ # has been added
211
+ # @param [Object] info the associated edge info that applies to
212
+ # relations.first
213
+ def added_edge(parent, child, relations, info)
214
+ relations.each do |rel|
215
+ if rel == Roby::EventStructure::Precedence
216
+ execution_engine.event_ordering.clear
217
+ end
218
+
219
+ if name = rel.child_name
220
+ parent.send("added_#{rel.child_name}", child, info)
221
+ child.send("added_#{rel.child_name}_parent", parent, info)
222
+ end
223
+ end
224
+
225
+ log(:added_edge, parent, child, relations, info)
226
+ end
227
+
228
+ # @api private
229
+ #
230
+ # Hook called to announce that the edge information of an existing edge
231
+ # will be updated
232
+ #
233
+ # @param parent the edge parent object
234
+ # @param child the edge child object
235
+ # @param [Class<Relations::Graph>] relation the relation graph ID
236
+ # @param [Object] info the new edge info
237
+ def updating_edge_info(parent, child, relation, info)
238
+ emit_relation_change_hook(parent, child, relation, info, prefix: 'updating')
239
+ end
240
+
241
+ # @api private
242
+ #
243
+ # Hook called when the edge information of an existing edge has been
244
+ # updated
245
+ #
246
+ # @param parent the edge parent object
247
+ # @param child the edge child object
248
+ # @param [Class<Relations::Graph>] relation the relation graph ID
249
+ # @param [Object] info the new edge info
250
+ def updated_edge_info(parent, child, relation, info)
251
+ emit_relation_change_hook(parent, child, relation, info, prefix: 'updated')
252
+ log(:updated_edge_info, parent, child, relation, info)
253
+ end
254
+
255
+ # @api private
256
+ #
257
+ # Hook called before an edge gets removed from this plan
258
+ #
259
+ # If an exception is raised, the edge will not be removed
260
+ #
261
+ # @param [Object] parent the parent object
262
+ # @param [Object] child the child object
263
+ # @param [Array<Class<Relations::Graph>>] relations the graphs in which an edge
264
+ # is being removed
265
+ def removing_edge(parent, child, relations)
266
+ unless parent.read_write? || child.child.read_write?
267
+ raise OwnershipError, "cannot remove a relation between two objects we don't own"
268
+ end
269
+
270
+ relations.each do |rel|
271
+ if name = rel.child_name
272
+ parent.send("removing_#{rel.child_name}", child)
273
+ child.send("removing_#{rel.child_name}_parent", parent)
274
+ end
275
+ end
276
+
277
+ for trsc in transactions
278
+ next unless trsc.proxying?
279
+ if (parent_proxy = trsc[parent, create: false]) && (child_proxy = trsc[child, create: false])
280
+ trsc.removing_plan_relation(parent_proxy, child_proxy, relations)
281
+ end
282
+ end
283
+ end
284
+
285
+ # @api private
286
+ #
287
+ # Hook called after an edge has been removed from this plan
288
+ #
289
+ # @param [Object] parent the child object
290
+ # @param [Object] child the child object
291
+ # @param [Array<Class<Relations::Graph>>] relations the graphs in which an edge
292
+ # has been removed
293
+ def removed_edge(parent, child, relations)
294
+ relations.each do |rel|
295
+ if name = rel.child_name
296
+ parent.send("removed_#{rel.child_name}", child)
297
+ child.send("removed_#{rel.child_name}_parent", parent)
298
+ end
299
+ end
300
+
301
+ log(:removed_edge, parent, child, relations)
302
+ end
303
+
304
+ # @api private
305
+ #
306
+ # Helper for {#updating_edge_info} and {#updated_edge_info}
307
+ def emit_relation_change_hook(parent, child, rel, *args, prefix: nil)
308
+ if name = rel.child_name
309
+ parent.send("#{prefix}_#{rel.child_name}", child, *args)
310
+ child.send("#{prefix}_#{rel.child_name}_parent", parent, *args)
311
+ end
312
+ end
313
+
314
+ # @api private
315
+ #
316
+ # Calls the added_* hook methods for all edges in a relation graph
317
+ #
318
+ # It is a helper for {#merged_plan}
319
+ def emit_relation_graph_merge_hooks(graph, prefix: nil)
320
+ rel = graph.class
321
+ if rel.child_name
322
+ added_child_hook = "#{prefix}_#{rel.child_name}"
323
+ added_parent_hook = "#{added_child_hook}_parent"
324
+ graph.each_edge do |parent, child, info|
325
+ parent.send(added_child_hook, child, info)
326
+ child.send(added_parent_hook, parent, info)
327
+ end
328
+ end
329
+ end
330
+
331
+ # @api private
332
+ #
333
+ # Calls the added_ and adding_ hooks for modifications originating from
334
+ # a transaction that involve tasks originally from the plan
335
+ def emit_relation_graph_transaction_application_hooks(list, prefix: nil)
336
+ hooks = Hash.new
337
+ list.each do |graph, parent, child, *args|
338
+ if !hooks.has_key?(graph)
339
+ rel = graph.class
340
+ if rel.child_name
341
+ parent_hook = "#{prefix}_#{rel.child_name}"
342
+ child_hook = "#{parent_hook}_parent"
343
+ hooks[graph] = [parent_hook, child_hook]
344
+ else
345
+ hooks[graph] = nil
346
+ end
347
+ end
348
+
349
+ parent_hook, child_hook = hooks[graph]
350
+ next if !child_hook
351
+
352
+ parent.send(parent_hook, child, *args)
353
+ child.send(child_hook, parent, *args)
354
+ end
355
+ end
356
+
357
+ # @api private
358
+ #
359
+ # Applies modification information extracted from a transaction. This is
360
+ # used by {Transaction#commit_transaction}
361
+ def merge_transaction(transaction, merged_graphs, added, removed, updated)
362
+ added.each do |_, parent, child, _|
363
+ if parent.garbage?
364
+ raise ReusingGarbage, "attempting to reuse #{parent} which is marked as garbage"
365
+ elsif child.garbage?
366
+ raise ReusingGarbage, "attempting to reuse #{child} which is marked as garbage"
367
+ end
368
+ end
369
+
370
+ emit_relation_graph_transaction_application_hooks(added, prefix: 'adding')
371
+ emit_relation_graph_transaction_application_hooks(removed, prefix: 'removing')
372
+ emit_relation_graph_transaction_application_hooks(updated, prefix: 'updating')
373
+
374
+ super
375
+
376
+ precedence_graph = event_relation_graph_for(EventStructure::Precedence)
377
+ precedence_edge_count = precedence_graph.num_edges
378
+ emit_relation_graph_transaction_application_hooks(added, prefix: 'added')
379
+ if precedence_edge_count != precedence_graph.num_edges
380
+ execution_engine.event_ordering.clear
381
+ end
382
+ emit_relation_graph_transaction_application_hooks(removed, prefix: 'removed')
383
+ if precedence_edge_count != precedence_graph.num_edges
384
+ execution_engine.event_ordering.clear
385
+ end
386
+ emit_relation_graph_transaction_application_hooks(updated, prefix: 'updated')
387
+
388
+ added.each do |graph, parent, child, info|
389
+ log(:added_edge, parent, child, [graph.class], info)
390
+ end
391
+ removed.each do |graph, parent, child|
392
+ log(:removed_edge, parent, child, [graph.class])
393
+ end
394
+ updated.each do |graph, parent, child, info|
395
+ log(:updated_edge_info, parent, child, graph.class, info)
396
+ end
397
+ end
398
+
399
+ # @api private
400
+ #
401
+ # Emits the adding_* hooks when a plan gets merged in self
402
+ def merging_plan(plan)
403
+ plan.each_task_relation_graph do |graph|
404
+ emit_relation_graph_merge_hooks(graph, prefix: 'adding')
405
+ end
406
+ plan.each_event_relation_graph do |graph|
407
+ emit_relation_graph_merge_hooks(graph, prefix: 'adding')
408
+ end
409
+ super
410
+ end
411
+
412
+ # @api private
413
+ #
414
+ # Emits the added_* hooks when a plan gets merged in self
415
+ def merged_plan(plan)
416
+ if !plan.event_relation_graph_for(EventStructure::Precedence).empty?
417
+ execution_engine.event_ordering.clear
418
+ end
419
+
420
+ plan.each_task_relation_graph do |graph|
421
+ emit_relation_graph_merge_hooks(graph, prefix: 'added')
422
+ end
423
+ plan.each_event_relation_graph do |graph|
424
+ emit_relation_graph_merge_hooks(graph, prefix: 'added')
425
+ end
426
+
427
+ super
428
+
429
+ log(:merged_plan, droby_id, plan)
430
+ end
431
+
432
+ # @api private
433
+ #
434
+ # Called to handle a task that should be garbage-collected
435
+ #
436
+ # What actually happens to the task is controlled by
437
+ # {PlanObject#can_finalize?}.
438
+ #
439
+ # If the task can be finalized, it is removed from the plan, after
440
+ # having triggered all relevant log events/hooks.
441
+ #
442
+ # Otherwise, it is isolated from the rest of the plan. Its relations and
443
+ # the relations of its events are cleared and the task is left in the
444
+ # plan. In the latter case, the task is marked as non-reusable.
445
+ #
446
+ # Always check {Task#reusable?} before using a task present in an
447
+ # {ExecutablePlan} in a new structure.
448
+ #
449
+ # @param [Task] task the task that is being garbage-collected
450
+ # @return [Boolean] true if the plan got modified, and false otherwise.
451
+ # In practice, it will return false only if the task cannot be
452
+ # finalized *and* has external relations.
453
+ def garbage_task(task)
454
+ log(:garbage_task, droby_id, task, task.can_finalize?)
455
+
456
+ if task.can_finalize?
457
+ remove_task(task)
458
+ true
459
+ else
460
+ task.garbage!
461
+ task.clear_relations(remove_internal: false, remove_strong: false)
462
+ end
463
+ end
464
+
465
+ # Called to handle a free event that should be garbage-collected
466
+ #
467
+ # What actually happens to the event is controlled by
468
+ # {PlanObject#can_finalize?}. If the event can be finalized, it is (i.e.
469
+ # removed from the plan, after having triggered all relevant log
470
+ # events/hooks). Otherwise, its relations are cleared and the task is
471
+ # left in the plan
472
+ #
473
+ # @return [Boolean] true if the plan got modified, and false otherwise.
474
+ # In practice, it will return false only for events that had no
475
+ # relations and that cannot be finalized.
476
+ def garbage_event(event)
477
+ log(:garbage_event, droby_id, event)
478
+ if event.can_finalize?
479
+ remove_free_event(event)
480
+ true
481
+ else
482
+ event.clear_relations(remove_strong: false)
483
+ end
484
+ end
485
+
486
+ include Roby::ExceptionHandlingObject
487
+
488
+ # Iterate over the plan-wide exception handlers
489
+ #
490
+ # @yieldparam [#===] matcher an object that allows to match an
491
+ # {ExecutionException}
492
+ # @yieldparam [#call] handler the exception handler, which will be
493
+ # called with the plan and the {ExecutionException} object as argument
494
+ def each_exception_handler(&block)
495
+ exception_handlers.each(&block)
496
+ end
497
+
498
+ # Register a new exception handler
499
+ #
500
+ # @param [#===,#to_execution_exception_matcher] matcher
501
+ # an object that matches exceptions for which the handler should be
502
+ # called. Exception classes can be used directly. If more advanced
503
+ # matching is needed, use .match to convert an exception class into
504
+ # {Queries::LocalizedErrorMatcher} or one of its subclasses.
505
+ #
506
+ # @yieldparam [ExecutablePlan] plan the plan in which the exception
507
+ # happened
508
+ # @yieldparam [ExecutionException] exception the exception that is being handled
509
+ def on_exception(matcher, &handler)
510
+ check_arity(handler, 2)
511
+ exception_handlers.unshift [matcher.to_execution_exception_matcher, handler]
512
+ end
513
+
514
+ # Actually remove a task from the plan
515
+ def remove_task(object, timestamp = nil)
516
+ if object.respond_to?(:running?) && object.running? && object.self_owned?
517
+ raise ArgumentError, "attempting to remove #{object}, which is a running task, from an executable plan"
518
+ end
519
+
520
+ super
521
+ @force_gc.delete(object)
522
+ end
523
+
524
+ # Clear the plan
525
+ def clear
526
+ super
527
+ @force_gc.clear
528
+ end
529
+
530
+ # Replace +task+ with a fresh copy of itself and start it.
531
+ #
532
+ # See #recreate for details about the new task.
533
+ def respawn(task)
534
+ new = recreate(task)
535
+ execution_engine.once { new.start!(nil) }
536
+ new
537
+ end
538
+
539
+ # @api private
540
+ #
541
+ # Called by {ExecutionEngine} to verify the plan's internal structure
542
+ def call_structure_check_handler(handler)
543
+ super
544
+ rescue Exception => e
545
+ execution_engine.add_framework_error(e, 'structure checking')
546
+ end
547
+ end
548
+ end
549
+