roby 0.7.3 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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,5 +1,3 @@
1
- require 'roby/task'
2
-
3
1
  module Roby::TaskStructure
4
2
  relation :PlannedBy, :child_name => :planning_task,
5
3
  :parent_name => :planned_task, :noinfo => true, :single_child => true do
@@ -21,7 +19,7 @@ module Roby::TaskStructure
21
19
 
22
20
  # Returns a set of PlanningFailedError exceptions for all abstract tasks
23
21
  # for which planning has failed
24
- def PlannedBy.check_planning(plan)
22
+ def PlannedBy.check_structure(plan)
25
23
  result = []
26
24
  Roby::TaskStructure::PlannedBy.each_edge do |planned_task, planning_task, _|
27
25
  next unless plan == planning_task.plan && planning_task.failed?
@@ -43,21 +41,23 @@ module Roby
43
41
 
44
42
  def initialize(planned_task, planning_task)
45
43
  @planned_task = planned_task
46
- super(planning_task.terminal_event)
44
+ super(planning_task.failure_event)
47
45
  end
46
+ def pretty_print(pp)
47
+ pp.text "failed to plan "
48
+ planned_task.pretty_print(pp)
49
+ pp.breakable
50
+ pp.breakable
51
+ pp.text "the following planning task failed with the #{failure_point.symbol} event"
52
+ pp.breakable
53
+ failed_task.pretty_print(pp)
54
+ pp.breakable
48
55
 
49
- def message # :nodoc:
50
- msg = "failed to plan #{planned_task}.planned_by(#{failed_task}): failed with #{failure_point.symbol}"
51
56
  if failure_point.context
52
- if failure_point.context.first.respond_to?(:full_message)
53
- msg << "\n" << failure_point.context.first.full_message
54
- else
55
- msg << "(" << failure_point.context.first.to_s << ")"
56
- end
57
+ pp.breakable
58
+ failure_point.context.first.pretty_print(pp)
57
59
  end
58
- msg
59
- end
60
+ end
60
61
  end
61
- Control.structure_checks << TaskStructure::PlannedBy.method(:check_planning)
62
62
  end
63
63
 
@@ -3,5 +3,51 @@ module Robot
3
3
  attr_accessor :logger
4
4
  end
5
5
  extend Logger::Forward
6
+
7
+ def self.prepare_action(name, arguments)
8
+ # Check if +name+ is a planner method, and in that case
9
+ # add a planning method for it and plan it
10
+ planner_model = Roby.app.planners.find do |planner_model|
11
+ planner_model.has_method?(name)
12
+ end
13
+ if !planner_model
14
+ raise ArgumentError, "no such planning method #{name}"
15
+ end
16
+
17
+ m = planner_model.model_of(name, arguments)
18
+
19
+ # HACK: m.returns should not be nil, but it sometimes happen
20
+ returns_model = (m.returns if m && m.returns) || Task
21
+
22
+ if returns_model.kind_of?(Roby::TaskModelTag)
23
+ task = Roby::Task.new
24
+ task.extend returns_model
25
+ else
26
+ # Create an abstract task which will be planned
27
+ task = returns_model.new
28
+ end
29
+
30
+ planner = Roby::PlanningTask.new(:planner_model => planner_model, :method_name => name, :method_options => arguments)
31
+ task.planned_by planner
32
+ return task, planner
33
+ end
34
+
35
+ def self.method_missing(name, *args)
36
+ if name.to_s =~ /!$/
37
+ name = $`.to_sym
38
+ else
39
+ super
40
+ end
41
+
42
+ if args.size > 1
43
+ raise ArgumentError, "wrong number of arguments (#{args.size} for 1) in #{name}!"
44
+ end
45
+
46
+ options = args.first || {}
47
+ task, planner = Robot.prepare_action(name, options)
48
+ Roby.plan.add_mission(task)
49
+
50
+ return task, planner
51
+ end
6
52
  end
7
53
 
@@ -0,0 +1,34 @@
1
+ module Roby
2
+ module Schedulers
3
+ class Basic
4
+ attr_reader :query
5
+ attr_reader :include_children
6
+ def initialize(include_children = false)
7
+ @include_children = include_children
8
+ @query = Roby.plan.find_tasks.
9
+ executable.
10
+ pending.
11
+ self_owned
12
+ end
13
+ def initial_events
14
+ for task in query.reset
15
+ if !(task.event(:start).root? && task.event(:start).controlable?)
16
+ next
17
+ end
18
+
19
+ root_task =
20
+ if task.root?(TaskStructure::Dependency)
21
+ true
22
+ else
23
+ task.planned_tasks.all? { |t| !t.executable? }
24
+ end
25
+
26
+ if root_task || (include_children && task.parents.any? { |t| t.running? })
27
+ task.start!
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+
@@ -0,0 +1,4 @@
1
+ require 'roby'
2
+ Dir.chdir(APP_DIR)
3
+ Roby.app.setup_global_singletons
4
+
@@ -1,4 +1,3 @@
1
- require 'pp'
2
1
  module Roby
3
2
  # This kind of errors are generated during the plan execution, allowing to
4
3
  # blame a fault on a plan object (#failure_point). The precise failure
@@ -76,6 +75,11 @@ module Roby
76
75
  # Raised when a consistency check failed in the Roby propagation code
77
76
  class PropagationError < InternalError; end
78
77
 
78
+ # Some operations need to be performed in the control thread, and some
79
+ # other (namely blocking operations) must not. This exception is raised
80
+ # when this constraint is not met.
81
+ class PhaseMismatch < RuntimeError; end
82
+
79
83
  # Some operations need to be performed in the control thread, and some
80
84
  # other (namely blocking operations) must not. This exception is raised
81
85
  # when this constraint is not met.
@@ -136,21 +140,25 @@ module Roby
136
140
  # Raised when an event has become unreachable while other parts of the plan
137
141
  # where waiting for its emission.
138
142
  class UnreachableEvent < LocalizedError
139
- # The generator which has become unreachable
140
- attr_reader :generator
143
+ # Why did the generator become unreachable
144
+ attr_reader :reason
145
+
141
146
  # Create an UnreachableEvent error for the given +generator+. +reason+
142
147
  # is supposed to be either nil or a plan object which is the reason why
143
148
  # +generator+ has become unreachable.
144
149
  def initialize(generator, reason)
145
- @generator = generator
146
- super(reason || generator)
150
+ @reason = reason
151
+ super(generator)
147
152
  end
148
153
 
149
154
  def pretty_print(pp) # :nodoc:
150
- pp.text "#{generator} has become unreachable"
151
- if failure_point
152
- pp.breakable ':'
153
- failure_point.pretty_print(pp)
155
+ pp.text "#{failed_generator} has become unreachable"
156
+ if reason
157
+ reason = [*reason]
158
+ reason.each do |e|
159
+ pp.breakable
160
+ e.pretty_print(pp)
161
+ end
154
162
  end
155
163
  end
156
164
  end
@@ -180,12 +188,10 @@ module Roby
180
188
  attr_reader :from
181
189
  # The task which should have replaced #from
182
190
  attr_reader :to
183
- # A description of the replacement failure
184
- attr_reader :error
185
191
 
186
192
  # Create a new InvalidReplace object
187
- def initialize(from, to, error)
188
- @from, @to, @error = from, to, error
193
+ def initialize(from, to)
194
+ @from, @to = from, to
189
195
  end
190
196
  def pretty_print(pp) # :nodoc:
191
197
  pp.text "invalid replacement: #{message}"
@@ -202,7 +208,7 @@ module Roby
202
208
  class MissionFailedError < LocalizedError
203
209
  # Create a new MissionFailedError for the given mission
204
210
  def initialize(task)
205
- super(task.terminal_event)
211
+ super(task.failure_event || task)
206
212
  end
207
213
 
208
214
  def pretty_print(pp)
@@ -213,6 +219,6 @@ module Roby
213
219
 
214
220
  # Exception raised in threads which are waiting for the control thread
215
221
  # See for instance Roby.execute
216
- class ControlQuitError < RuntimeError; end
222
+ class ExecutionQuitError < RuntimeError; end
217
223
  end
218
224
 
@@ -61,15 +61,16 @@ module Roby
61
61
  end
62
62
  end
63
63
 
64
- # Registered on Control to call the #poll method of state events
65
- def self.poll_state_events # :nodoc:
66
- for ev in Roby.plan.free_events
64
+ # Registered on the execution engines to call the #poll method of state
65
+ # events
66
+ def self.poll_state_events(plan) # :nodoc:
67
+ for ev in plan.free_events
67
68
  if ev.kind_of?(StateEvent) && ev.enabled?
68
69
  ev.poll
69
70
  end
70
71
  end
71
72
  end
72
- Roby::Control.each_cycle(&Roby.method(:poll_state_events))
73
+ Roby::ExecutionEngine.propagation_handlers << Roby.method(:poll_state_events)
73
74
 
74
75
  # A state event is an event which emits when some parameters over the state
75
76
  # are reached. See DeltaEvent and TimePointEvent.
@@ -1,9 +1,6 @@
1
- require 'active_support/inflector'
2
- class String # :nodoc: all
3
- include ActiveSupport::CoreExtensions::String::Inflections
4
- end
5
-
6
1
  require 'roby/config'
2
+ require 'facets/string/camelcase'
3
+ require 'facets/string/snakecase'
7
4
  require 'facets/kernel/constant'
8
5
  require 'utilrb/enumerable'
9
6
  require 'utilrb/time/to_hms'
@@ -45,11 +42,11 @@ module Enumerable
45
42
  end
46
43
 
47
44
  class Module
48
- # Defines a new constant under a given module
49
45
  # :call-seq
50
46
  # define_under(name, value) -> value
51
47
  # define_under(name) { ... } -> value
52
48
  #
49
+ # Defines a new constant under a given module
53
50
  # In the first form, the method gets its value from its argument.
54
51
  # In the second case, it calls the provided block
55
52
  def define_under(name, value = nil)
@@ -88,5 +85,109 @@ module Roby
88
85
 
89
86
  extend Logger::Hierarchy
90
87
  extend Logger::Forward
88
+
89
+ class Pool < Queue
90
+ def initialize(klass)
91
+ @klass = klass
92
+ super()
93
+ end
94
+
95
+ def pop
96
+ value = super(true) rescue nil
97
+ value || @klass.new
98
+ end
99
+ end
100
+
101
+ @mutexes = Pool.new(Mutex)
102
+ @condition_variables = Pool.new(ConditionVariable)
103
+ class << self
104
+ # A pool of mutexes (as a Queue)
105
+ attr_reader :mutexes
106
+ # A pool of condition variables (as a Queue)
107
+ attr_reader :condition_variables
108
+ end
109
+
110
+ # call-seq:
111
+ # condition_variable => cv
112
+ # condition_variable(true) => cv, mutex
113
+ # condition_variable { |cv| ... } => value returned by the block
114
+ # condition_variable(true) { |cv, mutex| ... } => value returned by the block
115
+ #
116
+ # Get a condition variable object from the Roby.condition_variables
117
+ # pool and, if mutex is not true, a Mutex object
118
+ #
119
+ # If a block is given, the two objects are yield and returned into the
120
+ # pool after the block has returned. In that case, the method returns
121
+ # the value returned by the block
122
+ def self.condition_variable(mutex = false)
123
+ cv = condition_variables.pop
124
+
125
+ if block_given?
126
+ begin
127
+ if mutex
128
+ mt = mutexes.pop
129
+ yield(cv, mt)
130
+ else
131
+ yield(cv)
132
+ end
133
+
134
+ ensure
135
+ return_condition_variable(cv, mt)
136
+ end
137
+ else
138
+ if mutex
139
+ return cv, mutexes.pop
140
+ else
141
+ return cv
142
+ end
143
+ end
144
+ end
145
+
146
+ # Returns a ConditionVariable and optionally a Mutex into the
147
+ # Roby.condition_variables and Roby.mutexes pools
148
+ def self.return_condition_variable(cv, mutex = nil)
149
+ condition_variables.push cv
150
+ if mutex
151
+ mutexes.push mutex
152
+ end
153
+ nil
154
+ end
155
+
156
+ @global_lock = Mutex.new
157
+ class << self
158
+ # This Mutex object is locked during the event propagation loop, and
159
+ # unlock while this loop is sleeping. It is used to wait for the
160
+ # availability of the main plan.
161
+ attr_reader :global_lock
162
+ end
163
+
164
+ def self.taken_global_lock?; Thread.current[:global_lock_taken] end
165
+
166
+ # Implements a recursive behaviour on Roby.mutex
167
+ def self.synchronize
168
+ if Thread.current[:global_lock_taken]
169
+ yield
170
+ else
171
+ global_lock.lock
172
+ begin
173
+ Thread.current[:global_lock_taken] = true
174
+ yield
175
+ ensure
176
+ Thread.current[:global_lock_taken] = false
177
+ global_lock.unlock
178
+ end
179
+ end
180
+ end
181
+
182
+ class << self
183
+ attr_accessor :enable_deprecation_warnings
184
+ end
185
+ @enable_deprecation_warnings = true
186
+
187
+ def self.warn_deprecated(msg)
188
+ if enable_deprecation_warnings
189
+ Roby.warn "Deprecation Warning: #{msg} at #{caller[1]}"
190
+ end
191
+ end
91
192
  end
92
193
 
@@ -1,5 +1,3 @@
1
- require 'roby/task'
2
-
3
1
  module Roby
4
2
  module TaskOperations
5
3
  def +(task)
@@ -60,31 +58,34 @@ module Roby
60
58
  def to_task(task = nil)
61
59
  return super() unless task
62
60
  task = task.new unless task.kind_of?(Roby::Task)
63
- @tasks.each { |t| task.realized_by t }
61
+ @tasks.each { |t| task.depends_on t }
64
62
 
65
- task.on(:start, @tasks.first, :start)
66
- @tasks.last.forward(:success, task, :success)
63
+ task.signals(:start, @tasks.first, :start)
64
+ @tasks.last.forward_to(:success, task, :success)
67
65
 
68
66
  delete
69
67
 
70
68
  task
71
69
  end
70
+ def child_of(task = nil)
71
+ to_task(task)
72
+ end
72
73
 
73
74
  def connect_start(task)
74
75
  if old = @tasks.first
75
76
  event(:start).remove_signal old.event(:start)
76
- task.on(:success, old, :start)
77
+ task.signals(:success, old, :start)
77
78
  end
78
79
 
79
- event(:start).on task.event(:start)
80
+ event(:start).signals task.event(:start)
80
81
  end
81
82
 
82
83
  def connect_stop(task)
83
84
  if old = @tasks.last
84
- old.on(:success, task, :start)
85
+ old.signals(:success, task, :start)
85
86
  old.event(:success).remove_forwarding event(:success)
86
87
  end
87
- task.forward(:success, self)
88
+ task.forward_to(:success, self, :success)
88
89
  end
89
90
  private :connect_stop, :connect_start
90
91
 
@@ -94,7 +95,7 @@ module Roby
94
95
  connect_stop(task) if @tasks.empty?
95
96
 
96
97
  @tasks.unshift(task)
97
- realized_by task
98
+ depends_on task
98
99
  self
99
100
  end
100
101
 
@@ -104,7 +105,7 @@ module Roby
104
105
  connect_stop(task)
105
106
 
106
107
  @tasks << task
107
- realized_by task
108
+ depends_on task
108
109
  self
109
110
  end
110
111
 
@@ -121,16 +122,19 @@ module Roby
121
122
  super
122
123
 
123
124
  @children_success = Roby::AndGenerator.new
124
- @children_success.forward event(:success)
125
+ @children_success.forward_to event(:success)
125
126
  end
126
127
 
128
+ def child_of(task = nil)
129
+ to_task(task)
130
+ end
127
131
  def to_task(task = nil)
128
132
  return super() unless task
129
133
 
130
134
  task = task.new unless task.kind_of?(Roby::Task)
131
135
  @tasks.each do |t|
132
- task.realized_by t
133
- task.on(:start, t, :start)
136
+ task.depends_on t
137
+ task.signals(:start, t, :start)
134
138
  end
135
139
  task.event(:success).emit_on children_success
136
140
 
@@ -143,8 +147,8 @@ module Roby
143
147
  raise "trying to change a running parallel task" if running?
144
148
  @tasks << task
145
149
 
146
- on(:start, task, :start)
147
- realized_by task
150
+ signals(:start, task, :start)
151
+ depends_on task
148
152
  children_success << task.event(:success)
149
153
 
150
154
  self
@@ -162,10 +166,10 @@ module Roby
162
166
 
163
167
  success = AndGenerator.new
164
168
  tasks.each do |task|
165
- realized_by task
166
- task.event(:success).on success
169
+ depends_on task
170
+ task.event(:success).signals success
167
171
  end
168
- success.forward event(:success)
172
+ success.forward_to event(:success)
169
173
  end
170
174
 
171
175
  event :start do