roby 0.7.3 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +7 -5
- data/Manifest.txt +91 -16
- data/README.txt +24 -24
- data/Rakefile +92 -64
- data/app/config/app.yml +42 -43
- data/app/config/init.rb +26 -0
- data/benchmark/alloc_misc.rb +123 -0
- data/benchmark/discovery_latency.rb +67 -0
- data/benchmark/garbage_collection.rb +48 -0
- data/benchmark/genom.rb +31 -0
- data/benchmark/transactions.rb +62 -0
- data/bin/roby +1 -1
- data/bin/roby-log +16 -6
- data/doc/guide/.gitignore +2 -0
- data/doc/guide/config.yaml +34 -0
- data/doc/guide/ext/init.rb +14 -0
- data/doc/guide/ext/previous_next.rb +40 -0
- data/doc/guide/ext/rdoc_links.rb +33 -0
- data/doc/guide/index.rdoc +16 -0
- data/doc/guide/overview.rdoc +62 -0
- data/doc/guide/plan_modifications.rdoc +67 -0
- data/doc/guide/src/abstraction/achieve_with.page +8 -0
- data/doc/guide/src/abstraction/forwarding.page +8 -0
- data/doc/guide/src/abstraction/hierarchy.page +19 -0
- data/doc/guide/src/abstraction/index.page +28 -0
- data/doc/guide/src/abstraction/task_models.page +13 -0
- data/doc/guide/src/basics.template +6 -0
- data/doc/guide/src/basics/app.page +139 -0
- data/doc/guide/src/basics/code_examples.page +33 -0
- data/doc/guide/src/basics/dry.page +69 -0
- data/doc/guide/src/basics/errors.page +443 -0
- data/doc/guide/src/basics/events.page +179 -0
- data/doc/guide/src/basics/hierarchy.page +275 -0
- data/doc/guide/src/basics/index.page +11 -0
- 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_4.png +0 -0
- data/doc/guide/src/basics/log_replay/goForward_5.png +0 -0
- data/doc/guide/src/basics/log_replay/hierarchy_error_1.png +0 -0
- data/doc/guide/src/basics/log_replay/hierarchy_error_2.png +0 -0
- data/doc/guide/src/basics/log_replay/hierarchy_error_3.png +0 -0
- data/doc/guide/src/basics/log_replay/plan_repair_1.png +0 -0
- data/doc/guide/src/basics/log_replay/plan_repair_2.png +0 -0
- data/doc/guide/src/basics/log_replay/plan_repair_3.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/log_replay/roby_log_relation_window.png +0 -0
- data/doc/guide/src/basics/log_replay/roby_replay_event_representation.png +0 -0
- data/doc/guide/src/basics/plan_objects.page +71 -0
- data/doc/guide/src/basics/relations_display.page +203 -0
- data/doc/guide/src/basics/roby_cycle_overview.png +0 -0
- data/doc/guide/src/basics/shell.page +102 -0
- data/doc/guide/src/basics/summary.page +32 -0
- data/doc/guide/src/basics/tasks.page +357 -0
- data/doc/guide/src/basics_shell_header.txt +16 -0
- data/doc/guide/src/cycle/cycle-overview.png +0 -0
- data/doc/guide/src/cycle/cycle-overview.svg +208 -0
- data/doc/guide/src/cycle/error_handling.page +168 -0
- data/doc/guide/src/cycle/error_instantaneous_repair.png +0 -0
- data/doc/guide/src/cycle/error_instantaneous_repair.svg +1224 -0
- data/doc/guide/src/cycle/garbage_collection.page +10 -0
- data/doc/guide/src/cycle/index.page +23 -0
- data/doc/guide/src/cycle/propagation.page +154 -0
- data/doc/guide/src/cycle/propagation_diamond.png +0 -0
- data/doc/guide/src/cycle/propagation_diamond.svg +1279 -0
- data/doc/guide/src/default.css +319 -0
- data/doc/guide/src/default.template +74 -0
- data/doc/guide/src/htmldoc.metainfo +20 -0
- data/doc/guide/src/htmldoc.virtual +18 -0
- data/doc/guide/src/images/bodybg.png +0 -0
- data/doc/guide/src/images/contbg.png +0 -0
- data/doc/guide/src/images/footerbg.png +0 -0
- data/doc/guide/src/images/gradient1.png +0 -0
- data/doc/guide/src/images/gradient2.png +0 -0
- data/doc/guide/src/index.page +7 -0
- data/doc/guide/src/introduction/index.page +29 -0
- data/doc/guide/src/introduction/install.page +133 -0
- data/doc/{papers.rdoc → guide/src/introduction/publications.page} +5 -2
- data/doc/{videos.rdoc → guide/src/introduction/videos.page} +4 -2
- data/doc/guide/src/plugins/fault_tolerance.page +44 -0
- data/doc/guide/src/plugins/index.page +11 -0
- data/doc/guide/src/plugins/subsystems.page +45 -0
- data/doc/guide/src/relations/dependency.page +89 -0
- data/doc/guide/src/relations/index.page +12 -0
- data/doc/misc/update_github +24 -0
- data/doc/tutorials/02-GoForward.rdoc +3 -3
- data/ext/graph/graph.cc +46 -0
- data/lib/roby.rb +57 -22
- data/lib/roby/app.rb +132 -112
- data/lib/roby/app/plugins/rake.rb +21 -0
- data/lib/roby/app/rake.rb +0 -7
- data/lib/roby/app/run.rb +1 -1
- data/lib/roby/app/scripts/distributed.rb +1 -2
- data/lib/roby/app/scripts/generate/bookmarks.rb +1 -1
- data/lib/roby/app/scripts/results.rb +2 -1
- data/lib/roby/app/scripts/run.rb +6 -2
- data/lib/roby/app/scripts/shell.rb +11 -11
- data/lib/roby/config.rb +1 -1
- data/lib/roby/decision_control.rb +62 -3
- data/lib/roby/distributed.rb +4 -0
- data/lib/roby/distributed/base.rb +8 -0
- data/lib/roby/distributed/communication.rb +12 -8
- data/lib/roby/distributed/connection_space.rb +61 -44
- data/lib/roby/distributed/distributed_object.rb +1 -1
- data/lib/roby/distributed/notifications.rb +22 -30
- data/lib/roby/distributed/peer.rb +13 -8
- data/lib/roby/distributed/proxy.rb +5 -5
- data/lib/roby/distributed/subscription.rb +4 -4
- data/lib/roby/distributed/transaction.rb +3 -3
- data/lib/roby/event.rb +176 -110
- data/lib/roby/exceptions.rb +12 -4
- data/lib/roby/execution_engine.rb +1604 -0
- data/lib/roby/external_process_task.rb +225 -0
- data/lib/roby/graph.rb +0 -6
- data/lib/roby/interface.rb +221 -137
- data/lib/roby/log/console.rb +5 -3
- data/lib/roby/log/data_stream.rb +94 -16
- data/lib/roby/log/dot.rb +8 -8
- data/lib/roby/log/event_stream.rb +13 -3
- data/lib/roby/log/file.rb +43 -18
- data/lib/roby/log/gui/basic_display_ui.rb +89 -0
- data/lib/roby/log/gui/chronicle_view_ui.rb +90 -0
- data/lib/roby/log/gui/data_displays.rb +4 -5
- data/lib/roby/log/gui/data_displays_ui.rb +146 -0
- data/lib/roby/log/gui/relations.rb +18 -18
- data/lib/roby/log/gui/relations_ui.rb +120 -0
- data/lib/roby/log/gui/relations_view_ui.rb +144 -0
- data/lib/roby/log/gui/replay.rb +41 -13
- data/lib/roby/log/gui/replay_controls.rb +3 -0
- data/lib/roby/log/gui/replay_controls.ui +133 -110
- data/lib/roby/log/gui/replay_controls_ui.rb +249 -0
- data/lib/roby/log/hooks.rb +19 -18
- data/lib/roby/log/logger.rb +7 -6
- data/lib/roby/log/notifications.rb +4 -4
- data/lib/roby/log/plan_rebuilder.rb +20 -22
- data/lib/roby/log/relations.rb +44 -16
- data/lib/roby/log/server.rb +1 -4
- data/lib/roby/log/timings.rb +88 -19
- data/lib/roby/plan-object.rb +135 -11
- data/lib/roby/plan.rb +408 -224
- data/lib/roby/planning/loops.rb +32 -25
- data/lib/roby/planning/model.rb +157 -51
- data/lib/roby/planning/task.rb +47 -20
- data/lib/roby/query.rb +128 -92
- data/lib/roby/relations.rb +254 -136
- data/lib/roby/relations/conflicts.rb +6 -9
- data/lib/roby/relations/dependency.rb +358 -0
- data/lib/roby/relations/ensured.rb +0 -1
- data/lib/roby/relations/error_handling.rb +0 -1
- data/lib/roby/relations/events.rb +0 -2
- data/lib/roby/relations/executed_by.rb +26 -11
- data/lib/roby/relations/planned_by.rb +14 -14
- data/lib/roby/robot.rb +46 -0
- data/lib/roby/schedulers/basic.rb +34 -0
- data/lib/roby/standalone.rb +4 -0
- data/lib/roby/standard_errors.rb +21 -15
- data/lib/roby/state/events.rb +5 -4
- data/lib/roby/support.rb +107 -6
- data/lib/roby/task-operations.rb +23 -19
- data/lib/roby/task.rb +522 -148
- data/lib/roby/task_index.rb +80 -0
- data/lib/roby/test/common.rb +283 -44
- data/lib/roby/test/distributed.rb +53 -37
- data/lib/roby/test/testcase.rb +9 -204
- data/lib/roby/test/tools.rb +3 -3
- data/lib/roby/transactions.rb +154 -111
- data/lib/roby/transactions/proxy.rb +40 -7
- data/manifest.xml +20 -0
- data/plugins/fault_injection/README.txt +0 -3
- data/plugins/fault_injection/Rakefile +2 -8
- data/plugins/fault_injection/app.rb +1 -1
- data/plugins/fault_injection/fault_injection.rb +3 -3
- data/plugins/fault_injection/test/test_fault_injection.rb +19 -25
- data/plugins/subsystems/README.txt +0 -3
- data/plugins/subsystems/Rakefile +2 -7
- data/plugins/subsystems/app.rb +27 -16
- data/plugins/subsystems/test/app/config/init.rb +3 -0
- data/plugins/subsystems/test/app/planners/main.rb +1 -1
- data/plugins/subsystems/test/app/tasks/services.rb +1 -1
- data/plugins/subsystems/test/test_subsystems.rb +23 -16
- data/test/distributed/test_communication.rb +32 -15
- data/test/distributed/test_connection.rb +28 -26
- data/test/distributed/test_execution.rb +59 -54
- data/test/distributed/test_mixed_plan.rb +34 -34
- data/test/distributed/test_plan_notifications.rb +26 -26
- data/test/distributed/test_protocol.rb +57 -48
- data/test/distributed/test_query.rb +11 -7
- data/test/distributed/test_remote_plan.rb +71 -71
- data/test/distributed/test_transaction.rb +50 -47
- data/test/mockups/external_process +28 -0
- data/test/planning/test_loops.rb +163 -119
- data/test/planning/test_model.rb +3 -3
- data/test/planning/test_task.rb +27 -7
- data/test/relations/test_conflicts.rb +3 -3
- data/test/relations/test_dependency.rb +324 -0
- data/test/relations/test_ensured.rb +2 -2
- data/test/relations/test_executed_by.rb +94 -19
- data/test/relations/test_planned_by.rb +11 -9
- data/test/suite_core.rb +6 -3
- data/test/suite_distributed.rb +1 -0
- data/test/suite_planning.rb +1 -0
- data/test/suite_relations.rb +2 -2
- data/test/tasks/test_external_process.rb +126 -0
- data/test/{test_thread_task.rb → tasks/test_thread_task.rb} +17 -20
- data/test/test_bgl.rb +21 -1
- data/test/test_event.rb +229 -155
- data/test/test_exceptions.rb +79 -80
- data/test/test_execution_engine.rb +987 -0
- data/test/test_gui.rb +1 -1
- data/test/test_interface.rb +11 -5
- data/test/test_log.rb +18 -7
- data/test/test_log_server.rb +1 -0
- data/test/test_plan.rb +229 -395
- data/test/test_query.rb +193 -35
- data/test/test_relations.rb +88 -8
- data/test/test_state.rb +55 -37
- data/test/test_support.rb +1 -1
- data/test/test_task.rb +371 -218
- data/test/test_testcase.rb +32 -16
- data/test/test_transactions.rb +211 -170
- data/test/test_transactions_proxy.rb +37 -19
- metadata +169 -71
- data/.gitignore +0 -29
- data/doc/styles/allison.css +0 -314
- data/doc/styles/allison.js +0 -316
- data/doc/styles/allison.rb +0 -276
- data/doc/styles/jamis.rb +0 -593
- data/lib/roby/control.rb +0 -746
- data/lib/roby/executives/simple.rb +0 -30
- data/lib/roby/propagation.rb +0 -562
- data/lib/roby/relations/hierarchy.rb +0 -239
- data/lib/roby/transactions/updates.rb +0 -139
- data/test/relations/test_hierarchy.rb +0 -158
- data/test/test_control.rb +0 -399
- data/test/test_propagation.rb +0 -210
data/lib/roby/transactions.rb
CHANGED
@@ -1,8 +1,3 @@
|
|
1
|
-
require 'roby/plan'
|
2
|
-
require 'utilrb/value_set'
|
3
|
-
require 'utilrb/kernel/swap'
|
4
|
-
require 'roby/transactions/proxy'
|
5
|
-
|
6
1
|
module Roby
|
7
2
|
# Exception raised when someone tries do commit an invalid transaction
|
8
3
|
class InvalidTransaction < RuntimeError; end
|
@@ -15,7 +10,8 @@ module Roby
|
|
15
10
|
|
16
11
|
# A transaction is not an executable plan
|
17
12
|
def executable?; false end
|
18
|
-
|
13
|
+
attr_predicate :freezed
|
14
|
+
attr_predicate :committed
|
19
15
|
|
20
16
|
def do_wrap(object, do_include = false) # :nodoc:
|
21
17
|
raise "transaction #{self} has been either committed or discarded. No modification allowed" if freezed?
|
@@ -23,7 +19,7 @@ module Roby
|
|
23
19
|
proxy = proxy_objects[object] = Proxy.proxy_class(object).new(object, self)
|
24
20
|
if do_include && object.root_object?
|
25
21
|
proxy.plan = self
|
26
|
-
|
22
|
+
add(proxy)
|
27
23
|
end
|
28
24
|
|
29
25
|
copy_object_relations(object, proxy)
|
@@ -38,7 +34,7 @@ module Roby
|
|
38
34
|
# This method copies on +proxy+ all relations of +object+ for which
|
39
35
|
# both ends of the relation are already in the transaction.
|
40
36
|
def copy_object_relations(object, proxy)
|
41
|
-
Roby
|
37
|
+
Roby.synchronize do
|
42
38
|
# Create edges between the neighbours that are really in the transaction
|
43
39
|
object.each_relation do |rel|
|
44
40
|
object.each_parent_object(rel) do |parent|
|
@@ -63,17 +59,19 @@ module Roby
|
|
63
59
|
elsif proxy = proxy_objects[object] then return proxy
|
64
60
|
end
|
65
61
|
|
62
|
+
if !object.plan && !object.finalized?
|
63
|
+
object.plan = self
|
64
|
+
add(object)
|
65
|
+
return object
|
66
|
+
end
|
67
|
+
|
66
68
|
if create
|
67
|
-
if
|
68
|
-
object.plan = self
|
69
|
-
discover(object)
|
70
|
-
return object
|
71
|
-
elsif object.plan == self.plan
|
69
|
+
if object.plan == self.plan
|
72
70
|
wrapped = do_wrap(object, true)
|
73
71
|
if plan.mission?(object)
|
74
|
-
|
72
|
+
add_mission(wrapped)
|
75
73
|
elsif plan.permanent?(object)
|
76
|
-
|
74
|
+
add_permanent(wrapped)
|
77
75
|
end
|
78
76
|
return wrapped
|
79
77
|
else
|
@@ -81,41 +79,20 @@ module Roby
|
|
81
79
|
end
|
82
80
|
end
|
83
81
|
nil
|
84
|
-
elsif object.respond_to?(:
|
82
|
+
elsif object.respond_to?(:to_ary)
|
85
83
|
object.map { |o| wrap(o, create) }
|
84
|
+
elsif object.respond_to?(:each)
|
85
|
+
raise ArgumentError, "don't know how to wrap containers of class #{objects.class}"
|
86
86
|
else
|
87
87
|
raise TypeError, "don't know how to wrap #{object || 'nil'} of type #{object.class.ancestors}"
|
88
88
|
end
|
89
89
|
end
|
90
90
|
alias :[] :wrap
|
91
91
|
|
92
|
-
# Remove +proxy+ from this transaction. While #remove_object is also
|
93
|
-
# removing the object from the plan itself, this method only removes it
|
94
|
-
# from the transaction, forgetting all modifications that have been
|
95
|
-
# done on +object+ in the transaction
|
96
|
-
def discard_modifications(object)
|
97
|
-
object = may_unwrap(object)
|
98
|
-
if object.respond_to?(:each_plan_child)
|
99
|
-
object.each_plan_child do |child|
|
100
|
-
discard_modifications(child)
|
101
|
-
end
|
102
|
-
end
|
103
|
-
removed_objects.delete(object)
|
104
|
-
discarded_tasks.delete(object)
|
105
|
-
auto_tasks.delete(object)
|
106
|
-
|
107
|
-
return unless proxy = proxy_objects.delete(object)
|
108
|
-
proxy.clear_vertex
|
109
|
-
|
110
|
-
missions.delete(proxy)
|
111
|
-
known_tasks.delete(proxy)
|
112
|
-
free_events.delete(proxy)
|
113
|
-
end
|
114
|
-
|
115
92
|
def restore_relation(proxy, relation)
|
116
93
|
object = proxy.__getobj__
|
117
94
|
|
118
|
-
|
95
|
+
Roby.synchronize do
|
119
96
|
proxy_children = proxy.child_objects(relation)
|
120
97
|
object.child_objects(relation).each do |object_child|
|
121
98
|
next unless proxy_child = wrap(object_child, false)
|
@@ -133,36 +110,56 @@ module Roby
|
|
133
110
|
end
|
134
111
|
end
|
135
112
|
|
136
|
-
|
113
|
+
added_objects.delete(proxy)
|
137
114
|
proxy.discovered_relations.delete(relation)
|
138
115
|
proxy.do_discover(relation, false)
|
139
116
|
end
|
140
117
|
|
141
|
-
|
118
|
+
# Removes an object from this transaction
|
119
|
+
#
|
120
|
+
# This does *not* remove the object from the underlying plan. Removing
|
121
|
+
# objects directly is (at best) dangerous, and should be handled by
|
122
|
+
# garbage collection.
|
142
123
|
def remove_object(object)
|
143
124
|
raise "transaction #{self} has been either committed or discarded. No modification allowed" if freezed?
|
144
125
|
|
145
126
|
object = may_unwrap(object)
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
127
|
+
proxy = proxy_objects.delete(object)
|
128
|
+
if (proxy || object).plan != self
|
129
|
+
raise InternalError, "inconsistency"
|
130
|
+
end
|
131
|
+
|
132
|
+
if proxy
|
133
|
+
discarded_tasks.delete(object)
|
134
|
+
auto_tasks.delete(object)
|
135
|
+
if proxy.respond_to?(:each_plan_child)
|
136
|
+
proxy.each_plan_child(true) do |child_proxy|
|
137
|
+
auto_tasks.delete(child_proxy)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
proxy ||= object
|
143
|
+
if proxy.root_object?
|
144
|
+
super(proxy)
|
145
|
+
end
|
146
|
+
self
|
159
147
|
end
|
160
148
|
|
161
|
-
def may_wrap(
|
162
|
-
|
149
|
+
def may_wrap(objects, create = true)
|
150
|
+
if objects.respond_to?(:to_ary)
|
151
|
+
objects.map { |obj| may_wrap(obj, create) }
|
152
|
+
elsif objects.respond_to?(:each)
|
153
|
+
raise ArgumentError, "don't know how to wrap containers of class #{objects.class}"
|
154
|
+
elsif objects.kind_of?(PlanObject)
|
155
|
+
wrap(objects, create)
|
156
|
+
else
|
157
|
+
objects
|
158
|
+
end
|
163
159
|
end
|
164
160
|
|
165
|
-
#
|
161
|
+
# If +object+ is in this transaction, may_unwrap will return the
|
162
|
+
# underlying plan object. In all other cases, returns object.
|
166
163
|
def may_unwrap(object)
|
167
164
|
if object.respond_to?(:plan)
|
168
165
|
if object.plan == self && object.respond_to?(:__getobj__)
|
@@ -178,93 +175,94 @@ module Roby
|
|
178
175
|
|
179
176
|
# The list of discarded
|
180
177
|
attr_reader :discarded_tasks
|
181
|
-
# The list of removed tasks and events
|
182
|
-
attr_reader :removed_objects
|
183
178
|
# The list of permanent tasks that have been auto'ed
|
184
179
|
attr_reader :auto_tasks
|
185
180
|
# The plan this transaction applies on
|
186
181
|
attr_reader :plan
|
187
182
|
# The proxy objects built for this transaction
|
188
183
|
attr_reader :proxy_objects
|
189
|
-
|
190
|
-
attr_reader :conflict_solver
|
184
|
+
# The option hash given at initialization
|
191
185
|
attr_reader :options
|
192
186
|
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
SolverUpdateRelations
|
197
|
-
when :invalidate
|
198
|
-
SolverInvalidateTransaction
|
199
|
-
when :ignore
|
200
|
-
SolverIgnoreUpdate.new
|
201
|
-
else value
|
202
|
-
end
|
203
|
-
end
|
187
|
+
# The decision control object associated with this transaction. It is
|
188
|
+
# in general plan.control
|
189
|
+
def control; plan.control end
|
204
190
|
|
205
191
|
# Creates a new transaction which applies on +plan+
|
206
192
|
def initialize(plan, options = {})
|
207
|
-
options = validate_options options,
|
208
|
-
:conflict_solver => :invalidate
|
209
|
-
|
210
193
|
@options = options
|
211
|
-
self.conflict_solver = options[:conflict_solver]
|
212
194
|
super()
|
213
195
|
|
214
|
-
@plan
|
196
|
+
@plan = plan
|
215
197
|
|
216
198
|
@proxy_objects = Hash.new
|
217
|
-
@removed_objects = ValueSet.new
|
218
199
|
@discarded_tasks = ValueSet.new
|
219
200
|
@auto_tasks = ValueSet.new
|
220
201
|
|
221
|
-
Roby
|
202
|
+
Roby.synchronize do
|
222
203
|
plan.transactions << self
|
223
204
|
plan.added_transaction(self)
|
224
205
|
end
|
225
206
|
end
|
226
207
|
|
208
|
+
# Calls the given block in the execution thread of the engine of the
|
209
|
+
# underlying plan. If there is no engine attached to this plan, yields
|
210
|
+
# immediately.
|
211
|
+
#
|
212
|
+
# See Plan#execute and ExecutionEngine#execute
|
213
|
+
def execute(&block)
|
214
|
+
plan.execute(&block)
|
215
|
+
end
|
216
|
+
|
227
217
|
def discover_neighborhood(object)
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
218
|
+
stack = object.transaction_stack
|
219
|
+
object = object.real_object
|
220
|
+
while stack.size > 1
|
221
|
+
plan = stack.pop
|
222
|
+
next_plan = stack.last
|
223
|
+
|
224
|
+
next_plan[object]
|
225
|
+
object.each_relation do |rel|
|
226
|
+
object.each_parent_object(rel) { |obj| next_plan[obj] }
|
227
|
+
object.each_child_object(rel) { |obj| next_plan[obj] }
|
228
|
+
end
|
229
|
+
object = next_plan[object]
|
230
|
+
end
|
231
|
+
nil
|
233
232
|
end
|
234
233
|
|
235
234
|
def replace(from, to)
|
236
235
|
# Make sure +from+, its events and all the related tasks and events
|
237
236
|
# are in the transaction
|
238
|
-
from = may_unwrap(from)
|
239
237
|
discover_neighborhood(from)
|
240
238
|
from.each_event do |ev|
|
241
239
|
discover_neighborhood(ev)
|
242
240
|
end
|
243
241
|
|
244
|
-
super(
|
242
|
+
super(from, to)
|
245
243
|
end
|
246
244
|
|
247
|
-
def
|
245
|
+
def add_mission(t)
|
248
246
|
raise "transaction #{self} has been either committed or discarded. No modification allowed" if freezed?
|
249
247
|
if proxy = self[t, false]
|
250
248
|
discarded_tasks.delete(may_unwrap(proxy))
|
251
249
|
end
|
252
|
-
super(
|
250
|
+
super(t)
|
253
251
|
end
|
254
|
-
def
|
252
|
+
def add_permanent(t)
|
255
253
|
raise "transaction #{self} has been either committed or discarded. No modification allowed" if freezed?
|
256
254
|
if proxy = self[t, false]
|
257
255
|
auto_tasks.delete(may_unwrap(proxy))
|
258
256
|
end
|
259
|
-
super(
|
257
|
+
super(t)
|
260
258
|
end
|
261
|
-
def
|
259
|
+
def add(objects)
|
262
260
|
raise "transaction #{self} has been either committed or discarded. No modification allowed" if freezed?
|
263
|
-
super(
|
261
|
+
super(objects)
|
264
262
|
self
|
265
263
|
end
|
266
264
|
|
267
|
-
def
|
265
|
+
def unmark_permanent(t)
|
268
266
|
raise "transaction #{self} has been either committed or discarded. No modification allowed" if freezed?
|
269
267
|
if proxy = self[t, false]
|
270
268
|
super(proxy)
|
@@ -276,7 +274,7 @@ module Roby
|
|
276
274
|
end
|
277
275
|
end
|
278
276
|
|
279
|
-
def
|
277
|
+
def unmark_mission(t)
|
280
278
|
raise "transaction #{self} has been either committed or discarded. No modification allowed" if freezed?
|
281
279
|
if proxy = self[t, false]
|
282
280
|
super(proxy)
|
@@ -328,12 +326,9 @@ module Roby
|
|
328
326
|
check_valid_transaction
|
329
327
|
freezed!
|
330
328
|
|
331
|
-
|
332
|
-
auto_tasks.each { |t| plan.
|
333
|
-
discarded_tasks.each { |t| plan.
|
334
|
-
removed_objects.each do |obj|
|
335
|
-
plan.remove_object(obj) if plan.include?(obj)
|
336
|
-
end
|
329
|
+
plan.execute do
|
330
|
+
auto_tasks.each { |t| plan.unmark_permanent(t) }
|
331
|
+
discarded_tasks.each { |t| plan.unmark_mission(t) }
|
337
332
|
|
338
333
|
discover_tasks = ValueSet.new
|
339
334
|
discover_events = ValueSet.new
|
@@ -351,8 +346,8 @@ module Roby
|
|
351
346
|
if missions.include?(t) && t.self_owned?
|
352
347
|
missions.delete(t)
|
353
348
|
insert << unwrapped
|
354
|
-
elsif
|
355
|
-
|
349
|
+
elsif permanent_tasks.include?(t) && t.self_owned?
|
350
|
+
permanent_tasks.delete(t)
|
356
351
|
permanent << unwrapped
|
357
352
|
end
|
358
353
|
|
@@ -367,18 +362,22 @@ module Roby
|
|
367
362
|
free_events.delete(ev)
|
368
363
|
ev
|
369
364
|
end
|
365
|
+
if permanent_events.include?(ev) && ev.self_owned?
|
366
|
+
permanent_events.delete(ev)
|
367
|
+
permanent << unwrapped
|
368
|
+
end
|
370
369
|
|
371
370
|
discover_events << unwrapped
|
372
371
|
end
|
373
372
|
|
374
|
-
new_tasks = plan.
|
373
|
+
new_tasks = plan.add_task_set(discover_tasks)
|
375
374
|
new_tasks.each do |task|
|
376
375
|
if task.respond_to?(:commit_transaction)
|
377
376
|
task.commit_transaction
|
378
377
|
end
|
379
378
|
end
|
380
379
|
|
381
|
-
new_events = plan.
|
380
|
+
new_events = plan.add_event_set(discover_events)
|
382
381
|
new_events.each do |event|
|
383
382
|
if event.respond_to?(:commit_transaction)
|
384
383
|
event.commit_transaction
|
@@ -390,8 +389,8 @@ module Roby
|
|
390
389
|
proxy_objects.each_value { |proxy| proxy.commit_transaction }
|
391
390
|
proxy_objects.each_value { |proxy| proxy.clear_relations }
|
392
391
|
|
393
|
-
insert.each { |t| plan.
|
394
|
-
permanent.each { |t| plan.
|
392
|
+
insert.each { |t| plan.add_mission(t) }
|
393
|
+
permanent.each { |t| plan.add_permanent(t) }
|
395
394
|
|
396
395
|
proxies = proxy_objects.dup
|
397
396
|
clear
|
@@ -402,6 +401,7 @@ module Roby
|
|
402
401
|
Kernel.swap! proxy, forwarder
|
403
402
|
end
|
404
403
|
|
404
|
+
@committed = true
|
405
405
|
committed_transaction
|
406
406
|
plan.remove_transaction(self)
|
407
407
|
@plan = nil
|
@@ -439,7 +439,7 @@ module Roby
|
|
439
439
|
clear
|
440
440
|
|
441
441
|
discarded_transaction
|
442
|
-
|
442
|
+
plan.execute do
|
443
443
|
plan.remove_transaction(self)
|
444
444
|
end
|
445
445
|
@plan = nil
|
@@ -451,14 +451,57 @@ module Roby
|
|
451
451
|
end
|
452
452
|
|
453
453
|
def clear
|
454
|
-
removed_objects.clear
|
455
454
|
discarded_tasks.clear
|
456
455
|
proxy_objects.each_value { |proxy| proxy.clear_relations }
|
457
456
|
proxy_objects.clear
|
458
457
|
super
|
459
458
|
end
|
459
|
+
|
460
|
+
def finalized_plan_task(task)
|
461
|
+
proxied_task = task.__getobj__
|
462
|
+
|
463
|
+
invalidate("task #{task} has been removed from the plan")
|
464
|
+
discard_modifications(proxied_task)
|
465
|
+
control.finalized_plan_task(self, task)
|
466
|
+
end
|
467
|
+
|
468
|
+
def finalized_plan_event(event)
|
469
|
+
proxied_event = event.__getobj__
|
470
|
+
|
471
|
+
invalidate("event #{event} has been removed from the plan")
|
472
|
+
discard_modifications(proxied_event)
|
473
|
+
control.finalized_plan_event(self, event)
|
474
|
+
end
|
475
|
+
|
476
|
+
def adding_plan_relation(parent, child, relations, info)
|
477
|
+
missing_relations = relations.find_all do |rel|
|
478
|
+
!parent.child_object?(child, rel)
|
479
|
+
end
|
480
|
+
unless missing_relations.empty?
|
481
|
+
invalidate("plan added a relation #{parent} -> #{child} in #{relations} with info #{info}")
|
482
|
+
control.adding_plan_relation(self, parent, child, relations, info)
|
483
|
+
end
|
484
|
+
end
|
485
|
+
|
486
|
+
def removing_plan_relation(parent, child, relations)
|
487
|
+
present_relations = relations.find_all do |rel|
|
488
|
+
parent.child_object?(child, rel)
|
489
|
+
end
|
490
|
+
unless present_relations.empty?
|
491
|
+
invalidate("plan removed a relation #{parent} -> #{child} in #{relations}")
|
492
|
+
control.removing_plan_relation(self, parent, child, relations)
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
496
|
+
# Run a garbage collection pass in the transaction. This is 'static', as
|
497
|
+
# it does not care about the task's state: it will simply remove *from
|
498
|
+
# the transaction* any task that is not useful *in the context of the
|
499
|
+
# transaction*.
|
500
|
+
def static_garbage_collect
|
501
|
+
for t in unneeded_tasks
|
502
|
+
remove_object(t)
|
503
|
+
end
|
504
|
+
end
|
460
505
|
end
|
461
506
|
end
|
462
507
|
|
463
|
-
require 'roby/transactions/updates'
|
464
|
-
|