/usr/include/gnuradio/flowgraph.h is in gnuradio-dev 3.7.9.1-2ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 | /* -*- c++ -*- */
/*
* Copyright 2006,2007,2013 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* GNU Radio is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU Radio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Radio; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef INCLUDED_GR_RUNTIME_FLOWGRAPH_H
#define INCLUDED_GR_RUNTIME_FLOWGRAPH_H
#include <gnuradio/api.h>
#include <gnuradio/basic_block.h>
#include <gnuradio/io_signature.h>
#include <iostream>
namespace gr {
/*!
* \brief Class representing a specific input or output graph endpoint
* \ingroup internal
*/
class GR_RUNTIME_API endpoint
{
private:
basic_block_sptr d_basic_block;
int d_port;
public:
endpoint() : d_basic_block(), d_port(0) { }
endpoint(basic_block_sptr block, int port) { d_basic_block = block; d_port = port; }
basic_block_sptr block() const { return d_basic_block; }
int port() const { return d_port; }
bool operator==(const endpoint &other) const;
};
inline bool endpoint::operator==(const endpoint &other) const
{
return (d_basic_block == other.d_basic_block &&
d_port == other.d_port);
}
class GR_RUNTIME_API msg_endpoint
{
private:
basic_block_sptr d_basic_block;
pmt::pmt_t d_port;
bool d_is_hier;
public:
msg_endpoint() : d_basic_block(), d_port(pmt::PMT_NIL) { }
msg_endpoint(basic_block_sptr block, pmt::pmt_t port, bool is_hier=false) {
d_basic_block = block; d_port = port; d_is_hier = is_hier;
}
basic_block_sptr block() const { return d_basic_block; }
pmt::pmt_t port() const { return d_port; }
bool is_hier() const { return d_is_hier; }
void set_hier(bool h) { d_is_hier = h; }
bool operator==(const msg_endpoint &other) const;
};
inline bool
msg_endpoint::operator==(const msg_endpoint &other) const
{
return (d_basic_block == other.d_basic_block &&
pmt::equal(d_port, other.d_port));
}
// Hold vectors of gr::endpoint objects
typedef std::vector<endpoint> endpoint_vector_t;
typedef std::vector<endpoint>::iterator endpoint_viter_t;
/*!
*\brief Class representing a connection between to graph endpoints
*/
class GR_RUNTIME_API edge
{
public:
edge() : d_src(), d_dst() { };
edge(const endpoint &src, const endpoint &dst)
: d_src(src), d_dst(dst) { }
~edge();
const endpoint &src() const { return d_src; }
const endpoint &dst() const { return d_dst; }
private:
endpoint d_src;
endpoint d_dst;
};
// Hold vectors of gr::edge objects
typedef std::vector<edge> edge_vector_t;
typedef std::vector<edge>::iterator edge_viter_t;
/*!
*\brief Class representing a msg connection between to graph msg endpoints
*/
class GR_RUNTIME_API msg_edge
{
public:
msg_edge() : d_src(), d_dst() { };
msg_edge(const msg_endpoint &src, const msg_endpoint &dst)
: d_src(src), d_dst(dst) { }
~msg_edge() {}
const msg_endpoint &src() const { return d_src; }
const msg_endpoint &dst() const { return d_dst; }
private:
msg_endpoint d_src;
msg_endpoint d_dst;
};
// Hold vectors of gr::msg_edge objects
typedef std::vector<msg_edge> msg_edge_vector_t;
typedef std::vector<msg_edge>::iterator msg_edge_viter_t;
// Create a shared pointer to a heap allocated flowgraph
// (types defined in runtime_types.h)
GR_RUNTIME_API flowgraph_sptr make_flowgraph();
/*!
* \brief Class representing a directed, acyclic graph of basic blocks
* \ingroup internal
*/
class GR_RUNTIME_API flowgraph
{
public:
friend GR_RUNTIME_API flowgraph_sptr make_flowgraph();
/*!
* \brief Destruct an arbitrary flowgraph
*/
virtual ~flowgraph();
/*!
* \brief Connect two endpoints
* \details
* Checks the validity of both endpoints, and whether the
* destination is unused so far, then adds the edge to the internal list of
* edges.
*/
void connect(const endpoint &src, const endpoint &dst);
/*!
* \brief Disconnect two endpoints
*/
void disconnect(const endpoint &src, const endpoint &dst);
/*!
* \brief convenience wrapper; used to connect two endpoints
*/
void connect(basic_block_sptr src_block, int src_port,
basic_block_sptr dst_block, int dst_port);
/*!
* \brief convenience wrapper; used to disconnect two endpoints
*/
void disconnect(basic_block_sptr src_block, int src_port,
basic_block_sptr dst_block, int dst_port);
/*!
* \brief Connect two message endpoints
* \details
* Checks the validity of both endpoints, then adds the edge to the
* internal list of edges.
*/
void connect(const msg_endpoint &src, const msg_endpoint &dst);
/*!
* \brief Disconnect two message endpoints
*/
void disconnect(const msg_endpoint &src, const msg_endpoint &dst);
/*!
* \brief Validate flow graph
* \details
* Gathers all used blocks, checks the contiguity of all connected in- and
* outputs, and calls the check_topology method of each block.
*/
void validate();
/*!
* \brief Clear existing flowgraph
*/
void clear();
/*!
* \brief Get vector of edges
*/
const edge_vector_t &edges() const { return d_edges; }
/*!
* \brief Get vector of message edges
*/
const msg_edge_vector_t &msg_edges() const { return d_msg_edges; }
/*!
* \brief calculates all used blocks in a flow graph
* \details
* Iterates over all message edges and stream edges, noting both endpoints in a vector.
*
* \return a unique vector of used blocks
*/
basic_block_vector_t calc_used_blocks();
/*!
* \brief topologically sort blocks
* \details
* Uses depth-first search to return a sorted vector of blocks
*
* \return toplogically sorted vector of blocks. All the sources come first.
*/
basic_block_vector_t topological_sort(basic_block_vector_t &blocks);
/*!
* \brief Calculate vector of disjoint graph partions
* \return vector of disjoint vectors of topologically sorted blocks
*/
std::vector<basic_block_vector_t> partition();
protected:
basic_block_vector_t d_blocks;
edge_vector_t d_edges;
msg_edge_vector_t d_msg_edges;
flowgraph();
std::vector<int> calc_used_ports(basic_block_sptr block, bool check_inputs);
basic_block_vector_t calc_downstream_blocks(basic_block_sptr block, int port);
edge_vector_t calc_upstream_edges(basic_block_sptr block);
bool has_block_p(basic_block_sptr block);
edge calc_upstream_edge(basic_block_sptr block, int port);
private:
void check_valid_port(gr::io_signature::sptr sig, int port);
void check_valid_port(const msg_endpoint &e);
void check_dst_not_used(const endpoint &dst);
void check_type_match(const endpoint &src, const endpoint &dst);
edge_vector_t calc_connections(basic_block_sptr block, bool check_inputs); // false=use outputs
void check_contiguity(basic_block_sptr block, const std::vector<int> &used_ports, bool check_inputs);
basic_block_vector_t calc_downstream_blocks(basic_block_sptr block);
basic_block_vector_t calc_reachable_blocks(basic_block_sptr block, basic_block_vector_t &blocks);
void reachable_dfs_visit(basic_block_sptr block, basic_block_vector_t &blocks);
basic_block_vector_t calc_adjacent_blocks(basic_block_sptr block, basic_block_vector_t &blocks);
basic_block_vector_t sort_sources_first(basic_block_vector_t &blocks);
bool source_p(basic_block_sptr block);
void topological_dfs_visit(basic_block_sptr block, basic_block_vector_t &output);
};
// Convenience functions
inline
void flowgraph::connect(basic_block_sptr src_block, int src_port,
basic_block_sptr dst_block, int dst_port)
{
connect(endpoint(src_block, src_port),
endpoint(dst_block, dst_port));
}
inline
void flowgraph::disconnect(basic_block_sptr src_block, int src_port,
basic_block_sptr dst_block, int dst_port)
{
disconnect(endpoint(src_block, src_port),
endpoint(dst_block, dst_port));
}
inline std::ostream&
operator <<(std::ostream &os, const endpoint endp)
{
os << endp.block()->alias() << ":" << endp.port();
return os;
}
inline std::ostream&
operator <<(std::ostream &os, const edge edge)
{
os << edge.src() << "->" << edge.dst();
return os;
}
inline std::ostream&
operator <<(std::ostream &os, const msg_endpoint endp)
{
os << endp.block()->alias() << ":" << pmt::symbol_to_string(endp.port());
return os;
}
inline std::ostream&
operator <<(std::ostream &os, const msg_edge edge)
{
os << edge.src() << "->" << edge.dst();
return os;
}
std::string dot_graph_fg (flowgraph_sptr fg);
} /* namespace gr */
#endif /* INCLUDED_GR_RUNTIME_FLOWGRAPH_H */
|