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,149 @@
|
|
|
1
|
+
module Roby
|
|
2
|
+
module Queries
|
|
3
|
+
# Object that allows to specify generalized matches on a
|
|
4
|
+
# Roby::LocalizedError object
|
|
5
|
+
class LocalizedErrorMatcher < MatcherBase
|
|
6
|
+
# @return [Class] the exception class that should be matched. It
|
|
7
|
+
# must be a subclass of LocalizedError, and is LocalizedError by
|
|
8
|
+
# default
|
|
9
|
+
attr_reader :model
|
|
10
|
+
# @return [#===] the object that will be used to match the error
|
|
11
|
+
# origin
|
|
12
|
+
attr_reader :failure_point_matcher
|
|
13
|
+
# @return [#===,nil] match object to validate the exception's
|
|
14
|
+
# ExeptionBase#original_exceptions
|
|
15
|
+
attr_reader :original_exception_model
|
|
16
|
+
|
|
17
|
+
def initialize
|
|
18
|
+
super
|
|
19
|
+
@model = LocalizedError
|
|
20
|
+
@failure_point_matcher = Queries.any
|
|
21
|
+
@original_exception_model = nil
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Specifies which subclass of LocalizedError this matcher should
|
|
25
|
+
# look for
|
|
26
|
+
# @return self
|
|
27
|
+
def with_model(model)
|
|
28
|
+
@model = model
|
|
29
|
+
self
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Specifies that the exception object should have an
|
|
33
|
+
# original_exception registered of the given model
|
|
34
|
+
#
|
|
35
|
+
# Set to nil to allow for no original exception at all
|
|
36
|
+
def with_original_exception(model)
|
|
37
|
+
if model.respond_to?(:exception_matcher)
|
|
38
|
+
@original_exception_model = model.exception_matcher
|
|
39
|
+
else
|
|
40
|
+
@original_exception_model = model
|
|
41
|
+
end
|
|
42
|
+
self
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Specifies a match on the error origin
|
|
46
|
+
#
|
|
47
|
+
# The resulting match is extended, i.e. a task matcher will match
|
|
48
|
+
# the origin's task event if the origin itself is an event.
|
|
49
|
+
#
|
|
50
|
+
# @return self
|
|
51
|
+
def with_origin(plan_object_matcher)
|
|
52
|
+
@failure_point_matcher = plan_object_matcher.match
|
|
53
|
+
if failure_point_matcher.respond_to?(:generalized?) && !plan_object_matcher.respond_to?(:generalized?)
|
|
54
|
+
failure_point_matcher.generalized
|
|
55
|
+
end
|
|
56
|
+
self
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# @return [Boolean] true if the given execution exception object
|
|
60
|
+
# matches self, false otherwise
|
|
61
|
+
def ===(exception)
|
|
62
|
+
if !(model === exception)
|
|
63
|
+
return false
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
if original_exception_model
|
|
67
|
+
original_exception = exception.original_exceptions.
|
|
68
|
+
find { |e| original_exception_model === e }
|
|
69
|
+
if !original_exception
|
|
70
|
+
return false
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
if !exception.failed_task
|
|
75
|
+
if !(failure_point_matcher === exception.failed_generator)
|
|
76
|
+
return false
|
|
77
|
+
end
|
|
78
|
+
elsif failure_point_matcher.respond_to?(:task_matcher)
|
|
79
|
+
if exception.failed_generator
|
|
80
|
+
return false if !(failure_point_matcher === exception.failed_generator)
|
|
81
|
+
else return false
|
|
82
|
+
end
|
|
83
|
+
else
|
|
84
|
+
return false if !(failure_point_matcher === exception.failed_task)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
original_exception || true
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def describe_failed_match(exception)
|
|
91
|
+
if !(model === exception)
|
|
92
|
+
return "exception model #{exception} does not match #{model}"
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
if original_exception_model
|
|
96
|
+
original_exception = exception.original_exceptions.
|
|
97
|
+
find { |e| original_exception_model === e }
|
|
98
|
+
if !original_exception
|
|
99
|
+
if exception.original_exceptions.empty?
|
|
100
|
+
return "expected one of the original exceptions to match #{original_exception_model}, but none are registered"
|
|
101
|
+
else
|
|
102
|
+
return "expected one of the original exceptions to match #{original_exception_model}, but got #{exception.original_exceptions.map(&:to_s).join(", ")}"
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
if !exception.failed_task
|
|
108
|
+
if !(failure_point_matcher === exception.failed_generator)
|
|
109
|
+
return "failure point #{exception.failed_generator} does not match #{failure_point_matcher}"
|
|
110
|
+
end
|
|
111
|
+
elsif failure_point_matcher.respond_to?(:task_matcher)
|
|
112
|
+
if exception.failed_generator
|
|
113
|
+
if !(failure_point_matcher === exception.failed_generator)
|
|
114
|
+
return "failure point #{exception.failed_generator} does not match #{failure_point_matcher}"
|
|
115
|
+
end
|
|
116
|
+
else
|
|
117
|
+
return "exception reports no failure generator but was expected to"
|
|
118
|
+
end
|
|
119
|
+
elsif !(failure_point_matcher === exception.failed_task)
|
|
120
|
+
return "failure point #{exception.failed_task} does not match #{failure_point_matcher}"
|
|
121
|
+
end
|
|
122
|
+
nil
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def to_s
|
|
126
|
+
description = "#{model}.with_origin(#{failure_point_matcher})"
|
|
127
|
+
if original_exception_model
|
|
128
|
+
description.concat(".with_original_exception(#{original_exception_model})")
|
|
129
|
+
end
|
|
130
|
+
description
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def matches_task?(task)
|
|
134
|
+
if failure_point_matcher.respond_to?(:task_matcher)
|
|
135
|
+
failure_point_matcher.task_matcher == task
|
|
136
|
+
else failure_point_matcher === task
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
match_predicate :fatal?
|
|
141
|
+
|
|
142
|
+
def to_execution_exception_matcher
|
|
143
|
+
Roby::Queries::ExecutionExceptionMatcher.new.with_exception(self)
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
module Roby
|
|
2
|
+
module Queries
|
|
3
|
+
class MatcherBase
|
|
4
|
+
# Returns true if calling #filter with a task set and a relevant
|
|
5
|
+
# index will return the exact query result or not
|
|
6
|
+
def indexed_query?; false end
|
|
7
|
+
|
|
8
|
+
# Enumerates all tasks of +plan+ which match this TaskMatcher object
|
|
9
|
+
#
|
|
10
|
+
# It is O(N). You should prefer use Query which uses the plan's task
|
|
11
|
+
# indexes, thus leading to O(1) in simple cases.
|
|
12
|
+
def each(plan)
|
|
13
|
+
return enum_for(__method__, plan) if !block_given?
|
|
14
|
+
plan.each_task do |t|
|
|
15
|
+
yield(t) if self === t
|
|
16
|
+
end
|
|
17
|
+
self
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Negates this predicate
|
|
21
|
+
#
|
|
22
|
+
# The returned task matcher will yield tasks that are *not* matched by
|
|
23
|
+
# +self+
|
|
24
|
+
def negate; NotMatcher.new(self) end
|
|
25
|
+
# AND-combination of two predicates
|
|
26
|
+
#
|
|
27
|
+
# The returned task matcher will yield tasks that are matched by both
|
|
28
|
+
# predicates.
|
|
29
|
+
def &(other); AndMatcher.new(self, other) end
|
|
30
|
+
# OR-combination of two predicates
|
|
31
|
+
#
|
|
32
|
+
# The returned task matcher will yield tasks that match either one
|
|
33
|
+
# predicate or the other.
|
|
34
|
+
def |(other); OrMatcher.new(self, other) end
|
|
35
|
+
|
|
36
|
+
# Set of predicates that should be true for the object
|
|
37
|
+
# @return [Array<Symbol>]
|
|
38
|
+
attr_reader :predicates
|
|
39
|
+
|
|
40
|
+
# Set of predicats that should be false for the object
|
|
41
|
+
#
|
|
42
|
+
# The predicates are predicate method names (e.g. 'executable' for #executable?)
|
|
43
|
+
#
|
|
44
|
+
# @return [Array<Symbol>]
|
|
45
|
+
attr_reader :neg_predicates
|
|
46
|
+
|
|
47
|
+
class << self
|
|
48
|
+
def declare_class_methods(*names) # :nodoc:
|
|
49
|
+
names.each do |name|
|
|
50
|
+
raise "no instance method #{name} on #{self}" unless method_defined?(name)
|
|
51
|
+
singleton_class.send(:define_method, name) do |*args|
|
|
52
|
+
self.new.send(name, *args)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def match_predicate(name)
|
|
58
|
+
method_name = name.to_s.gsub(/\?$/, '')
|
|
59
|
+
class_eval <<-EOD, __FILE__, __LINE__+1
|
|
60
|
+
def #{method_name}
|
|
61
|
+
if neg_predicates.include?(:#{name})
|
|
62
|
+
raise ArgumentError, "trying to match (#{name} & !#{name})"
|
|
63
|
+
end
|
|
64
|
+
predicates << :#{name}
|
|
65
|
+
self
|
|
66
|
+
end
|
|
67
|
+
def not_#{method_name}
|
|
68
|
+
if predicates.include?(:#{name})
|
|
69
|
+
raise ArgumentError, "trying to match (#{name} & !#{name})"
|
|
70
|
+
end
|
|
71
|
+
neg_predicates << :#{name}
|
|
72
|
+
self
|
|
73
|
+
end
|
|
74
|
+
EOD
|
|
75
|
+
declare_class_methods(method_name, "not_#{method_name}")
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# For each name in +names+, define a #name and a #not_name method.
|
|
79
|
+
# If the first is called, the matcher will match only tasks whose
|
|
80
|
+
# #name? method returns true. If the second is called, the
|
|
81
|
+
# opposite will be done.
|
|
82
|
+
def match_predicates(*names)
|
|
83
|
+
names.each do |name|
|
|
84
|
+
match_predicate(name)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# The {#match} method is used to convert any object to the
|
|
90
|
+
# corresponding Query object. For instance, Models::TaskEvent#match
|
|
91
|
+
# returns the corresponding TaskEventGeneratorMatcher.
|
|
92
|
+
#
|
|
93
|
+
# For matchers, it returns self
|
|
94
|
+
def match
|
|
95
|
+
self
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Describe a failed match in a human-readable way
|
|
99
|
+
#
|
|
100
|
+
# It is meant to help debugging in tests
|
|
101
|
+
#
|
|
102
|
+
# @return [nil,String]
|
|
103
|
+
def describe_failed_match(exception)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Roby
|
|
2
|
+
module Queries
|
|
3
|
+
# Implementation of a singleton object that matches no other object
|
|
4
|
+
module None
|
|
5
|
+
# @return [Boolean] match operator, always returns false
|
|
6
|
+
def self.===(other)
|
|
7
|
+
false
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class DRoby
|
|
11
|
+
def proxy(peer)
|
|
12
|
+
Queries.none
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
def self.droby_dump(peer)
|
|
16
|
+
DRoby.new
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# @return [None] an object that matches nothing
|
|
21
|
+
def self.none
|
|
22
|
+
None
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Roby
|
|
2
|
+
module Queries
|
|
3
|
+
|
|
4
|
+
# Negate a given task-matching predicate
|
|
5
|
+
#
|
|
6
|
+
# This matcher will match if the underlying predicate does not match.
|
|
7
|
+
class NotMatcher < MatcherBase
|
|
8
|
+
# Create a new TaskMatcher which matches if and only if +op+ does not
|
|
9
|
+
def initialize(op)
|
|
10
|
+
@op = op
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Filters as much as non-matching tasks as possible out of +task_set+,
|
|
14
|
+
# based on the information in +task_index+
|
|
15
|
+
def filter(initial_set, task_index)
|
|
16
|
+
# WARNING: the value returned by filter is a SUPERSET of the
|
|
17
|
+
# possible values for the query. Therefore, the result of
|
|
18
|
+
# NegateTaskMatcher#filter is NOT
|
|
19
|
+
#
|
|
20
|
+
# initial_set - @op.filter(...)
|
|
21
|
+
initial_set
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# True if the task matches at least one of the underlying predicates
|
|
25
|
+
def ===(task)
|
|
26
|
+
!(@op === task)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module Roby
|
|
2
|
+
module Queries
|
|
3
|
+
|
|
4
|
+
# Combines multiple task matching predicates through a OR boolean operator.
|
|
5
|
+
# I.e. it will match if any of the underlying predicates match.
|
|
6
|
+
class OrMatcher < MatcherBase
|
|
7
|
+
# Create a new OrMatcher object combining the given predicates.
|
|
8
|
+
def initialize(*ops)
|
|
9
|
+
@ops = ops
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Overload of TaskMatcher#filter
|
|
13
|
+
def filter(task_set, task_index)
|
|
14
|
+
result = Set.new
|
|
15
|
+
for child in @ops
|
|
16
|
+
result.merge child.filter(task_set, task_index)
|
|
17
|
+
end
|
|
18
|
+
result
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Add a new predicate to the combination
|
|
22
|
+
def <<(op); @ops << op end
|
|
23
|
+
|
|
24
|
+
def ===(task)
|
|
25
|
+
@ops.any? { |op| op === task }
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
module Roby
|
|
2
|
+
module Queries
|
|
3
|
+
# Predicate that matches characteristics on a plan object
|
|
4
|
+
class PlanObjectMatcher < MatcherBase
|
|
5
|
+
# @api private
|
|
6
|
+
#
|
|
7
|
+
# The actual instance that should match
|
|
8
|
+
#
|
|
9
|
+
# @return [nil,Object]
|
|
10
|
+
attr_reader :instance
|
|
11
|
+
|
|
12
|
+
# @api private
|
|
13
|
+
#
|
|
14
|
+
# A set of models that should be provided by the object
|
|
15
|
+
#
|
|
16
|
+
# @return [Array<Class>]
|
|
17
|
+
attr_reader :model
|
|
18
|
+
|
|
19
|
+
# @api private
|
|
20
|
+
#
|
|
21
|
+
# Set of owners that the object should have
|
|
22
|
+
#
|
|
23
|
+
# @return [Array<DRobyID>]
|
|
24
|
+
attr_reader :owners
|
|
25
|
+
|
|
26
|
+
# @api private
|
|
27
|
+
#
|
|
28
|
+
# Set of predicates that should be true on the object, and for which
|
|
29
|
+
# the index maintains a set of objects for which it is true
|
|
30
|
+
#
|
|
31
|
+
# @return [Array<Symbol>]
|
|
32
|
+
attr_reader :indexed_predicates
|
|
33
|
+
|
|
34
|
+
# @api private
|
|
35
|
+
#
|
|
36
|
+
# Set of predicates that should be false on the object, and for which
|
|
37
|
+
# the index maintains a set of objects for which it is true
|
|
38
|
+
#
|
|
39
|
+
# @return [Array<Symbol>]
|
|
40
|
+
attr_reader :indexed_neg_predicates
|
|
41
|
+
|
|
42
|
+
# @api private
|
|
43
|
+
#
|
|
44
|
+
# Per-relation list of in-edges that the matched object is expected to have
|
|
45
|
+
#
|
|
46
|
+
# @return [Hash]
|
|
47
|
+
attr_reader :parents
|
|
48
|
+
|
|
49
|
+
# @api private
|
|
50
|
+
#
|
|
51
|
+
# Per relation list of out-edges that the matched object is expected to have
|
|
52
|
+
#
|
|
53
|
+
# @return [Hash]
|
|
54
|
+
attr_reader :children
|
|
55
|
+
|
|
56
|
+
# Initializes an empty TaskMatcher object
|
|
57
|
+
def initialize(instance = nil)
|
|
58
|
+
@instance = instance
|
|
59
|
+
@indexed_query = !@instance
|
|
60
|
+
@model = Array.new
|
|
61
|
+
@predicates = Array.new
|
|
62
|
+
@neg_predicates = Array.new
|
|
63
|
+
@indexed_predicates = Array.new
|
|
64
|
+
@indexed_neg_predicates = Array.new
|
|
65
|
+
@owners = Array.new
|
|
66
|
+
@parents = Hash.new
|
|
67
|
+
@children = Hash.new
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Match an instance explicitely
|
|
71
|
+
def with_instance(instance)
|
|
72
|
+
@instance = instance
|
|
73
|
+
@indexed_query = false
|
|
74
|
+
self
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Filters on ownership
|
|
78
|
+
#
|
|
79
|
+
# Matches if the object is owned by the listed peers.
|
|
80
|
+
#
|
|
81
|
+
# Use #self_owned to match if it is owned by the local plan manager.
|
|
82
|
+
def owned_by(*ids)
|
|
83
|
+
@owners |= ids
|
|
84
|
+
self
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Filters locally-owned tasks
|
|
88
|
+
#
|
|
89
|
+
# Matches if the object is owned by the local plan manager.
|
|
90
|
+
def self_owned
|
|
91
|
+
predicates << :self_owned?
|
|
92
|
+
self
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Filters out locally-owned tasks
|
|
96
|
+
#
|
|
97
|
+
# Matches if the object is owned by the local plan manager.
|
|
98
|
+
def not_self_owned
|
|
99
|
+
neg_predicates << :self_owned?
|
|
100
|
+
self
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Filters on the task model
|
|
104
|
+
#
|
|
105
|
+
# Will match if the task is an instance of +model+ or one of its
|
|
106
|
+
# subclasses.
|
|
107
|
+
def with_model(model)
|
|
108
|
+
@model = Array(model)
|
|
109
|
+
self
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
class << self
|
|
113
|
+
# @api private
|
|
114
|
+
def match_predicate(name, positive_index = nil, negative_index = nil)
|
|
115
|
+
method_name = name.to_s.gsub(/\?$/, '')
|
|
116
|
+
if Index::PREDICATES.include?(name)
|
|
117
|
+
indexed_predicate = true
|
|
118
|
+
positive_index ||= [["#{name}"], []]
|
|
119
|
+
negative_index ||= [[], ["#{name}"]]
|
|
120
|
+
end
|
|
121
|
+
positive_index ||= [[], []]
|
|
122
|
+
negative_index ||= [[], []]
|
|
123
|
+
class_eval <<-EOD, __FILE__, __LINE__+1
|
|
124
|
+
def #{method_name}
|
|
125
|
+
if neg_predicates.include?(:#{name})
|
|
126
|
+
raise ArgumentError, "trying to match (#{name} & !#{name})"
|
|
127
|
+
end
|
|
128
|
+
#{"@indexed_query = false" if !indexed_predicate}
|
|
129
|
+
predicates << :#{name}
|
|
130
|
+
#{if !positive_index[0].empty? then ["indexed_predicates", *positive_index[0]].join(" << :") end}
|
|
131
|
+
#{if !positive_index[1].empty? then ["indexed_neg_predicates", *positive_index[1]].join(" << :") end}
|
|
132
|
+
self
|
|
133
|
+
end
|
|
134
|
+
def not_#{method_name}
|
|
135
|
+
if predicates.include?(:#{name})
|
|
136
|
+
raise ArgumentError, "trying to match (#{name} & !#{name})"
|
|
137
|
+
end
|
|
138
|
+
#{"@indexed_query = false" if !indexed_predicate}
|
|
139
|
+
neg_predicates << :#{name}
|
|
140
|
+
#{if !negative_index[0].empty? then ["indexed_predicates", *negative_index[0]].join(" << :") end}
|
|
141
|
+
#{if !negative_index[1].empty? then ["indexed_neg_predicates", *negative_index[1]].join(" << :") end}
|
|
142
|
+
self
|
|
143
|
+
end
|
|
144
|
+
EOD
|
|
145
|
+
declare_class_methods(method_name, "not_#{method_name}")
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
##
|
|
150
|
+
# :method: executable
|
|
151
|
+
#
|
|
152
|
+
# Matches if the object is executable
|
|
153
|
+
#
|
|
154
|
+
# See also #not_executable, PlanObject#executable?
|
|
155
|
+
|
|
156
|
+
##
|
|
157
|
+
# :method: not_executable
|
|
158
|
+
#
|
|
159
|
+
# Matches if the object is not executable
|
|
160
|
+
#
|
|
161
|
+
# See also #executable, PlanObject#executable?
|
|
162
|
+
|
|
163
|
+
match_predicates :executable?
|
|
164
|
+
|
|
165
|
+
declare_class_methods :with_model, :owned_by, :self_owned
|
|
166
|
+
|
|
167
|
+
# Helper method for #with_child and #with_parent
|
|
168
|
+
def handle_parent_child_arguments(other_query, relation, relation_options) # :nodoc:
|
|
169
|
+
return relation, [other_query.match, relation_options]
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# Filters based on the object's children
|
|
173
|
+
#
|
|
174
|
+
# Matches if this object has at least one child which matches +query+.
|
|
175
|
+
#
|
|
176
|
+
# If +relation+ is given, then only the children in this relation are
|
|
177
|
+
# considered. Moreover, relation options can be used to restrict the
|
|
178
|
+
# search even more.
|
|
179
|
+
#
|
|
180
|
+
# Examples:
|
|
181
|
+
#
|
|
182
|
+
# parent.depends_on(child)
|
|
183
|
+
# TaskMatcher.new.
|
|
184
|
+
# with_child(TaskMatcher.new.pending) === parent # => true
|
|
185
|
+
# TaskMatcher.new.
|
|
186
|
+
# with_child(TaskMatcher.new.pending, Roby::TaskStructure::Dependency) === parent # => true
|
|
187
|
+
# TaskMatcher.new.
|
|
188
|
+
# with_child(TaskMatcher.new.pending, Roby::TaskStructure::PlannedBy) === parent # => false
|
|
189
|
+
#
|
|
190
|
+
# TaskMatcher.new.
|
|
191
|
+
# with_child(TaskMatcher.new.pending,
|
|
192
|
+
# Roby::TaskStructure::Dependency,
|
|
193
|
+
# roles: ["trajectory_following"]) === parent # => false
|
|
194
|
+
# parent.depends_on child, role: "trajectory_following"
|
|
195
|
+
# TaskMatcher.new.
|
|
196
|
+
# with_child(TaskMatcher.new.pending,
|
|
197
|
+
# Roby::TaskStructure::Dependency,
|
|
198
|
+
# roles: ["trajectory_following"]) === parent # => true
|
|
199
|
+
#
|
|
200
|
+
def with_child(other_query, relation = nil, relation_options = nil)
|
|
201
|
+
relation, spec = handle_parent_child_arguments(other_query, relation, relation_options)
|
|
202
|
+
(@children[relation] ||= Array.new) << spec
|
|
203
|
+
@indexed_query = false
|
|
204
|
+
self
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# Filters based on the object's parents
|
|
208
|
+
#
|
|
209
|
+
# Matches if this object has at least one parent which matches +query+.
|
|
210
|
+
#
|
|
211
|
+
# If +relation+ is given, then only the parents in this relation are
|
|
212
|
+
# considered. Moreover, relation options can be used to restrict the
|
|
213
|
+
# search even more.
|
|
214
|
+
#
|
|
215
|
+
# See examples for #with_child
|
|
216
|
+
def with_parent(other_query, relation = nil, relation_options = nil)
|
|
217
|
+
relation, spec = handle_parent_child_arguments(other_query, relation, relation_options)
|
|
218
|
+
(@parents[relation] ||= Array.new) << spec
|
|
219
|
+
@indexed_query = false
|
|
220
|
+
self
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# Helper method for handling parent/child matches in #===
|
|
224
|
+
def handle_parent_child_match(object, match_spec) # :nodoc:
|
|
225
|
+
relation, matchers = *match_spec
|
|
226
|
+
return false if !relation && object.relations.empty?
|
|
227
|
+
for match_spec in matchers
|
|
228
|
+
m, relation_options = *match_spec
|
|
229
|
+
if relation
|
|
230
|
+
if !yield(relation, m, relation_options)
|
|
231
|
+
return false
|
|
232
|
+
end
|
|
233
|
+
else
|
|
234
|
+
result = object.relations.any? do |rel|
|
|
235
|
+
yield(rel, m, relation_options)
|
|
236
|
+
end
|
|
237
|
+
return false if !result
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
true
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# Returns true if filtering with this TaskMatcher using #=== is
|
|
244
|
+
# equivalent to calling #filter() using a Index. This is used to
|
|
245
|
+
# avoid an explicit O(N) filtering step after filter() has been called
|
|
246
|
+
def indexed_query?
|
|
247
|
+
@indexed_query
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
def to_s
|
|
251
|
+
description =
|
|
252
|
+
if instance
|
|
253
|
+
instance.to_s
|
|
254
|
+
elsif model.size == 1
|
|
255
|
+
model.first.to_s
|
|
256
|
+
else
|
|
257
|
+
"(#{model.map(&:to_s).join(",")})"
|
|
258
|
+
end
|
|
259
|
+
([description] + predicates.map(&:to_s) + neg_predicates.map { |p| "not_#{p}" }).join(".")
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
# Tests whether the given object matches this predicate
|
|
264
|
+
#
|
|
265
|
+
# @param [PlanObject] object the object to match
|
|
266
|
+
# @return [Boolean]
|
|
267
|
+
def ===(object)
|
|
268
|
+
if instance
|
|
269
|
+
return false if object != instance
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
if !model.empty?
|
|
273
|
+
return unless object.fullfills?(model)
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
for parent_spec in @parents
|
|
277
|
+
result = handle_parent_child_match(object, parent_spec) do |relation, m, relation_options|
|
|
278
|
+
object.each_parent_object(relation).
|
|
279
|
+
any? { |parent| m === parent && (!relation_options || relation_options === parent[object, relation]) }
|
|
280
|
+
end
|
|
281
|
+
return false if !result
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
for child_spec in @children
|
|
285
|
+
result = handle_parent_child_match(object, child_spec) do |relation, m, relation_options|
|
|
286
|
+
object.each_child_object(relation).
|
|
287
|
+
any? { |child| m === child && (!relation_options || relation_options === object[child, relation]) }
|
|
288
|
+
end
|
|
289
|
+
return false if !result
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
for pred in predicates
|
|
293
|
+
return false if !object.send(pred)
|
|
294
|
+
end
|
|
295
|
+
for pred in neg_predicates
|
|
296
|
+
return false if object.send(pred)
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
return false if !owners.empty? && !(object.owners - owners).empty?
|
|
300
|
+
true
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
# @api private
|
|
304
|
+
#
|
|
305
|
+
# Resolve the indexed sets needed to filter an initial set in {#filter}
|
|
306
|
+
#
|
|
307
|
+
# @return [(Set,Set)] the positive (intersection) and
|
|
308
|
+
# negative (difference) sets
|
|
309
|
+
def indexed_sets(index)
|
|
310
|
+
positive_sets = []
|
|
311
|
+
for m in @model
|
|
312
|
+
positive_sets << index.by_model[m]
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
for o in @owners
|
|
316
|
+
if candidates = index.by_owner[o]
|
|
317
|
+
positive_sets << candidates
|
|
318
|
+
else
|
|
319
|
+
return [Set.new, Set.new]
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
for pred in @indexed_predicates
|
|
324
|
+
positive_sets << index.by_predicate[pred]
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
negative_sets = @indexed_neg_predicates.
|
|
328
|
+
map { |pred| index.by_predicate[pred] }
|
|
329
|
+
|
|
330
|
+
return positive_sets, negative_sets
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
# Filters the tasks in +initial_set+ by using the information in
|
|
334
|
+
# +index+, and returns the result. The resulting set must
|
|
335
|
+
# include all tasks in +initial_set+ which match with #===, but can
|
|
336
|
+
# include tasks which do not match #===
|
|
337
|
+
#
|
|
338
|
+
# @param [Set] initial_set
|
|
339
|
+
# @param [Index] index
|
|
340
|
+
# @return [Set]
|
|
341
|
+
def filter(initial_set, index, initial_is_complete: false)
|
|
342
|
+
positive_sets, negative_sets = indexed_sets(index)
|
|
343
|
+
positive_sets << initial_set if !initial_is_complete || positive_sets.empty?
|
|
344
|
+
|
|
345
|
+
negative = negative_sets.shift || Set.new
|
|
346
|
+
if negative_sets.size > 1
|
|
347
|
+
negative = negative.dup
|
|
348
|
+
negative_sets.each { |set| negative.merge(set) }
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
positive_sets = positive_sets.sort_by(&:size)
|
|
352
|
+
|
|
353
|
+
result = Set.new
|
|
354
|
+
result.compare_by_identity
|
|
355
|
+
positive_sets.shift.each do |obj|
|
|
356
|
+
result.add(obj) if !negative.include?(obj) && positive_sets.all? { |set| set.include?(obj) }
|
|
357
|
+
end
|
|
358
|
+
return result
|
|
359
|
+
end
|
|
360
|
+
end
|
|
361
|
+
end
|
|
362
|
+
end
|
|
363
|
+
|