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,69 @@
1
+ module Roby
2
+ module Coordination
3
+ class ResolvingUnboundObject < RuntimeError; end
4
+
5
+ # Base functionality for task-like objects in coordination models
6
+ # (Task, Child)
7
+ class TaskBase
8
+ # @return [Base] the underlying execution context
9
+ attr_reader :execution_context
10
+ # @return [Coordination::Models::Task]
11
+ attr_reader :model
12
+
13
+ def initialize(execution_context, model)
14
+ @execution_context = execution_context
15
+ @model = model
16
+ end
17
+
18
+ # Method that must be reimplemented in the task objects actually
19
+ # used in the coordination primitives
20
+ def resolve
21
+ raise NotImplementedError, "#resolve must be reimplemented in objects meant to be used in the coordination primitives"
22
+ end
23
+
24
+ def find_child(role, child_model = nil)
25
+ child_model ||= model.find_child_model(role)
26
+ if !child_model
27
+ begin
28
+ task = self.resolve
29
+ if child_task = task.find_child_from_role(role)
30
+ child_model = child_task.model
31
+ end
32
+ rescue ResolvingUnboundObject
33
+ end
34
+ end
35
+
36
+ if child = model.find_child(role, child_model)
37
+ execution_context.instance_for(child)
38
+ end
39
+ end
40
+
41
+ def find_event(symbol)
42
+ if event = model.find_event(symbol)
43
+ execution_context.instance_for(event)
44
+ end
45
+ end
46
+
47
+ def find_through_method_missing(m, args)
48
+ MetaRuby::DSLs.find_through_method_missing(
49
+ self, m, args,
50
+ '_child' => :find_child,
51
+ '_port' => :find_port,
52
+ '_event' => :find_event) || super
53
+ end
54
+ def has_through_method_missing?(m)
55
+ MetaRuby::DSLs.has_through_method_missing?(
56
+ self, m,
57
+ '_child' => :has_child?,
58
+ '_port' => :has_port?,
59
+ '_event' => :has_event?) || super
60
+ end
61
+
62
+ include MetaRuby::DSLs::FindThroughMethodMissing
63
+
64
+ def to_coordination_task(task_model); model.to_coordination_task(task_model) end
65
+ end
66
+ end
67
+ end
68
+
69
+
@@ -0,0 +1,293 @@
1
+ module Roby
2
+ module Coordination
3
+ extend Logger::Forward
4
+ extend Logger::Hierarchy
5
+
6
+ # Implementation of a task script
7
+ #
8
+ # The model-level accessors and API is described in {Models::Script}
9
+ class TaskScript < Base
10
+ extend Models::Script
11
+ include Script
12
+
13
+ attr_reader :definition_block
14
+
15
+ # @deprecated
16
+ #
17
+ # Use #root_task instead
18
+ def task
19
+ root_task
20
+ end
21
+
22
+ def parse(&block)
23
+ @definition_block = block
24
+ instance_eval(&block)
25
+ end
26
+
27
+ def bind(task)
28
+ result_model = self.class.superclass.new_submodel(root: model.root.model)
29
+ result = result_model.new(task)
30
+ result.parse(&definition_block)
31
+ result.prepare
32
+ result
33
+ end
34
+
35
+ def resolve_instructions
36
+ super
37
+ model.each_task do |model_task|
38
+ script_task = instance_for(model_task)
39
+ if script_task.respond_to?(:task) && !script_task.task # Not bound ? Check if the model can be instanciated
40
+ task = model_task.instanciate(root_task.plan)
41
+ bind_coordination_task_to_instance(script_task, task, on_replace: :copy)
42
+
43
+ # Protect from scheduling until the start is executed
44
+ #
45
+ # #start_task will be called by the Start instruction
46
+ root_task.start_event.add_causal_link(task.start_event)
47
+ end
48
+ end
49
+ # Now, make the dependencies based on what we do / wait for with
50
+ # the tasks. Namely, we look at Start (dependency options) and
51
+ # Wait (success events)
52
+ instructions.each do |ins|
53
+ case ins
54
+ when Coordination::Models::Script::Start
55
+ task = ins.task.resolve
56
+ root_task.depends_on task, ins.dependency_options
57
+ end
58
+ end
59
+ end
60
+
61
+ # Resolve the given event object into a Coordination::Task and a
62
+ # Coordination::Models::Task
63
+ def resolve_task(task)
64
+ if root_task && task.kind_of?(Roby::Task)
65
+ root_task.plan.add(task)
66
+ model_task = Coordination::Models::Task.new(task.model)
67
+ script_task = instance_for(model_task)
68
+ bind_coordination_task_to_instance(script_task, task, on_replace: :copy)
69
+ else
70
+ model_task = self.model.task(task)
71
+ script_task = instance_for(model_task)
72
+ end
73
+
74
+ return script_task, model_task
75
+ end
76
+
77
+ # Resolve the given event object into a Coordination::Event and a
78
+ # Coordination::Models::Event
79
+ def resolve_event(event)
80
+ if event.respond_to?(:to_sym)
81
+ symbol = event
82
+ if root_task
83
+ event = root_task.find_event(symbol)
84
+ else
85
+ event = model.root.find_event(symbol)
86
+ end
87
+ if !event
88
+ raise ArgumentError, "#{model.root} has no event called #{symbol}"
89
+ end
90
+ end
91
+ script_task, model_task = resolve_task(event.task)
92
+ model_event = model_task.find_event(event.symbol)
93
+ script_event = instance_for(model_event)
94
+ return script_event, model_event
95
+ end
96
+
97
+ # Start the given task at that point in the script, and wait for it
98
+ # to emit its start event
99
+ #
100
+ # @param [Task] task the task that should be started
101
+ # @param [Hash] dependency_options options that should be passed to
102
+ # TaskStructure::Dependency::Extension#depends_on
103
+ def start(task, explicit_start: false, **dependency_options)
104
+ task, model_task = resolve_task(task)
105
+ model.start(model_task, explicit_start: explicit_start, **dependency_options)
106
+ task
107
+ end
108
+
109
+ # @overload execute(task)
110
+ # Deploy and start the given task, and wait for it to finish
111
+ # successfully
112
+ #
113
+ # @overload execute { ... }
114
+ # Execute the content of the given block once
115
+ def execute(task = nil, &block)
116
+ if task
117
+ task, model_task = resolve_task(task)
118
+ model.execute(model_task)
119
+ task
120
+ else
121
+ model.instructions << BlockExecute.new(block)
122
+ nil
123
+ end
124
+ end
125
+
126
+ # Wait for an event to be emitted
127
+ #
128
+ # @param [Hash] options
129
+ # @option options [Time,nil] after (nil) if set, only event
130
+ # emissions that happened after this value will make the script
131
+ # pass this instruction. The default of nil means "from the point
132
+ # of this instruction on"
133
+ #
134
+ # @example wait first_child.start_event
135
+ # Waits until start event has been emitted. Will wait forever if
136
+ # the start event has already been emitted
137
+ # @example wait first_child.start_event, after: Time.at(0)
138
+ # Waits for start event to be emitted. Will return immediately if
139
+ # it has already been emitted.
140
+ def wait(event, options = Hash.new)
141
+ event, model_event = resolve_event(event)
142
+ model.wait(model_event, options)
143
+ event
144
+ end
145
+
146
+ # @deprecated
147
+ #
148
+ # Use wait(event after: Time.at(0)) instead
149
+ def wait_any(event, options = Hash.new)
150
+ wait(event, options.merge(after: Time.at(0)))
151
+ end
152
+
153
+ # Sleep for a given number of seconds
154
+ #
155
+ # @param [Float] seconds the number of seconds to stop the script
156
+ # execution
157
+ def sleep(seconds)
158
+ task = start(Tasks::Timeout.new(delay: seconds), explicit_start: true)
159
+ wait task.stop_event
160
+ end
161
+
162
+ # Emit the given event
163
+ def emit(event)
164
+ event, model_event = resolve_event(event)
165
+ model.emit(model_event)
166
+ event
167
+ end
168
+
169
+ # Executes the provided block once per execution cycle
170
+ #
171
+ # Call {#transition!} to quit the block
172
+ def poll(&block)
173
+ poll_until(poll_transition_event, &block)
174
+ end
175
+
176
+ # Execute the provided block once per execution cycle, until the
177
+ # given event is emitted
178
+ def poll_until(event, &block)
179
+ event, model_event = resolve_event(event)
180
+ model.instructions << Script::Models::PollUntil.new(model_event, block)
181
+ event
182
+ end
183
+
184
+ # Quit a {#poll} block
185
+ def transition!
186
+ root_task.poll_transition_event.emit
187
+ end
188
+
189
+ # Execute the script instructions given as block. If they take more
190
+ # than the specified number of seconds, either generate an error or
191
+ # emit an event (and quit the block)
192
+ #
193
+ # @param [Hash] options
194
+ # @option options [Event] :event (nil) if set, the given event will
195
+ # be emitted when the timeout is reached. Otherwise, a
196
+ # Script::TimedOut exception is generated with the script's
197
+ # supporting task as origin
198
+ def timeout(seconds, options = Hash.new, &block)
199
+ timeout = timeout_start(seconds, options)
200
+ parse(&block)
201
+ timeout_stop(timeout)
202
+ end
203
+
204
+ # Start a timeout operation. Usually not used directly
205
+ #
206
+ # @see timeout
207
+ def timeout_start(seconds, options = Hash.new)
208
+ options, timeout_options = Kernel.filter_options options, emit: nil
209
+ if event = options[:emit]
210
+ script_event, model_event = resolve_event(event)
211
+ end
212
+ model.timeout_start(seconds, timeout_options.merge(emit: model_event))
213
+ end
214
+
215
+ # Stop a timeout operation. Usually not used directly
216
+ #
217
+ # @see timeout
218
+ def timeout_stop(timeout)
219
+ model.timeout_stop(timeout)
220
+ end
221
+
222
+ # Used by Script
223
+ def start_task(task, explicit_start: false)
224
+ root_task.start_event.remove_causal_link(task.resolve.start_event)
225
+ if explicit_start
226
+ task.resolve.start_event.call
227
+ end
228
+ end
229
+
230
+ def respond_to_missing?(m, include_private)
231
+ if m =~ /_(?:event|child)$/
232
+ instance_for(model.root).respond_to?(m)
233
+ else super
234
+ end
235
+ end
236
+
237
+ def method_missing(m, *args, &block)
238
+ if m =~ /_(?:event|child)$/
239
+ instance_for(model.root).send(m, *args, &block)
240
+ else super
241
+ end
242
+ end
243
+ end
244
+ end
245
+
246
+ class Task
247
+ Models::Task.inherited_attribute(:script, :scripts) { Array.new }
248
+
249
+ event :poll_transition
250
+
251
+ def self.create_script(*task, &block)
252
+ script_model = Coordination::TaskScript.new_submodel(root: self)
253
+ script = script_model.new(*task)
254
+ if block_given?
255
+ script.parse(&block)
256
+ end
257
+ script
258
+ end
259
+
260
+ # Adds a script that is going to be executed for every instance of this
261
+ # task model
262
+ def self.script(&block)
263
+ s = create_script(&block)
264
+ scripts << s
265
+ s
266
+ end
267
+
268
+ on :start do |event|
269
+ model.each_script do |s|
270
+ s = s.bind(self)
271
+ s.step
272
+ end
273
+ end
274
+
275
+ # Adds a task script that is going to be executed while this task
276
+ # instance runs.
277
+ def script(options = Hash.new, &block)
278
+ execute do |task|
279
+ script = model.create_script(task, &block)
280
+ script.prepare
281
+ script.step
282
+ end
283
+ model.create_script(self, &block)
284
+ end
285
+
286
+ def transition!
287
+ poll_transition_event.emit
288
+ end
289
+ end
290
+ end
291
+
292
+
293
+
@@ -0,0 +1,308 @@
1
+ require 'state_machine/machine'
2
+
3
+ module Roby
4
+ # Helper to get a more roby-like feeling to the state machine definitions
5
+ class StateMachineDefinitionContext
6
+ attr_reader :task_model
7
+ attr_reader :state_machine
8
+
9
+ def initialize(task_model, state_machine)
10
+ @task_model = task_model
11
+ @state_machine = state_machine
12
+ end
13
+
14
+ def script_in_state(state, &block)
15
+ script_engine = task_model.create_script(&block)
16
+
17
+ state_machine.before_transition state_machine.any => state, do: lambda { |proxy|
18
+ proxy.instance_variable_set :@script_engine, nil
19
+ }
20
+ state_machine.state(state) do
21
+ define_method(:poll) do |task|
22
+ if !@script_engine
23
+ @script_engine = script_engine.bind(task)
24
+ @script_engine.prepare
25
+ @script_engine.step
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ def poll_in_state(state, &block)
32
+ state_machine.state(state) do
33
+ define_method(:poll, &block)
34
+ end
35
+ end
36
+
37
+ def on(event, &block)
38
+ state_machine.event(event, &block)
39
+ end
40
+
41
+ def respond_to_missing?(m, include_private)
42
+ state_machine.respond_to?(m)
43
+ end
44
+
45
+ def method_missing(m, *args, &block)
46
+ state_machine.public_send(m, *args, &block)
47
+ end
48
+ end
49
+
50
+ # The state machine that can be associate with a task
51
+ #
52
+ class TaskStateMachine
53
+ # The proxy object class the state machine is working on
54
+ attr_accessor :proxy
55
+
56
+ # Underlying state machine
57
+ attr_accessor :machine
58
+
59
+ # Existing transitions
60
+ # Transition comes with methods: event, from_name, to_name
61
+ attr_reader :transitions
62
+
63
+ # All state of the state machine
64
+ attr_reader :states
65
+
66
+ def initialize(machine)
67
+ # Required to initialize underlying state_machine
68
+ super()
69
+
70
+ @proxy = machine.owner_class.new
71
+ @machine = machine
72
+
73
+ update
74
+ end
75
+
76
+ def update
77
+ @states = []
78
+
79
+ # introspect to retrieve all transactions of the statemachine
80
+ @transitions = []
81
+ collection = @machine.states
82
+ collection.each do |s_o|
83
+ collection.each do |s_i|
84
+ # status_transitions is added to TaskStateMachine using meta programming
85
+ transitions = proxy.status_transitions(from: s_o.name.to_sym, to: s_i.name.to_sym)
86
+ @transitions << transitions
87
+ end
88
+ @transitions.flatten!
89
+ end
90
+
91
+ # Infer all available states from existing transitions
92
+ @transitions.each do |t|
93
+ @states << t.from_name unless @states.index(t.from_name)
94
+ @states << t.to_name unless @states.index(t.to_name)
95
+ end
96
+ end
97
+
98
+ def initialize_copy(other)
99
+ other.name = name
100
+ other.proxy = name.new
101
+ other.machine = machine.dup
102
+ other.update
103
+ end
104
+
105
+ def respond_to_missing?(m, include_private)
106
+ proxy.respond_to?(m) || super
107
+ end
108
+
109
+ def method_missing(m, *args, &block)
110
+ # If proxy provides missing method, then use the proxy
111
+ if proxy.respond_to?(m)
112
+ proxy.public_send(m, *args, &block)
113
+ else
114
+ # otherwise pass it on
115
+ super
116
+ end
117
+ end
118
+
119
+ # Define general poll handler
120
+ def do_poll(task)
121
+ begin
122
+ proxy.poll(task)
123
+ rescue NoMethodError => e
124
+ # poll only if the state has a poll handler defined
125
+ end
126
+ end
127
+
128
+ # Identifies the current state given a list of subsequent events
129
+ # Provides a list with the most recent event being last in the list
130
+ #
131
+ def identify_state(event_list)
132
+ # initalize with all transitions possible
133
+ paths = {}
134
+ @transitions.each do |transition|
135
+ paths[transition] = []
136
+ end
137
+
138
+ paths = []
139
+ new_paths = []
140
+ initialized = false
141
+
142
+ while event_list.size > 0
143
+ current_event = event_list.first
144
+ # expand path
145
+ @transitions.each do |transition|
146
+ # Get transitions that match event
147
+ if current_event == transition.event()
148
+ # expand first set of transactions
149
+ if not initialized
150
+ new_paths << [ transition ]
151
+ else
152
+ # find transitions that lead to the last transition
153
+ paths.each do |path|
154
+ if path.last.from_name == transition.to_name
155
+ path << transition
156
+ new_paths << path
157
+ end
158
+ end
159
+ end
160
+ end
161
+ end
162
+ paths = new_paths
163
+ new_paths = []
164
+ initialized = true
165
+ event_list.delete_at(0)
166
+ end
167
+
168
+ if paths.size == 1
169
+ # Retrieve last (by time) transitions target state
170
+ return paths[0].last.to_name
171
+ elsif paths.size > 0
172
+ throw "Event list is ambigious, requiring more events"
173
+ end
174
+
175
+ throw "Event list is invalid"
176
+ end
177
+ end # module TaskStateHelper
178
+
179
+ # The TaskStateHelper allows to add a statemachine to
180
+ # a Roby::Task and allows the tracking of events within
181
+ # the 'running' state
182
+ module TaskStateHelper
183
+ # The default namespace that is added to statemachine methods, e.g.
184
+ # when action for transitions are defined
185
+ def namespace
186
+ @namespace ||= nil
187
+ end
188
+
189
+ def namespace=(name)
190
+ @namespace=name
191
+ end
192
+
193
+ # Proxy object used in the definition of state machines on Roby::Task
194
+ class Proxy
195
+ def self.state_machine(*args, &block)
196
+ StateMachine::Machine.find_or_create(self, *args, &block)
197
+ end
198
+ end
199
+
200
+ # The state machine model that is running on all tasks of this task
201
+ # model
202
+ def state_machine
203
+ if @state_machine then @state_machine
204
+ elsif superclass.respond_to?(:state_machine)
205
+ superclass.state_machine
206
+ end
207
+ end
208
+
209
+ # Refine the running state of the Roby::Task
210
+ # using a state machine description. The initial
211
+ # state of the machine is set to 'running' by default.
212
+ #
213
+ # Example:
214
+ # refine_running_state do
215
+ # on :pause do
216
+ # transition [:running] => paused
217
+ # end
218
+ #
219
+ # on :resume do
220
+ # transition [:paused] => :running
221
+ # end
222
+ #
223
+ # state :paused do
224
+ # def poll(task)
225
+ # sleep 4
226
+ # task.emit :resume
227
+ # end
228
+ # end
229
+ # end
230
+ #
231
+ # Events are translated into roby events
232
+ # and the statemachine in hooked into the
233
+ # on(:yourevent) {|context| ... }
234
+ # You can add additional event handlers as ususal
235
+ # using on(:yourevent) .. syntax
236
+ #
237
+ # The current status (substate of the running state)
238
+ # can be retrieved via
239
+ # yourtask.state_machine.status
240
+ #
241
+ def refine_running_state (*args, &block)
242
+ if args.last.kind_of?(Hash)
243
+ options = args.pop
244
+ end
245
+ options = Kernel.validate_options(options || Hash.new, namespace: nil)
246
+
247
+ if options.has_key?(:namespace)
248
+ self.namespace=options[:namespace]
249
+ end
250
+
251
+ # Check if a model of a class ancestor already exists
252
+ # If a parent_model exists, prepare the proxy class accordingly
253
+ # The proxy allows us to use the state_machine library even
254
+ # with instances
255
+ if parent_model = self.superclass.state_machine
256
+ proxy_model = Class.new(parent_model.owner_class)
257
+ else
258
+ proxy_model = Class.new(Proxy)
259
+ end
260
+
261
+ # Create the state machine instance that will serve as base model
262
+ # for instances of the Roby::Task (or its subclasses) this machine
263
+ # is associated with The namespace allows to pre/postfix
264
+ # automatically generated functions, such as for sending events:
265
+ # <task>.state_machine.pause_<namespace>! or querying the status
266
+ # <task>.state_machine.<namespace>_paused? Note cannot use :state
267
+ # instead of :status here for yet unknown reason Changing the
268
+ # attribute :status also changes other method definitions, due to
269
+ # meta programming approach of the underlying library, e.g.
270
+ # status_transitions(from: ..., to: ...)
271
+
272
+ if self.namespace
273
+ machine = StateMachine::Machine.find_or_create(proxy_model, :status, initial: :running, namespace: self.namespace)
274
+ else
275
+ machine = StateMachine::Machine.find_or_create(proxy_model, :status, initial: :running)
276
+ end
277
+
278
+ machine_loader = StateMachineDefinitionContext.new(self, machine)
279
+ machine_loader.instance_eval(&block)
280
+ @state_machine = machine
281
+
282
+ import_events_to_roby(machine)
283
+ end
284
+
285
+ def import_events_to_roby(machine)
286
+ # Roby requires the self to be the subclassed Roby::Task
287
+ # Thus embed import into refine_running_state and using eval here
288
+ machine.events.each do |e|
289
+ if !has_event?(e.name)
290
+ event e.name, controlable: true
291
+ end
292
+ # when event is called transition the state_machine
293
+ on(e.name) do |event|
294
+ state_machine.send("#{e.name.to_sym}!")
295
+ end
296
+ end
297
+ end
298
+ end
299
+
300
+ class Task
301
+ extend TaskStateHelper
302
+ attr_reader :state_machine
303
+
304
+ # Setup is done in #initialize
305
+ # Polling is done in Task.do_poll
306
+ end
307
+ end # module Roby
308
+