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