1 #if !defined(FLOW_GRAPH_H)
25 typedef std::map<std::string, std::shared_ptr<node>> nodes_t;
26 nodes_t d_producers, d_transformers, d_consumers;
28 typedef std::map<std::string, std::unique_ptr<std::thread>> threads_t;
31 typedef std::map<std::string, std::map<size_t, std::pair<std::string, size_t>>> connections_t;
32 connections_t connections;
36 graph(
const std::string name_r =
"graph") :
named(name_r)
50 virtual void add(std::shared_ptr<node> node_p,
const std::string& name_r = std::string())
54 node_p->rename(name_r);
57 if(std::dynamic_pointer_cast<detail::transformer>(node_p))
59 d_transformers[node_p->name()] = node_p;
61 else if(std::dynamic_pointer_cast<detail::producer>(node_p))
63 d_producers[node_p->name()] = node_p;
65 else if(std::dynamic_pointer_cast<detail::consumer>(node_p))
67 d_consumers[node_p->name()] = node_p;
70 connections[node_p->name()];
78 virtual std::shared_ptr<node>
remove(
const std::string& name_r)
80 std::shared_ptr<node> p;
84 if(n = find(name_r, i))
91 connections.erase(name_r);
99 virtual void remove(
const std::shared_ptr<node>& sp_node)
101 remove(sp_node->name());
115 bool connect(
const std::string& p_name_r,
const size_t p_pin,
const std::string& c_name_r,
const size_t c_pin,
const size_t max_length = 0,
const size_t max_weight = 0)
117 nodes_t::iterator p, c;
120 if(!find(p_name_r, p) || !find(c_name_r, c))
125 std::dynamic_pointer_cast<
producer<T>>(p->second)->
connect(p_pin, std::dynamic_pointer_cast<
consumer<T>>(c->second).get(), c_pin, max_length, max_weight);
127 connections[p_name_r][p_pin] = std::make_pair(c_name_r, c_pin);
148 if(!find(sp_p->name(), i) || !find(sp_c->name(), i))
153 sp_p->connect(p_pin, sp_c.get(), c_pin, max_length, max_weight);
155 connections[sp_p->name()][p_pin] = std::make_pair(sp_c->name(), c_pin);
167 sp_p->disconnect(p_pin);
169 connections[sp_p->name()][p_pin] = std::make_pair(std::string(), 0);
179 sp_c->disconnect(c_pin);
181 connections[sp_c->name()][c_pin] = std::make_pair(std::string(), 0);
190 auto start_f = [
this](nodes_t::value_type& i)
194 if(d_threads.find(i.first) == d_threads.end())
197 d_threads[i.first] = std::unique_ptr<std::thread>(
new std::thread([&i]{ i.second->operator()(); }));
201 for(
auto& i : d_consumers){ start_f(i); }
202 for(
auto& i : d_transformers){ start_f(i); }
203 for(
auto& i : d_producers){ start_f(i); }
211 auto pause_f = [
this](nodes_t::value_type& i)
216 for(
auto& i : d_producers){ pause_f(i); }
217 for(
auto& i : d_transformers){ pause_f(i); }
218 for(
auto& i : d_consumers){ pause_f(i); }
226 auto stop_f = [
this](nodes_t::value_type& i)
230 graph::threads_t::iterator j = d_threads.find(i.first);
231 if(j != d_threads.end())
238 for(
auto& i : d_producers){ stop_f(i); }
239 for(
auto& i : d_transformers){ stop_f(i); }
240 for(
auto& i : d_consumers){ stop_f(i); }
246 virtual std::ostream&
to_dot(std::ostream& o)
248 o <<
"digraph " << (
name() ==
"graph" ?
"graph1" :
name()) <<
"\n{\n";
249 o <<
"\trankdir = LR\n";
250 o <<
"\tnode [shape = record, fontname = \"Helvetica\"]\n";
251 o <<
"\tedge [color = \"midnightblue\", labelfontname = \"Courier\"]\n";
253 for(
auto& p : connections)
255 for(
auto& i : p.second)
257 o <<
"\t" << p.first <<
" -> " << i.second.first <<
" [taillabel = \"" << i.first <<
"\", headlabel = \"" << i.second.second <<
"\"]\n";
261 o <<
"}" << std::endl;
267 virtual nodes_t* find(
const std::string& name_r, nodes_t::iterator& i)
269 i = d_producers.find(name_r);
271 if(i != d_producers.end())
275 else if((i = d_transformers.find(name_r)) != d_transformers.end())
277 return &d_transformers;
279 else if((i = d_consumers.find(name_r)) != d_consumers.end())