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.
- data/.gitignore +29 -0
- data/History.txt +4 -0
- data/License-fr.txt +519 -0
- data/License.txt +515 -0
- data/Manifest.txt +245 -0
- data/NOTES +4 -0
- data/README.txt +163 -0
- data/Rakefile +161 -0
- data/TODO.txt +146 -0
- data/app/README.txt +24 -0
- data/app/Rakefile +8 -0
- data/app/config/ROBOT.rb +5 -0
- data/app/config/app.yml +91 -0
- data/app/config/init.rb +7 -0
- data/app/config/roby.yml +3 -0
- data/app/controllers/.gitattributes +0 -0
- data/app/controllers/ROBOT.rb +2 -0
- data/app/data/.gitattributes +0 -0
- data/app/planners/ROBOT/main.rb +6 -0
- data/app/planners/main.rb +5 -0
- data/app/scripts/distributed +3 -0
- data/app/scripts/generate/bookmarks +3 -0
- data/app/scripts/replay +3 -0
- data/app/scripts/results +3 -0
- data/app/scripts/run +3 -0
- data/app/scripts/server +3 -0
- data/app/scripts/shell +3 -0
- data/app/scripts/test +3 -0
- data/app/tasks/.gitattributes +0 -0
- data/app/tasks/ROBOT/.gitattributes +0 -0
- data/bin/roby +210 -0
- data/bin/roby-log +168 -0
- data/bin/roby-shell +25 -0
- data/doc/images/event_generalization.png +0 -0
- data/doc/images/exception_propagation_1.png +0 -0
- data/doc/images/exception_propagation_2.png +0 -0
- data/doc/images/exception_propagation_3.png +0 -0
- data/doc/images/exception_propagation_4.png +0 -0
- data/doc/images/exception_propagation_5.png +0 -0
- data/doc/images/replay_handler_error.png +0 -0
- data/doc/images/replay_handler_error_0.png +0 -0
- data/doc/images/replay_handler_error_1.png +0 -0
- data/doc/images/roby_cycle_overview.png +0 -0
- data/doc/images/roby_replay_02.png +0 -0
- data/doc/images/roby_replay_03.png +0 -0
- data/doc/images/roby_replay_04.png +0 -0
- data/doc/images/roby_replay_event_representation.png +0 -0
- data/doc/images/roby_replay_first_state.png +0 -0
- data/doc/images/roby_replay_relations.png +0 -0
- data/doc/images/roby_replay_startup.png +0 -0
- data/doc/images/task_event_generalization.png +0 -0
- data/doc/papers.rdoc +11 -0
- data/doc/styles/allison.css +314 -0
- data/doc/styles/allison.js +316 -0
- data/doc/styles/allison.rb +276 -0
- data/doc/styles/jamis.rb +593 -0
- data/doc/tutorials/01-GettingStarted.rdoc +86 -0
- data/doc/tutorials/02-GoForward.rdoc +220 -0
- data/doc/tutorials/03-PlannedPath.rdoc +268 -0
- data/doc/tutorials/04-EventPropagation.rdoc +236 -0
- data/doc/tutorials/05-ErrorHandling.rdoc +319 -0
- data/doc/tutorials/06-Overview.rdoc +40 -0
- data/doc/videos.rdoc +69 -0
- data/ext/droby/dump.cc +175 -0
- data/ext/droby/extconf.rb +3 -0
- data/ext/graph/algorithm.cc +746 -0
- data/ext/graph/extconf.rb +7 -0
- data/ext/graph/graph.cc +529 -0
- data/ext/graph/graph.hh +183 -0
- data/ext/graph/iterator_sequence.hh +102 -0
- data/ext/graph/undirected_dfs.hh +226 -0
- data/ext/graph/undirected_graph.hh +421 -0
- data/lib/roby.rb +41 -0
- data/lib/roby/app.rb +870 -0
- data/lib/roby/app/rake.rb +56 -0
- data/lib/roby/app/run.rb +14 -0
- data/lib/roby/app/scripts/distributed.rb +13 -0
- data/lib/roby/app/scripts/generate/bookmarks.rb +162 -0
- data/lib/roby/app/scripts/replay.rb +31 -0
- data/lib/roby/app/scripts/results.rb +15 -0
- data/lib/roby/app/scripts/run.rb +26 -0
- data/lib/roby/app/scripts/server.rb +18 -0
- data/lib/roby/app/scripts/shell.rb +88 -0
- data/lib/roby/app/scripts/test.rb +40 -0
- data/lib/roby/basic_object.rb +151 -0
- data/lib/roby/config.rb +5 -0
- data/lib/roby/control.rb +747 -0
- data/lib/roby/decision_control.rb +17 -0
- data/lib/roby/distributed.rb +32 -0
- data/lib/roby/distributed/base.rb +440 -0
- data/lib/roby/distributed/communication.rb +871 -0
- data/lib/roby/distributed/connection_space.rb +592 -0
- data/lib/roby/distributed/distributed_object.rb +206 -0
- data/lib/roby/distributed/drb.rb +62 -0
- data/lib/roby/distributed/notifications.rb +539 -0
- data/lib/roby/distributed/peer.rb +550 -0
- data/lib/roby/distributed/protocol.rb +529 -0
- data/lib/roby/distributed/proxy.rb +343 -0
- data/lib/roby/distributed/subscription.rb +311 -0
- data/lib/roby/distributed/transaction.rb +498 -0
- data/lib/roby/event.rb +897 -0
- data/lib/roby/exceptions.rb +234 -0
- data/lib/roby/executives/simple.rb +30 -0
- data/lib/roby/graph.rb +166 -0
- data/lib/roby/interface.rb +390 -0
- data/lib/roby/log.rb +3 -0
- data/lib/roby/log/chronicle.rb +303 -0
- data/lib/roby/log/console.rb +72 -0
- data/lib/roby/log/data_stream.rb +197 -0
- data/lib/roby/log/dot.rb +279 -0
- data/lib/roby/log/event_stream.rb +151 -0
- data/lib/roby/log/file.rb +340 -0
- data/lib/roby/log/gui/basic_display.ui +83 -0
- data/lib/roby/log/gui/chronicle.rb +26 -0
- data/lib/roby/log/gui/chronicle_view.rb +40 -0
- data/lib/roby/log/gui/chronicle_view.ui +70 -0
- data/lib/roby/log/gui/data_displays.rb +172 -0
- data/lib/roby/log/gui/data_displays.ui +155 -0
- data/lib/roby/log/gui/notifications.rb +26 -0
- data/lib/roby/log/gui/relations.rb +248 -0
- data/lib/roby/log/gui/relations.ui +123 -0
- data/lib/roby/log/gui/relations_view.rb +185 -0
- data/lib/roby/log/gui/relations_view.ui +149 -0
- data/lib/roby/log/gui/replay.rb +327 -0
- data/lib/roby/log/gui/replay_controls.rb +200 -0
- data/lib/roby/log/gui/replay_controls.ui +259 -0
- data/lib/roby/log/gui/runtime.rb +130 -0
- data/lib/roby/log/hooks.rb +185 -0
- data/lib/roby/log/logger.rb +202 -0
- data/lib/roby/log/notifications.rb +244 -0
- data/lib/roby/log/plan_rebuilder.rb +470 -0
- data/lib/roby/log/relations.rb +1056 -0
- data/lib/roby/log/server.rb +550 -0
- data/lib/roby/log/sqlite.rb +47 -0
- data/lib/roby/log/timings.rb +164 -0
- data/lib/roby/plan-object.rb +247 -0
- data/lib/roby/plan.rb +762 -0
- data/lib/roby/planning.rb +13 -0
- data/lib/roby/planning/loops.rb +302 -0
- data/lib/roby/planning/model.rb +906 -0
- data/lib/roby/planning/task.rb +151 -0
- data/lib/roby/propagation.rb +562 -0
- data/lib/roby/query.rb +619 -0
- data/lib/roby/relations.rb +583 -0
- data/lib/roby/relations/conflicts.rb +70 -0
- data/lib/roby/relations/ensured.rb +20 -0
- data/lib/roby/relations/error_handling.rb +23 -0
- data/lib/roby/relations/events.rb +9 -0
- data/lib/roby/relations/executed_by.rb +193 -0
- data/lib/roby/relations/hierarchy.rb +239 -0
- data/lib/roby/relations/influence.rb +10 -0
- data/lib/roby/relations/planned_by.rb +63 -0
- data/lib/roby/robot.rb +7 -0
- data/lib/roby/standard_errors.rb +218 -0
- data/lib/roby/state.rb +5 -0
- data/lib/roby/state/events.rb +221 -0
- data/lib/roby/state/information.rb +55 -0
- data/lib/roby/state/pos.rb +110 -0
- data/lib/roby/state/shapes.rb +32 -0
- data/lib/roby/state/state.rb +353 -0
- data/lib/roby/support.rb +92 -0
- data/lib/roby/task-operations.rb +182 -0
- data/lib/roby/task.rb +1618 -0
- data/lib/roby/test/common.rb +399 -0
- data/lib/roby/test/distributed.rb +214 -0
- data/lib/roby/test/tasks/empty_task.rb +9 -0
- data/lib/roby/test/tasks/goto.rb +36 -0
- data/lib/roby/test/tasks/simple_task.rb +23 -0
- data/lib/roby/test/testcase.rb +519 -0
- data/lib/roby/test/tools.rb +160 -0
- data/lib/roby/thread_task.rb +87 -0
- data/lib/roby/transactions.rb +462 -0
- data/lib/roby/transactions/proxy.rb +292 -0
- data/lib/roby/transactions/updates.rb +139 -0
- data/plugins/fault_injection/History.txt +4 -0
- data/plugins/fault_injection/README.txt +37 -0
- data/plugins/fault_injection/Rakefile +18 -0
- data/plugins/fault_injection/TODO.txt +0 -0
- data/plugins/fault_injection/app.rb +52 -0
- data/plugins/fault_injection/fault_injection.rb +89 -0
- data/plugins/fault_injection/test/test_fault_injection.rb +84 -0
- data/plugins/subsystems/README.txt +40 -0
- data/plugins/subsystems/Rakefile +18 -0
- data/plugins/subsystems/app.rb +171 -0
- data/plugins/subsystems/test/app/README +24 -0
- data/plugins/subsystems/test/app/Rakefile +8 -0
- data/plugins/subsystems/test/app/config/app.yml +71 -0
- data/plugins/subsystems/test/app/config/init.rb +9 -0
- data/plugins/subsystems/test/app/config/roby.yml +3 -0
- data/plugins/subsystems/test/app/planners/main.rb +20 -0
- data/plugins/subsystems/test/app/scripts/distributed +3 -0
- data/plugins/subsystems/test/app/scripts/replay +3 -0
- data/plugins/subsystems/test/app/scripts/results +3 -0
- data/plugins/subsystems/test/app/scripts/run +3 -0
- data/plugins/subsystems/test/app/scripts/server +3 -0
- data/plugins/subsystems/test/app/scripts/shell +3 -0
- data/plugins/subsystems/test/app/scripts/test +3 -0
- data/plugins/subsystems/test/app/tasks/services.rb +15 -0
- data/plugins/subsystems/test/test_subsystems.rb +71 -0
- data/test/distributed/test_communication.rb +178 -0
- data/test/distributed/test_connection.rb +282 -0
- data/test/distributed/test_execution.rb +373 -0
- data/test/distributed/test_mixed_plan.rb +341 -0
- data/test/distributed/test_plan_notifications.rb +238 -0
- data/test/distributed/test_protocol.rb +516 -0
- data/test/distributed/test_query.rb +102 -0
- data/test/distributed/test_remote_plan.rb +491 -0
- data/test/distributed/test_transaction.rb +463 -0
- data/test/mockups/tasks.rb +27 -0
- data/test/planning/test_loops.rb +380 -0
- data/test/planning/test_model.rb +427 -0
- data/test/planning/test_task.rb +106 -0
- data/test/relations/test_conflicts.rb +42 -0
- data/test/relations/test_ensured.rb +38 -0
- data/test/relations/test_executed_by.rb +149 -0
- data/test/relations/test_hierarchy.rb +158 -0
- data/test/relations/test_planned_by.rb +54 -0
- data/test/suite_core.rb +24 -0
- data/test/suite_distributed.rb +9 -0
- data/test/suite_planning.rb +3 -0
- data/test/suite_relations.rb +8 -0
- data/test/test_bgl.rb +508 -0
- data/test/test_control.rb +399 -0
- data/test/test_event.rb +894 -0
- data/test/test_exceptions.rb +592 -0
- data/test/test_interface.rb +37 -0
- data/test/test_log.rb +114 -0
- data/test/test_log_server.rb +132 -0
- data/test/test_plan.rb +584 -0
- data/test/test_propagation.rb +210 -0
- data/test/test_query.rb +266 -0
- data/test/test_relations.rb +180 -0
- data/test/test_state.rb +414 -0
- data/test/test_support.rb +16 -0
- data/test/test_task.rb +938 -0
- data/test/test_testcase.rb +122 -0
- data/test/test_thread_task.rb +73 -0
- data/test/test_transactions.rb +569 -0
- data/test/test_transactions_proxy.rb +198 -0
- metadata +570 -0
data/ext/graph/graph.cc
ADDED
|
@@ -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
|
+
|