GNU Radio 3.4.0 C++ API
gr_basic_block.h
Go to the documentation of this file.
00001 /* -*- c++ -*- */
00002 /*
00003  * Copyright 2006,2008,2009,2011 Free Software Foundation, Inc.
00004  * 
00005  * This file is part of GNU Radio
00006  * 
00007  * GNU Radio is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 3, or (at your option)
00010  * any later version.
00011  * 
00012  * GNU Radio is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU General Public License
00018  * along with GNU Radio; see the file COPYING.  If not, write to
00019  * the Free Software Foundation, Inc., 51 Franklin Street,
00020  * Boston, MA 02110-1301, USA.
00021  */
00022 
00023 #ifndef INCLUDED_GR_BASIC_BLOCK_H
00024 #define INCLUDED_GR_BASIC_BLOCK_H
00025 
00026 #include <gr_runtime_types.h>
00027 #include <gr_sptr_magic.h>
00028 #include <boost/enable_shared_from_this.hpp>
00029 #include <boost/function.hpp>
00030 #include <gr_msg_accepter.h>
00031 #include <string>
00032 
00033 /*!
00034  * \brief The abstract base class for all signal processing blocks.
00035  * \ingroup internal
00036  *
00037  * Basic blocks are the bare abstraction of an entity that has a name,
00038  * a set of inputs and outputs, and a message queue.  These are never instantiated
00039  * directly; rather, this is the abstract parent class of both gr_hier_block,
00040  * which is a recursive container, and gr_block, which implements actual
00041  * signal processing functions.
00042  */
00043 
00044 class gr_basic_block : public gr_msg_accepter, public boost::enable_shared_from_this<gr_basic_block>
00045 {
00046     typedef boost::function<void(pmt::pmt_t)> msg_handler_t;
00047 
00048 private:
00049     /*
00050      * This function is called by the runtime system to dispatch messages.
00051      *
00052      * The thread-safety guarantees mentioned in set_msg_handler are implemented
00053      * by the callers of this method.
00054      */
00055     void dispatch_msg(pmt::pmt_t msg)
00056     {
00057       if (d_msg_handler)        // Is there a handler?
00058         d_msg_handler(msg);     // Yes, invoke it.
00059     };
00060 
00061     msg_handler_t        d_msg_handler;
00062 
00063 protected:
00064     friend class gr_flowgraph;
00065     friend class gr_flat_flowgraph; // TODO: will be redundant
00066     friend class gr_tpb_thread_body;
00067 
00068     enum vcolor { WHITE, GREY, BLACK };
00069 
00070     std::string          d_name;
00071     gr_io_signature_sptr d_input_signature;
00072     gr_io_signature_sptr d_output_signature;
00073     long                 d_unique_id;
00074     vcolor               d_color;
00075 
00076     gr_basic_block(void){} //allows pure virtual interface sub-classes
00077 
00078     //! Protected constructor prevents instantiation by non-derived classes
00079     gr_basic_block(const std::string &name,
00080                    gr_io_signature_sptr input_signature,
00081                    gr_io_signature_sptr output_signature);
00082 
00083     //! may only be called during constructor
00084     void set_input_signature(gr_io_signature_sptr iosig) {
00085         d_input_signature = iosig;
00086     }
00087     
00088     //! may only be called during constructor
00089     void set_output_signature(gr_io_signature_sptr iosig) {
00090         d_output_signature = iosig;
00091     }
00092 
00093     /*!
00094      * \brief Allow the flowgraph to set for sorting and partitioning
00095      */
00096     void set_color(vcolor color) { d_color = color; }
00097     vcolor color() const { return d_color; }
00098 
00099 public:
00100     virtual ~gr_basic_block();
00101     long unique_id() const { return d_unique_id; }
00102     std::string name() const { return d_name; }
00103     gr_io_signature_sptr input_signature() const  { return d_input_signature; }
00104     gr_io_signature_sptr output_signature() const { return d_output_signature; }
00105     gr_basic_block_sptr to_basic_block(); // Needed for Python/Guile type coercion
00106 
00107     /*!
00108      * \brief Confirm that ninputs and noutputs is an acceptable combination.
00109      *
00110      * \param ninputs   number of input streams connected
00111      * \param noutputs  number of output streams connected
00112      *
00113      * \returns true if this is a valid configuration for this block.
00114      *
00115      * This function is called by the runtime system whenever the
00116      * topology changes.  Most classes do not need to override this.
00117      * This check is in addition to the constraints specified by the input
00118      * and output gr_io_signatures.
00119      */
00120     virtual bool check_topology(int ninputs, int noutputs) { return true; }
00121 
00122     /*!
00123      * \brief Set the callback that is fired when messages are available.
00124      *
00125      * \p msg_handler can be any kind of function pointer or function object
00126      * that has the signature:
00127      * <pre>
00128      *    void msg_handler(pmt::pmt msg);
00129      * </pre>
00130      *
00131      * (You may want to use boost::bind to massage your callable into the
00132      * correct form.  See gr_nop.{h,cc} for an example that sets up a class
00133      * method as the callback.)
00134      *
00135      * Blocks that desire to handle messages must call this method in their
00136      * constructors to register the handler that will be invoked when messages
00137      * are available.
00138      *
00139      * If the block inherits from gr_block, the runtime system will ensure that
00140      * msg_handler is called in a thread-safe manner, such that work and
00141      * msg_handler will never be called concurrently.  This allows msg_handler
00142      * to update state variables without having to worry about thread-safety
00143      * issues with work, general_work or another invocation of msg_handler.
00144      *
00145      * If the block inherits from gr_hier_block2, the runtime system will
00146      * ensure that no reentrant calls are made to msg_handler.
00147      */
00148     template <typename T> void set_msg_handler(T msg_handler){
00149       d_msg_handler = msg_handler_t(msg_handler);
00150     }
00151 };
00152 
00153 inline bool operator<(gr_basic_block_sptr lhs, gr_basic_block_sptr rhs)
00154 {
00155   return lhs->unique_id() < rhs->unique_id();
00156 }
00157 
00158 typedef std::vector<gr_basic_block_sptr> gr_basic_block_vector_t;
00159 typedef std::vector<gr_basic_block_sptr>::iterator gr_basic_block_viter_t;
00160 
00161 long gr_basic_block_ncurrently_allocated();
00162 
00163 inline std::ostream &operator << (std::ostream &os, gr_basic_block_sptr basic_block)
00164 {
00165     os << basic_block->name() << "(" << basic_block->unique_id() << ")";
00166     return os;
00167 }
00168 
00169 #endif /* INCLUDED_GR_BASIC_BLOCK_H */