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.
- checksums.yaml +7 -0
- data/.deep-cover.rb +3 -0
- data/.gitattributes +1 -0
- data/.gitignore +24 -0
- data/.simplecov +10 -0
- data/.travis.yml +17 -0
- data/.yardopts +4 -0
- data/Gemfile +15 -0
- data/README.md +11 -0
- data/Rakefile +47 -177
- data/benchmark/{alloc_misc.rb → attic/alloc_misc.rb} +2 -2
- data/benchmark/{discovery_latency.rb → attic/discovery_latency.rb} +19 -19
- data/benchmark/{garbage_collection.rb → attic/garbage_collection.rb} +9 -9
- data/benchmark/{genom.rb → attic/genom.rb} +0 -0
- data/benchmark/attic/transactions.rb +62 -0
- data/benchmark/plan_basic_operations.rb +28 -0
- data/benchmark/relations/graph.rb +63 -0
- data/benchmark/ruby/identity.rb +18 -0
- data/benchmark/ruby/set_intersect_vs_hash_merge.rb +39 -0
- data/benchmark/ruby/yield_vs_block.rb +35 -0
- data/benchmark/run +5 -0
- data/benchmark/synthetic_plan_modifications_with_transactions.rb +79 -0
- data/benchmark/transactions.rb +99 -51
- data/bin/roby +38 -197
- data/bin/roby-display +14 -0
- data/bin/roby-log +3 -176
- data/doc/guide/{src → attic}/abstraction/achieve_with.page +1 -1
- data/doc/guide/{src → attic}/abstraction/forwarding.page +1 -1
- data/doc/guide/{src → attic}/abstraction/hierarchy.page +1 -1
- data/doc/guide/{src → attic}/abstraction/index.page +1 -1
- data/doc/guide/{src → attic}/abstraction/task_models.page +1 -1
- data/doc/guide/{overview.rdoc → attic/cycle/api_overview.rdoc} +6 -1
- data/doc/guide/{src → attic}/cycle/cycle-overview.png +0 -0
- data/doc/guide/{src → attic}/cycle/cycle-overview.svg +0 -0
- data/doc/guide/attic/cycle/error_handling.page +98 -0
- data/doc/guide/{src → attic}/cycle/error_instantaneous_repair.png +0 -0
- data/doc/guide/{src → attic}/cycle/error_instantaneous_repair.svg +0 -0
- data/doc/guide/{src/cycle/error_handling.page → attic/cycle/error_sources.page} +46 -89
- data/doc/guide/{src → attic}/cycle/garbage_collection.page +1 -1
- data/doc/guide/{src → attic}/cycle/index.page +1 -1
- data/doc/guide/{src → attic}/cycle/propagation.page +11 -1
- data/doc/guide/{src → attic}/cycle/propagation_diamond.png +0 -0
- data/doc/guide/{src → attic}/cycle/propagation_diamond.svg +0 -0
- data/doc/guide/attic/plans/building_plans.page +89 -0
- data/doc/guide/attic/plans/code.page +192 -0
- data/doc/guide/{src/basics → attic/plans}/events.page +3 -4
- data/doc/guide/attic/plans/index.page +7 -0
- data/doc/guide/{plan_modifications.rdoc → attic/plans/plan_modifications.rdoc} +5 -3
- data/doc/guide/{src/basics → attic/plans}/plan_objects.page +2 -1
- data/doc/guide/attic/plans/querying_plans.page +5 -0
- data/doc/guide/{src/basics → attic/plans}/tasks.page +20 -20
- data/doc/guide/config.yaml +7 -4
- data/doc/guide/ext/extended_menu.rb +29 -0
- data/doc/guide/ext/init.rb +6 -0
- data/doc/guide/ext/rdoc_links.rb +7 -6
- data/doc/guide/src/advanced_concepts/history.page +5 -0
- data/doc/guide/src/advanced_concepts/index.page +11 -0
- data/doc/guide/src/advanced_concepts/recognizing_patterns.page +83 -0
- data/doc/guide/src/advanced_concepts/scheduling.page +87 -0
- data/doc/guide/src/advanced_concepts/transactions.page +5 -0
- data/doc/guide/src/advanced_concepts/unreachability.page +42 -0
- data/doc/guide/src/base.template +96 -0
- data/doc/guide/src/basics_shell_header.txt +5 -7
- data/doc/guide/src/building/action_coordination.page +96 -0
- data/doc/guide/src/building/actions.page +124 -0
- data/doc/guide/src/building/file_layout.page +71 -0
- data/doc/guide/src/building/index.page +50 -0
- data/doc/guide/src/building/patterns.page +86 -0
- data/doc/guide/src/building/patterns_forwarding.png +0 -0
- data/doc/guide/src/building/patterns_forwarding.svg +277 -0
- data/doc/guide/src/building/runtime.page +95 -0
- data/doc/guide/src/building/task_models.page +94 -0
- data/doc/guide/src/building/tasks.page +284 -0
- data/doc/guide/src/concepts/error_handling.page +100 -0
- data/doc/guide/src/concepts/exception_propagation.png +0 -0
- data/doc/guide/src/concepts/exception_propagation.svg +445 -0
- data/doc/guide/src/concepts/execution.page +85 -0
- data/doc/guide/src/concepts/execution.png +0 -0
- data/doc/guide/src/concepts/execution.svg +573 -0
- data/doc/guide/src/concepts/execution_cycle.png +0 -0
- data/doc/guide/src/concepts/garbage_collection.page +57 -0
- data/doc/guide/src/concepts/index.page +27 -0
- data/doc/guide/src/concepts/plans.page +101 -0
- data/doc/guide/src/concepts/policy.page +31 -0
- data/doc/guide/src/concepts/reactor.page +61 -0
- data/doc/guide/src/concepts/simple_plan_example.png +0 -0
- data/doc/guide/src/concepts/simple_plan_example.svg +376 -0
- data/doc/guide/src/default.template +9 -74
- data/doc/guide/src/event_relations/forward.page +71 -0
- data/doc/guide/src/event_relations/index.page +12 -0
- data/doc/guide/src/event_relations/scheduling_constraints.page +43 -0
- data/doc/guide/src/event_relations/signal.page +55 -0
- data/doc/guide/src/event_relations/temporal_constraints.page +77 -0
- data/doc/guide/src/htmldoc.metainfo +21 -8
- data/doc/guide/src/index.page +8 -3
- data/doc/guide/src/{introduction/install.page → installation/index.page} +37 -25
- data/doc/guide/src/installation/publications.page +14 -0
- data/doc/guide/src/{introduction → installation}/videos.page +14 -7
- data/doc/guide/src/interacting/index.page +16 -0
- data/doc/guide/src/interacting/run.page +33 -0
- data/doc/guide/src/interacting/shell.page +95 -0
- data/doc/guide/src/plugins/creating_plugins.page +72 -0
- data/doc/guide/src/plugins/index.page +27 -5
- data/doc/guide/src/plugins/{fault_tolerance.page → standard_plugins/fault_tolerance.page} +2 -2
- data/doc/guide/src/plugins/standard_plugins/index.page +11 -0
- data/doc/guide/src/plugins/{subsystems.page → standard_plugins/subsystems.page} +2 -2
- data/doc/guide/src/style_screen.css +687 -0
- data/doc/guide/src/task_relations/dependency.page +107 -0
- data/doc/guide/src/task_relations/executed_by.page +77 -0
- data/doc/guide/src/task_relations/index.page +12 -0
- data/doc/guide/src/task_relations/new_relations.page +119 -0
- data/doc/guide/src/task_relations/planned_by.page +46 -0
- data/doc/guide/src/tutorial/app.page +117 -0
- data/doc/guide/src/{basics → tutorial}/code_examples.page +6 -5
- data/doc/guide/src/{basics → tutorial}/dry.page +15 -15
- data/doc/guide/src/{basics → tutorial}/errors.page +43 -68
- data/doc/guide/src/tutorial/events.page +195 -0
- data/doc/guide/src/{basics → tutorial}/hierarchy.page +53 -52
- data/doc/guide/src/tutorial/index.page +13 -0
- data/doc/guide/src/tutorial/log_replay/goForward_1.png +0 -0
- data/doc/guide/src/tutorial/log_replay/goForward_2.png +0 -0
- data/doc/guide/src/tutorial/log_replay/goForward_3.png +0 -0
- data/doc/guide/src/{basics → tutorial}/log_replay/goForward_4.png +0 -0
- data/doc/guide/src/tutorial/log_replay/goForward_5.png +0 -0
- data/doc/guide/src/{basics → tutorial}/log_replay/hierarchy_error_1.png +0 -0
- data/doc/guide/src/{basics → tutorial}/log_replay/hierarchy_error_2.png +0 -0
- data/doc/guide/src/{basics → tutorial}/log_replay/hierarchy_error_3.png +0 -0
- data/doc/guide/src/tutorial/log_replay/moveto_code_error.png +0 -0
- data/doc/guide/src/{basics → tutorial}/log_replay/plan_repair_1.png +0 -0
- data/doc/guide/src/{basics → tutorial}/log_replay/plan_repair_2.png +0 -0
- data/doc/guide/src/{basics → tutorial}/log_replay/plan_repair_3.png +0 -0
- data/doc/guide/src/tutorial/log_replay/plan_repair_4.png +0 -0
- data/doc/guide/src/tutorial/log_replay/roby_log_main_window.png +0 -0
- data/doc/guide/src/{basics → tutorial}/log_replay/roby_log_relation_window.png +0 -0
- data/doc/guide/src/{basics → tutorial}/log_replay/roby_replay_event_representation.png +0 -0
- data/doc/guide/src/tutorial/relations_display.page +153 -0
- data/doc/guide/src/{basics → tutorial}/roby_cycle_overview.png +0 -0
- data/doc/guide/src/tutorial/shell.page +121 -0
- data/doc/guide/src/{basics → tutorial}/summary.page +1 -1
- data/doc/guide/src/tutorial/tasks.page +374 -0
- data/lib/roby.rb +102 -47
- data/lib/roby/actions.rb +17 -0
- data/lib/roby/actions/action.rb +80 -0
- data/lib/roby/actions/interface.rb +45 -0
- data/lib/roby/actions/library.rb +23 -0
- data/lib/roby/actions/models/action.rb +224 -0
- data/lib/roby/actions/models/coordination_action.rb +58 -0
- data/lib/roby/actions/models/interface.rb +22 -0
- data/lib/roby/actions/models/interface_base.rb +294 -0
- data/lib/roby/actions/models/library.rb +12 -0
- data/lib/roby/actions/models/method_action.rb +90 -0
- data/lib/roby/actions/task.rb +114 -0
- data/lib/roby/and_generator.rb +125 -0
- data/lib/roby/app.rb +2795 -829
- data/lib/roby/app/autotest_console_reporter.rb +138 -0
- data/lib/roby/app/base.rb +21 -0
- data/lib/roby/app/cucumber.rb +2 -0
- data/lib/roby/app/cucumber/controller.rb +439 -0
- data/lib/roby/app/cucumber/helpers.rb +280 -0
- data/lib/roby/app/cucumber/world.rb +32 -0
- data/lib/roby/app/debug.rb +136 -0
- data/lib/roby/app/gen.rb +2 -0
- data/lib/roby/app/rake.rb +178 -38
- data/lib/roby/app/robot_config.rb +9 -0
- data/lib/roby/app/robot_names.rb +115 -0
- data/lib/roby/app/run.rb +3 -2
- data/lib/roby/app/scripts.rb +72 -0
- data/lib/roby/app/scripts/autotest.rb +173 -0
- data/lib/roby/app/scripts/display.rb +2 -0
- data/lib/roby/app/scripts/restart.rb +52 -0
- data/lib/roby/app/scripts/results.rb +17 -8
- data/lib/roby/app/scripts/run.rb +155 -24
- data/lib/roby/app/scripts/shell.rb +147 -62
- data/lib/roby/app/scripts/test.rb +107 -22
- data/lib/roby/app/test_reporter.rb +74 -0
- data/lib/roby/app/test_server.rb +159 -0
- data/lib/roby/app/vagrant.rb +47 -0
- data/lib/roby/backports.rb +16 -0
- data/lib/roby/cli/display.rb +190 -0
- data/lib/roby/cli/exceptions.rb +17 -0
- data/lib/roby/cli/gen/actions/class.rb +5 -0
- data/lib/roby/cli/gen/actions/test.rb +6 -0
- data/lib/roby/cli/gen/app/.yardopts +6 -0
- data/lib/roby/cli/gen/app/README.md +28 -0
- data/lib/roby/cli/gen/app/Rakefile +15 -0
- data/{app → lib/roby/cli/gen/app}/config/app.yml +29 -39
- data/lib/roby/cli/gen/app/models/.gitattributes +1 -0
- data/{app → lib/roby/cli/gen/app/scripts}/controllers/.gitattributes +0 -0
- data/{app/data/.gitattributes → lib/roby/cli/gen/app/test/.gitignore} +0 -0
- data/lib/roby/cli/gen/class/class.rb +6 -0
- data/lib/roby/cli/gen/class/test.rb +7 -0
- data/lib/roby/cli/gen/helpers.rb +203 -0
- data/lib/roby/cli/gen/module/module.rb +5 -0
- data/lib/roby/cli/gen/module/test.rb +6 -0
- data/lib/roby/cli/gen/roby_app/config/init.rb +17 -0
- data/lib/roby/cli/gen/roby_app/config/robots/robot.rb +40 -0
- data/lib/roby/cli/gen/task/class.rb +44 -0
- data/lib/roby/cli/gen/task/test.rb +6 -0
- data/lib/roby/cli/gen_main.rb +120 -0
- data/lib/roby/cli/log.rb +276 -0
- data/lib/roby/cli/log/flamegraph.html +499 -0
- data/lib/roby/cli/log/flamegraph_renderer.rb +88 -0
- data/lib/roby/cli/main.rb +153 -0
- data/lib/roby/coordination.rb +60 -0
- data/lib/roby/coordination/action_script.rb +25 -0
- data/lib/roby/coordination/action_state_machine.rb +125 -0
- data/lib/roby/coordination/actions.rb +106 -0
- data/lib/roby/coordination/base.rb +145 -0
- data/lib/roby/coordination/calculus.rb +40 -0
- data/lib/roby/coordination/child.rb +28 -0
- data/lib/roby/coordination/event.rb +29 -0
- data/lib/roby/coordination/fault_handler.rb +25 -0
- data/lib/roby/coordination/fault_handling_task.rb +13 -0
- data/lib/roby/coordination/fault_response_table.rb +110 -0
- data/lib/roby/coordination/models/action_script.rb +64 -0
- data/lib/roby/coordination/models/action_state_machine.rb +224 -0
- data/lib/roby/coordination/models/actions.rb +191 -0
- data/lib/roby/coordination/models/arguments.rb +55 -0
- data/lib/roby/coordination/models/base.rb +176 -0
- data/lib/roby/coordination/models/capture.rb +86 -0
- data/lib/roby/coordination/models/child.rb +35 -0
- data/lib/roby/coordination/models/event.rb +41 -0
- data/lib/roby/coordination/models/exceptions.rb +42 -0
- data/lib/roby/coordination/models/fault_handler.rb +219 -0
- data/lib/roby/coordination/models/fault_response_table.rb +77 -0
- data/lib/roby/coordination/models/root.rb +22 -0
- data/lib/roby/coordination/models/script.rb +283 -0
- data/lib/roby/coordination/models/task.rb +184 -0
- data/lib/roby/coordination/models/task_from_action.rb +50 -0
- data/lib/roby/coordination/models/task_from_as_plan.rb +33 -0
- data/lib/roby/coordination/models/task_from_instanciation_object.rb +31 -0
- data/lib/roby/coordination/models/task_from_variable.rb +27 -0
- data/lib/roby/coordination/models/task_with_dependencies.rb +48 -0
- data/lib/roby/coordination/models/variable.rb +32 -0
- data/lib/roby/coordination/script.rb +200 -0
- data/lib/roby/coordination/script_instruction.rb +12 -0
- data/lib/roby/coordination/task.rb +45 -0
- data/lib/roby/coordination/task_base.rb +69 -0
- data/lib/roby/coordination/task_script.rb +293 -0
- data/lib/roby/coordination/task_state_machine.rb +308 -0
- data/lib/roby/decision_control.rb +33 -21
- data/lib/roby/distributed_object.rb +76 -0
- data/lib/roby/droby.rb +17 -0
- data/lib/roby/droby/droby_id.rb +6 -0
- data/lib/roby/droby/enable.rb +153 -0
- data/lib/roby/droby/event_logger.rb +189 -0
- data/lib/roby/droby/event_logging.rb +57 -0
- data/lib/roby/droby/exceptions.rb +14 -0
- data/lib/roby/droby/identifiable.rb +22 -0
- data/lib/roby/droby/logfile.rb +141 -0
- data/lib/roby/droby/logfile/client.rb +176 -0
- data/lib/roby/droby/logfile/file_format.md +97 -0
- data/lib/roby/droby/logfile/index.rb +117 -0
- data/lib/roby/droby/logfile/reader.rb +139 -0
- data/lib/roby/droby/logfile/server.rb +199 -0
- data/lib/roby/droby/logfile/writer.rb +114 -0
- data/lib/roby/droby/marshal.rb +264 -0
- data/lib/roby/droby/marshallable.rb +12 -0
- data/lib/roby/droby/null_event_logger.rb +25 -0
- data/lib/roby/droby/object_manager.rb +205 -0
- data/lib/roby/droby/peer_id.rb +6 -0
- data/lib/roby/droby/plan_rebuilder.rb +373 -0
- data/lib/roby/droby/rebuilt_plan.rb +160 -0
- data/lib/roby/droby/remote_droby_id.rb +6 -0
- data/lib/roby/droby/timepoints.rb +205 -0
- data/lib/roby/droby/timepoints_ctf.metadata.erb +101 -0
- data/lib/roby/droby/timepoints_ctf.rb +125 -0
- data/lib/roby/droby/v5.rb +14 -0
- data/lib/roby/droby/v5/builtin.rb +120 -0
- data/lib/roby/droby/v5/droby_class.rb +45 -0
- data/lib/roby/droby/v5/droby_constant.rb +81 -0
- data/lib/roby/droby/v5/droby_dump.rb +1026 -0
- data/lib/roby/droby/v5/droby_id.rb +44 -0
- data/lib/roby/droby/v5/droby_model.rb +82 -0
- data/lib/roby/droby/v5/peer_id.rb +10 -0
- data/lib/roby/droby/v5/remote_droby_id.rb +42 -0
- data/lib/roby/event.rb +79 -957
- data/lib/roby/event_constraints.rb +835 -0
- data/lib/roby/event_generator.rb +1047 -0
- data/lib/roby/event_structure/causal_link.rb +6 -0
- data/lib/roby/event_structure/forwarding.rb +6 -0
- data/lib/roby/event_structure/precedence.rb +7 -0
- data/lib/roby/event_structure/signal.rb +8 -0
- data/lib/roby/event_structure/temporal_constraints.rb +640 -0
- data/lib/roby/exceptions.rb +446 -152
- data/lib/roby/executable_plan.rb +549 -0
- data/lib/roby/execution_engine.rb +1997 -950
- data/lib/roby/filter_generator.rb +26 -0
- data/lib/roby/gui/chronicle_view.rb +225 -0
- data/lib/roby/gui/chronicle_widget.rb +925 -0
- data/lib/roby/gui/dot_id.rb +11 -0
- data/lib/roby/gui/exception_view.rb +44 -0
- data/lib/roby/gui/log_display.rb +273 -0
- data/lib/roby/gui/model_views.rb +2 -0
- data/lib/roby/gui/model_views/action_interface.rb +53 -0
- data/lib/roby/gui/model_views/task.rb +47 -0
- data/lib/roby/gui/model_views/task.rhtml +41 -0
- data/lib/roby/gui/object_info_view.rb +89 -0
- data/lib/roby/gui/plan_dot_layout.rb +427 -0
- data/lib/roby/gui/plan_rebuilder_widget.rb +357 -0
- data/lib/roby/gui/qt4_toMSecsSinceEpoch.rb +8 -0
- data/lib/roby/gui/relations_view.rb +278 -0
- data/lib/roby/gui/relations_view/relations.ui +139 -0
- data/lib/roby/gui/relations_view/relations_canvas.rb +1088 -0
- data/lib/roby/gui/relations_view/relations_config.rb +292 -0
- data/lib/roby/gui/relations_view/relations_view.ui +53 -0
- data/lib/roby/gui/scheduler_view.css +24 -0
- data/lib/roby/gui/scheduler_view.rb +46 -0
- data/lib/roby/gui/scheduler_view.rhtml +53 -0
- data/lib/roby/gui/stepping.rb +93 -0
- data/lib/roby/gui/stepping.ui +181 -0
- data/lib/roby/gui/styles.rb +81 -0
- data/lib/roby/gui/task_display_configuration.rb +42 -0
- data/lib/roby/gui/task_state_at.rb +38 -0
- data/lib/roby/hooks.rb +26 -0
- data/lib/roby/interface.rb +136 -469
- data/lib/roby/interface/async.rb +20 -0
- data/lib/roby/interface/async/action_monitor.rb +188 -0
- data/lib/roby/interface/async/interface.rb +498 -0
- data/lib/roby/interface/async/job_monitor.rb +213 -0
- data/lib/roby/interface/async/log.rb +238 -0
- data/lib/roby/interface/async/new_job_listener.rb +79 -0
- data/lib/roby/interface/async/ui_connector.rb +183 -0
- data/lib/roby/interface/client.rb +553 -0
- data/lib/roby/interface/command.rb +24 -0
- data/lib/roby/interface/command_argument.rb +16 -0
- data/lib/roby/interface/command_library.rb +92 -0
- data/lib/roby/interface/droby_channel.rb +174 -0
- data/lib/roby/interface/exceptions.rb +22 -0
- data/lib/roby/interface/interface.rb +655 -0
- data/lib/roby/interface/job.rb +47 -0
- data/lib/roby/interface/rest.rb +10 -0
- data/lib/roby/interface/rest/api.rb +29 -0
- data/lib/roby/interface/rest/helpers.rb +24 -0
- data/lib/roby/interface/rest/server.rb +212 -0
- data/lib/roby/interface/server.rb +154 -0
- data/lib/roby/interface/shell_client.rb +468 -0
- data/lib/roby/interface/shell_subcommand.rb +24 -0
- data/lib/roby/interface/subcommand_client.rb +35 -0
- data/lib/roby/interface/tcp.rb +168 -0
- data/lib/roby/models/arguments.rb +112 -0
- data/lib/roby/models/plan_object.rb +83 -0
- data/lib/roby/models/task.rb +835 -0
- data/lib/roby/models/task_event.rb +62 -0
- data/lib/roby/models/task_service.rb +78 -0
- data/lib/roby/or_generator.rb +88 -0
- data/lib/roby/plan.rb +1751 -864
- data/lib/roby/plan_object.rb +611 -0
- data/lib/roby/plan_service.rb +200 -0
- data/lib/roby/promise.rb +332 -0
- data/lib/roby/queries.rb +23 -0
- data/lib/roby/queries/and_matcher.rb +32 -0
- data/lib/roby/queries/any.rb +27 -0
- data/lib/roby/queries/code_error_matcher.rb +58 -0
- data/lib/roby/queries/event_generator_matcher.rb +9 -0
- data/lib/roby/queries/execution_exception_matcher.rb +165 -0
- data/lib/roby/queries/index.rb +165 -0
- data/lib/roby/queries/localized_error_matcher.rb +149 -0
- data/lib/roby/queries/matcher_base.rb +107 -0
- data/lib/roby/queries/none.rb +27 -0
- data/lib/roby/queries/not_matcher.rb +30 -0
- data/lib/roby/queries/op_matcher.rb +8 -0
- data/lib/roby/queries/or_matcher.rb +30 -0
- data/lib/roby/queries/plan_object_matcher.rb +363 -0
- data/lib/roby/queries/query.rb +188 -0
- data/lib/roby/queries/task_event_generator_matcher.rb +86 -0
- data/lib/roby/queries/task_matcher.rb +344 -0
- data/lib/roby/relations.rb +42 -678
- data/lib/roby/relations/bidirectional_directed_adjacency_graph.rb +492 -0
- data/lib/roby/relations/directed_relation_support.rb +268 -0
- data/lib/roby/relations/event_relation_graph.rb +19 -0
- data/lib/roby/relations/fork_merge_visitor.rb +154 -0
- data/lib/roby/relations/graph.rb +533 -0
- data/lib/roby/relations/models/directed_relation_support.rb +11 -0
- data/lib/roby/relations/models/graph.rb +75 -0
- data/lib/roby/relations/models/task_relation_graph.rb +18 -0
- data/lib/roby/relations/space.rb +380 -0
- data/lib/roby/relations/task_relation_graph.rb +20 -0
- data/lib/roby/robot.rb +85 -38
- data/lib/roby/schedulers/basic.rb +155 -25
- data/lib/roby/schedulers/null.rb +20 -0
- data/lib/roby/schedulers/reporting.rb +31 -0
- data/lib/roby/schedulers/state.rb +129 -0
- data/lib/roby/schedulers/temporal.rb +91 -0
- data/lib/roby/singletons.rb +87 -0
- data/lib/roby/standalone.rb +4 -2
- data/lib/roby/standard_errors.rb +405 -82
- data/lib/roby/state.rb +6 -3
- data/lib/roby/state/conf_model.rb +5 -0
- data/lib/roby/state/events.rb +181 -95
- data/lib/roby/state/goal_model.rb +77 -0
- data/lib/roby/state/open_struct.rb +591 -0
- data/lib/roby/state/open_struct_model.rb +68 -0
- data/lib/roby/state/pos.rb +45 -45
- data/lib/roby/state/shapes.rb +11 -11
- data/lib/roby/state/state_model.rb +303 -0
- data/lib/roby/state/task.rb +43 -0
- data/lib/roby/support.rb +88 -148
- data/lib/roby/task.rb +1361 -1750
- data/lib/roby/task_arguments.rb +428 -0
- data/lib/roby/task_event.rb +127 -0
- data/lib/roby/task_event_generator.rb +337 -0
- data/lib/roby/task_service.rb +6 -0
- data/lib/roby/task_structure/conflicts.rb +104 -0
- data/lib/roby/task_structure/dependency.rb +932 -0
- data/lib/roby/task_structure/error_handling.rb +118 -0
- data/lib/roby/task_structure/executed_by.rb +234 -0
- data/lib/roby/task_structure/planned_by.rb +90 -0
- data/lib/roby/tasks/aggregator.rb +37 -0
- data/lib/roby/tasks/external_process.rb +275 -0
- data/lib/roby/tasks/group.rb +27 -0
- data/lib/roby/tasks/null.rb +19 -0
- data/lib/roby/tasks/parallel.rb +43 -0
- data/lib/roby/tasks/sequence.rb +88 -0
- data/lib/roby/tasks/simple.rb +21 -0
- data/lib/roby/{thread_task.rb → tasks/thread.rb} +50 -24
- data/lib/roby/tasks/timeout.rb +17 -0
- data/lib/roby/tasks/virtual.rb +55 -0
- data/lib/roby/template_plan.rb +7 -0
- data/lib/roby/test/aruba_minitest.rb +74 -0
- data/lib/roby/test/assertion.rb +16 -0
- data/lib/roby/test/assertions.rb +490 -0
- data/lib/roby/test/common.rb +368 -591
- data/lib/roby/test/dsl.rb +149 -0
- data/lib/roby/test/error.rb +18 -0
- data/lib/roby/test/event_reporter.rb +83 -0
- data/lib/roby/test/execution_expectations.rb +1134 -0
- data/lib/roby/test/expect_execution.rb +151 -0
- data/lib/roby/test/minitest_helpers.rb +166 -0
- data/lib/roby/test/roby_app_helpers.rb +200 -0
- data/lib/roby/test/run_planners.rb +155 -0
- data/lib/roby/test/self.rb +112 -0
- data/lib/roby/test/spec.rb +198 -0
- data/lib/roby/test/tasks/empty_task.rb +4 -4
- data/lib/roby/test/tasks/goto.rb +28 -27
- data/lib/roby/test/teardown_plans.rb +100 -0
- data/lib/roby/test/testcase.rb +239 -307
- data/lib/roby/test/tools.rb +159 -155
- data/lib/roby/test/validate_state_machine.rb +75 -0
- data/lib/roby/transaction.rb +1125 -0
- data/lib/roby/transaction/event_generator_proxy.rb +63 -0
- data/lib/roby/transaction/plan_object_proxy.rb +99 -0
- data/lib/roby/transaction/plan_service_proxy.rb +43 -0
- data/lib/roby/transaction/proxying.rb +120 -0
- data/lib/roby/transaction/task_event_generator_proxy.rb +19 -0
- data/lib/roby/transaction/task_proxy.rb +135 -0
- data/lib/roby/until_generator.rb +30 -0
- data/lib/roby/version.rb +5 -0
- data/lib/roby/yard.rb +169 -0
- data/lib/yard-roby.rb +1 -0
- data/manifest.xml +32 -6
- data/roby.gemspec +59 -0
- metadata +788 -587
- data/Manifest.txt +0 -321
- data/NOTES +0 -4
- data/README.txt +0 -166
- data/TODO.txt +0 -146
- data/app/README.txt +0 -24
- data/app/Rakefile +0 -8
- data/app/config/ROBOT.rb +0 -5
- data/app/config/init.rb +0 -33
- data/app/config/roby.yml +0 -3
- data/app/controllers/ROBOT.rb +0 -2
- data/app/planners/ROBOT/main.rb +0 -6
- data/app/planners/main.rb +0 -5
- data/app/scripts/distributed +0 -3
- data/app/scripts/generate/bookmarks +0 -3
- data/app/scripts/replay +0 -3
- data/app/scripts/results +0 -3
- data/app/scripts/run +0 -3
- data/app/scripts/server +0 -3
- data/app/scripts/shell +0 -3
- data/app/scripts/test +0 -3
- data/app/tasks/.gitattributes +0 -0
- data/app/tasks/ROBOT/.gitattributes +0 -0
- data/bin/roby-shell +0 -25
- data/doc/guide/src/basics/app.page +0 -139
- data/doc/guide/src/basics/index.page +0 -11
- data/doc/guide/src/basics/log_replay/goForward_1.png +0 -0
- data/doc/guide/src/basics/log_replay/goForward_2.png +0 -0
- data/doc/guide/src/basics/log_replay/goForward_3.png +0 -0
- data/doc/guide/src/basics/log_replay/goForward_5.png +0 -0
- data/doc/guide/src/basics/log_replay/plan_repair_4.png +0 -0
- data/doc/guide/src/basics/log_replay/roby_log_main_window.png +0 -0
- data/doc/guide/src/basics/relations_display.page +0 -203
- data/doc/guide/src/basics/shell.page +0 -102
- data/doc/guide/src/default.css +0 -319
- data/doc/guide/src/introduction/index.page +0 -29
- data/doc/guide/src/introduction/publications.page +0 -14
- data/doc/guide/src/relations/dependency.page +0 -89
- data/doc/guide/src/relations/index.page +0 -12
- data/ext/droby/dump.cc +0 -175
- data/ext/droby/extconf.rb +0 -3
- data/ext/graph/algorithm.cc +0 -746
- data/ext/graph/extconf.rb +0 -7
- data/ext/graph/graph.cc +0 -575
- data/ext/graph/graph.hh +0 -183
- data/ext/graph/iterator_sequence.hh +0 -102
- data/ext/graph/undirected_dfs.hh +0 -226
- data/ext/graph/undirected_graph.hh +0 -421
- data/lib/roby/app/scripts/generate/bookmarks.rb +0 -162
- data/lib/roby/app/scripts/replay.rb +0 -31
- data/lib/roby/app/scripts/server.rb +0 -18
- data/lib/roby/basic_object.rb +0 -151
- data/lib/roby/config.rb +0 -14
- data/lib/roby/distributed.rb +0 -36
- data/lib/roby/distributed/base.rb +0 -448
- data/lib/roby/distributed/communication.rb +0 -875
- data/lib/roby/distributed/connection_space.rb +0 -616
- data/lib/roby/distributed/distributed_object.rb +0 -206
- data/lib/roby/distributed/drb.rb +0 -62
- data/lib/roby/distributed/notifications.rb +0 -531
- data/lib/roby/distributed/peer.rb +0 -555
- data/lib/roby/distributed/protocol.rb +0 -529
- data/lib/roby/distributed/proxy.rb +0 -343
- data/lib/roby/distributed/subscription.rb +0 -311
- data/lib/roby/distributed/transaction.rb +0 -498
- data/lib/roby/external_process_task.rb +0 -225
- data/lib/roby/graph.rb +0 -160
- data/lib/roby/log.rb +0 -3
- data/lib/roby/log/chronicle.rb +0 -303
- data/lib/roby/log/console.rb +0 -74
- data/lib/roby/log/data_stream.rb +0 -275
- data/lib/roby/log/dot.rb +0 -279
- data/lib/roby/log/event_stream.rb +0 -161
- data/lib/roby/log/file.rb +0 -396
- data/lib/roby/log/gui/basic_display.ui +0 -83
- data/lib/roby/log/gui/basic_display_ui.rb +0 -89
- data/lib/roby/log/gui/chronicle.rb +0 -26
- data/lib/roby/log/gui/chronicle_view.rb +0 -40
- data/lib/roby/log/gui/chronicle_view.ui +0 -70
- data/lib/roby/log/gui/chronicle_view_ui.rb +0 -90
- data/lib/roby/log/gui/data_displays.rb +0 -171
- data/lib/roby/log/gui/data_displays.ui +0 -155
- data/lib/roby/log/gui/data_displays_ui.rb +0 -146
- data/lib/roby/log/gui/notifications.rb +0 -26
- data/lib/roby/log/gui/relations.rb +0 -269
- data/lib/roby/log/gui/relations.ui +0 -123
- data/lib/roby/log/gui/relations_ui.rb +0 -120
- data/lib/roby/log/gui/relations_view.rb +0 -185
- data/lib/roby/log/gui/relations_view.ui +0 -149
- data/lib/roby/log/gui/relations_view_ui.rb +0 -144
- data/lib/roby/log/gui/replay.rb +0 -366
- data/lib/roby/log/gui/replay_controls.rb +0 -206
- data/lib/roby/log/gui/replay_controls.ui +0 -282
- data/lib/roby/log/gui/replay_controls_ui.rb +0 -249
- data/lib/roby/log/gui/runtime.rb +0 -130
- data/lib/roby/log/hooks.rb +0 -186
- data/lib/roby/log/logger.rb +0 -203
- data/lib/roby/log/notifications.rb +0 -244
- data/lib/roby/log/plan_rebuilder.rb +0 -468
- data/lib/roby/log/relations.rb +0 -1084
- data/lib/roby/log/server.rb +0 -547
- data/lib/roby/log/sqlite.rb +0 -47
- data/lib/roby/log/timings.rb +0 -233
- data/lib/roby/plan-object.rb +0 -371
- data/lib/roby/planning.rb +0 -13
- data/lib/roby/planning/loops.rb +0 -309
- data/lib/roby/planning/model.rb +0 -1012
- data/lib/roby/planning/task.rb +0 -180
- data/lib/roby/query.rb +0 -655
- data/lib/roby/relations/conflicts.rb +0 -67
- data/lib/roby/relations/dependency.rb +0 -358
- data/lib/roby/relations/ensured.rb +0 -19
- data/lib/roby/relations/error_handling.rb +0 -22
- data/lib/roby/relations/events.rb +0 -7
- data/lib/roby/relations/executed_by.rb +0 -208
- data/lib/roby/relations/influence.rb +0 -10
- data/lib/roby/relations/planned_by.rb +0 -63
- data/lib/roby/state/information.rb +0 -55
- data/lib/roby/state/state.rb +0 -367
- data/lib/roby/task-operations.rb +0 -186
- data/lib/roby/task_index.rb +0 -80
- data/lib/roby/test/distributed.rb +0 -230
- data/lib/roby/test/tasks/simple_task.rb +0 -23
- data/lib/roby/transactions.rb +0 -507
- data/lib/roby/transactions/proxy.rb +0 -325
- data/plugins/fault_injection/History.txt +0 -4
- data/plugins/fault_injection/README.txt +0 -34
- data/plugins/fault_injection/Rakefile +0 -12
- data/plugins/fault_injection/TODO.txt +0 -0
- data/plugins/fault_injection/app.rb +0 -52
- data/plugins/fault_injection/fault_injection.rb +0 -89
- data/plugins/fault_injection/test/test_fault_injection.rb +0 -78
- data/plugins/subsystems/README.txt +0 -37
- data/plugins/subsystems/Rakefile +0 -13
- data/plugins/subsystems/app.rb +0 -182
- data/plugins/subsystems/test/app/README +0 -24
- data/plugins/subsystems/test/app/Rakefile +0 -8
- data/plugins/subsystems/test/app/config/app.yml +0 -71
- data/plugins/subsystems/test/app/config/init.rb +0 -12
- data/plugins/subsystems/test/app/config/roby.yml +0 -3
- data/plugins/subsystems/test/app/planners/main.rb +0 -20
- data/plugins/subsystems/test/app/scripts/distributed +0 -3
- data/plugins/subsystems/test/app/scripts/replay +0 -3
- data/plugins/subsystems/test/app/scripts/results +0 -3
- data/plugins/subsystems/test/app/scripts/run +0 -3
- data/plugins/subsystems/test/app/scripts/server +0 -3
- data/plugins/subsystems/test/app/scripts/shell +0 -3
- data/plugins/subsystems/test/app/scripts/test +0 -3
- data/plugins/subsystems/test/app/tasks/services.rb +0 -15
- data/plugins/subsystems/test/test_subsystems.rb +0 -78
- data/test/distributed/test_communication.rb +0 -195
- data/test/distributed/test_connection.rb +0 -284
- data/test/distributed/test_execution.rb +0 -378
- data/test/distributed/test_mixed_plan.rb +0 -341
- data/test/distributed/test_plan_notifications.rb +0 -238
- data/test/distributed/test_protocol.rb +0 -525
- data/test/distributed/test_query.rb +0 -106
- data/test/distributed/test_remote_plan.rb +0 -491
- data/test/distributed/test_transaction.rb +0 -466
- data/test/mockups/external_process +0 -28
- data/test/mockups/tasks.rb +0 -27
- data/test/planning/test_loops.rb +0 -432
- data/test/planning/test_model.rb +0 -427
- data/test/planning/test_task.rb +0 -126
- data/test/relations/test_conflicts.rb +0 -42
- data/test/relations/test_dependency.rb +0 -324
- data/test/relations/test_ensured.rb +0 -38
- data/test/relations/test_executed_by.rb +0 -224
- data/test/relations/test_planned_by.rb +0 -56
- data/test/suite_core.rb +0 -29
- data/test/suite_distributed.rb +0 -10
- data/test/suite_planning.rb +0 -4
- data/test/suite_relations.rb +0 -8
- data/test/tasks/test_external_process.rb +0 -126
- data/test/tasks/test_thread_task.rb +0 -70
- data/test/test_bgl.rb +0 -528
- data/test/test_event.rb +0 -969
- data/test/test_exceptions.rb +0 -591
- data/test/test_execution_engine.rb +0 -987
- data/test/test_gui.rb +0 -20
- data/test/test_interface.rb +0 -43
- data/test/test_log.rb +0 -125
- data/test/test_log_server.rb +0 -133
- data/test/test_plan.rb +0 -418
- data/test/test_query.rb +0 -424
- data/test/test_relations.rb +0 -260
- data/test/test_state.rb +0 -432
- data/test/test_support.rb +0 -16
- data/test/test_task.rb +0 -1181
- data/test/test_testcase.rb +0 -138
- data/test/test_transactions.rb +0 -610
- data/test/test_transactions_proxy.rb +0 -216
|
@@ -0,0 +1,611 @@
|
|
|
1
|
+
module Roby
|
|
2
|
+
# Base class for all objects which are included in a plan.
|
|
3
|
+
class PlanObject < DistributedObject
|
|
4
|
+
extend Models::PlanObject
|
|
5
|
+
include Relations::DirectedRelationSupport
|
|
6
|
+
|
|
7
|
+
# This object's model
|
|
8
|
+
#
|
|
9
|
+
# This is usually self.class, unless {#specialize} has been called in
|
|
10
|
+
# which case it is this object's singleton class
|
|
11
|
+
attr_reader :model
|
|
12
|
+
|
|
13
|
+
# The non-specialized model for self
|
|
14
|
+
#
|
|
15
|
+
# It is always self.class
|
|
16
|
+
def concrete_model; self.class end
|
|
17
|
+
|
|
18
|
+
# The underlying execution engine if {#plan} is executable
|
|
19
|
+
attr_reader :execution_engine
|
|
20
|
+
|
|
21
|
+
# A thread pool that ensures that any work queued using {#promise} is
|
|
22
|
+
# serialized
|
|
23
|
+
attr_reader :promise_executor
|
|
24
|
+
|
|
25
|
+
def connection_space
|
|
26
|
+
if plan
|
|
27
|
+
plan.connection_space
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Whether this task can be finalized
|
|
32
|
+
#
|
|
33
|
+
# Unlike plan-level structure, a task that is marked as keepalive *will*
|
|
34
|
+
# be processed by garbage collection (e.g. stopping it). However, it
|
|
35
|
+
# will not be finalized (removed from the plan). The garbage collection
|
|
36
|
+
# will clear its relations instead of finalizing it
|
|
37
|
+
#
|
|
38
|
+
# The default returns true
|
|
39
|
+
def can_finalize?
|
|
40
|
+
true
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Generic handling object for blocks that are stored on tasks (event
|
|
44
|
+
# handlers,poll, ...)
|
|
45
|
+
#
|
|
46
|
+
# The only configurable behaviour so far is the ability to specify what
|
|
47
|
+
# to do with the block when a task is replaced by another one. This is
|
|
48
|
+
# given as a :on_replace option, which can take only two values:
|
|
49
|
+
#
|
|
50
|
+
# drop:: the handler is not copied
|
|
51
|
+
# copy:: the handler is copied
|
|
52
|
+
#
|
|
53
|
+
# The default is dependent on the receiving's object state. For
|
|
54
|
+
# instance, abstract tasks will use a default of 'copy' while
|
|
55
|
+
# non-abstract one will use a default of 'drop'.
|
|
56
|
+
class InstanceHandler
|
|
57
|
+
# The poll Proc object
|
|
58
|
+
attr_reader :block
|
|
59
|
+
## :method:copy_on_replace?
|
|
60
|
+
#
|
|
61
|
+
# If true, this poll handler gets copied to the new task when the
|
|
62
|
+
# task holding the handler gets replaced
|
|
63
|
+
attr_predicate :copy_on_replace?, true
|
|
64
|
+
|
|
65
|
+
# Helper method for validate_options and filter_options
|
|
66
|
+
#
|
|
67
|
+
# @param [:validate,:filter] method which of the filter_options or
|
|
68
|
+
# validate_options should be called.
|
|
69
|
+
# @!macro InstanceHandlerOptions
|
|
70
|
+
# @option options [:copy,:drop] :on_replace defines the behaviour
|
|
71
|
+
# when this object gets replaced in the plan. If :copy is used,
|
|
72
|
+
# the handler is added to the replacing task and is also kept
|
|
73
|
+
# in the original task. If :drop, it is not copied (but is
|
|
74
|
+
# kept).
|
|
75
|
+
def self.handle_options(method, options, defaults)
|
|
76
|
+
options, other = Kernel.send("#{method}_options", options,
|
|
77
|
+
on_replace: (defaults[:on_replace] || :drop))
|
|
78
|
+
|
|
79
|
+
if ![:drop, :copy].include?(options[:on_replace])
|
|
80
|
+
raise ArgumentError, "wrong value for the :on_replace option. Expecting either :drop or :copy, got #{options[:on_replace]}"
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
if other
|
|
84
|
+
return options, other
|
|
85
|
+
else return options
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def self.validate_options(options, defaults = Hash.new)
|
|
90
|
+
handle_options(:validate, options, defaults)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def self.filter_options(options, defaults)
|
|
94
|
+
handle_options(:filter, options, defaults)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def initialize(block, copy_on_replace)
|
|
98
|
+
@block, @copy_on_replace =
|
|
99
|
+
block, copy_on_replace
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Creates an option hash from this poll handler parameters that is
|
|
103
|
+
# valid for Task#poll
|
|
104
|
+
def as_options
|
|
105
|
+
on_replace = if copy_on_replace? then :copy
|
|
106
|
+
else :drop
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
{ on_replace: on_replace }
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def ==(other)
|
|
113
|
+
@copy_on_replace == other.copy_on_replace? &&
|
|
114
|
+
@block == other.block
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def initialize(plan: TemplatePlan.new)
|
|
119
|
+
super()
|
|
120
|
+
|
|
121
|
+
@plan = plan
|
|
122
|
+
self.plan = @plan
|
|
123
|
+
|
|
124
|
+
@removed_at = nil
|
|
125
|
+
@executable = nil
|
|
126
|
+
@garbage = false
|
|
127
|
+
@finalization_handlers = Array.new
|
|
128
|
+
@model = self.class
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def initialize_copy(other)
|
|
132
|
+
# Consider whether subclasses initialized the plan before calling us
|
|
133
|
+
# ... in which case we handle it specially and propagate it
|
|
134
|
+
super
|
|
135
|
+
@plan = nil
|
|
136
|
+
@relation_graphs = nil
|
|
137
|
+
@finalization_handlers = other.finalization_handlers.dup
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# The plan this object belongs to
|
|
141
|
+
attr_reader :plan
|
|
142
|
+
|
|
143
|
+
# @deprecated use {#execution_engine} instead
|
|
144
|
+
def engine
|
|
145
|
+
Roby.warn_deprecated "PlanObject#engine is deprecated, use #execution_engine instead"
|
|
146
|
+
execution_engine
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# True if this object is a transaction proxy, false otherwise
|
|
150
|
+
def transaction_proxy?; false end
|
|
151
|
+
|
|
152
|
+
# The place where this object has been removed from its plan. Once an
|
|
153
|
+
# object is removed from its plan, it cannot be added back again.
|
|
154
|
+
attr_accessor :removed_at
|
|
155
|
+
|
|
156
|
+
# True if this object has been included in a plan, but has been removed
|
|
157
|
+
# from it since
|
|
158
|
+
def finalized?; !!removed_at end
|
|
159
|
+
|
|
160
|
+
# Sets the new plan. Since it is forbidden to re-use a plan object that
|
|
161
|
+
# has been removed from a plan, it raises ArgumentError if it is the
|
|
162
|
+
# case
|
|
163
|
+
def plan=(new_plan)
|
|
164
|
+
if removed_at
|
|
165
|
+
if PlanObject.debug_finalization_place?
|
|
166
|
+
raise ArgumentError, "#{self} has been removed from plan, cannot add it back\n" +
|
|
167
|
+
"Removed at\n #{removed_at.join("\n ")}"
|
|
168
|
+
else
|
|
169
|
+
raise ArgumentError, "#{self} has been removed from plan, cannot add it back. Set PlanObject.debug_finalization_place to true to get the backtrace of where (in the code) the object got finalized"
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
@addition_time = Time.now
|
|
173
|
+
@plan = new_plan
|
|
174
|
+
@local_owner_id = plan.droby_id
|
|
175
|
+
if new_plan && new_plan.executable?
|
|
176
|
+
@execution_engine = new_plan.execution_engine
|
|
177
|
+
@promise_executor = Concurrent::SerializedExecutionDelegator.
|
|
178
|
+
new(@execution_engine.thread_pool)
|
|
179
|
+
else
|
|
180
|
+
@execution_engine = nil
|
|
181
|
+
@promise_executor = nil
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# Create a promise that is serialized with all promises created for this
|
|
186
|
+
# object
|
|
187
|
+
#
|
|
188
|
+
# @param [String] description a textual description of the promise's
|
|
189
|
+
# role (used for debugging and timing)
|
|
190
|
+
# @return [Promise]
|
|
191
|
+
def promise(description: "#{self}.promise", executor: promise_executor, &block)
|
|
192
|
+
execution_engine.promise(description: description, executor: executor, &block)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# Used in plan management as a way to extract a plan object from any
|
|
196
|
+
# object
|
|
197
|
+
def as_plan; self end
|
|
198
|
+
|
|
199
|
+
# If +self+ is a transaction proxy, returns the underlying plan object,
|
|
200
|
+
# regardless of how many transactions there is on the stack. Otherwise,
|
|
201
|
+
# return self.
|
|
202
|
+
def real_object
|
|
203
|
+
result = self
|
|
204
|
+
while result.respond_to?(:__getobj__)
|
|
205
|
+
result = result.__getobj__
|
|
206
|
+
end
|
|
207
|
+
result
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# Returns the stack of transactions/plans this object is part of,
|
|
211
|
+
# starting with self.plan.
|
|
212
|
+
def transaction_stack
|
|
213
|
+
result = [plan]
|
|
214
|
+
obj = self
|
|
215
|
+
while obj.respond_to?(:__getobj__)
|
|
216
|
+
obj = obj.__getobj__
|
|
217
|
+
result << obj.plan
|
|
218
|
+
end
|
|
219
|
+
result
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def each_in_neighbour_merged(relation, intrusive: nil, &block)
|
|
223
|
+
if intrusive.nil?
|
|
224
|
+
raise ArgumentError, "you must give a true or false to the intrusive flag"
|
|
225
|
+
end
|
|
226
|
+
merged_relations(
|
|
227
|
+
proc { |o, &b| o.each_in_neighbour(relation, &b) },
|
|
228
|
+
intrusive, &block)
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def each_out_neighbour_merged(relation, intrusive: nil, &block)
|
|
232
|
+
if intrusive.nil?
|
|
233
|
+
raise ArgumentError, "you must give a true or false to the intrusive flag"
|
|
234
|
+
end
|
|
235
|
+
merged_relations(
|
|
236
|
+
proc { |o, &b| o.each_out_neighbour(relation, &b) },
|
|
237
|
+
intrusive, &block)
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
# call-seq:
|
|
241
|
+
# merged_relation(enumeration_method, false[, arg1, arg2]) do |self_t, related_t|
|
|
242
|
+
# end
|
|
243
|
+
# merged_relation(enumeration_method, true[, arg1, arg2]) do |related_t|
|
|
244
|
+
# end
|
|
245
|
+
#
|
|
246
|
+
# It is assumed that +enumeration_method+ is the name of a method on
|
|
247
|
+
# +self+ that will yield an object related to +self+.
|
|
248
|
+
#
|
|
249
|
+
# This method computes the same set of related objects, but does so
|
|
250
|
+
# while merging all the changes that underlying transactions may have
|
|
251
|
+
# applied. I.e. it is equivalent to calling +enumeration_method+ on the
|
|
252
|
+
# plan that would be the result of the application of the whole
|
|
253
|
+
# transaction stack
|
|
254
|
+
#
|
|
255
|
+
# If +instrusive+ is false, the edges are yielded at the level they
|
|
256
|
+
# appear. I.e. both +self+ and the related object are given, and
|
|
257
|
+
# [self_t, related_t] may be part of a parent plan of self.plan. I.e.
|
|
258
|
+
# +self_t+ is either +self+ itself, or the task that +self+ represents
|
|
259
|
+
# in a parent plan / transaction.
|
|
260
|
+
#
|
|
261
|
+
# If +instrusive+ is true, the related objects are recursively added to
|
|
262
|
+
# all transactions in the transaction stack, and are given at the end.
|
|
263
|
+
# I.e. only the related object is yield, and it is guaranteed to be
|
|
264
|
+
# included in self.plan.
|
|
265
|
+
#
|
|
266
|
+
# For instance,
|
|
267
|
+
#
|
|
268
|
+
# merged_relations(:each_child, false) do |parent, child|
|
|
269
|
+
# ...
|
|
270
|
+
# end
|
|
271
|
+
#
|
|
272
|
+
# yields the children of +self+ according to the modifications that the
|
|
273
|
+
# transactions apply, but may do so in the transaction's parent plans.
|
|
274
|
+
#
|
|
275
|
+
# merged_relations(:each_child, true) do |child|
|
|
276
|
+
# ...
|
|
277
|
+
# end
|
|
278
|
+
#
|
|
279
|
+
# Will yield the same set of tasks, but included in +self.plan+.
|
|
280
|
+
def merged_relations(enumerator, intrusive)
|
|
281
|
+
return enum_for(__method__, enumerator, intrusive) if !block_given?
|
|
282
|
+
|
|
283
|
+
plan_chain = self.transaction_stack
|
|
284
|
+
object = self.real_object
|
|
285
|
+
enumerator = enumerator.to_proc
|
|
286
|
+
|
|
287
|
+
pending = Array.new
|
|
288
|
+
while plan_chain.size > 1
|
|
289
|
+
plan = plan_chain.pop
|
|
290
|
+
next_plan = plan_chain.last
|
|
291
|
+
|
|
292
|
+
# Objects that are in +plan+ but not in +next_plan+ are
|
|
293
|
+
# automatically added, as +next_plan+ is not able to change
|
|
294
|
+
# them. Those that are included in +next_plan+ are handled
|
|
295
|
+
# later.
|
|
296
|
+
new_objects = Array.new
|
|
297
|
+
enumerator.call(object) do |related_object|
|
|
298
|
+
next if next_plan[related_object, create: false]
|
|
299
|
+
|
|
300
|
+
if !intrusive
|
|
301
|
+
yield(object, related_object)
|
|
302
|
+
else
|
|
303
|
+
new_objects << related_object
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
# Here, pending contains objects from the previous plan (i.e. in
|
|
308
|
+
# plan.plan). Proxy them in +plan+.
|
|
309
|
+
#
|
|
310
|
+
# It is important to do that *after* we enumerated the relations
|
|
311
|
+
# that exist in +plan+ (above), as it reduces the number of
|
|
312
|
+
# relations at each level.
|
|
313
|
+
pending.map! { |t| plan[t] }
|
|
314
|
+
# And add the new objects that we just discovered
|
|
315
|
+
pending.concat(new_objects)
|
|
316
|
+
|
|
317
|
+
if next_plan
|
|
318
|
+
object = next_plan[object]
|
|
319
|
+
end
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
if intrusive
|
|
323
|
+
enumerator.call(self, &Proc.new)
|
|
324
|
+
for related_object in pending
|
|
325
|
+
yield(self.plan[related_object])
|
|
326
|
+
end
|
|
327
|
+
else
|
|
328
|
+
enumerator.call(self) do |related_object|
|
|
329
|
+
yield(self, related_object)
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
# A three-state flag with the following values:
|
|
335
|
+
# nil:: the object is executable if its plan is
|
|
336
|
+
# true:: the object is executable
|
|
337
|
+
# false:: the object is not executable
|
|
338
|
+
attr_writer :executable
|
|
339
|
+
|
|
340
|
+
# If this object is executable
|
|
341
|
+
def executable?
|
|
342
|
+
@executable || (@executable.nil? && !garbage? && plan && plan.executable?)
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
# @!method garbage?
|
|
346
|
+
#
|
|
347
|
+
# Whether this task has been marked as garbage by the garbage collection
|
|
348
|
+
# process
|
|
349
|
+
#
|
|
350
|
+
# @see garbage!
|
|
351
|
+
attr_predicate :garbage?
|
|
352
|
+
|
|
353
|
+
# Mark this task as garbage
|
|
354
|
+
#
|
|
355
|
+
# Garbage tasks cannot be involved in new relations, and cannot be
|
|
356
|
+
# executed
|
|
357
|
+
#
|
|
358
|
+
# Once set, this flag cannot be unset
|
|
359
|
+
#
|
|
360
|
+
# @see garbage?
|
|
361
|
+
def garbage!
|
|
362
|
+
@garbage = true
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
# True if we are explicitely subscribed to this object
|
|
366
|
+
def subscribed?
|
|
367
|
+
if root_object?
|
|
368
|
+
(plan && plan.subscribed?) ||
|
|
369
|
+
(!self_owned? && owners.any? { |peer| peer.subscribed_plan? }) ||
|
|
370
|
+
super
|
|
371
|
+
else
|
|
372
|
+
root_object.subscribed?
|
|
373
|
+
end
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
# Method called to apply modifications needed to commit this object into
|
|
377
|
+
# the underlying plan
|
|
378
|
+
#
|
|
379
|
+
# For instance, {Task} will make sure that argument objects that are
|
|
380
|
+
# transaction proxies are unwrapped
|
|
381
|
+
#
|
|
382
|
+
# Note that the method should only deal with modifications that are
|
|
383
|
+
# internal to the task itself. Modifications of the relation graphs are
|
|
384
|
+
# handled by {Transaction} itself in
|
|
385
|
+
# {Transaction#apply_modifications_to_plan}
|
|
386
|
+
#
|
|
387
|
+
# The default implementation does nothing
|
|
388
|
+
def commit_transaction
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
alias :__freeze__ :freeze
|
|
392
|
+
|
|
393
|
+
# True if we should send updates about this object to +peer+
|
|
394
|
+
def update_on?(peer); (plan && plan.update_on?(peer)) || super end
|
|
395
|
+
# True if we receive updates for this object from +peer+
|
|
396
|
+
def updated_by?(peer); (plan && plan.updated_by?(peer)) || super end
|
|
397
|
+
# True if this object is useful for one of our peers
|
|
398
|
+
def remotely_useful?; (plan && plan.remotely_useful?) || super end
|
|
399
|
+
|
|
400
|
+
# Checks that we do not link two objects from two different plans and
|
|
401
|
+
# updates the +plan+ attribute accordingly
|
|
402
|
+
#
|
|
403
|
+
# It raises RuntimeError if both objects are already included in a
|
|
404
|
+
# plan, but their plan mismatches.
|
|
405
|
+
def synchronize_plan(other) # :nodoc:
|
|
406
|
+
if !plan
|
|
407
|
+
raise RuntimeError, "cannot add a relation with #{self}, which has already been finalized"
|
|
408
|
+
elsif !other.plan
|
|
409
|
+
raise RuntimeError, "cannot add a relation with #{other}, which has already been finalized"
|
|
410
|
+
end
|
|
411
|
+
return if plan == other.plan
|
|
412
|
+
|
|
413
|
+
if other.plan.template?
|
|
414
|
+
plan.add(other)
|
|
415
|
+
elsif plan.template?
|
|
416
|
+
other.plan.add(self)
|
|
417
|
+
else
|
|
418
|
+
raise RuntimeError, "cannot add a relation between two objects from different plans. #{self} is from #{plan} and #{other} is from #{other.plan}"
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
protected :synchronize_plan
|
|
422
|
+
|
|
423
|
+
# Called when all links to +peer+ should be removed.
|
|
424
|
+
def forget_peer(peer)
|
|
425
|
+
if !root_object?
|
|
426
|
+
raise ArgumentError, "#{self} is not root"
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
each_plan_child do |child|
|
|
430
|
+
child.forget_peer(peer)
|
|
431
|
+
end
|
|
432
|
+
super
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
# Synchronizes the plan of this object from the one of its peer
|
|
436
|
+
def add_child_object(child, type, info = nil) # :nodoc:
|
|
437
|
+
if child.plan != plan
|
|
438
|
+
root_object.synchronize_plan(child.root_object)
|
|
439
|
+
if !type.kind_of?(Class)
|
|
440
|
+
# If given a graph, we need to re-resolve it as #plan might
|
|
441
|
+
# have changed
|
|
442
|
+
type = relation_graphs.fetch(type.class)
|
|
443
|
+
end
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
super
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
# Return the root plan object for this object.
|
|
450
|
+
def root_object; self end
|
|
451
|
+
# True if this object is a root object in the plan.
|
|
452
|
+
def root_object?; root_object == self end
|
|
453
|
+
# Iterates on all the children of this root object
|
|
454
|
+
def each_plan_child; self end
|
|
455
|
+
|
|
456
|
+
# Transfers a set of relations from this plan object to +object+.
|
|
457
|
+
# +changes+ is formatted as a sequence of <tt>relation, parents,
|
|
458
|
+
# children</tt> slices, where +parents+ and +children+ are sets of
|
|
459
|
+
# objects.
|
|
460
|
+
#
|
|
461
|
+
# For each of these slices, the method removes the
|
|
462
|
+
# <tt>parent->self</tt> and <tt>self->child</tt> edges in the given
|
|
463
|
+
# relation, and then adds the corresponding <tt>parent->object</tt> and
|
|
464
|
+
# <tt>object->child</tt> edges.
|
|
465
|
+
def apply_relation_changes(object, changes)
|
|
466
|
+
# The operation is done in two parts to avoid problems with
|
|
467
|
+
# creating cycles in the graph: first we remove the old edges, then
|
|
468
|
+
# we add the new ones.
|
|
469
|
+
changes.each_slice(3) do |rel, parents, children|
|
|
470
|
+
next if rel.copy_on_replace?
|
|
471
|
+
|
|
472
|
+
parents.each_slice(2) do |parent, info|
|
|
473
|
+
parent.remove_child_object(self, rel)
|
|
474
|
+
end
|
|
475
|
+
children.each_slice(2) do |child, info|
|
|
476
|
+
remove_child_object(child, rel)
|
|
477
|
+
end
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
changes.each_slice(3) do |rel, parents, children|
|
|
481
|
+
parents.each_slice(2) do |parent, info|
|
|
482
|
+
parent.add_child_object(object, rel, info)
|
|
483
|
+
end
|
|
484
|
+
children.each_slice(2) do |child, info|
|
|
485
|
+
object.add_child_object(child, rel, info)
|
|
486
|
+
end
|
|
487
|
+
end
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
# Replaces, in the plan, the subplan generated by this plan object by
|
|
491
|
+
# the one generated by +object+. In practice, it means that we transfer
|
|
492
|
+
# all parent edges whose target is +self+ from the receiver to
|
|
493
|
+
# +object+. It calls the various add/remove hooks defined in
|
|
494
|
+
# {Relations::DirectedRelationSupport}.
|
|
495
|
+
def replace_subplan_by(object)
|
|
496
|
+
raise NotImplementedError, "#{self.class} did not reimplement #replace_subplan_by"
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
# Replaces +self+ by +object+ in all graphs +self+ is part of.
|
|
500
|
+
def replace_by(object)
|
|
501
|
+
raise NotImplementedError, "#{self.class} did not reimplement #replace_by"
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
# Called by #replace_by and #replace_subplan_by to do object-specific
|
|
505
|
+
# initialization of +object+ when +object+ is used to replace +self+ in
|
|
506
|
+
# a plan
|
|
507
|
+
#
|
|
508
|
+
# The default implementation does nothing
|
|
509
|
+
def initialize_replacement(object)
|
|
510
|
+
finalization_handlers.each do |handler|
|
|
511
|
+
if handler.copy_on_replace?
|
|
512
|
+
object ||= yield
|
|
513
|
+
object.when_finalized(handler.as_options, &handler.block)
|
|
514
|
+
end
|
|
515
|
+
end
|
|
516
|
+
end
|
|
517
|
+
|
|
518
|
+
# True if this object can be modified by the local plan manager
|
|
519
|
+
def read_write?
|
|
520
|
+
if self_owned?
|
|
521
|
+
true
|
|
522
|
+
elsif plan.self_owned?
|
|
523
|
+
owners.all? { |p| plan.owned_by?(p) }
|
|
524
|
+
end
|
|
525
|
+
end
|
|
526
|
+
|
|
527
|
+
# @return [Array<InstanceHandler>] set of finalization handlers defined
|
|
528
|
+
# on this task instance
|
|
529
|
+
# @see when_finalized
|
|
530
|
+
attr_reader :finalization_handlers
|
|
531
|
+
|
|
532
|
+
# Enumerates the finalization handlers that should be applied in
|
|
533
|
+
# finalized!
|
|
534
|
+
#
|
|
535
|
+
# @yieldparam [#call] block the handler's block
|
|
536
|
+
# @return [void]
|
|
537
|
+
def each_finalization_handler(&block)
|
|
538
|
+
finalization_handlers.each do |handler|
|
|
539
|
+
yield(handler.block)
|
|
540
|
+
end
|
|
541
|
+
self.class.each_finalization_handler do |model_handler|
|
|
542
|
+
model_handler.bind(self).call(&block)
|
|
543
|
+
end
|
|
544
|
+
end
|
|
545
|
+
|
|
546
|
+
# Called when a particular object has been removed from its plan
|
|
547
|
+
#
|
|
548
|
+
# If PlanObject.debug_finalization_place? is true (set with
|
|
549
|
+
# {PlanObject.debug_finalization_place=}, the backtrace in this call is
|
|
550
|
+
# stored in {PlanObject#removed_at}. It is false by default, as it is
|
|
551
|
+
# pretty expensive.
|
|
552
|
+
#
|
|
553
|
+
# @param [Time,nil] timestamp the time at which it got finalized. It is stored in
|
|
554
|
+
# {#finalization_time}
|
|
555
|
+
# @return [void]
|
|
556
|
+
def finalized!(timestamp = nil)
|
|
557
|
+
if self.plan.executable?
|
|
558
|
+
# call finalization handlers
|
|
559
|
+
each_finalization_handler do |handler|
|
|
560
|
+
handler.call(self)
|
|
561
|
+
end
|
|
562
|
+
end
|
|
563
|
+
|
|
564
|
+
if root_object?
|
|
565
|
+
self.plan = nil
|
|
566
|
+
if PlanObject.debug_finalization_place?
|
|
567
|
+
self.removed_at = caller
|
|
568
|
+
else
|
|
569
|
+
self.removed_at = []
|
|
570
|
+
end
|
|
571
|
+
self.finalization_time = timestamp || Time.now
|
|
572
|
+
self.finalized = true
|
|
573
|
+
end
|
|
574
|
+
end
|
|
575
|
+
|
|
576
|
+
# Called when the task gets finalized, i.e. removed from the main plan
|
|
577
|
+
#
|
|
578
|
+
# @option options [:copy,:drop] :on_replace (:drop) behaviour to be
|
|
579
|
+
# followed when the task gets replaced. If :drop, the handler is not
|
|
580
|
+
# passed, if :copy it is installed on the new task as well as kept on
|
|
581
|
+
# the old one
|
|
582
|
+
# @yieldparam [Roby::Task] task the task that got finalized. It might be
|
|
583
|
+
# different than the one on which the handler got installed because of
|
|
584
|
+
# replacements
|
|
585
|
+
# @return [void]
|
|
586
|
+
def when_finalized(options = Hash.new, &block)
|
|
587
|
+
options = InstanceHandler.validate_options options
|
|
588
|
+
check_arity(block, 1)
|
|
589
|
+
finalization_handlers << InstanceHandler.new(block, (options[:on_replace] == :copy))
|
|
590
|
+
end
|
|
591
|
+
|
|
592
|
+
# True if this plan object has been finalized (i.e. removed from plan),
|
|
593
|
+
# or false otherwise
|
|
594
|
+
attr_predicate :finalized?, true
|
|
595
|
+
|
|
596
|
+
# The time at which this plan object has been added into its first plan
|
|
597
|
+
attr_accessor :addition_time
|
|
598
|
+
|
|
599
|
+
# The time at which this plan object has been finalized (i.e. removed
|
|
600
|
+
# from plan), or nil if it has not been (yet)
|
|
601
|
+
attr_accessor :finalization_time
|
|
602
|
+
|
|
603
|
+
# @return [Boolean] true if this object provides all the given models
|
|
604
|
+
def fullfills?(models)
|
|
605
|
+
Array(models).all? do |m|
|
|
606
|
+
self.model <= m
|
|
607
|
+
end
|
|
608
|
+
end
|
|
609
|
+
end
|
|
610
|
+
end
|
|
611
|
+
|