GNU Radio 3.5.3.2 C++ API
gr_basic_block.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2006,2008,2009,2011 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_BASIC_BLOCK_H
24 #define INCLUDED_GR_BASIC_BLOCK_H
25 
26 #include <gr_core_api.h>
27 #include <gr_runtime_types.h>
28 #include <gr_sptr_magic.h>
29 #include <boost/enable_shared_from_this.hpp>
30 #include <boost/function.hpp>
31 #include <gr_msg_accepter.h>
32 #include <string>
33 
34 /*!
35  * \brief The abstract base class for all signal processing blocks.
36  * \ingroup internal
37  *
38  * Basic blocks are the bare abstraction of an entity that has a name,
39  * a set of inputs and outputs, and a message queue. These are never instantiated
40  * directly; rather, this is the abstract parent class of both gr_hier_block,
41  * which is a recursive container, and gr_block, which implements actual
42  * signal processing functions.
43  */
44 
45 class GR_CORE_API gr_basic_block : public gr_msg_accepter, public boost::enable_shared_from_this<gr_basic_block>
46 {
47  typedef boost::function<void(pmt::pmt_t)> msg_handler_t;
48 
49 private:
50  /*
51  * This function is called by the runtime system to dispatch messages.
52  *
53  * The thread-safety guarantees mentioned in set_msg_handler are implemented
54  * by the callers of this method.
55  */
56  void dispatch_msg(pmt::pmt_t msg)
57  {
58  if (d_msg_handler) // Is there a handler?
59  d_msg_handler(msg); // Yes, invoke it.
60  };
61 
62  msg_handler_t d_msg_handler;
63 
64 protected:
65  friend class gr_flowgraph;
66  friend class gr_flat_flowgraph; // TODO: will be redundant
67  friend class gr_tpb_thread_body;
68 
69  enum vcolor { WHITE, GREY, BLACK };
70 
71  std::string d_name;
76 
77  gr_basic_block(void){} //allows pure virtual interface sub-classes
78 
79  //! Protected constructor prevents instantiation by non-derived classes
80  gr_basic_block(const std::string &name,
81  gr_io_signature_sptr input_signature,
82  gr_io_signature_sptr output_signature);
83 
84  //! may only be called during constructor
86  d_input_signature = iosig;
87  }
88 
89  //! may only be called during constructor
91  d_output_signature = iosig;
92  }
93 
94  /*!
95  * \brief Allow the flowgraph to set for sorting and partitioning
96  */
97  void set_color(vcolor color) { d_color = color; }
98  vcolor color() const { return d_color; }
99 
100 public:
101  virtual ~gr_basic_block();
102  long unique_id() const { return d_unique_id; }
103  std::string name() const { return d_name; }
104  gr_io_signature_sptr input_signature() const { return d_input_signature; }
105  gr_io_signature_sptr output_signature() const { return d_output_signature; }
106  gr_basic_block_sptr to_basic_block(); // Needed for Python/Guile type coercion
107 
108  /*!
109  * \brief Confirm that ninputs and noutputs is an acceptable combination.
110  *
111  * \param ninputs number of input streams connected
112  * \param noutputs number of output streams connected
113  *
114  * \returns true if this is a valid configuration for this block.
115  *
116  * This function is called by the runtime system whenever the
117  * topology changes. Most classes do not need to override this.
118  * This check is in addition to the constraints specified by the input
119  * and output gr_io_signatures.
120  */
121  virtual bool check_topology(int ninputs, int noutputs) { return true; }
122 
123  /*!
124  * \brief Set the callback that is fired when messages are available.
125  *
126  * \p msg_handler can be any kind of function pointer or function object
127  * that has the signature:
128  * <pre>
129  * void msg_handler(pmt::pmt msg);
130  * </pre>
131  *
132  * (You may want to use boost::bind to massage your callable into the
133  * correct form. See gr_nop.{h,cc} for an example that sets up a class
134  * method as the callback.)
135  *
136  * Blocks that desire to handle messages must call this method in their
137  * constructors to register the handler that will be invoked when messages
138  * are available.
139  *
140  * If the block inherits from gr_block, the runtime system will ensure that
141  * msg_handler is called in a thread-safe manner, such that work and
142  * msg_handler will never be called concurrently. This allows msg_handler
143  * to update state variables without having to worry about thread-safety
144  * issues with work, general_work or another invocation of msg_handler.
145  *
146  * If the block inherits from gr_hier_block2, the runtime system will
147  * ensure that no reentrant calls are made to msg_handler.
148  */
149  template <typename T> void set_msg_handler(T msg_handler){
150  d_msg_handler = msg_handler_t(msg_handler);
151  }
152 };
153 
155 {
156  return lhs->unique_id() < rhs->unique_id();
157 }
158 
159 typedef std::vector<gr_basic_block_sptr> gr_basic_block_vector_t;
160 typedef std::vector<gr_basic_block_sptr>::iterator gr_basic_block_viter_t;
161 
163 
164 inline std::ostream &operator << (std::ostream &os, gr_basic_block_sptr basic_block)
165 {
166  os << basic_block->name() << "(" << basic_block->unique_id() << ")";
167  return os;
168 }
169 
170 #endif /* INCLUDED_GR_BASIC_BLOCK_H */