GNU Radio 3.6.1 C++ API
gr_flowgraph.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2006,2007 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  *
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING. If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #ifndef INCLUDED_GR_FLOWGRAPH_H
24 #define INCLUDED_GR_FLOWGRAPH_H
25 
26 #include <gr_core_api.h>
27 #include <gr_basic_block.h>
28 #include <iostream>
29 
30 /*!
31  * \brief Class representing a specific input or output graph endpoint
32  * \ingroup internal
33  */
35 {
36 private:
37  gr_basic_block_sptr d_basic_block;
38  int d_port;
39 
40 public:
41  gr_endpoint() : d_basic_block(), d_port(0) { }
42  gr_endpoint(gr_basic_block_sptr block, int port) { d_basic_block = block; d_port = port; }
43  gr_basic_block_sptr block() const { return d_basic_block; }
44  int port() const { return d_port; }
45 
46  bool operator==(const gr_endpoint &other) const;
47 };
48 
49 inline bool gr_endpoint::operator==(const gr_endpoint &other) const
50 {
51  return (d_basic_block == other.d_basic_block &&
52  d_port == other.d_port);
53 }
54 
55 // Hold vectors of gr_endpoint objects
56 typedef std::vector<gr_endpoint> gr_endpoint_vector_t;
57 typedef std::vector<gr_endpoint>::iterator gr_endpoint_viter_t;
58 
59 /*!
60  *\brief Class representing a connection between to graph endpoints
61  *
62  */
64 {
65 public:
66  gr_edge() : d_src(), d_dst() { };
67  gr_edge(const gr_endpoint &src, const gr_endpoint &dst) : d_src(src), d_dst(dst) { }
68  ~gr_edge();
69 
70  const gr_endpoint &src() const { return d_src; }
71  const gr_endpoint &dst() const { return d_dst; }
72 
73 private:
74  gr_endpoint d_src;
75  gr_endpoint d_dst;
76 };
77 
78 // Hold vectors of gr_edge objects
79 typedef std::vector<gr_edge> gr_edge_vector_t;
80 typedef std::vector<gr_edge>::iterator gr_edge_viter_t;
81 
82 
83 // Create a shared pointer to a heap allocated flowgraph
84 // (types defined in gr_runtime_types.h)
86 
87 /*!
88  * \brief Class representing a directed, acyclic graph of basic blocks
89  * \ingroup internal
90  */
92 {
93 public:
95 
96  // Destruct an arbitrary flowgraph
97  ~gr_flowgraph();
98 
99  // Connect two endpoints
100  void connect(const gr_endpoint &src, const gr_endpoint &dst);
101 
102  // Disconnect two endpoints
103  void disconnect(const gr_endpoint &src, const gr_endpoint &dst);
104 
105  // Connect an output port to an input port (convenience)
106  void connect(gr_basic_block_sptr src_block, int src_port,
107  gr_basic_block_sptr dst_block, int dst_port);
108 
109  // Disconnect an input port from an output port (convenience)
110  void disconnect(gr_basic_block_sptr src_block, int src_port,
111  gr_basic_block_sptr dst_block, int dst_port);
112 
113  // Validate connectivity, raise exception if invalid
114  void validate();
115 
116  // Clear existing flowgraph
117  void clear();
118 
119  // Return vector of edges
120  const gr_edge_vector_t &edges() const { return d_edges; }
121 
122  // Return vector of connected blocks
123  gr_basic_block_vector_t calc_used_blocks();
124 
125  // Return toplogically sorted vector of blocks. All the sources come first.
126  gr_basic_block_vector_t topological_sort(gr_basic_block_vector_t &blocks);
127 
128  // Return vector of vectors of disjointly connected blocks, topologically
129  // sorted.
130  std::vector<gr_basic_block_vector_t> partition();
131 
132 protected:
135 
136  gr_flowgraph();
137  std::vector<int> calc_used_ports(gr_basic_block_sptr block, bool check_inputs);
138  gr_basic_block_vector_t calc_downstream_blocks(gr_basic_block_sptr block, int port);
139  gr_edge_vector_t calc_upstream_edges(gr_basic_block_sptr block);
140  bool has_block_p(gr_basic_block_sptr block);
141  gr_edge calc_upstream_edge(gr_basic_block_sptr block, int port);
142 
143 private:
144 
145  void check_valid_port(gr_io_signature_sptr sig, int port);
146  void check_dst_not_used(const gr_endpoint &dst);
147  void check_type_match(const gr_endpoint &src, const gr_endpoint &dst);
148  gr_edge_vector_t calc_connections(gr_basic_block_sptr block, bool check_inputs); // false=use outputs
149  void check_contiguity(gr_basic_block_sptr block, const std::vector<int> &used_ports, bool check_inputs);
150 
151  gr_basic_block_vector_t calc_downstream_blocks(gr_basic_block_sptr block);
152  gr_basic_block_vector_t calc_reachable_blocks(gr_basic_block_sptr block, gr_basic_block_vector_t &blocks);
153  void reachable_dfs_visit(gr_basic_block_sptr block, gr_basic_block_vector_t &blocks);
154  gr_basic_block_vector_t calc_adjacent_blocks(gr_basic_block_sptr block, gr_basic_block_vector_t &blocks);
155  gr_basic_block_vector_t sort_sources_first(gr_basic_block_vector_t &blocks);
156  bool source_p(gr_basic_block_sptr block);
157  void topological_dfs_visit(gr_basic_block_sptr block, gr_basic_block_vector_t &output);
158 };
159 
160 // Convenience functions
161 inline
162 void gr_flowgraph::connect(gr_basic_block_sptr src_block, int src_port,
163  gr_basic_block_sptr dst_block, int dst_port)
164 {
165  connect(gr_endpoint(src_block, src_port),
166  gr_endpoint(dst_block, dst_port));
167 }
168 
169 inline
170 void gr_flowgraph::disconnect(gr_basic_block_sptr src_block, int src_port,
171  gr_basic_block_sptr dst_block, int dst_port)
172 {
173  disconnect(gr_endpoint(src_block, src_port),
174  gr_endpoint(dst_block, dst_port));
175 }
176 
177 inline std::ostream&
178 operator <<(std::ostream &os, const gr_endpoint endp)
179 {
180  os << endp.block() << ":" << endp.port();
181  return os;
182 }
183 
184 inline std::ostream&
185 operator <<(std::ostream &os, const gr_edge edge)
186 {
187  os << edge.src() << "->" << edge.dst();
188  return os;
189 }
190 
191 #endif /* INCLUDED_GR_FLOWGRAPH_H */