roby 0.7

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 (240) hide show
  1. data/.gitignore +29 -0
  2. data/History.txt +4 -0
  3. data/License-fr.txt +519 -0
  4. data/License.txt +515 -0
  5. data/Manifest.txt +245 -0
  6. data/NOTES +4 -0
  7. data/README.txt +163 -0
  8. data/Rakefile +161 -0
  9. data/TODO.txt +146 -0
  10. data/app/README.txt +24 -0
  11. data/app/Rakefile +8 -0
  12. data/app/config/ROBOT.rb +5 -0
  13. data/app/config/app.yml +91 -0
  14. data/app/config/init.rb +7 -0
  15. data/app/config/roby.yml +3 -0
  16. data/app/controllers/.gitattributes +0 -0
  17. data/app/controllers/ROBOT.rb +2 -0
  18. data/app/data/.gitattributes +0 -0
  19. data/app/planners/ROBOT/main.rb +6 -0
  20. data/app/planners/main.rb +5 -0
  21. data/app/scripts/distributed +3 -0
  22. data/app/scripts/generate/bookmarks +3 -0
  23. data/app/scripts/replay +3 -0
  24. data/app/scripts/results +3 -0
  25. data/app/scripts/run +3 -0
  26. data/app/scripts/server +3 -0
  27. data/app/scripts/shell +3 -0
  28. data/app/scripts/test +3 -0
  29. data/app/tasks/.gitattributes +0 -0
  30. data/app/tasks/ROBOT/.gitattributes +0 -0
  31. data/bin/roby +210 -0
  32. data/bin/roby-log +168 -0
  33. data/bin/roby-shell +25 -0
  34. data/doc/images/event_generalization.png +0 -0
  35. data/doc/images/exception_propagation_1.png +0 -0
  36. data/doc/images/exception_propagation_2.png +0 -0
  37. data/doc/images/exception_propagation_3.png +0 -0
  38. data/doc/images/exception_propagation_4.png +0 -0
  39. data/doc/images/exception_propagation_5.png +0 -0
  40. data/doc/images/replay_handler_error.png +0 -0
  41. data/doc/images/replay_handler_error_0.png +0 -0
  42. data/doc/images/replay_handler_error_1.png +0 -0
  43. data/doc/images/roby_cycle_overview.png +0 -0
  44. data/doc/images/roby_replay_02.png +0 -0
  45. data/doc/images/roby_replay_03.png +0 -0
  46. data/doc/images/roby_replay_04.png +0 -0
  47. data/doc/images/roby_replay_event_representation.png +0 -0
  48. data/doc/images/roby_replay_first_state.png +0 -0
  49. data/doc/images/roby_replay_relations.png +0 -0
  50. data/doc/images/roby_replay_startup.png +0 -0
  51. data/doc/images/task_event_generalization.png +0 -0
  52. data/doc/papers.rdoc +11 -0
  53. data/doc/styles/allison.css +314 -0
  54. data/doc/styles/allison.js +316 -0
  55. data/doc/styles/allison.rb +276 -0
  56. data/doc/styles/jamis.rb +593 -0
  57. data/doc/tutorials/01-GettingStarted.rdoc +86 -0
  58. data/doc/tutorials/02-GoForward.rdoc +220 -0
  59. data/doc/tutorials/03-PlannedPath.rdoc +268 -0
  60. data/doc/tutorials/04-EventPropagation.rdoc +236 -0
  61. data/doc/tutorials/05-ErrorHandling.rdoc +319 -0
  62. data/doc/tutorials/06-Overview.rdoc +40 -0
  63. data/doc/videos.rdoc +69 -0
  64. data/ext/droby/dump.cc +175 -0
  65. data/ext/droby/extconf.rb +3 -0
  66. data/ext/graph/algorithm.cc +746 -0
  67. data/ext/graph/extconf.rb +7 -0
  68. data/ext/graph/graph.cc +529 -0
  69. data/ext/graph/graph.hh +183 -0
  70. data/ext/graph/iterator_sequence.hh +102 -0
  71. data/ext/graph/undirected_dfs.hh +226 -0
  72. data/ext/graph/undirected_graph.hh +421 -0
  73. data/lib/roby.rb +41 -0
  74. data/lib/roby/app.rb +870 -0
  75. data/lib/roby/app/rake.rb +56 -0
  76. data/lib/roby/app/run.rb +14 -0
  77. data/lib/roby/app/scripts/distributed.rb +13 -0
  78. data/lib/roby/app/scripts/generate/bookmarks.rb +162 -0
  79. data/lib/roby/app/scripts/replay.rb +31 -0
  80. data/lib/roby/app/scripts/results.rb +15 -0
  81. data/lib/roby/app/scripts/run.rb +26 -0
  82. data/lib/roby/app/scripts/server.rb +18 -0
  83. data/lib/roby/app/scripts/shell.rb +88 -0
  84. data/lib/roby/app/scripts/test.rb +40 -0
  85. data/lib/roby/basic_object.rb +151 -0
  86. data/lib/roby/config.rb +5 -0
  87. data/lib/roby/control.rb +747 -0
  88. data/lib/roby/decision_control.rb +17 -0
  89. data/lib/roby/distributed.rb +32 -0
  90. data/lib/roby/distributed/base.rb +440 -0
  91. data/lib/roby/distributed/communication.rb +871 -0
  92. data/lib/roby/distributed/connection_space.rb +592 -0
  93. data/lib/roby/distributed/distributed_object.rb +206 -0
  94. data/lib/roby/distributed/drb.rb +62 -0
  95. data/lib/roby/distributed/notifications.rb +539 -0
  96. data/lib/roby/distributed/peer.rb +550 -0
  97. data/lib/roby/distributed/protocol.rb +529 -0
  98. data/lib/roby/distributed/proxy.rb +343 -0
  99. data/lib/roby/distributed/subscription.rb +311 -0
  100. data/lib/roby/distributed/transaction.rb +498 -0
  101. data/lib/roby/event.rb +897 -0
  102. data/lib/roby/exceptions.rb +234 -0
  103. data/lib/roby/executives/simple.rb +30 -0
  104. data/lib/roby/graph.rb +166 -0
  105. data/lib/roby/interface.rb +390 -0
  106. data/lib/roby/log.rb +3 -0
  107. data/lib/roby/log/chronicle.rb +303 -0
  108. data/lib/roby/log/console.rb +72 -0
  109. data/lib/roby/log/data_stream.rb +197 -0
  110. data/lib/roby/log/dot.rb +279 -0
  111. data/lib/roby/log/event_stream.rb +151 -0
  112. data/lib/roby/log/file.rb +340 -0
  113. data/lib/roby/log/gui/basic_display.ui +83 -0
  114. data/lib/roby/log/gui/chronicle.rb +26 -0
  115. data/lib/roby/log/gui/chronicle_view.rb +40 -0
  116. data/lib/roby/log/gui/chronicle_view.ui +70 -0
  117. data/lib/roby/log/gui/data_displays.rb +172 -0
  118. data/lib/roby/log/gui/data_displays.ui +155 -0
  119. data/lib/roby/log/gui/notifications.rb +26 -0
  120. data/lib/roby/log/gui/relations.rb +248 -0
  121. data/lib/roby/log/gui/relations.ui +123 -0
  122. data/lib/roby/log/gui/relations_view.rb +185 -0
  123. data/lib/roby/log/gui/relations_view.ui +149 -0
  124. data/lib/roby/log/gui/replay.rb +327 -0
  125. data/lib/roby/log/gui/replay_controls.rb +200 -0
  126. data/lib/roby/log/gui/replay_controls.ui +259 -0
  127. data/lib/roby/log/gui/runtime.rb +130 -0
  128. data/lib/roby/log/hooks.rb +185 -0
  129. data/lib/roby/log/logger.rb +202 -0
  130. data/lib/roby/log/notifications.rb +244 -0
  131. data/lib/roby/log/plan_rebuilder.rb +470 -0
  132. data/lib/roby/log/relations.rb +1056 -0
  133. data/lib/roby/log/server.rb +550 -0
  134. data/lib/roby/log/sqlite.rb +47 -0
  135. data/lib/roby/log/timings.rb +164 -0
  136. data/lib/roby/plan-object.rb +247 -0
  137. data/lib/roby/plan.rb +762 -0
  138. data/lib/roby/planning.rb +13 -0
  139. data/lib/roby/planning/loops.rb +302 -0
  140. data/lib/roby/planning/model.rb +906 -0
  141. data/lib/roby/planning/task.rb +151 -0
  142. data/lib/roby/propagation.rb +562 -0
  143. data/lib/roby/query.rb +619 -0
  144. data/lib/roby/relations.rb +583 -0
  145. data/lib/roby/relations/conflicts.rb +70 -0
  146. data/lib/roby/relations/ensured.rb +20 -0
  147. data/lib/roby/relations/error_handling.rb +23 -0
  148. data/lib/roby/relations/events.rb +9 -0
  149. data/lib/roby/relations/executed_by.rb +193 -0
  150. data/lib/roby/relations/hierarchy.rb +239 -0
  151. data/lib/roby/relations/influence.rb +10 -0
  152. data/lib/roby/relations/planned_by.rb +63 -0
  153. data/lib/roby/robot.rb +7 -0
  154. data/lib/roby/standard_errors.rb +218 -0
  155. data/lib/roby/state.rb +5 -0
  156. data/lib/roby/state/events.rb +221 -0
  157. data/lib/roby/state/information.rb +55 -0
  158. data/lib/roby/state/pos.rb +110 -0
  159. data/lib/roby/state/shapes.rb +32 -0
  160. data/lib/roby/state/state.rb +353 -0
  161. data/lib/roby/support.rb +92 -0
  162. data/lib/roby/task-operations.rb +182 -0
  163. data/lib/roby/task.rb +1618 -0
  164. data/lib/roby/test/common.rb +399 -0
  165. data/lib/roby/test/distributed.rb +214 -0
  166. data/lib/roby/test/tasks/empty_task.rb +9 -0
  167. data/lib/roby/test/tasks/goto.rb +36 -0
  168. data/lib/roby/test/tasks/simple_task.rb +23 -0
  169. data/lib/roby/test/testcase.rb +519 -0
  170. data/lib/roby/test/tools.rb +160 -0
  171. data/lib/roby/thread_task.rb +87 -0
  172. data/lib/roby/transactions.rb +462 -0
  173. data/lib/roby/transactions/proxy.rb +292 -0
  174. data/lib/roby/transactions/updates.rb +139 -0
  175. data/plugins/fault_injection/History.txt +4 -0
  176. data/plugins/fault_injection/README.txt +37 -0
  177. data/plugins/fault_injection/Rakefile +18 -0
  178. data/plugins/fault_injection/TODO.txt +0 -0
  179. data/plugins/fault_injection/app.rb +52 -0
  180. data/plugins/fault_injection/fault_injection.rb +89 -0
  181. data/plugins/fault_injection/test/test_fault_injection.rb +84 -0
  182. data/plugins/subsystems/README.txt +40 -0
  183. data/plugins/subsystems/Rakefile +18 -0
  184. data/plugins/subsystems/app.rb +171 -0
  185. data/plugins/subsystems/test/app/README +24 -0
  186. data/plugins/subsystems/test/app/Rakefile +8 -0
  187. data/plugins/subsystems/test/app/config/app.yml +71 -0
  188. data/plugins/subsystems/test/app/config/init.rb +9 -0
  189. data/plugins/subsystems/test/app/config/roby.yml +3 -0
  190. data/plugins/subsystems/test/app/planners/main.rb +20 -0
  191. data/plugins/subsystems/test/app/scripts/distributed +3 -0
  192. data/plugins/subsystems/test/app/scripts/replay +3 -0
  193. data/plugins/subsystems/test/app/scripts/results +3 -0
  194. data/plugins/subsystems/test/app/scripts/run +3 -0
  195. data/plugins/subsystems/test/app/scripts/server +3 -0
  196. data/plugins/subsystems/test/app/scripts/shell +3 -0
  197. data/plugins/subsystems/test/app/scripts/test +3 -0
  198. data/plugins/subsystems/test/app/tasks/services.rb +15 -0
  199. data/plugins/subsystems/test/test_subsystems.rb +71 -0
  200. data/test/distributed/test_communication.rb +178 -0
  201. data/test/distributed/test_connection.rb +282 -0
  202. data/test/distributed/test_execution.rb +373 -0
  203. data/test/distributed/test_mixed_plan.rb +341 -0
  204. data/test/distributed/test_plan_notifications.rb +238 -0
  205. data/test/distributed/test_protocol.rb +516 -0
  206. data/test/distributed/test_query.rb +102 -0
  207. data/test/distributed/test_remote_plan.rb +491 -0
  208. data/test/distributed/test_transaction.rb +463 -0
  209. data/test/mockups/tasks.rb +27 -0
  210. data/test/planning/test_loops.rb +380 -0
  211. data/test/planning/test_model.rb +427 -0
  212. data/test/planning/test_task.rb +106 -0
  213. data/test/relations/test_conflicts.rb +42 -0
  214. data/test/relations/test_ensured.rb +38 -0
  215. data/test/relations/test_executed_by.rb +149 -0
  216. data/test/relations/test_hierarchy.rb +158 -0
  217. data/test/relations/test_planned_by.rb +54 -0
  218. data/test/suite_core.rb +24 -0
  219. data/test/suite_distributed.rb +9 -0
  220. data/test/suite_planning.rb +3 -0
  221. data/test/suite_relations.rb +8 -0
  222. data/test/test_bgl.rb +508 -0
  223. data/test/test_control.rb +399 -0
  224. data/test/test_event.rb +894 -0
  225. data/test/test_exceptions.rb +592 -0
  226. data/test/test_interface.rb +37 -0
  227. data/test/test_log.rb +114 -0
  228. data/test/test_log_server.rb +132 -0
  229. data/test/test_plan.rb +584 -0
  230. data/test/test_propagation.rb +210 -0
  231. data/test/test_query.rb +266 -0
  232. data/test/test_relations.rb +180 -0
  233. data/test/test_state.rb +414 -0
  234. data/test/test_support.rb +16 -0
  235. data/test/test_task.rb +938 -0
  236. data/test/test_testcase.rb +122 -0
  237. data/test/test_thread_task.rb +73 -0
  238. data/test/test_transactions.rb +569 -0
  239. data/test/test_transactions_proxy.rb +198 -0
  240. metadata +570 -0
@@ -0,0 +1,7 @@
1
+ require 'mkmf'
2
+ CONFIG['CC'] = "g++"
3
+ dir_config 'boost'
4
+ $LDFLAGS += "-module"
5
+
6
+ create_makefile("roby_bgl")
7
+
@@ -0,0 +1,529 @@
1
+ #include "graph.hh"
2
+ #include <boost/bind.hpp>
3
+ #include <functional>
4
+
5
+ static ID id_rb_graph_map;
6
+
7
+ typedef RubyGraph::vertex_iterator vertex_iterator;
8
+ typedef RubyGraph::vertex_descriptor vertex_descriptor;
9
+ typedef RubyGraph::edge_iterator edge_iterator;
10
+ typedef RubyGraph::edge_descriptor edge_descriptor;
11
+
12
+ using namespace boost;
13
+ using namespace std;
14
+
15
+ VALUE bglModule;
16
+ VALUE bglGraph;
17
+ VALUE bglReverseGraph;
18
+ VALUE bglUndirectedGraph;
19
+ VALUE bglVertex;
20
+
21
+ /**********************************************************************
22
+ * BGL::Graph
23
+ */
24
+
25
+ template <typename descriptor> static
26
+ void graph_mark_object_property(RubyGraph& graph, descriptor object)
27
+ {
28
+ }
29
+
30
+ static
31
+ void graph_mark(RubyGraph* graph) {
32
+ { vertex_iterator it, end;
33
+ for (tie(it, end) = vertices(*graph); it != end; ++it)
34
+ {
35
+ VALUE value = (*graph)[*it];
36
+ if (! NIL_P(value))
37
+ rb_gc_mark(value);
38
+ }
39
+ }
40
+
41
+ { edge_iterator it, end;
42
+ for (tie(it, end) = edges(*graph); it != end; ++it)
43
+ {
44
+ VALUE value = (*graph)[*it].info;
45
+ if (! NIL_P(value))
46
+ rb_gc_mark(value);
47
+ }
48
+ }
49
+ }
50
+
51
+ static void graph_free(RubyGraph* graph) { delete graph; }
52
+ static VALUE graph_alloc(VALUE klass)
53
+ {
54
+ RubyGraph* graph = new RubyGraph;
55
+ VALUE rb_graph = Data_Wrap_Struct(klass, graph_mark, graph_free, graph);
56
+ return rb_graph;
57
+ }
58
+
59
+ /*
60
+ * call-seq:
61
+ * graph.each_vertex { |vertex| ... } => graph
62
+ *
63
+ * Iterates on all vertices in +graph+.
64
+ */
65
+ static
66
+ VALUE graph_each_vertex(VALUE self)
67
+ {
68
+ RubyGraph& graph = graph_wrapped(self);
69
+
70
+ vertex_iterator begin, end;
71
+ tie(begin, end) = vertices(graph);
72
+
73
+ for (vertex_iterator it = begin; it != end;)
74
+ {
75
+ VALUE vertex = graph[*it];
76
+ ++it;
77
+ rb_yield(vertex);
78
+ }
79
+ return self;
80
+ }
81
+
82
+ /*
83
+ * call-seq:
84
+ * graph.insert(vertex) => graph
85
+ *
86
+ * Add +vertex+ in this graph.
87
+ */
88
+ static
89
+ VALUE graph_insert(VALUE self, VALUE vertex)
90
+ {
91
+ RubyGraph& graph = graph_wrapped(self);
92
+ graph_map& vertex_graphs = vertex_descriptor_map(vertex);
93
+
94
+ graph_map::iterator it;
95
+ bool inserted;
96
+ tie(it, inserted) = vertex_graphs.insert( make_pair(self, static_cast<void*>(0)) );
97
+ if (inserted)
98
+ it->second = add_vertex(vertex, graph);
99
+
100
+ return self;
101
+ }
102
+
103
+ /*
104
+ * call-seq:
105
+ * graph.remove(vertex) => graph
106
+ *
107
+ * Remove +vertex+ from this graph.
108
+ */
109
+ static
110
+ VALUE graph_remove(VALUE self, VALUE vertex)
111
+ {
112
+ RubyGraph& graph = graph_wrapped(self);
113
+ graph_map& vertex_graphs = vertex_descriptor_map(vertex);
114
+
115
+ graph_map::iterator it = vertex_graphs.find(self);
116
+ if (it == vertex_graphs.end())
117
+ return self;
118
+
119
+ clear_vertex(it->second, graph);
120
+ remove_vertex(it->second, graph);
121
+ vertex_graphs.erase(it);
122
+ return self;
123
+ }
124
+
125
+ /*
126
+ * call-seq:
127
+ * graph.include?(vertex) => true of false
128
+ *
129
+ * Returns true if +vertex+ is part of this graph.
130
+ */
131
+ static
132
+ VALUE graph_include_p(VALUE self, VALUE vertex)
133
+ {
134
+ bool includes;
135
+ tie(tuples::ignore, includes) = rb_to_vertex(vertex, self);
136
+ return includes ? Qtrue : Qfalse;
137
+ }
138
+
139
+ // Make sure that the Vertex object +vertex+ is present in +self+, and returns
140
+ // its descriptor
141
+ static vertex_descriptor graph_ensure_inserted_vertex(VALUE self, VALUE vertex)
142
+ {
143
+ vertex_descriptor v; bool exists;
144
+ tie(v, exists) = rb_to_vertex(vertex, self);
145
+ if (! exists)
146
+ {
147
+ graph_insert(self, vertex);
148
+ tie(v, tuples::ignore) = rb_to_vertex(vertex, self);
149
+ }
150
+
151
+ return v;
152
+ }
153
+
154
+ /*
155
+ * call-seq:
156
+ * graph.link(source, target, info) => graph
157
+ *
158
+ * Adds an edge from +source+ to +target+, with +info+ as property
159
+ * Raises ArgumentError if the edge already exists.
160
+ */
161
+ static
162
+ VALUE graph_link(VALUE self, VALUE source, VALUE target, VALUE info)
163
+ {
164
+ RubyGraph& graph = graph_wrapped(self);
165
+
166
+ vertex_descriptor
167
+ s = graph_ensure_inserted_vertex(self, source),
168
+ t = graph_ensure_inserted_vertex(self, target);
169
+
170
+ bool inserted = add_edge(s, t, EdgeProperty(info), graph).second;
171
+ if (! inserted)
172
+ rb_raise(rb_eArgError, "edge already exists");
173
+
174
+ return self;
175
+ }
176
+
177
+ /*
178
+ * call-seq:
179
+ * graph.unlink(source, target, info) => graph
180
+ *
181
+ * Removes the edge from +source+ to +target+. Does nothing if the
182
+ * edge does not exist.
183
+ */
184
+ static
185
+ VALUE graph_unlink(VALUE self, VALUE source, VALUE target)
186
+ {
187
+ RubyGraph& graph = graph_wrapped(self);
188
+
189
+ vertex_descriptor s, t; bool exists;
190
+ tie(s, exists) = rb_to_vertex(source, self);
191
+ if (! exists) return self;
192
+ tie(t, exists) = rb_to_vertex(target, self);
193
+ if (! exists) return self;
194
+ remove_edge(s, t, graph);
195
+ return self;
196
+ }
197
+
198
+ /*
199
+ * call-seq:
200
+ * graph.linked?(source, target) => true or false
201
+ *
202
+ * Checks if there is an edge from +source+ to +target+
203
+ */
204
+ static
205
+ VALUE graph_linked_p(VALUE self, VALUE source, VALUE target)
206
+ {
207
+ RubyGraph& graph = graph_wrapped(self);
208
+
209
+ vertex_descriptor s, t; bool exists;
210
+ tie(s, exists) = rb_to_vertex(source, self);
211
+ if (! exists) return Qfalse;
212
+ tie(t, exists) = rb_to_vertex(target, self);
213
+ if (! exists) return Qfalse;
214
+ return edge(s, t, graph).second ? Qtrue : Qfalse;
215
+ }
216
+
217
+ /*
218
+ * call-seq:
219
+ * graph.each_edge { |source, target, info| ... } => graph
220
+ *
221
+ * Iterates on all edges in this graph. +source+ and +target+ are the
222
+ * edge vertices, +info+ is the data associated with the edge. See #link.
223
+ */
224
+ static
225
+ VALUE graph_each_edge(VALUE self)
226
+ {
227
+ RubyGraph& graph = graph_wrapped(self);
228
+
229
+ edge_iterator begin, end;
230
+ tie(begin, end) = edges(graph);
231
+
232
+ for (edge_iterator it = begin; it != end;)
233
+ {
234
+ VALUE from = graph[source(*it, graph)];
235
+ VALUE to = graph[target(*it, graph)];
236
+ VALUE data = graph[*it].info;
237
+ ++it;
238
+
239
+ rb_yield_values(3, from, to, data);
240
+ }
241
+ return self;
242
+ }
243
+
244
+
245
+
246
+
247
+ /**********************************************************************
248
+ * BGL::Vertex
249
+ */
250
+
251
+ static void vertex_free(graph_map* map) { delete map; }
252
+ static void vertex_mark(graph_map* map)
253
+ {
254
+ for (graph_map::iterator it = map->begin(); it != map->end(); ++it)
255
+ rb_gc_mark(it->first);
256
+ }
257
+
258
+ /* Returns the graph => descriptor map for +self+ */
259
+ graph_map& vertex_descriptor_map(VALUE self)
260
+ {
261
+ graph_map* map;
262
+ VALUE descriptors = rb_ivar_get(self, id_rb_graph_map);
263
+ if (RTEST(descriptors))
264
+ {
265
+ Data_Get_Struct(descriptors, graph_map, map);
266
+ }
267
+ else
268
+ {
269
+ map = new graph_map;
270
+ VALUE rb_map = Data_Wrap_Struct(rb_cObject, vertex_mark, vertex_free, map);
271
+ rb_ivar_set(self, id_rb_graph_map, rb_map);
272
+ }
273
+
274
+ return *map;
275
+ }
276
+
277
+ /*
278
+ * call-seq:
279
+ * vertex.each_graph { |graph| ... } => self
280
+ *
281
+ * Iterates on all graphs this object is part of
282
+ */
283
+ static VALUE vertex_each_graph(VALUE self)
284
+ {
285
+ graph_map& graphs = vertex_descriptor_map(self);
286
+ for (graph_map::iterator it = graphs.begin(); it != graphs.end();)
287
+ {
288
+ VALUE graph = it->first;
289
+ // increment before calling rb_yield since the block
290
+ // can call Graph#remove for instance
291
+ ++it;
292
+ rb_yield(graph);
293
+ }
294
+ return self;
295
+ }
296
+
297
+ /*
298
+ * call-seq:
299
+ * vertex.parent_object?(object[, graph]) => true of false
300
+ *
301
+ * Checks if +object+ is a parent of +vertex+. If +graph+ is given,
302
+ * check only in this graph. Otherwise, check in all graphs +vertex+
303
+ * is part of.
304
+ */
305
+ static VALUE vertex_parent_p(int argc, VALUE* argv, VALUE self)
306
+ {
307
+ VALUE rb_parent, rb_graph = Qnil;
308
+ rb_scan_args(argc, argv, "11", &rb_parent, &rb_graph);
309
+
310
+ if (! NIL_P(rb_graph))
311
+ return graph_linked_p(rb_graph, rb_parent, self);
312
+
313
+ graph_map::iterator it, end;
314
+ for (tie(it, end) = vertex_descriptors(self); it != end; ++it)
315
+ {
316
+ RubyGraph& graph = graph_wrapped(it->first);
317
+ vertex_descriptor child = it->second;
318
+ vertex_descriptor parent; bool in_graph;
319
+ tie(parent, in_graph) = rb_to_vertex(rb_parent, it->first);
320
+
321
+ if (in_graph && edge(parent, child, graph).second)
322
+ return Qtrue;
323
+ }
324
+ return Qfalse;
325
+ }
326
+
327
+ /*
328
+ * call-seq:
329
+ * vertex.child_vertex?(object[, graph]) => true or false
330
+ *
331
+ * Checks if +object+ is a child of +vertex+ in +graph+. If +graph+ is given,
332
+ * check only in this graph. Otherwise, check in all graphs +vertex+ is part
333
+ * of.
334
+ */
335
+ static VALUE vertex_child_p(int argc, VALUE* argv, VALUE self)
336
+ {
337
+ swap(argv[0], self);
338
+ return vertex_parent_p(argc, argv, self);
339
+ }
340
+
341
+ /*
342
+ * call-seq:
343
+ * vertex.related_vertex?(object[, graph]) => true or false
344
+ *
345
+ * Checks if +object+ is a child or a parent of +vertex+ in +graph+. If
346
+ * +graph+ is given, check only in this graph. Otherwise, check in all graphs
347
+ * +vertex+ is part of.
348
+ */
349
+ static VALUE vertex_related_p(int argc, VALUE* argv, VALUE self)
350
+ {
351
+ if (vertex_parent_p(argc, argv, self) == Qtrue)
352
+ return Qtrue;
353
+ return vertex_child_p(argc, argv, self);
354
+ }
355
+
356
+ template <bool directed>
357
+ static VALUE vertex_each_related(int argc, VALUE* argv, VALUE self)
358
+ {
359
+ VALUE graph = Qnil;
360
+ rb_scan_args(argc, argv, "01", &graph);
361
+
362
+ if (NIL_P(graph))
363
+ {
364
+ set<VALUE> already_seen;
365
+ for_each_graph(self, bind(for_each_adjacent_uniq<RubyGraph, directed>, _1, _2, ref(already_seen)));
366
+ }
367
+ else
368
+ {
369
+ vertex_descriptor v; bool exists;
370
+ tie(v, exists) = rb_to_vertex(self, graph);
371
+ if (! exists)
372
+ return self;
373
+
374
+ RubyGraph& g = graph_wrapped(graph);
375
+ for_each_value(details::vertex_range<RubyGraph, directed>::get(v, g), g, rb_yield);
376
+ }
377
+ return self;
378
+ }
379
+
380
+ /*
381
+ * call-seq:
382
+ * vertex.each_parent_vertex([graph]) { |object| ... } => vertex
383
+ *
384
+ * Iterates on all parents of +vertex+. If +graph+ is given, only iterate on
385
+ * the vertices that are parent in +graph+.
386
+ */
387
+ static VALUE vertex_each_parent(int argc, VALUE* argv, VALUE self)
388
+ { return vertex_each_related<false>(argc, argv, self); }
389
+
390
+ /*
391
+ * call-seq:
392
+ * vertex.each_child_vertex([graph]) { |child| ... } => vertex
393
+ *
394
+ * Iterates on all children of +vertex+. If +graph+ is given, iterates only on
395
+ * the vertices which are a child of +vertex+ in +graph+
396
+ */
397
+ static VALUE vertex_each_child(int argc, VALUE* argv, VALUE self)
398
+ { return vertex_each_related<true>(argc, argv, self); }
399
+
400
+ /*
401
+ * call-seq:
402
+ * vertex.singleton_vertex? => true or false
403
+ *
404
+ * Returns true if the vertex is linked to no other vertex
405
+ */
406
+ static VALUE vertex_singleton_p(VALUE self)
407
+ {
408
+ graph_map::iterator it, end;
409
+ for (tie(it, end) = vertex_descriptors(self); it != end; ++it)
410
+ {
411
+ RubyGraph& graph = graph_wrapped(it->first);
412
+ vertex_descriptor v = it->second;
413
+ if (in_degree(v, graph) || out_degree(v, graph))
414
+ return Qfalse;
415
+ }
416
+ return Qtrue;
417
+ }
418
+
419
+ /*
420
+ * call-seq:
421
+ * vertex[child, graph] => info
422
+ *
423
+ * Get the data associated with the vertex => +child+ edge in +graph+.
424
+ * Raises ArgumentError if there is no such edge.
425
+ */
426
+ static VALUE vertex_get_info(VALUE self, VALUE child, VALUE rb_graph)
427
+ {
428
+ vertex_descriptor source, target; bool exists;
429
+
430
+ tie(source, exists) = rb_to_vertex(self, rb_graph);
431
+ if (! exists)
432
+ rb_raise(rb_eArgError, "self is not in graph");
433
+ tie(target, exists) = rb_to_vertex(child, rb_graph);
434
+ if (! exists)
435
+ rb_raise(rb_eArgError, "child is not in graph");
436
+
437
+ RubyGraph& graph = graph_wrapped(rb_graph);
438
+ edge_descriptor e;
439
+ tie(e, exists) = edge(source, target, graph);
440
+ if (! exists)
441
+ rb_raise(rb_eArgError, "no such edge in graph");
442
+
443
+ return graph[e].info;
444
+ }
445
+
446
+ /*
447
+ * call-seq:
448
+ * vertex[child, graph] = new_value => new_value
449
+ *
450
+ * Sets the data associated with the vertex => +child+ edge in +graph+.
451
+ * Raises ArgumentError if there is no such edge.
452
+ */
453
+ static VALUE vertex_set_info(VALUE self, VALUE child, VALUE rb_graph, VALUE new_value)
454
+ {
455
+ vertex_descriptor source, target; bool exists;
456
+
457
+ tie(source, exists) = rb_to_vertex(self, rb_graph);
458
+ if (! exists)
459
+ rb_raise(rb_eArgError, "self is not in graph");
460
+ tie(target, exists) = rb_to_vertex(child, rb_graph);
461
+ if (! exists)
462
+ rb_raise(rb_eArgError, "child is not in graph");
463
+
464
+ RubyGraph& graph = graph_wrapped(rb_graph);
465
+ edge_descriptor e;
466
+ tie(e, exists) = edge(source, target, graph);
467
+ if (! exists)
468
+ rb_raise(rb_eArgError, "no such edge in graph");
469
+
470
+ return (graph[e].info = new_value);
471
+ }
472
+
473
+
474
+ /*
475
+ * call-seq:
476
+ * vertex.root?([graph])
477
+ *
478
+ * Checks if +vertex+ is a root node in +graph+ (it has no parents), or if graph is not given, in all graphs
479
+ */
480
+ static VALUE vertex_root_p(int argc, VALUE* argv, VALUE self)
481
+ { return vertex_has_adjacent<false>(argc, argv, self); }
482
+
483
+
484
+ /*
485
+ * call-seq:
486
+ * vertex.leaf?([graph])
487
+ *
488
+ * Checks if +vertex+ is a root node in +graph+ (it has no children), or if graph is not given, in all graphs
489
+ */
490
+ static VALUE vertex_leaf_p(int argc, VALUE* argv, VALUE self)
491
+ { return vertex_has_adjacent<true>(argc, argv, self); }
492
+
493
+ void Init_graph_algorithms();
494
+ extern "C" void Init_roby_bgl()
495
+ {
496
+ id_rb_graph_map = rb_intern("@__bgl_graphs__");
497
+
498
+ bglModule = rb_define_module("BGL");
499
+ bglGraph = rb_define_class_under(bglModule, "Graph", rb_cObject);
500
+ rb_define_alloc_func(bglGraph, graph_alloc);
501
+
502
+ // Functions to manipulate BGL::Vertex objects in Graphs
503
+ rb_define_method(bglGraph, "insert", RUBY_METHOD_FUNC(graph_insert), 1);
504
+ rb_define_method(bglGraph, "remove", RUBY_METHOD_FUNC(graph_remove), 1);
505
+ rb_define_method(bglGraph, "include?", RUBY_METHOD_FUNC(graph_include_p), 1);
506
+ rb_define_method(bglGraph, "link", RUBY_METHOD_FUNC(graph_link), 3);
507
+ rb_define_method(bglGraph, "unlink", RUBY_METHOD_FUNC(graph_unlink), 2);
508
+ rb_define_method(bglGraph, "linked?", RUBY_METHOD_FUNC(graph_linked_p), 2);
509
+ rb_define_method(bglGraph, "each_vertex", RUBY_METHOD_FUNC(graph_each_vertex), 0);
510
+ rb_define_method(bglGraph, "each_edge", RUBY_METHOD_FUNC(graph_each_edge), 0);
511
+
512
+ bglVertex = rb_define_module_under(bglModule, "Vertex");
513
+ rb_define_method(bglVertex, "related_vertex?", RUBY_METHOD_FUNC(vertex_related_p), -1);
514
+ rb_define_method(bglVertex, "parent_vertex?", RUBY_METHOD_FUNC(vertex_parent_p), -1);
515
+ rb_define_method(bglVertex, "child_vertex?", RUBY_METHOD_FUNC(vertex_child_p), -1);
516
+ rb_define_method(bglVertex, "each_child_vertex", RUBY_METHOD_FUNC(vertex_each_child), -1);
517
+ rb_define_method(bglVertex, "each_parent_vertex", RUBY_METHOD_FUNC(vertex_each_parent), -1);
518
+ rb_define_method(bglVertex, "each_graph", RUBY_METHOD_FUNC(vertex_each_graph), 0);
519
+ rb_define_method(bglVertex, "root?", RUBY_METHOD_FUNC(vertex_root_p), -1);
520
+ rb_define_method(bglVertex, "leaf?", RUBY_METHOD_FUNC(vertex_leaf_p), -1);
521
+ rb_define_method(bglVertex, "[]", RUBY_METHOD_FUNC(vertex_get_info), 2);
522
+ rb_define_method(bglVertex, "[]=", RUBY_METHOD_FUNC(vertex_set_info), 3);
523
+ rb_define_method(bglVertex, "singleton_vertex?", RUBY_METHOD_FUNC(vertex_singleton_p), 0);
524
+
525
+ bglReverseGraph = rb_define_class_under(bglGraph, "Reverse", rb_cObject);
526
+ bglUndirectedGraph = rb_define_class_under(bglGraph, "Undirected", rb_cObject);
527
+ Init_graph_algorithms();
528
+ }
529
+