roby 0.7.3 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. data/History.txt +7 -5
  2. data/Manifest.txt +91 -16
  3. data/README.txt +24 -24
  4. data/Rakefile +92 -64
  5. data/app/config/app.yml +42 -43
  6. data/app/config/init.rb +26 -0
  7. data/benchmark/alloc_misc.rb +123 -0
  8. data/benchmark/discovery_latency.rb +67 -0
  9. data/benchmark/garbage_collection.rb +48 -0
  10. data/benchmark/genom.rb +31 -0
  11. data/benchmark/transactions.rb +62 -0
  12. data/bin/roby +1 -1
  13. data/bin/roby-log +16 -6
  14. data/doc/guide/.gitignore +2 -0
  15. data/doc/guide/config.yaml +34 -0
  16. data/doc/guide/ext/init.rb +14 -0
  17. data/doc/guide/ext/previous_next.rb +40 -0
  18. data/doc/guide/ext/rdoc_links.rb +33 -0
  19. data/doc/guide/index.rdoc +16 -0
  20. data/doc/guide/overview.rdoc +62 -0
  21. data/doc/guide/plan_modifications.rdoc +67 -0
  22. data/doc/guide/src/abstraction/achieve_with.page +8 -0
  23. data/doc/guide/src/abstraction/forwarding.page +8 -0
  24. data/doc/guide/src/abstraction/hierarchy.page +19 -0
  25. data/doc/guide/src/abstraction/index.page +28 -0
  26. data/doc/guide/src/abstraction/task_models.page +13 -0
  27. data/doc/guide/src/basics.template +6 -0
  28. data/doc/guide/src/basics/app.page +139 -0
  29. data/doc/guide/src/basics/code_examples.page +33 -0
  30. data/doc/guide/src/basics/dry.page +69 -0
  31. data/doc/guide/src/basics/errors.page +443 -0
  32. data/doc/guide/src/basics/events.page +179 -0
  33. data/doc/guide/src/basics/hierarchy.page +275 -0
  34. data/doc/guide/src/basics/index.page +11 -0
  35. data/doc/guide/src/basics/log_replay/goForward_1.png +0 -0
  36. data/doc/guide/src/basics/log_replay/goForward_2.png +0 -0
  37. data/doc/guide/src/basics/log_replay/goForward_3.png +0 -0
  38. data/doc/guide/src/basics/log_replay/goForward_4.png +0 -0
  39. data/doc/guide/src/basics/log_replay/goForward_5.png +0 -0
  40. data/doc/guide/src/basics/log_replay/hierarchy_error_1.png +0 -0
  41. data/doc/guide/src/basics/log_replay/hierarchy_error_2.png +0 -0
  42. data/doc/guide/src/basics/log_replay/hierarchy_error_3.png +0 -0
  43. data/doc/guide/src/basics/log_replay/plan_repair_1.png +0 -0
  44. data/doc/guide/src/basics/log_replay/plan_repair_2.png +0 -0
  45. data/doc/guide/src/basics/log_replay/plan_repair_3.png +0 -0
  46. data/doc/guide/src/basics/log_replay/plan_repair_4.png +0 -0
  47. data/doc/guide/src/basics/log_replay/roby_log_main_window.png +0 -0
  48. data/doc/guide/src/basics/log_replay/roby_log_relation_window.png +0 -0
  49. data/doc/guide/src/basics/log_replay/roby_replay_event_representation.png +0 -0
  50. data/doc/guide/src/basics/plan_objects.page +71 -0
  51. data/doc/guide/src/basics/relations_display.page +203 -0
  52. data/doc/guide/src/basics/roby_cycle_overview.png +0 -0
  53. data/doc/guide/src/basics/shell.page +102 -0
  54. data/doc/guide/src/basics/summary.page +32 -0
  55. data/doc/guide/src/basics/tasks.page +357 -0
  56. data/doc/guide/src/basics_shell_header.txt +16 -0
  57. data/doc/guide/src/cycle/cycle-overview.png +0 -0
  58. data/doc/guide/src/cycle/cycle-overview.svg +208 -0
  59. data/doc/guide/src/cycle/error_handling.page +168 -0
  60. data/doc/guide/src/cycle/error_instantaneous_repair.png +0 -0
  61. data/doc/guide/src/cycle/error_instantaneous_repair.svg +1224 -0
  62. data/doc/guide/src/cycle/garbage_collection.page +10 -0
  63. data/doc/guide/src/cycle/index.page +23 -0
  64. data/doc/guide/src/cycle/propagation.page +154 -0
  65. data/doc/guide/src/cycle/propagation_diamond.png +0 -0
  66. data/doc/guide/src/cycle/propagation_diamond.svg +1279 -0
  67. data/doc/guide/src/default.css +319 -0
  68. data/doc/guide/src/default.template +74 -0
  69. data/doc/guide/src/htmldoc.metainfo +20 -0
  70. data/doc/guide/src/htmldoc.virtual +18 -0
  71. data/doc/guide/src/images/bodybg.png +0 -0
  72. data/doc/guide/src/images/contbg.png +0 -0
  73. data/doc/guide/src/images/footerbg.png +0 -0
  74. data/doc/guide/src/images/gradient1.png +0 -0
  75. data/doc/guide/src/images/gradient2.png +0 -0
  76. data/doc/guide/src/index.page +7 -0
  77. data/doc/guide/src/introduction/index.page +29 -0
  78. data/doc/guide/src/introduction/install.page +133 -0
  79. data/doc/{papers.rdoc → guide/src/introduction/publications.page} +5 -2
  80. data/doc/{videos.rdoc → guide/src/introduction/videos.page} +4 -2
  81. data/doc/guide/src/plugins/fault_tolerance.page +44 -0
  82. data/doc/guide/src/plugins/index.page +11 -0
  83. data/doc/guide/src/plugins/subsystems.page +45 -0
  84. data/doc/guide/src/relations/dependency.page +89 -0
  85. data/doc/guide/src/relations/index.page +12 -0
  86. data/doc/misc/update_github +24 -0
  87. data/doc/tutorials/02-GoForward.rdoc +3 -3
  88. data/ext/graph/graph.cc +46 -0
  89. data/lib/roby.rb +57 -22
  90. data/lib/roby/app.rb +132 -112
  91. data/lib/roby/app/plugins/rake.rb +21 -0
  92. data/lib/roby/app/rake.rb +0 -7
  93. data/lib/roby/app/run.rb +1 -1
  94. data/lib/roby/app/scripts/distributed.rb +1 -2
  95. data/lib/roby/app/scripts/generate/bookmarks.rb +1 -1
  96. data/lib/roby/app/scripts/results.rb +2 -1
  97. data/lib/roby/app/scripts/run.rb +6 -2
  98. data/lib/roby/app/scripts/shell.rb +11 -11
  99. data/lib/roby/config.rb +1 -1
  100. data/lib/roby/decision_control.rb +62 -3
  101. data/lib/roby/distributed.rb +4 -0
  102. data/lib/roby/distributed/base.rb +8 -0
  103. data/lib/roby/distributed/communication.rb +12 -8
  104. data/lib/roby/distributed/connection_space.rb +61 -44
  105. data/lib/roby/distributed/distributed_object.rb +1 -1
  106. data/lib/roby/distributed/notifications.rb +22 -30
  107. data/lib/roby/distributed/peer.rb +13 -8
  108. data/lib/roby/distributed/proxy.rb +5 -5
  109. data/lib/roby/distributed/subscription.rb +4 -4
  110. data/lib/roby/distributed/transaction.rb +3 -3
  111. data/lib/roby/event.rb +176 -110
  112. data/lib/roby/exceptions.rb +12 -4
  113. data/lib/roby/execution_engine.rb +1604 -0
  114. data/lib/roby/external_process_task.rb +225 -0
  115. data/lib/roby/graph.rb +0 -6
  116. data/lib/roby/interface.rb +221 -137
  117. data/lib/roby/log/console.rb +5 -3
  118. data/lib/roby/log/data_stream.rb +94 -16
  119. data/lib/roby/log/dot.rb +8 -8
  120. data/lib/roby/log/event_stream.rb +13 -3
  121. data/lib/roby/log/file.rb +43 -18
  122. data/lib/roby/log/gui/basic_display_ui.rb +89 -0
  123. data/lib/roby/log/gui/chronicle_view_ui.rb +90 -0
  124. data/lib/roby/log/gui/data_displays.rb +4 -5
  125. data/lib/roby/log/gui/data_displays_ui.rb +146 -0
  126. data/lib/roby/log/gui/relations.rb +18 -18
  127. data/lib/roby/log/gui/relations_ui.rb +120 -0
  128. data/lib/roby/log/gui/relations_view_ui.rb +144 -0
  129. data/lib/roby/log/gui/replay.rb +41 -13
  130. data/lib/roby/log/gui/replay_controls.rb +3 -0
  131. data/lib/roby/log/gui/replay_controls.ui +133 -110
  132. data/lib/roby/log/gui/replay_controls_ui.rb +249 -0
  133. data/lib/roby/log/hooks.rb +19 -18
  134. data/lib/roby/log/logger.rb +7 -6
  135. data/lib/roby/log/notifications.rb +4 -4
  136. data/lib/roby/log/plan_rebuilder.rb +20 -22
  137. data/lib/roby/log/relations.rb +44 -16
  138. data/lib/roby/log/server.rb +1 -4
  139. data/lib/roby/log/timings.rb +88 -19
  140. data/lib/roby/plan-object.rb +135 -11
  141. data/lib/roby/plan.rb +408 -224
  142. data/lib/roby/planning/loops.rb +32 -25
  143. data/lib/roby/planning/model.rb +157 -51
  144. data/lib/roby/planning/task.rb +47 -20
  145. data/lib/roby/query.rb +128 -92
  146. data/lib/roby/relations.rb +254 -136
  147. data/lib/roby/relations/conflicts.rb +6 -9
  148. data/lib/roby/relations/dependency.rb +358 -0
  149. data/lib/roby/relations/ensured.rb +0 -1
  150. data/lib/roby/relations/error_handling.rb +0 -1
  151. data/lib/roby/relations/events.rb +0 -2
  152. data/lib/roby/relations/executed_by.rb +26 -11
  153. data/lib/roby/relations/planned_by.rb +14 -14
  154. data/lib/roby/robot.rb +46 -0
  155. data/lib/roby/schedulers/basic.rb +34 -0
  156. data/lib/roby/standalone.rb +4 -0
  157. data/lib/roby/standard_errors.rb +21 -15
  158. data/lib/roby/state/events.rb +5 -4
  159. data/lib/roby/support.rb +107 -6
  160. data/lib/roby/task-operations.rb +23 -19
  161. data/lib/roby/task.rb +522 -148
  162. data/lib/roby/task_index.rb +80 -0
  163. data/lib/roby/test/common.rb +283 -44
  164. data/lib/roby/test/distributed.rb +53 -37
  165. data/lib/roby/test/testcase.rb +9 -204
  166. data/lib/roby/test/tools.rb +3 -3
  167. data/lib/roby/transactions.rb +154 -111
  168. data/lib/roby/transactions/proxy.rb +40 -7
  169. data/manifest.xml +20 -0
  170. data/plugins/fault_injection/README.txt +0 -3
  171. data/plugins/fault_injection/Rakefile +2 -8
  172. data/plugins/fault_injection/app.rb +1 -1
  173. data/plugins/fault_injection/fault_injection.rb +3 -3
  174. data/plugins/fault_injection/test/test_fault_injection.rb +19 -25
  175. data/plugins/subsystems/README.txt +0 -3
  176. data/plugins/subsystems/Rakefile +2 -7
  177. data/plugins/subsystems/app.rb +27 -16
  178. data/plugins/subsystems/test/app/config/init.rb +3 -0
  179. data/plugins/subsystems/test/app/planners/main.rb +1 -1
  180. data/plugins/subsystems/test/app/tasks/services.rb +1 -1
  181. data/plugins/subsystems/test/test_subsystems.rb +23 -16
  182. data/test/distributed/test_communication.rb +32 -15
  183. data/test/distributed/test_connection.rb +28 -26
  184. data/test/distributed/test_execution.rb +59 -54
  185. data/test/distributed/test_mixed_plan.rb +34 -34
  186. data/test/distributed/test_plan_notifications.rb +26 -26
  187. data/test/distributed/test_protocol.rb +57 -48
  188. data/test/distributed/test_query.rb +11 -7
  189. data/test/distributed/test_remote_plan.rb +71 -71
  190. data/test/distributed/test_transaction.rb +50 -47
  191. data/test/mockups/external_process +28 -0
  192. data/test/planning/test_loops.rb +163 -119
  193. data/test/planning/test_model.rb +3 -3
  194. data/test/planning/test_task.rb +27 -7
  195. data/test/relations/test_conflicts.rb +3 -3
  196. data/test/relations/test_dependency.rb +324 -0
  197. data/test/relations/test_ensured.rb +2 -2
  198. data/test/relations/test_executed_by.rb +94 -19
  199. data/test/relations/test_planned_by.rb +11 -9
  200. data/test/suite_core.rb +6 -3
  201. data/test/suite_distributed.rb +1 -0
  202. data/test/suite_planning.rb +1 -0
  203. data/test/suite_relations.rb +2 -2
  204. data/test/tasks/test_external_process.rb +126 -0
  205. data/test/{test_thread_task.rb → tasks/test_thread_task.rb} +17 -20
  206. data/test/test_bgl.rb +21 -1
  207. data/test/test_event.rb +229 -155
  208. data/test/test_exceptions.rb +79 -80
  209. data/test/test_execution_engine.rb +987 -0
  210. data/test/test_gui.rb +1 -1
  211. data/test/test_interface.rb +11 -5
  212. data/test/test_log.rb +18 -7
  213. data/test/test_log_server.rb +1 -0
  214. data/test/test_plan.rb +229 -395
  215. data/test/test_query.rb +193 -35
  216. data/test/test_relations.rb +88 -8
  217. data/test/test_state.rb +55 -37
  218. data/test/test_support.rb +1 -1
  219. data/test/test_task.rb +371 -218
  220. data/test/test_testcase.rb +32 -16
  221. data/test/test_transactions.rb +211 -170
  222. data/test/test_transactions_proxy.rb +37 -19
  223. metadata +169 -71
  224. data/.gitignore +0 -29
  225. data/doc/styles/allison.css +0 -314
  226. data/doc/styles/allison.js +0 -316
  227. data/doc/styles/allison.rb +0 -276
  228. data/doc/styles/jamis.rb +0 -593
  229. data/lib/roby/control.rb +0 -746
  230. data/lib/roby/executives/simple.rb +0 -30
  231. data/lib/roby/propagation.rb +0 -562
  232. data/lib/roby/relations/hierarchy.rb +0 -239
  233. data/lib/roby/transactions/updates.rb +0 -139
  234. data/test/relations/test_hierarchy.rb +0 -158
  235. data/test/test_control.rb +0 -399
  236. data/test/test_propagation.rb +0 -210
@@ -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
- def freezed?; @freezed end
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
- discover(proxy)
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::Control.synchronize do
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 !object.plan
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
- insert(wrapped)
72
+ add_mission(wrapped)
75
73
  elsif plan.permanent?(object)
76
- permanent(wrapped)
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?(:each)
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
- Control.synchronize do
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
- discovered_objects.delete(proxy)
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
- alias :remove_plan_object :remove_object
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
- proxy = proxy_objects[object] || object
147
-
148
- # removing the proxy may trigger some discovery (event relations
149
- # for instance, if proxy is a task). Do it first, or #discover
150
- # will be called and the modifications of internal structures
151
- # nulled (like #removed_objects) ...
152
- remove_plan_object(proxy)
153
- proxy_objects.delete(object)
154
-
155
- if object.plan == self.plan
156
- # +object+ is new in the transaction
157
- removed_objects.insert(object)
158
- end
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(object, create = true)
162
- (wrap(object, create) || object) rescue object
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
- # may_unwrap may return objects from transaction
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
- def conflict_solver=(value)
194
- @conflict_solver = case value
195
- when :update
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 = 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::Control.synchronize do
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
- self[object]
229
- object.each_relation do |rel|
230
- object.each_parent_object(rel) { |obj| self[obj] }
231
- object.each_child_object(rel) { |obj| self[obj] }
232
- end
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(self[from], self[to])
242
+ super(from, to)
245
243
  end
246
244
 
247
- def insert(t)
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(self[t, true])
250
+ super(t)
253
251
  end
254
- def permanent(t)
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(self[t, true])
257
+ super(t)
260
258
  end
261
- def discover(objects)
259
+ def add(objects)
262
260
  raise "transaction #{self} has been either committed or discarded. No modification allowed" if freezed?
263
- super(self[objects, true])
261
+ super(objects)
264
262
  self
265
263
  end
266
264
 
267
- def auto(t)
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 discard(t)
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
- Roby.execute do
332
- auto_tasks.each { |t| plan.auto(t) }
333
- discarded_tasks.each { |t| plan.discard(t) }
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 keepalive.include?(t) && t.self_owned?
355
- keepalive.delete(t)
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.discover_task_set(discover_tasks)
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.discover_event_set(discover_events)
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.insert(t) }
394
- permanent.each { |t| plan.permanent(t) }
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
- Roby.execute do
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
-