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,89 @@
1
+ module Roby
2
+ module GUI
3
+ # Widget that can be used to display the information about a plan object
4
+ # (either relation or task)
5
+ #
6
+ # The object should be provided to #display to update the view.
7
+ # #activate can then be used to show the widget and make it toplevel
8
+ # (force its visibility).
9
+ class ObjectInfoView < Qt::ListWidget
10
+ def initialize(parent = nil)
11
+ super
12
+ resize(400, 400)
13
+
14
+ connect(SIGNAL('itemDoubleClicked(QListWidgetItem*)')) do |item|
15
+ emit selectedTime(item.data(Qt::UserRole).to_date_time)
16
+ end
17
+ end
18
+
19
+ # Emitted when the user double-clicks a time field in the view (e.g.
20
+ # an event in a task history)
21
+ signals 'selectedTime(QDateTime)'
22
+
23
+ # Updates the view to display the information about +obj+
24
+ def display(obj)
25
+ sections = []
26
+ if obj.kind_of?(Array)
27
+ from, to, rel = obj
28
+ section = [
29
+ "#{rel}",
30
+ [ "from: #{from}",
31
+ "to: #{to}",
32
+ "info: #{from[to, rel]}"]
33
+ ]
34
+ sections << section
35
+
36
+ elsif obj.kind_of?(Task)
37
+ sections << ["Model", [obj.model.name]]
38
+ # Add general task information (owner, arguments, ...)
39
+ text = obj.arguments.map do |key, value|
40
+ "#{key}: #{value}"
41
+ end
42
+ sections << ["Arguments", text]
43
+
44
+ # Add the history
45
+ if obj.failed_to_start?
46
+ text = []
47
+ text << ["Failed to start at #{Roby.format_time(obj.failed_to_start_time)}", obj.failed_to_start_time]
48
+ text.concat(Roby.format_exception(obj))
49
+ else
50
+ text = obj.history.map do |event|
51
+ time_as_text = "#{Roby.format_time(event.time)}"
52
+ ["#{time_as_text}: #{event.symbol}", event.time]
53
+ end
54
+ end
55
+ sections << ["History", text]
56
+ sections << ["Model Ancestry", obj.model.ancestors.map(&:name)]
57
+ else return false
58
+ end
59
+
60
+ self.windowTitle = "Details for #{obj}"
61
+ clear
62
+ sections.each do |header, lines|
63
+ if header
64
+ item = Qt::ListWidgetItem.new(self)
65
+ item.text = header
66
+ item.background = Qt::Brush.new(Qt::Color.new("#45C1FF"))
67
+ font = item.font
68
+ font.weight = Qt::Font::Bold
69
+ item.font = font
70
+ end
71
+ lines.each do |txt, time|
72
+ item = Qt::ListWidgetItem.new(" #{txt}")
73
+ if time
74
+ item.setData(Qt::UserRole, Qt::Variant.new(Qt::DateTime.new(time)))
75
+ end
76
+ addItem(item)
77
+ end
78
+ end
79
+ end
80
+
81
+ # Shows the widget and makes it visible (i.e. toplevel)
82
+ def activate
83
+ show
84
+ activateWindow
85
+ end
86
+ end
87
+ end
88
+ end
89
+
@@ -0,0 +1,427 @@
1
+ require 'roby/gui/dot_id'
2
+ require 'tempfile'
3
+ require 'fileutils'
4
+
5
+ module Roby
6
+ module GUI
7
+ module GraphvizPlan
8
+ attr_accessor :layout_level
9
+ def all_events(display)
10
+ tasks.inject(free_events.dup) do |events, task|
11
+ if display.displayed?(task)
12
+ events.merge(task.events.values.to_set)
13
+ else
14
+ events
15
+ end
16
+ end
17
+ end
18
+
19
+ def to_dot(display, io, level)
20
+ @layout_level = level
21
+ io << "subgraph cluster_#{dot_id} {\n"
22
+ (tasks | finalized_tasks | free_events | finalized_events).
23
+ each do |obj|
24
+ obj.to_dot(display, io) if display.displayed?(obj)
25
+ end
26
+
27
+ io << "};\n"
28
+
29
+ transactions.each do |trsc|
30
+ trsc.to_dot(display, io, level + 1)
31
+ end
32
+
33
+ relations_to_dot(display, io, each_task_relation_graph, tasks)
34
+ end
35
+
36
+ def each_edge(graph, display, objects)
37
+ objects.each do |from|
38
+ next unless display.displayed?(from)
39
+ unless display[from]
40
+ DRoby::Logfile.warn "no display item for #{from} in #each_displayed_relation"
41
+ next
42
+ end
43
+
44
+ graph.each_out_neighbour(from) do |to|
45
+ next unless display.displayed?(to)
46
+ unless display[to]
47
+ DRoby::Logfile.warn "no display item for child in #{from} <#{rel}> #{to} in #each_displayed_relation"
48
+ next
49
+ end
50
+
51
+ yield(graph, from, to)
52
+ end
53
+ end
54
+ end
55
+
56
+ def each_layout_relation(display, graphs, objects, &block)
57
+ graphs.each do |g|
58
+ next unless display.layout_relation?(g.class)
59
+ each_edge(g, display, objects, &block)
60
+ end
61
+ end
62
+
63
+ def each_displayed_relation(display, graphs, objects, &block)
64
+ graphs.each do |g|
65
+ next unless display.relation_enabled?(g.class)
66
+ each_edge(g, display, objects, &block)
67
+ end
68
+ end
69
+
70
+ def relations_to_dot(display, io, graphs, objects)
71
+ each_layout_relation(display, graphs, objects) do |graph, from, to|
72
+ from_id, to_id = from.dot_id, to.dot_id
73
+ if from_id && to_id
74
+ io << " #{from_id} -> #{to_id}\n"
75
+ else
76
+ DRoby::Logfile.warn "ignoring #{from}(#{from.object_id} #{from_id}) -> #{to}(#{to.object_id} #{to_id}) in #{graph.class} in #{caller(1).join("\n ")}"
77
+ end
78
+ end
79
+ end
80
+
81
+ def layout_relations(positions, display, graphs, objects)
82
+ each_displayed_relation(display, graphs, objects) do |graph, from, to|
83
+ display.task_relation(from, to, graph.class, graph.edge_info(from, to))
84
+ end
85
+ end
86
+
87
+ # The distance from the root plan
88
+ attr_reader :depth
89
+
90
+ # Computes the plan depths and max_depth for this plan and all its
91
+ # children. +depth+ is this plan depth
92
+ #
93
+ # Returns max_depth
94
+ def compute_depth(depth)
95
+ @depth = depth
96
+ child_depth = transactions.
97
+ map { |trsc| trsc.compute_depth(depth + 1) }.
98
+ max
99
+ child_depth || depth
100
+ end
101
+
102
+ def apply_layout(bounding_rects, positions, display, max_depth = nil)
103
+ max_depth ||= compute_depth(0)
104
+
105
+ if rect = bounding_rects[dot_id]
106
+ item = display[self]
107
+ item.z_value = PLAN_LAYER + depth - max_depth
108
+ item.rect = rect
109
+ else
110
+ DRoby::Logfile.warn "no bounding rectangle for #{self} (#{dot_id})"
111
+ end
112
+
113
+
114
+ (tasks | finalized_tasks | free_events | finalized_events).
115
+ each do |obj|
116
+ next if !display.displayed?(obj)
117
+ obj.apply_layout(bounding_rects, positions, display)
118
+ end
119
+
120
+ transactions.each do |trsc|
121
+ trsc.apply_layout(bounding_rects, positions, display, max_depth)
122
+ end
123
+ layout_relations(positions, display, each_task_relation_graph.to_a, tasks)
124
+ end
125
+ end
126
+
127
+ module GraphvizPlanObject
128
+ def dot_label(display); display_name(display) end
129
+
130
+ # Adds the dot definition for this object in +io+
131
+ def to_dot(display, io)
132
+ return unless display.displayed?(self)
133
+ graphics = display.graphics[self]
134
+ bounding_rect = graphics.bounding_rect
135
+ if graphics.respond_to?(:text)
136
+ bounding_rect |= graphics.text.bounding_rect
137
+ end
138
+
139
+ io << " #{dot_id}[label=\"#{dot_label(display).split("\n").join('\n')}\",width=#{bounding_rect.width},height=#{bounding_rect.height},fixedsize=true];\n"
140
+ end
141
+
142
+ # Applys the layout in +positions+ to this particular object
143
+ def apply_layout(bounding_rects, positions, display)
144
+ return unless display.displayed?(self)
145
+ if p = positions[dot_id]
146
+ raise "no graphics for #{self}" unless graphics_item = display[self]
147
+ graphics_item.pos = p
148
+ elsif b = bounding_rects[dot_id]
149
+ raise "no graphics for #{self}" unless graphics_item = display[self]
150
+ graphics_item.rect = b
151
+ else
152
+ STDERR.puts "WARN: #{self} has not been layouted (#{dot_id.inspect})"
153
+ end
154
+ end
155
+ end
156
+
157
+ module GraphvizTaskEventGenerator
158
+ include GraphvizPlanObject
159
+ def dot_label(display); symbol.to_s end
160
+ end
161
+
162
+ module GraphvizTask
163
+ include GraphvizPlanObject
164
+ def to_dot_events(display, io)
165
+ return unless display.displayed?(self)
166
+ io << "subgraph cluster_#{dot_id} {\n"
167
+ graphics = display.graphics[self]
168
+ text_bb = graphics.text.bounding_rect
169
+ has_event = false
170
+ each_event do |ev|
171
+ if display.displayed?(ev)
172
+ ev.to_dot(display, io)
173
+ has_event = true
174
+ end
175
+ end
176
+ task_height = if !has_event then DEFAULT_TASK_HEIGHT + text_bb.height
177
+ else text_bb.height
178
+ end
179
+
180
+ io << " #{dot_id}[width=#{[DEFAULT_TASK_WIDTH, text_bb.width].max},height=#{task_height},fixedsize=true];\n"
181
+ io << "}\n"
182
+ end
183
+
184
+ def dot_label(display)
185
+ event_names = each_event.find_all { |ev| display.displayed?(ev) }.
186
+ map { |ev| ev.dot_label(display) }.
187
+ join(" ")
188
+
189
+ own = super
190
+ if own.size > event_names.size then own
191
+ else event_names
192
+ end
193
+ end
194
+
195
+ def apply_layout(bounding_rects, positions, display)
196
+ if !(task = positions[dot_id])
197
+ puts "No layout for #{self}"
198
+ return
199
+ end
200
+ each_event do |ev|
201
+ next if !display.displayed?(ev)
202
+ positions[ev.dot_id] += task
203
+ end
204
+ # Apply the layout on the events
205
+ each_event do |ev|
206
+ ev.apply_layout(bounding_rects, positions, display)
207
+ end
208
+ # And recalculate the bounding box
209
+ bounding_rect = Qt::RectF.new
210
+ each_event.map do |ev|
211
+ next if !display.displayed?(ev)
212
+ graphics = display[ev]
213
+ bounding_rect |= graphics.map_rect_to_scene(graphics.bounding_rect)
214
+ bounding_rect |= graphics.text.map_rect_to_scene(graphics.text.bounding_rect)
215
+ end
216
+ if !graphics_item = display[self]
217
+ raise "no graphics for #{self}" unless graphics_item = display[self]
218
+ end
219
+ if bounding_rect.null? # no events, we need to take the bounding box from the fake task node
220
+ bounding_rect = Qt::RectF.new(
221
+ task.x - DEFAULT_TASK_WIDTH / 2,
222
+ task.y - DEFAULT_TASK_HEIGHT / 2, DEFAULT_TASK_WIDTH, DEFAULT_TASK_HEIGHT)
223
+ else
224
+ bounding_rect.y -= 5
225
+ end
226
+ graphics_item.rect = bounding_rect
227
+
228
+ text_pos = Qt::PointF.new(
229
+ bounding_rect.x + bounding_rect.width / 2 - graphics_item.text.bounding_rect.width / 2,
230
+ bounding_rect.y + bounding_rect.height)
231
+ graphics_item.text.pos = text_pos
232
+ end
233
+ end
234
+
235
+ Roby::Plan.include GraphvizPlan
236
+ Roby::PlanObject.include GraphvizPlanObject
237
+ Roby::TaskEventGenerator.include GraphvizTaskEventGenerator
238
+ Roby::Task.include GraphvizTask
239
+ Roby::Transaction::TaskProxy.include GraphvizTask
240
+
241
+ # This class uses Graphviz (i.e. the "dot" tool) to compute a layout for
242
+ # a given plan
243
+ class PlanDotLayout
244
+ # The set of IDs for the objects in the plan
245
+ attribute(:object_ids) { Hash.new }
246
+
247
+ attr_reader :dot_input
248
+
249
+ # Add a string to the resulting Dot input file
250
+ def <<(string); dot_input << string end
251
+
252
+ FLOAT_VALUE = "\\d+(?:\\.\\d+)?(?:e[+-]\\d+)?"
253
+ DOT_TO_QT_SCALE_FACTOR_X = 1.0 / 55
254
+ DOT_TO_QT_SCALE_FACTOR_Y = 1.0 / 55
255
+
256
+ def self.parse_dot_layout(dot_layout, options = Hash.new)
257
+ options = Kernel.validate_options options,
258
+ scale_x: DOT_TO_QT_SCALE_FACTOR_X,
259
+ scale_y: DOT_TO_QT_SCALE_FACTOR_Y
260
+ scale_x = options[:scale_x]
261
+ scale_y = options[:scale_y]
262
+
263
+ current_graph_id = nil
264
+ bounding_rects = Hash.new
265
+ object_pos = Hash.new
266
+ full_line = ""
267
+ dot_layout.each do |line|
268
+ line.chomp!
269
+ full_line << line.strip
270
+ if line[-1] == ?\\ or line[-1] == ?,
271
+ full_line.chomp!
272
+ next
273
+ end
274
+
275
+ case full_line
276
+ when /(\w+).*\[.*pos="(#{FLOAT_VALUE}),(#{FLOAT_VALUE})"/
277
+ object_pos[$1] = Qt::PointF.new(Float($2) * scale_x, Float($3) * scale_y)
278
+ when /subgraph cluster_(\w+)/
279
+ current_graph_id = $1
280
+ when /bb="(#{FLOAT_VALUE}),(#{FLOAT_VALUE}),(#{FLOAT_VALUE}),(#{FLOAT_VALUE})"/
281
+ bb = [$1, $2, $3, $4].map { |c| Float(c) }
282
+ bb[0] *= scale_x
283
+ bb[2] *= scale_x
284
+ bb[1] *= scale_x
285
+ bb[3] *= scale_x
286
+ bounding_rects[current_graph_id] = Qt::RectF.new(bb[0], bb[1], bb[2] - bb[0], bb[3] - bb[1])
287
+ end
288
+ full_line = ""
289
+ end
290
+
291
+ graph_bb = bounding_rects.delete(nil)
292
+ if !graph_bb
293
+ raise "Graphviz failed to generate a layout for this plan"
294
+ end
295
+ bounding_rects.each_value do |bb|
296
+ bb.x -= graph_bb.x
297
+ bb.y = graph_bb.y - bb.y - bb.height
298
+ end
299
+ object_pos.each do |id, pos|
300
+ pos.x -= graph_bb.x
301
+ pos.y = graph_bb.y - pos.y
302
+ end
303
+
304
+ return bounding_rects, object_pos
305
+ end
306
+
307
+ def run_dot(options = Hash.new)
308
+ options, parsing_options = Kernel.filter_options options,
309
+ graph_type: 'digraph', layout_method: display.layout_method
310
+
311
+ @@index ||= 0
312
+ @@index += 1
313
+
314
+ # Dot input file
315
+ @dot_input = Tempfile.new("roby_dot")
316
+ # Dot output file
317
+ dot_output = Tempfile.new("roby_layout")
318
+
319
+ dot_input << "#{options[:graph_type]} relations {\n"
320
+ yield(dot_input)
321
+ dot_input << "}\n"
322
+
323
+ dot_input.flush
324
+
325
+ # Make sure the GUI keeps being updated while dot is processing
326
+ FileUtils.cp dot_input.path, "/tmp/dot-input-#{@@index}.dot"
327
+ system("#{options[:layout_method]} #{dot_input.path} > #{dot_output.path}")
328
+ FileUtils.cp dot_output.path, "/tmp/dot-output-#{@@index}.dot"
329
+
330
+ # Load only task bounding boxes from dot, update arrows later
331
+ lines = File.open(dot_output.path) { |io| io.readlines }
332
+ PlanDotLayout.parse_dot_layout(lines, parsing_options)
333
+ end
334
+
335
+ # Generates a layout internal for each task, allowing to place the
336
+ # events according to the propagations
337
+ def layout(display, plan, options = Hash.new)
338
+ @display = display
339
+ options = Kernel.validate_options options,
340
+ scale_x: DOT_TO_QT_SCALE_FACTOR_X, scale_y: DOT_TO_QT_SCALE_FACTOR_Y
341
+
342
+ # We first layout only the tasks separately. This allows to find
343
+ # how to layout the events within the task, and know the overall
344
+ # task sizes
345
+ all_tasks = Set.new
346
+ bounding_boxes, positions = run_dot(graph_type: 'graph', layout_method: 'fdp', scale_x: 1.0 / 100, scale_y: 1.0 / 100) do
347
+ display.plans.each do |p|
348
+ p_tasks = p.tasks | p.finalized_tasks
349
+ p_tasks.each do |task|
350
+ task.to_dot_events(display, self)
351
+ end
352
+ all_tasks.merge(p_tasks)
353
+ p.propagated_events.each do |_, sources, to, _|
354
+ sources.each do |from|
355
+ if from.respond_to?(:task) && to.respond_to?(:task) && from.task == to.task
356
+ from_id, to_id = from.dot_id, to.dot_id
357
+ if from_id && to_id
358
+ self << " #{from.dot_id} -- #{to.dot_id}\n"
359
+ end
360
+ end
361
+ end
362
+ end
363
+ end
364
+ end
365
+
366
+ # Ignore graphviz-generated BBs, recompute from the event
367
+ # positions and then make their positions relative
368
+ event_positions = Hash.new
369
+ all_tasks.each do |t|
370
+ next if !display.displayed?(t)
371
+ bb = Qt::RectF.new
372
+ if p = positions[t.dot_id]
373
+ bb |= Qt::RectF.new(p, p)
374
+ end
375
+ t.each_event do |ev|
376
+ next if !display.displayed?(ev)
377
+ p = positions[ev.dot_id]
378
+ bb |= Qt::RectF.new(p, p)
379
+ end
380
+ t.each_event do |ev|
381
+ next if !display.displayed?(ev)
382
+ event_positions[ev.dot_id] = positions[ev.dot_id] - bb.topLeft
383
+ end
384
+ graphics = display.graphics[t]
385
+ graphics.rect = Qt::RectF.new(0, 0, bb.width, bb.height)
386
+ end
387
+
388
+ @bounding_rects, @object_pos = run_dot(scale_x: 1.0 / 50, scale_y: 1.0 / 15) do
389
+ # Finally, generate the whole plan
390
+ plan.to_dot(display, self, 0)
391
+
392
+ # Take the signalling into account for the layout. At this stage,
393
+ # task events are represented by their tasks
394
+ display.plans.each do |p|
395
+ p.propagated_events.each do |_, sources, to, _|
396
+ to_id =
397
+ if to.respond_to?(:task) then to.task.dot_id
398
+ else to.dot_id
399
+ end
400
+
401
+ sources.each do |from|
402
+ from_id =
403
+ if from.respond_to?(:task)
404
+ from.task.dot_id
405
+ else
406
+ from.dot_id
407
+ end
408
+
409
+ if from_id && to_id
410
+ self << " #{from.dot_id} -> #{to.dot_id}\n"
411
+ end
412
+ end
413
+ end
414
+ end
415
+ end
416
+ object_pos.merge!(event_positions)
417
+
418
+ @plan = plan
419
+ end
420
+
421
+ attr_reader :bounding_rects, :object_pos, :display, :plan
422
+ def apply
423
+ plan.apply_layout(bounding_rects, object_pos, display)
424
+ end
425
+ end
426
+ end
427
+ end