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,611 @@
1
+ module Roby
2
+ # Base class for all objects which are included in a plan.
3
+ class PlanObject < DistributedObject
4
+ extend Models::PlanObject
5
+ include Relations::DirectedRelationSupport
6
+
7
+ # This object's model
8
+ #
9
+ # This is usually self.class, unless {#specialize} has been called in
10
+ # which case it is this object's singleton class
11
+ attr_reader :model
12
+
13
+ # The non-specialized model for self
14
+ #
15
+ # It is always self.class
16
+ def concrete_model; self.class end
17
+
18
+ # The underlying execution engine if {#plan} is executable
19
+ attr_reader :execution_engine
20
+
21
+ # A thread pool that ensures that any work queued using {#promise} is
22
+ # serialized
23
+ attr_reader :promise_executor
24
+
25
+ def connection_space
26
+ if plan
27
+ plan.connection_space
28
+ end
29
+ end
30
+
31
+ # Whether this task can be finalized
32
+ #
33
+ # Unlike plan-level structure, a task that is marked as keepalive *will*
34
+ # be processed by garbage collection (e.g. stopping it). However, it
35
+ # will not be finalized (removed from the plan). The garbage collection
36
+ # will clear its relations instead of finalizing it
37
+ #
38
+ # The default returns true
39
+ def can_finalize?
40
+ true
41
+ end
42
+
43
+ # Generic handling object for blocks that are stored on tasks (event
44
+ # handlers,poll, ...)
45
+ #
46
+ # The only configurable behaviour so far is the ability to specify what
47
+ # to do with the block when a task is replaced by another one. This is
48
+ # given as a :on_replace option, which can take only two values:
49
+ #
50
+ # drop:: the handler is not copied
51
+ # copy:: the handler is copied
52
+ #
53
+ # The default is dependent on the receiving's object state. For
54
+ # instance, abstract tasks will use a default of 'copy' while
55
+ # non-abstract one will use a default of 'drop'.
56
+ class InstanceHandler
57
+ # The poll Proc object
58
+ attr_reader :block
59
+ ## :method:copy_on_replace?
60
+ #
61
+ # If true, this poll handler gets copied to the new task when the
62
+ # task holding the handler gets replaced
63
+ attr_predicate :copy_on_replace?, true
64
+
65
+ # Helper method for validate_options and filter_options
66
+ #
67
+ # @param [:validate,:filter] method which of the filter_options or
68
+ # validate_options should be called.
69
+ # @!macro InstanceHandlerOptions
70
+ # @option options [:copy,:drop] :on_replace defines the behaviour
71
+ # when this object gets replaced in the plan. If :copy is used,
72
+ # the handler is added to the replacing task and is also kept
73
+ # in the original task. If :drop, it is not copied (but is
74
+ # kept).
75
+ def self.handle_options(method, options, defaults)
76
+ options, other = Kernel.send("#{method}_options", options,
77
+ on_replace: (defaults[:on_replace] || :drop))
78
+
79
+ if ![:drop, :copy].include?(options[:on_replace])
80
+ raise ArgumentError, "wrong value for the :on_replace option. Expecting either :drop or :copy, got #{options[:on_replace]}"
81
+ end
82
+
83
+ if other
84
+ return options, other
85
+ else return options
86
+ end
87
+ end
88
+
89
+ def self.validate_options(options, defaults = Hash.new)
90
+ handle_options(:validate, options, defaults)
91
+ end
92
+
93
+ def self.filter_options(options, defaults)
94
+ handle_options(:filter, options, defaults)
95
+ end
96
+
97
+ def initialize(block, copy_on_replace)
98
+ @block, @copy_on_replace =
99
+ block, copy_on_replace
100
+ end
101
+
102
+ # Creates an option hash from this poll handler parameters that is
103
+ # valid for Task#poll
104
+ def as_options
105
+ on_replace = if copy_on_replace? then :copy
106
+ else :drop
107
+ end
108
+
109
+ { on_replace: on_replace }
110
+ end
111
+
112
+ def ==(other)
113
+ @copy_on_replace == other.copy_on_replace? &&
114
+ @block == other.block
115
+ end
116
+ end
117
+
118
+ def initialize(plan: TemplatePlan.new)
119
+ super()
120
+
121
+ @plan = plan
122
+ self.plan = @plan
123
+
124
+ @removed_at = nil
125
+ @executable = nil
126
+ @garbage = false
127
+ @finalization_handlers = Array.new
128
+ @model = self.class
129
+ end
130
+
131
+ def initialize_copy(other)
132
+ # Consider whether subclasses initialized the plan before calling us
133
+ # ... in which case we handle it specially and propagate it
134
+ super
135
+ @plan = nil
136
+ @relation_graphs = nil
137
+ @finalization_handlers = other.finalization_handlers.dup
138
+ end
139
+
140
+ # The plan this object belongs to
141
+ attr_reader :plan
142
+
143
+ # @deprecated use {#execution_engine} instead
144
+ def engine
145
+ Roby.warn_deprecated "PlanObject#engine is deprecated, use #execution_engine instead"
146
+ execution_engine
147
+ end
148
+
149
+ # True if this object is a transaction proxy, false otherwise
150
+ def transaction_proxy?; false end
151
+
152
+ # The place where this object has been removed from its plan. Once an
153
+ # object is removed from its plan, it cannot be added back again.
154
+ attr_accessor :removed_at
155
+
156
+ # True if this object has been included in a plan, but has been removed
157
+ # from it since
158
+ def finalized?; !!removed_at end
159
+
160
+ # Sets the new plan. Since it is forbidden to re-use a plan object that
161
+ # has been removed from a plan, it raises ArgumentError if it is the
162
+ # case
163
+ def plan=(new_plan)
164
+ if removed_at
165
+ if PlanObject.debug_finalization_place?
166
+ raise ArgumentError, "#{self} has been removed from plan, cannot add it back\n" +
167
+ "Removed at\n #{removed_at.join("\n ")}"
168
+ else
169
+ raise ArgumentError, "#{self} has been removed from plan, cannot add it back. Set PlanObject.debug_finalization_place to true to get the backtrace of where (in the code) the object got finalized"
170
+ end
171
+ end
172
+ @addition_time = Time.now
173
+ @plan = new_plan
174
+ @local_owner_id = plan.droby_id
175
+ if new_plan && new_plan.executable?
176
+ @execution_engine = new_plan.execution_engine
177
+ @promise_executor = Concurrent::SerializedExecutionDelegator.
178
+ new(@execution_engine.thread_pool)
179
+ else
180
+ @execution_engine = nil
181
+ @promise_executor = nil
182
+ end
183
+ end
184
+
185
+ # Create a promise that is serialized with all promises created for this
186
+ # object
187
+ #
188
+ # @param [String] description a textual description of the promise's
189
+ # role (used for debugging and timing)
190
+ # @return [Promise]
191
+ def promise(description: "#{self}.promise", executor: promise_executor, &block)
192
+ execution_engine.promise(description: description, executor: executor, &block)
193
+ end
194
+
195
+ # Used in plan management as a way to extract a plan object from any
196
+ # object
197
+ def as_plan; self end
198
+
199
+ # If +self+ is a transaction proxy, returns the underlying plan object,
200
+ # regardless of how many transactions there is on the stack. Otherwise,
201
+ # return self.
202
+ def real_object
203
+ result = self
204
+ while result.respond_to?(:__getobj__)
205
+ result = result.__getobj__
206
+ end
207
+ result
208
+ end
209
+
210
+ # Returns the stack of transactions/plans this object is part of,
211
+ # starting with self.plan.
212
+ def transaction_stack
213
+ result = [plan]
214
+ obj = self
215
+ while obj.respond_to?(:__getobj__)
216
+ obj = obj.__getobj__
217
+ result << obj.plan
218
+ end
219
+ result
220
+ end
221
+
222
+ def each_in_neighbour_merged(relation, intrusive: nil, &block)
223
+ if intrusive.nil?
224
+ raise ArgumentError, "you must give a true or false to the intrusive flag"
225
+ end
226
+ merged_relations(
227
+ proc { |o, &b| o.each_in_neighbour(relation, &b) },
228
+ intrusive, &block)
229
+ end
230
+
231
+ def each_out_neighbour_merged(relation, intrusive: nil, &block)
232
+ if intrusive.nil?
233
+ raise ArgumentError, "you must give a true or false to the intrusive flag"
234
+ end
235
+ merged_relations(
236
+ proc { |o, &b| o.each_out_neighbour(relation, &b) },
237
+ intrusive, &block)
238
+ end
239
+
240
+ # call-seq:
241
+ # merged_relation(enumeration_method, false[, arg1, arg2]) do |self_t, related_t|
242
+ # end
243
+ # merged_relation(enumeration_method, true[, arg1, arg2]) do |related_t|
244
+ # end
245
+ #
246
+ # It is assumed that +enumeration_method+ is the name of a method on
247
+ # +self+ that will yield an object related to +self+.
248
+ #
249
+ # This method computes the same set of related objects, but does so
250
+ # while merging all the changes that underlying transactions may have
251
+ # applied. I.e. it is equivalent to calling +enumeration_method+ on the
252
+ # plan that would be the result of the application of the whole
253
+ # transaction stack
254
+ #
255
+ # If +instrusive+ is false, the edges are yielded at the level they
256
+ # appear. I.e. both +self+ and the related object are given, and
257
+ # [self_t, related_t] may be part of a parent plan of self.plan. I.e.
258
+ # +self_t+ is either +self+ itself, or the task that +self+ represents
259
+ # in a parent plan / transaction.
260
+ #
261
+ # If +instrusive+ is true, the related objects are recursively added to
262
+ # all transactions in the transaction stack, and are given at the end.
263
+ # I.e. only the related object is yield, and it is guaranteed to be
264
+ # included in self.plan.
265
+ #
266
+ # For instance,
267
+ #
268
+ # merged_relations(:each_child, false) do |parent, child|
269
+ # ...
270
+ # end
271
+ #
272
+ # yields the children of +self+ according to the modifications that the
273
+ # transactions apply, but may do so in the transaction's parent plans.
274
+ #
275
+ # merged_relations(:each_child, true) do |child|
276
+ # ...
277
+ # end
278
+ #
279
+ # Will yield the same set of tasks, but included in +self.plan+.
280
+ def merged_relations(enumerator, intrusive)
281
+ return enum_for(__method__, enumerator, intrusive) if !block_given?
282
+
283
+ plan_chain = self.transaction_stack
284
+ object = self.real_object
285
+ enumerator = enumerator.to_proc
286
+
287
+ pending = Array.new
288
+ while plan_chain.size > 1
289
+ plan = plan_chain.pop
290
+ next_plan = plan_chain.last
291
+
292
+ # Objects that are in +plan+ but not in +next_plan+ are
293
+ # automatically added, as +next_plan+ is not able to change
294
+ # them. Those that are included in +next_plan+ are handled
295
+ # later.
296
+ new_objects = Array.new
297
+ enumerator.call(object) do |related_object|
298
+ next if next_plan[related_object, create: false]
299
+
300
+ if !intrusive
301
+ yield(object, related_object)
302
+ else
303
+ new_objects << related_object
304
+ end
305
+ end
306
+
307
+ # Here, pending contains objects from the previous plan (i.e. in
308
+ # plan.plan). Proxy them in +plan+.
309
+ #
310
+ # It is important to do that *after* we enumerated the relations
311
+ # that exist in +plan+ (above), as it reduces the number of
312
+ # relations at each level.
313
+ pending.map! { |t| plan[t] }
314
+ # And add the new objects that we just discovered
315
+ pending.concat(new_objects)
316
+
317
+ if next_plan
318
+ object = next_plan[object]
319
+ end
320
+ end
321
+
322
+ if intrusive
323
+ enumerator.call(self, &Proc.new)
324
+ for related_object in pending
325
+ yield(self.plan[related_object])
326
+ end
327
+ else
328
+ enumerator.call(self) do |related_object|
329
+ yield(self, related_object)
330
+ end
331
+ end
332
+ end
333
+
334
+ # A three-state flag with the following values:
335
+ # nil:: the object is executable if its plan is
336
+ # true:: the object is executable
337
+ # false:: the object is not executable
338
+ attr_writer :executable
339
+
340
+ # If this object is executable
341
+ def executable?
342
+ @executable || (@executable.nil? && !garbage? && plan && plan.executable?)
343
+ end
344
+
345
+ # @!method garbage?
346
+ #
347
+ # Whether this task has been marked as garbage by the garbage collection
348
+ # process
349
+ #
350
+ # @see garbage!
351
+ attr_predicate :garbage?
352
+
353
+ # Mark this task as garbage
354
+ #
355
+ # Garbage tasks cannot be involved in new relations, and cannot be
356
+ # executed
357
+ #
358
+ # Once set, this flag cannot be unset
359
+ #
360
+ # @see garbage?
361
+ def garbage!
362
+ @garbage = true
363
+ end
364
+
365
+ # True if we are explicitely subscribed to this object
366
+ def subscribed?
367
+ if root_object?
368
+ (plan && plan.subscribed?) ||
369
+ (!self_owned? && owners.any? { |peer| peer.subscribed_plan? }) ||
370
+ super
371
+ else
372
+ root_object.subscribed?
373
+ end
374
+ end
375
+
376
+ # Method called to apply modifications needed to commit this object into
377
+ # the underlying plan
378
+ #
379
+ # For instance, {Task} will make sure that argument objects that are
380
+ # transaction proxies are unwrapped
381
+ #
382
+ # Note that the method should only deal with modifications that are
383
+ # internal to the task itself. Modifications of the relation graphs are
384
+ # handled by {Transaction} itself in
385
+ # {Transaction#apply_modifications_to_plan}
386
+ #
387
+ # The default implementation does nothing
388
+ def commit_transaction
389
+ end
390
+
391
+ alias :__freeze__ :freeze
392
+
393
+ # True if we should send updates about this object to +peer+
394
+ def update_on?(peer); (plan && plan.update_on?(peer)) || super end
395
+ # True if we receive updates for this object from +peer+
396
+ def updated_by?(peer); (plan && plan.updated_by?(peer)) || super end
397
+ # True if this object is useful for one of our peers
398
+ def remotely_useful?; (plan && plan.remotely_useful?) || super end
399
+
400
+ # Checks that we do not link two objects from two different plans and
401
+ # updates the +plan+ attribute accordingly
402
+ #
403
+ # It raises RuntimeError if both objects are already included in a
404
+ # plan, but their plan mismatches.
405
+ def synchronize_plan(other) # :nodoc:
406
+ if !plan
407
+ raise RuntimeError, "cannot add a relation with #{self}, which has already been finalized"
408
+ elsif !other.plan
409
+ raise RuntimeError, "cannot add a relation with #{other}, which has already been finalized"
410
+ end
411
+ return if plan == other.plan
412
+
413
+ if other.plan.template?
414
+ plan.add(other)
415
+ elsif plan.template?
416
+ other.plan.add(self)
417
+ else
418
+ raise RuntimeError, "cannot add a relation between two objects from different plans. #{self} is from #{plan} and #{other} is from #{other.plan}"
419
+ end
420
+ end
421
+ protected :synchronize_plan
422
+
423
+ # Called when all links to +peer+ should be removed.
424
+ def forget_peer(peer)
425
+ if !root_object?
426
+ raise ArgumentError, "#{self} is not root"
427
+ end
428
+
429
+ each_plan_child do |child|
430
+ child.forget_peer(peer)
431
+ end
432
+ super
433
+ end
434
+
435
+ # Synchronizes the plan of this object from the one of its peer
436
+ def add_child_object(child, type, info = nil) # :nodoc:
437
+ if child.plan != plan
438
+ root_object.synchronize_plan(child.root_object)
439
+ if !type.kind_of?(Class)
440
+ # If given a graph, we need to re-resolve it as #plan might
441
+ # have changed
442
+ type = relation_graphs.fetch(type.class)
443
+ end
444
+ end
445
+
446
+ super
447
+ end
448
+
449
+ # Return the root plan object for this object.
450
+ def root_object; self end
451
+ # True if this object is a root object in the plan.
452
+ def root_object?; root_object == self end
453
+ # Iterates on all the children of this root object
454
+ def each_plan_child; self end
455
+
456
+ # Transfers a set of relations from this plan object to +object+.
457
+ # +changes+ is formatted as a sequence of <tt>relation, parents,
458
+ # children</tt> slices, where +parents+ and +children+ are sets of
459
+ # objects.
460
+ #
461
+ # For each of these slices, the method removes the
462
+ # <tt>parent->self</tt> and <tt>self->child</tt> edges in the given
463
+ # relation, and then adds the corresponding <tt>parent->object</tt> and
464
+ # <tt>object->child</tt> edges.
465
+ def apply_relation_changes(object, changes)
466
+ # The operation is done in two parts to avoid problems with
467
+ # creating cycles in the graph: first we remove the old edges, then
468
+ # we add the new ones.
469
+ changes.each_slice(3) do |rel, parents, children|
470
+ next if rel.copy_on_replace?
471
+
472
+ parents.each_slice(2) do |parent, info|
473
+ parent.remove_child_object(self, rel)
474
+ end
475
+ children.each_slice(2) do |child, info|
476
+ remove_child_object(child, rel)
477
+ end
478
+ end
479
+
480
+ changes.each_slice(3) do |rel, parents, children|
481
+ parents.each_slice(2) do |parent, info|
482
+ parent.add_child_object(object, rel, info)
483
+ end
484
+ children.each_slice(2) do |child, info|
485
+ object.add_child_object(child, rel, info)
486
+ end
487
+ end
488
+ end
489
+
490
+ # Replaces, in the plan, the subplan generated by this plan object by
491
+ # the one generated by +object+. In practice, it means that we transfer
492
+ # all parent edges whose target is +self+ from the receiver to
493
+ # +object+. It calls the various add/remove hooks defined in
494
+ # {Relations::DirectedRelationSupport}.
495
+ def replace_subplan_by(object)
496
+ raise NotImplementedError, "#{self.class} did not reimplement #replace_subplan_by"
497
+ end
498
+
499
+ # Replaces +self+ by +object+ in all graphs +self+ is part of.
500
+ def replace_by(object)
501
+ raise NotImplementedError, "#{self.class} did not reimplement #replace_by"
502
+ end
503
+
504
+ # Called by #replace_by and #replace_subplan_by to do object-specific
505
+ # initialization of +object+ when +object+ is used to replace +self+ in
506
+ # a plan
507
+ #
508
+ # The default implementation does nothing
509
+ def initialize_replacement(object)
510
+ finalization_handlers.each do |handler|
511
+ if handler.copy_on_replace?
512
+ object ||= yield
513
+ object.when_finalized(handler.as_options, &handler.block)
514
+ end
515
+ end
516
+ end
517
+
518
+ # True if this object can be modified by the local plan manager
519
+ def read_write?
520
+ if self_owned?
521
+ true
522
+ elsif plan.self_owned?
523
+ owners.all? { |p| plan.owned_by?(p) }
524
+ end
525
+ end
526
+
527
+ # @return [Array<InstanceHandler>] set of finalization handlers defined
528
+ # on this task instance
529
+ # @see when_finalized
530
+ attr_reader :finalization_handlers
531
+
532
+ # Enumerates the finalization handlers that should be applied in
533
+ # finalized!
534
+ #
535
+ # @yieldparam [#call] block the handler's block
536
+ # @return [void]
537
+ def each_finalization_handler(&block)
538
+ finalization_handlers.each do |handler|
539
+ yield(handler.block)
540
+ end
541
+ self.class.each_finalization_handler do |model_handler|
542
+ model_handler.bind(self).call(&block)
543
+ end
544
+ end
545
+
546
+ # Called when a particular object has been removed from its plan
547
+ #
548
+ # If PlanObject.debug_finalization_place? is true (set with
549
+ # {PlanObject.debug_finalization_place=}, the backtrace in this call is
550
+ # stored in {PlanObject#removed_at}. It is false by default, as it is
551
+ # pretty expensive.
552
+ #
553
+ # @param [Time,nil] timestamp the time at which it got finalized. It is stored in
554
+ # {#finalization_time}
555
+ # @return [void]
556
+ def finalized!(timestamp = nil)
557
+ if self.plan.executable?
558
+ # call finalization handlers
559
+ each_finalization_handler do |handler|
560
+ handler.call(self)
561
+ end
562
+ end
563
+
564
+ if root_object?
565
+ self.plan = nil
566
+ if PlanObject.debug_finalization_place?
567
+ self.removed_at = caller
568
+ else
569
+ self.removed_at = []
570
+ end
571
+ self.finalization_time = timestamp || Time.now
572
+ self.finalized = true
573
+ end
574
+ end
575
+
576
+ # Called when the task gets finalized, i.e. removed from the main plan
577
+ #
578
+ # @option options [:copy,:drop] :on_replace (:drop) behaviour to be
579
+ # followed when the task gets replaced. If :drop, the handler is not
580
+ # passed, if :copy it is installed on the new task as well as kept on
581
+ # the old one
582
+ # @yieldparam [Roby::Task] task the task that got finalized. It might be
583
+ # different than the one on which the handler got installed because of
584
+ # replacements
585
+ # @return [void]
586
+ def when_finalized(options = Hash.new, &block)
587
+ options = InstanceHandler.validate_options options
588
+ check_arity(block, 1)
589
+ finalization_handlers << InstanceHandler.new(block, (options[:on_replace] == :copy))
590
+ end
591
+
592
+ # True if this plan object has been finalized (i.e. removed from plan),
593
+ # or false otherwise
594
+ attr_predicate :finalized?, true
595
+
596
+ # The time at which this plan object has been added into its first plan
597
+ attr_accessor :addition_time
598
+
599
+ # The time at which this plan object has been finalized (i.e. removed
600
+ # from plan), or nil if it has not been (yet)
601
+ attr_accessor :finalization_time
602
+
603
+ # @return [Boolean] true if this object provides all the given models
604
+ def fullfills?(models)
605
+ Array(models).all? do |m|
606
+ self.model <= m
607
+ end
608
+ end
609
+ end
610
+ end
611
+