summaryrefslogtreecommitdiff
path: root/gnuradio-core/src/lib
diff options
context:
space:
mode:
authorjcorgan2006-12-12 20:00:39 +0000
committerjcorgan2006-12-12 20:00:39 +0000
commit76ed4c2fea5f59bfe02bbbb17754ef7eda44feca (patch)
treec30952925ea02e52f137e1e7f4da658629994936 /gnuradio-core/src/lib
parent5de36fac220305307d6fb64eabe6f417a26c0982 (diff)
downloadgnuradio-76ed4c2fea5f59bfe02bbbb17754ef7eda44feca.tar.gz
gnuradio-76ed4c2fea5f59bfe02bbbb17754ef7eda44feca.tar.bz2
gnuradio-76ed4c2fea5f59bfe02bbbb17754ef7eda44feca.zip
Merge jcorgan/hier developer branch into trunk. Enables creation of true hierarchical blocks, from either C++ or Python, as well as creating pure C++ gnuradio applications. EXPERIMENTAL.
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@4070 221aa14e-8319-0410-a670-987f0aec2ac5
Diffstat (limited to 'gnuradio-core/src/lib')
-rw-r--r--gnuradio-core/src/lib/runtime/Makefile.am20
-rw-r--r--gnuradio-core/src/lib/runtime/gr_basic_block.cc59
-rw-r--r--gnuradio-core/src/lib/runtime/gr_basic_block.h99
-rw-r--r--gnuradio-core/src/lib/runtime/gr_basic_block.i52
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block.cc23
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block.h66
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block.i16
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block_detail.cc3
-rw-r--r--gnuradio-core/src/lib/runtime/gr_block_detail.h28
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2.cc63
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2.h67
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2.i52
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc227
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h66
-rw-r--r--gnuradio-core/src/lib/runtime/gr_runtime.cc70
-rw-r--r--gnuradio-core/src/lib/runtime/gr_runtime.h49
-rw-r--r--gnuradio-core/src/lib/runtime/gr_runtime.i42
-rw-r--r--gnuradio-core/src/lib/runtime/gr_runtime_impl.cc130
-rw-r--r--gnuradio-core/src/lib/runtime/gr_runtime_impl.h74
-rw-r--r--gnuradio-core/src/lib/runtime/gr_runtime_types.h24
-rw-r--r--gnuradio-core/src/lib/runtime/gr_simple_flowgraph.cc67
-rw-r--r--gnuradio-core/src/lib/runtime/gr_simple_flowgraph.h52
-rw-r--r--gnuradio-core/src/lib/runtime/gr_simple_flowgraph.i45
-rw-r--r--gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.cc471
-rw-r--r--gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.h128
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_block.cc1
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_hier_block2.cc46
-rw-r--r--gnuradio-core/src/lib/runtime/qa_gr_hier_block2.h43
-rw-r--r--gnuradio-core/src/lib/runtime/qa_runtime.cc2
-rw-r--r--gnuradio-core/src/lib/runtime/runtime.i7
30 files changed, 1992 insertions, 100 deletions
diff --git a/gnuradio-core/src/lib/runtime/Makefile.am b/gnuradio-core/src/lib/runtime/Makefile.am
index 2c1ea7eff..47ae07a6b 100644
--- a/gnuradio-core/src/lib/runtime/Makefile.am
+++ b/gnuradio-core/src/lib/runtime/Makefile.am
@@ -30,8 +30,13 @@ libruntime_la_LIBADD = \
libruntime_la_SOURCES = \
+ gr_basic_block.cc \
+ gr_simple_flowgraph.cc \
+ gr_simple_flowgraph_detail.cc \
gr_block.cc \
gr_block_detail.cc \
+ gr_hier_block2.cc \
+ gr_hier_block2_detail.cc \
gr_buffer.cc \
gr_dispatcher.cc \
gr_error_handler.cc \
@@ -43,6 +48,8 @@ libruntime_la_SOURCES = \
gr_pagesize.cc \
gr_preferences.cc \
gr_realtime.cc \
+ gr_runtime.cc \
+ gr_runtime_impl.cc \
gr_single_threaded_scheduler.cc \
gr_tmp_path.cc \
gr_vmcircbuf.cc \
@@ -54,14 +61,20 @@ libruntime_la_SOURCES = \
libruntime_qa_la_SOURCES = \
qa_gr_block.cc \
+ qa_gr_hier_block2.cc \
qa_gr_buffer.cc \
qa_gr_io_signature.cc \
qa_gr_vmcircbuf.cc \
qa_runtime.cc
grinclude_HEADERS = \
+ gr_basic_block.h \
+ gr_simple_flowgraph.h \
+ gr_simple_flowgraph_detail.h \
gr_block.h \
gr_block_detail.h \
+ gr_hier_block2.h \
+ gr_hier_block2_detail.h \
gr_buffer.h \
gr_complex.h \
gr_dispatcher.h \
@@ -74,6 +87,8 @@ grinclude_HEADERS = \
gr_pagesize.h \
gr_preferences.h \
gr_realtime.h \
+ gr_runtime.h \
+ gr_runtime_impl.h \
gr_runtime_types.h \
gr_select_handler.h \
gr_single_threaded_scheduler.h \
@@ -88,14 +103,17 @@ noinst_HEADERS = \
gr_vmcircbuf_sysv_shm.h \
gr_vmcircbuf_createfilemapping.h \
qa_gr_block.h \
+ qa_gr_hier_block2.h \
qa_gr_buffer.h \
qa_gr_io_signature.h \
qa_gr_vmcircbuf.h \
qa_runtime.h
swiginclude_HEADERS = \
+ gr_basic_block.i \
gr_block.i \
gr_block_detail.i \
+ gr_hier_block2.i \
gr_buffer.i \
gr_dispatcher.i \
gr_error_handler.i \
@@ -104,6 +122,8 @@ swiginclude_HEADERS = \
gr_msg_handler.i \
gr_msg_queue.i \
gr_realtime.i \
+ gr_runtime.i \
+ gr_simple_flowgraph.i \
gr_single_threaded_scheduler.i \
gr_swig_block_magic.i \
runtime.i
diff --git a/gnuradio-core/src/lib/runtime/gr_basic_block.cc b/gnuradio-core/src/lib/runtime/gr_basic_block.cc
new file mode 100644
index 000000000..a5f1a4f83
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_basic_block.cc
@@ -0,0 +1,59 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_basic_block.h>
+#include <stdexcept>
+
+static long s_next_id = 0;
+static long s_ncurrently_allocated = 0;
+
+long
+gr_basic_block_ncurrently_allocated()
+{
+ return s_ncurrently_allocated;
+}
+
+gr_basic_block::gr_basic_block(const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature)
+ : d_name(name),
+ d_input_signature(input_signature),
+ d_output_signature(output_signature),
+ d_unique_id(s_next_id++)
+{
+ s_ncurrently_allocated++;
+}
+
+gr_basic_block::~gr_basic_block()
+{
+ s_ncurrently_allocated--;
+}
+
+gr_basic_block_sptr
+gr_basic_block::basic_block()
+{
+ return shared_from_this();
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_basic_block.h b/gnuradio-core/src/lib/runtime/gr_basic_block.h
new file mode 100644
index 000000000..583c3241d
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_basic_block.h
@@ -0,0 +1,99 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, 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_BASIC_BLOCK_H
+#define INCLUDED_GR_BASIC_BLOCK_H
+
+#include <gr_runtime_types.h>
+#include <boost/enable_shared_from_this.hpp>
+#include <string>
+
+/*!
+ * \brief The abstract base class for all signal processing blocks.
+ * \ingroup block
+ *
+ * Basic blocks are the bare abstraction of an entity that has a name
+ * and a set of inputs and outputs. These are never instantiated
+ * directly; rather, this is the abstract parent class of both gr_hier_block,
+ * which is a recursive container, and gr_block, which implements actual
+ * signal processing functions.
+ */
+
+class gr_basic_block : public boost::enable_shared_from_this<gr_basic_block>
+{
+protected:
+ std::string d_name;
+ gr_io_signature_sptr d_input_signature;
+ gr_io_signature_sptr d_output_signature;
+ long d_unique_id;
+
+ //! Protected constructor prevents instantiation by non-derived classes
+ gr_basic_block(const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature);
+
+ //! may only be called during constructor
+ void set_input_signature(gr_io_signature_sptr iosig) {
+ d_input_signature = iosig;
+ }
+
+ //! may only be called during constructor
+ void set_output_signature(gr_io_signature_sptr iosig) {
+ d_output_signature = iosig;
+ }
+
+public:
+ virtual ~gr_basic_block();
+ long unique_id() const { return d_unique_id; }
+ std::string name() const { return d_name; }
+ gr_io_signature_sptr input_signature() const { return d_input_signature; }
+ gr_io_signature_sptr output_signature() const { return d_output_signature; }
+ gr_basic_block_sptr basic_block(); // Needed for Python type coercion
+
+ /*!
+ * \brief Confirm that ninputs and noutputs is an acceptable combination.
+ *
+ * \param ninputs number of input streams connected
+ * \param noutputs number of output streams connected
+ *
+ * \returns true if this is a valid configuration for this block.
+ *
+ * This function is called by the runtime system whenever the
+ * topology changes. Most classes do not need to override this.
+ * This check is in addition to the constraints specified by the input
+ * and output gr_io_signatures.
+ */
+ virtual bool check_topology(int ninputs, int noutputs) { return true; }
+};
+
+typedef std::vector<gr_basic_block_sptr> gr_basic_block_vector_t;
+typedef std::vector<gr_basic_block_sptr>::iterator gr_basic_block_viter_t;
+
+long gr_basic_block_ncurrently_allocated();
+
+inline std::ostream &operator << (std::ostream &os, gr_basic_block_sptr basic_block)
+{
+ os << basic_block->name() << "(" << basic_block->unique_id() << ")";
+ return os;
+}
+
+#endif /* INCLUDED_GR_BASIC_BLOCK_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_basic_block.i b/gnuradio-core/src/lib/runtime/gr_basic_block.i
new file mode 100644
index 000000000..33b895d43
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_basic_block.i
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, 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.
+ */
+
+class gr_basic_block;
+typedef boost::shared_ptr<gr_basic_block> gr_basic_block_sptr;
+%template(gr_basic_block_sptr) boost::shared_ptr<gr_basic_block>;
+
+// support vectors of these...
+namespace std {
+ %template(x_vector_gr_basic_block_sptr) vector<gr_basic_block_sptr>;
+};
+
+class gr_basic_block
+{
+protected:
+ gr_basic_block();
+
+public:
+ virtual ~gr_basic_block();
+ std::string name() const;
+ gr_io_signature_sptr input_signature() const;
+ gr_io_signature_sptr output_signature() const;
+ long unique_id() const;
+ gr_basic_block_sptr basic_block();
+ bool check_topology (int ninputs, int noutputs);
+};
+
+%rename(block_ncurrently_allocated) gr_basic_block_ncurrently_allocated;
+long gr_basic_block_ncurrently_allocated();
+
+%pythoncode %{
+gr_basic_block_sptr.__repr__ = lambda self: "<gr_basic_block %s (%d)>" % (self.name(), self.unique_id ())
+%}
diff --git a/gnuradio-core/src/lib/runtime/gr_block.cc b/gnuradio-core/src/lib/runtime/gr_block.cc
index 65e16045a..1b1d35756 100644
--- a/gnuradio-core/src/lib/runtime/gr_block.cc
+++ b/gnuradio-core/src/lib/runtime/gr_block.cc
@@ -27,34 +27,21 @@
#include <gr_block.h>
#include <gr_block_detail.h>
#include <stdexcept>
-
-static long s_next_id = 0;
-static long s_ncurrently_allocated = 0;
-
-long
-gr_block_ncurrently_allocated ()
-{
- return s_ncurrently_allocated;
-}
+#include <iostream>
gr_block::gr_block (const std::string &name,
gr_io_signature_sptr input_signature,
gr_io_signature_sptr output_signature)
- : d_name (name),
- d_input_signature (input_signature),
- d_output_signature (output_signature),
+ : gr_basic_block(name, input_signature, output_signature),
d_output_multiple (1),
d_relative_rate (1.0),
- d_unique_id (s_next_id++),
d_history(1),
d_fixed_rate(false)
{
- s_ncurrently_allocated++;
}
gr_block::~gr_block ()
{
- s_ncurrently_allocated--;
}
// stub implementation: 1:1
@@ -70,12 +57,6 @@ gr_block::forecast (int noutput_items, gr_vector_int &ninput_items_required)
// default implementation
bool
-gr_block::check_topology (int ninputs, int noutputs)
-{
- return true;
-}
-
-bool
gr_block::start()
{
return true;
diff --git a/gnuradio-core/src/lib/runtime/gr_block.h b/gnuradio-core/src/lib/runtime/gr_block.h
index 9723be108..247238bb0 100644
--- a/gnuradio-core/src/lib/runtime/gr_block.h
+++ b/gnuradio-core/src/lib/runtime/gr_block.h
@@ -23,13 +23,17 @@
#ifndef INCLUDED_GR_BLOCK_H
#define INCLUDED_GR_BLOCK_H
-#include <gr_runtime_types.h>
-#include <string>
+#include <gr_basic_block.h>
/*!
- * \brief The abstract base class for all signal processing blocks.
+ * \brief The abstract base class for all 'terminal' processing blocks.
* \ingroup block
*
+ * A signal processing flow is constructed by creating a tree of
+ * hierarchical blocks, which at any level may also contain terminal nodes
+ * that actually implement signal processing functions. This is the base
+ * class for all such leaf nodes.
+
* Blocks have a set of input streams and output streams. The
* input_signature and output_signature define the number of input
* streams and output streams respectively, and the type of the data
@@ -49,16 +53,11 @@
* It reads the input items and writes the output items.
*/
-class gr_block {
+class gr_block : public gr_basic_block {
public:
virtual ~gr_block ();
-
- std::string name () const { return d_name; }
- gr_io_signature_sptr input_signature () const { return d_input_signature; }
- gr_io_signature_sptr output_signature () const { return d_output_signature; }
- long unique_id () const { return d_unique_id; }
/*!
* Assume block computes y_i = f(x_i, x_i-1, x_i-2, x_i-3...)
@@ -114,21 +113,6 @@ class gr_block {
gr_vector_void_star &output_items) = 0;
/*!
- * \brief Confirm that ninputs and noutputs is an acceptable combination.
- *
- * \param ninputs number of input streams connected
- * \param noutputs number of output streams connected
- *
- * \returns true if this is a valid configuration for this block.
- *
- * This function is called by the runtime system whenever the
- * topology changes. Most classes do not need to override this.
- * This check is in addition to the constraints specified by the input
- * and output gr_io_signatures.
- */
- virtual bool check_topology (int ninputs, int noutputs);
-
- /*!
* \brief Called to enable drivers, etc for i/o devices.
*
* This allows a block to enable an associated driver to begin
@@ -205,32 +189,17 @@ class gr_block {
private:
- std::string d_name;
- gr_io_signature_sptr d_input_signature;
- gr_io_signature_sptr d_output_signature;
- int d_output_multiple;
- double d_relative_rate; // approx output_rate / input_rate
- gr_block_detail_sptr d_detail; // implementation details
- long d_unique_id; // convenient for debugging
- unsigned d_history;
- bool d_fixed_rate;
-
-
+ int d_output_multiple;
+ double d_relative_rate; // approx output_rate / input_rate
+ gr_block_detail_sptr d_detail; // implementation details
+ unsigned d_history;
+ bool d_fixed_rate;
+
protected:
gr_block (const std::string &name,
- gr_io_signature_sptr input_signature,
- gr_io_signature_sptr output_signature);
-
- //! may only be called during constructor
- void set_input_signature (gr_io_signature_sptr iosig){
- d_input_signature = iosig;
- }
-
- //! may only be called during constructor
- void set_output_signature (gr_io_signature_sptr iosig){
- d_output_signature = iosig;
- }
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature);
void set_fixed_rate(bool fixed_rate){ d_fixed_rate = fixed_rate; }
@@ -242,6 +211,7 @@ class gr_block {
void set_detail (gr_block_detail_sptr detail) { d_detail = detail; }
};
-long gr_block_ncurrently_allocated ();
+typedef std::vector<gr_block_sptr> gr_block_vector_t;
+typedef std::vector<gr_block_sptr>::iterator gr_block_viter_t;
#endif /* INCLUDED_GR_BLOCK_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_block.i b/gnuradio-core/src/lib/runtime/gr_block.i
index 3bfd24367..5d0f5fb1b 100644
--- a/gnuradio-core/src/lib/runtime/gr_block.i
+++ b/gnuradio-core/src/lib/runtime/gr_block.i
@@ -20,6 +20,8 @@
* Boston, MA 02110-1301, USA.
*/
+%include <gr_basic_block.i>
+
class gr_block;
typedef boost::shared_ptr<gr_block> gr_block_sptr;
%template(gr_block_sptr) boost::shared_ptr<gr_block>;
@@ -29,26 +31,21 @@ namespace std {
%template(x_vector_gr_block_sptr) vector<gr_block_sptr>;
};
-class gr_block {
+class gr_block : public gr_basic_block {
protected:
gr_block (const std::string &name,
- gr_io_signature_sptr input_signature,
- gr_io_signature_sptr output_signature);
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature);
public:
virtual ~gr_block ();
- std::string name () const;
- gr_io_signature_sptr input_signature () const;
- gr_io_signature_sptr output_signature () const;
- long unique_id () const;
unsigned history () const;
int output_multiple () const;
double relative_rate () const;
- bool check_topology (int ninputs, int noutputs);
bool start();
bool stop();
@@ -57,9 +54,6 @@ class gr_block {
void set_detail (gr_block_detail_sptr detail) { d_detail = detail; }
};
-%rename(block_ncurrently_allocated) gr_block_ncurrently_allocated;
-long gr_block_ncurrently_allocated ();
-
%pythoncode %{
gr_block_sptr.__repr__ = lambda self: "<gr_block %s (%d)>" % (self.name(), self.unique_id ())
gr_block_sptr.block = lambda self: self
diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.cc b/gnuradio-core/src/lib/runtime/gr_block_detail.cc
index ed414d472..5feb180f7 100644
--- a/gnuradio-core/src/lib/runtime/gr_block_detail.cc
+++ b/gnuradio-core/src/lib/runtime/gr_block_detail.cc
@@ -38,7 +38,8 @@ gr_block_detail_ncurrently_allocated ()
gr_block_detail::gr_block_detail (unsigned int ninputs, unsigned int noutputs)
: d_ninputs (ninputs), d_noutputs (noutputs),
d_input (ninputs), d_output (noutputs),
- d_done (false)
+ d_done (false),
+ d_color (gr_block_detail::WHITE)
{
s_ncurrently_allocated++;
}
diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.h b/gnuradio-core/src/lib/runtime/gr_block_detail.h
index 8c4615919..d89b7fea1 100644
--- a/gnuradio-core/src/lib/runtime/gr_block_detail.h
+++ b/gnuradio-core/src/lib/runtime/gr_block_detail.h
@@ -1,19 +1,19 @@
/* -*- c++ -*- */
/*
* Copyright 2004 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 2, 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 detail.
- *
+ *
* 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,
@@ -75,18 +75,26 @@ class gr_block_detail {
void produce_each (int how_many_items);
+ /*!
+ * \brief Allow the flowgraph to set for sorting and partitioning
+ */
+ enum vcolor { WHITE, GREY, BLACK };
+ void set_color(vcolor color) { d_color = color; }
+ vcolor color() const { return d_color; }
+
// ----------------------------------------------------------------------------
private:
- unsigned int d_ninputs;
- unsigned int d_noutputs;
+ unsigned int d_ninputs;
+ unsigned int d_noutputs;
std::vector<gr_buffer_reader_sptr> d_input;
- std::vector<gr_buffer_sptr> d_output;
- bool d_done;
-
+ std::vector<gr_buffer_sptr> d_output;
+ bool d_done;
+ vcolor d_color;
+
gr_block_detail (unsigned int ninputs, unsigned int noutputs);
- friend gr_block_detail_sptr
+ friend gr_block_detail_sptr
gr_make_block_detail (unsigned int ninputs, unsigned int noutputs);
};
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2.cc b/gnuradio-core/src/lib/runtime/gr_hier_block2.cc
new file mode 100644
index 000000000..65dea95fb
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2.cc
@@ -0,0 +1,63 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_hier_block2.h>
+#include <gr_io_signature.h>
+#include <gr_hier_block2_detail.h>
+#include <iostream>
+
+gr_hier_block2_sptr gr_make_hier_block2(const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature)
+{
+ return gr_hier_block2_sptr(new gr_hier_block2(name, input_signature, output_signature));
+}
+
+gr_hier_block2::gr_hier_block2(const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature)
+ : gr_basic_block(name, input_signature, output_signature),
+ d_detail(new gr_hier_block2_detail(this))
+{
+}
+
+gr_hier_block2::~gr_hier_block2()
+{
+ delete d_detail;
+}
+
+void
+gr_hier_block2::define_component(const std::string &name, gr_basic_block_sptr block)
+{
+ d_detail->define_component(name, block);
+}
+
+void
+gr_hier_block2::connect(const std::string &src_name, int src_port,
+ const std::string &dst_name, int dst_port)
+{
+ d_detail->connect(src_name, src_port, dst_name, dst_port);
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2.h b/gnuradio-core/src/lib/runtime/gr_hier_block2.h
new file mode 100644
index 000000000..9d2dd3569
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2.h
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, 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_HIER_BLOCK2_H
+#define INCLUDED_GR_HIER_BLOCK2_H
+
+#include <gr_basic_block.h>
+
+/*!
+ * \brief public constructor for gr_hier_block2
+ */
+gr_hier_block2_sptr gr_make_hier_block2(const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature);
+
+class gr_hier_block2_detail;
+
+/*!
+ * \brief gr_hier_block2 - Hierarchical container class for gr_block's
+ *
+ */
+class gr_hier_block2 : public gr_basic_block
+{
+private:
+ friend class gr_hier_block2_detail;
+ friend class gr_runtime_impl;
+ friend gr_hier_block2_sptr gr_make_hier_block2(const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature);
+
+ /*!
+ * \brief Private implementation details of gr_hier_block2
+ */
+ gr_hier_block2_detail *d_detail;
+
+protected:
+ gr_hier_block2(const std::string &name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature);
+
+public:
+ virtual ~gr_hier_block2();
+
+ void define_component(const std::string &name, gr_basic_block_sptr basic_block);
+ void connect(const std::string &src_name, int src_port,
+ const std::string &dst_name, int dst_port);
+};
+
+#endif /* INCLUDED_GR_HIER_BLOCK2_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2.i b/gnuradio-core/src/lib/runtime/gr_hier_block2.i
new file mode 100644
index 000000000..c5a676534
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2.i
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2005 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 2, 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.
+ */
+
+%include <gr_basic_block.i>
+
+class gr_hier_block2;
+typedef boost::shared_ptr<gr_hier_block2> gr_hier_block2_sptr;
+%template(gr_hier_block2_sptr) boost::shared_ptr<gr_hier_block2>;
+
+// Hack to have a Python shim implementation of gr.hier_block2
+// that instantiates one of these and passes through calls
+%rename(hier_block2_swig) gr_make_hier_block2;
+gr_hier_block2_sptr gr_make_hier_block2(const std::string name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature);
+
+class gr_hier_block2 : public gr_basic_block
+{
+private:
+ gr_hier_block2(const std::string name,
+ gr_io_signature_sptr input_signature,
+ gr_io_signature_sptr output_signature);
+
+public:
+ ~gr_hier_block2 ();
+
+ // Add a named block to the container
+ void define_component(const std::string &name, gr_basic_block_sptr basic_block)
+ throw (std::invalid_argument);
+ void connect(const std::string &src_name, int src_port,
+ const std::string &dst_name, int dst_port)
+ throw (std::invalid_argument);
+};
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc
new file mode 100644
index 000000000..545a64bfd
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc
@@ -0,0 +1,227 @@
+/*
+ * Copyright 2006 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 2, 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_hier_block2_detail.h>
+#include <gr_simple_flowgraph.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <iostream>
+
+gr_hier_block2_detail::gr_hier_block2_detail(gr_hier_block2 *owner) :
+d_owner(owner)
+{
+}
+
+gr_hier_block2_detail::~gr_hier_block2_detail()
+{
+ d_owner = 0; // Don't use delete, we didn't allocate
+}
+
+gr_basic_block_sptr
+gr_hier_block2_detail::lookup_block(const std::string &name)
+{
+ gr_hier_component_miter_t p = d_components.find(name);
+ if (p != d_components.end())
+ return p->second;
+ else
+ return gr_basic_block_sptr();
+}
+
+void
+gr_hier_block2_detail::define_component(const std::string &name, gr_basic_block_sptr block)
+{
+ if (!block)
+ throw std::invalid_argument("null block passed");
+
+ if (name == "self")
+ throw std::invalid_argument("name is reserved");
+
+ // TODO: reject names with '.' inside
+
+ if (!lookup_block(name))
+ d_components[name] = block;
+ else
+ throw std::invalid_argument("name already in use");
+}
+
+void
+gr_hier_block2_detail::connect(const std::string &src_name, int src_port,
+ const std::string &dst_name, int dst_port)
+{
+ gr_io_signature_sptr src_io_signature;
+ gr_io_signature_sptr dst_io_signature;
+
+ // Check against our *input_signature* if we're wiring from one of our external inputs
+ if (src_name == "self")
+ src_io_signature = d_owner->input_signature();
+ else {
+ gr_basic_block_sptr src_block = lookup_block(src_name);
+ if (!src_block)
+ throw std::invalid_argument("undefined src name");
+ src_io_signature = src_block->output_signature();
+ }
+
+ // Check against our *output_signature* if we're wiring to one of our external outputs
+ if (dst_name == "self")
+ dst_io_signature = d_owner->output_signature();
+ else {
+ gr_basic_block_sptr dst_block = lookup_block(dst_name);
+ if (!dst_block)
+ throw std::invalid_argument("undefined dst name");
+ dst_io_signature = dst_block->input_signature();
+ }
+
+ // Check port numbers are valid
+ check_valid_port(src_io_signature, src_port);
+ check_valid_port(dst_io_signature, dst_port);
+
+ // Check destination port not already in use
+ check_dst_not_used(dst_name, dst_port);
+
+ // Check endpoint types match
+ check_type_match(src_io_signature, src_port, dst_io_signature, dst_port);
+
+ d_edges.push_back(gr_make_edge(src_name, src_port, dst_name, dst_port));
+}
+
+void
+gr_hier_block2_detail::check_valid_port(gr_io_signature_sptr sig, int port)
+{
+ if (port < 0)
+ throw std::invalid_argument("port number must not be negative");
+
+ if (sig->max_streams() >= 0 && port >= sig->max_streams())
+ throw std::invalid_argument("port number exceeds max streams");
+}
+
+void
+gr_hier_block2_detail::check_dst_not_used(const std::string name, int port)
+{
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++)
+ if ((*p)->dst_name() == name && (*p)->dst_port() == port)
+ throw std::invalid_argument("destination port in use");
+}
+
+void
+gr_hier_block2_detail::check_type_match(gr_io_signature_sptr src_sig, int src_port,
+ gr_io_signature_sptr dst_sig, int dst_port)
+{
+ if (src_sig->sizeof_stream_item(src_port) != dst_sig->sizeof_stream_item(dst_port))
+ throw std::invalid_argument("type mismatch");
+}
+
+std::string
+gr_hier_block2_detail::prepend_prefix(const std::string &prefix, const std::string &str)
+{
+ return prefix + ((prefix == "") ? "" : ".") + str;
+}
+
+gr_endpoint
+gr_hier_block2_detail::match_endpoint(const std::string &name, int port, bool is_input)
+{
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
+ if (is_input) {
+ if ((*p)->src_name() == name && (*p)->src_port() == port)
+ return resolve_endpoint((*p)->dst_name(), (*p)->dst_port(), "", !is_input);
+ }
+ else {
+ if ((*p)->dst_name() == name && (*p)->dst_port() == port)
+ return resolve_endpoint((*p)->src_name(), (*p)->src_port(), "", !is_input);
+ }
+ }
+
+ // Should never get here
+ throw std::runtime_error("unable to match endpoint");
+}
+
+gr_endpoint
+gr_hier_block2_detail::resolve_endpoint(const std::string &name, int port,
+ const std::string &prefix, bool is_input)
+{
+ gr_basic_block_sptr basic_block = lookup_block(name);
+
+ // Check if 'name' points to gr_block (leaf node)
+ gr_block_sptr block(boost::dynamic_pointer_cast<gr_block, gr_basic_block>(basic_block));
+ if (block)
+ return gr_endpoint(prepend_prefix(prefix, name), port);
+
+ // Check if 'name' points to hierarchical block
+ gr_hier_block2_sptr hier_block2(boost::dynamic_pointer_cast<gr_hier_block2, gr_basic_block>(basic_block));
+ if (hier_block2) {
+ std::string child_prefix = prepend_prefix(prefix, name);
+ gr_endpoint match(hier_block2->d_detail->match_endpoint("self", port, !is_input));
+ return gr_endpoint(prepend_prefix(child_prefix, match.name()), match.port());
+ }
+
+ // Shouldn't ever get here
+ throw std::runtime_error("unable to resolve endpoint");
+}
+
+void
+gr_hier_block2_detail::flatten(gr_simple_flowgraph_sptr sfg, const std::string &prefix)
+{
+ flatten_components(sfg, prefix);
+ flatten_edges(sfg, prefix);
+}
+
+void
+gr_hier_block2_detail::flatten_components(gr_simple_flowgraph_sptr sfg, const std::string &prefix)
+{
+ // Add my non-hierarchical components to the simple flowgraph, then recurse
+ for (gr_hier_component_miter_t p = d_components.begin(); p != d_components.end(); p++) {
+ std::string name = prepend_prefix(prefix, p->first);
+
+ gr_basic_block_sptr basic_block = p->second;
+ gr_block_sptr block(boost::dynamic_pointer_cast<gr_block, gr_basic_block>(basic_block));
+ if (block)
+ sfg->define_component(name, block);
+
+ gr_hier_block2_sptr hier_block2(boost::dynamic_pointer_cast<gr_hier_block2, gr_basic_block>(basic_block));
+ if (hier_block2)
+ hier_block2->d_detail->flatten_components(sfg, name);
+ }
+}
+
+void
+gr_hier_block2_detail::flatten_edges(gr_simple_flowgraph_sptr sfg, const std::string &prefix)
+{
+ // Add my edges to the flow graph, resolving references to actual endpoints
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
+ // Connections to self get resolved/added by parent if actually connected
+ if ((*p)->src_name() == "self" || (*p)->dst_name() == "self")
+ continue;
+
+ gr_endpoint src_endp = resolve_endpoint((*p)->src_name(), (*p)->src_port(), prefix, true);
+ gr_endpoint dst_endp = resolve_endpoint((*p)->dst_name(), (*p)->dst_port(), prefix, false);
+ sfg->connect(src_endp.name(), src_endp.port(), dst_endp.name(), dst_endp.port());
+ }
+
+ // Recurse hierarchical children
+ for (gr_hier_component_miter_t p = d_components.begin(); p != d_components.end(); p++) {
+ gr_hier_block2_sptr hier_block2(boost::dynamic_pointer_cast<gr_hier_block2, gr_basic_block>(p->second));
+ if (hier_block2)
+ hier_block2->d_detail->flatten_edges(sfg, prepend_prefix(prefix, p->first));
+ }
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h
new file mode 100644
index 000000000..095bd40f5
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2006 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 2, 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_HIER_BLOCK2_DETAIL_H
+#define INCLUDED_GR_HIER_BLOCK2_DETAIL_H
+
+#include <gr_hier_block2.h>
+#include <gr_simple_flowgraph_detail.h>
+#include <boost/utility.hpp>
+
+typedef std::map<std::string, gr_basic_block_sptr> gr_hier_component_map_t;
+typedef std::map<std::string, gr_basic_block_sptr>::iterator gr_hier_component_miter_t;
+
+class gr_hier_block2_detail : boost::noncopyable
+{
+private:
+ friend class gr_hier_block2;
+ friend class gr_runtime_impl;
+
+ // Constructor--it's private, only friends can instantiate
+ gr_hier_block2_detail(gr_hier_block2 *owner);
+
+ // Private implementation data
+ gr_hier_block2 *d_owner;
+ gr_hier_component_map_t d_components;
+ gr_edge_vector_t d_edges;
+
+ // Private implementation methods
+ void define_component(const std::string &name, gr_basic_block_sptr block);
+ gr_basic_block_sptr lookup_block(const std::string &name);
+ void connect(const std::string &src_name, int src_port,
+ const std::string &dst_name, int dst_port);
+ void check_valid_port(gr_io_signature_sptr sig, int port);
+ void check_dst_not_used(const std::string name, int port);
+ void check_type_match(gr_io_signature_sptr src_sig, int src_port,
+ gr_io_signature_sptr dst_sig, int dst_port);
+ std::string prepend_prefix(const std::string &prefix, const std::string &str);
+ void flatten(gr_simple_flowgraph_sptr sfg, const std::string &prefix = "");
+ void flatten_components(gr_simple_flowgraph_sptr sfg, const std::string &prefix);
+ void flatten_edges(gr_simple_flowgraph_sptr sfg, const std::string &prefix);
+ gr_endpoint match_endpoint(const std::string &name, int port, bool is_input);
+ gr_endpoint resolve_endpoint(const std::string &name, int port,
+ const std::string &prefix, bool is_input);
+
+public:
+ ~gr_hier_block2_detail();
+};
+
+#endif /* INCLUDED_GR_HIER_BLOCK2_DETAIL_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_runtime.cc b/gnuradio-core/src/lib/runtime/gr_runtime.cc
new file mode 100644
index 000000000..926e87857
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_runtime.cc
@@ -0,0 +1,70 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_runtime.h>
+#include <gr_runtime_impl.h>
+#include <iostream>
+
+gr_runtime_sptr
+gr_make_runtime(gr_hier_block2_sptr top_block)
+{
+ return gr_runtime_sptr(new gr_runtime(top_block));
+}
+
+gr_runtime::gr_runtime(gr_hier_block2_sptr top_block)
+{
+ d_impl = new gr_runtime_impl(top_block);
+}
+
+gr_runtime::~gr_runtime()
+{
+ delete d_impl;
+}
+
+void
+gr_runtime::start()
+{
+ d_impl->start();
+}
+
+void
+gr_runtime::stop()
+{
+ d_impl->stop();
+}
+
+void
+gr_runtime::wait()
+{
+ d_impl->wait();
+}
+
+void
+gr_runtime::run()
+{
+ start();
+ wait();
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_runtime.h b/gnuradio-core/src/lib/runtime/gr_runtime.h
new file mode 100644
index 000000000..fc58da456
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_runtime.h
@@ -0,0 +1,49 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, 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_H
+#define INCLUDED_GR_RUNTIME_H
+
+#include <gr_runtime_types.h>
+
+class gr_runtime_impl;
+
+gr_runtime_sptr gr_make_runtime(gr_hier_block2_sptr top_block);
+
+class gr_runtime
+{
+private:
+ gr_runtime(gr_hier_block2_sptr top_block);
+ friend gr_runtime_sptr gr_make_runtime(gr_hier_block2_sptr top_block);
+
+ gr_runtime_impl *d_impl;
+
+public:
+ ~gr_runtime();
+
+ void start();
+ void stop();
+ void wait();
+ void run();
+};
+
+#endif /* INCLUDED_GR_RUNTIME_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_runtime.i b/gnuradio-core/src/lib/runtime/gr_runtime.i
new file mode 100644
index 000000000..496adff37
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_runtime.i
@@ -0,0 +1,42 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004 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 2, 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.
+ */
+
+class gr_runtime;
+typedef boost::shared_ptr<gr_runtime> gr_runtime_sptr;
+%template(gr_runtime_sptr) boost::shared_ptr<gr_runtime>;
+
+%rename(runtime) gr_make_runtime;
+gr_runtime_sptr gr_make_runtime(gr_hier_block2_sptr top_block);
+
+class gr_runtime
+{
+protected:
+ gr_runtime(gr_hier_block2_sptr top_block);
+
+public:
+ void start()
+ throw (std::runtime_error);
+ void stop();
+ void wait();
+ void run()
+ throw (std::runtime_error);
+};
diff --git a/gnuradio-core/src/lib/runtime/gr_runtime_impl.cc b/gnuradio-core/src/lib/runtime/gr_runtime_impl.cc
new file mode 100644
index 000000000..2b104cd99
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_runtime_impl.cc
@@ -0,0 +1,130 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define GR_RUNTIME_IMPL_DEBUG 0
+
+#include <gr_runtime_impl.h>
+#include <gr_simple_flowgraph.h>
+#include <gr_hier_block2.h>
+#include <gr_hier_block2_detail.h>
+#include <stdexcept>
+#include <iostream>
+
+gr_runtime_impl::gr_runtime_impl(gr_hier_block2_sptr top_block) :
+d_running(false),
+d_top_block(top_block),
+d_sfg(gr_make_simple_flowgraph()),
+d_graphs()
+{
+}
+
+gr_runtime_impl::~gr_runtime_impl()
+{
+}
+
+void
+gr_runtime_impl::start()
+{
+ if (d_running)
+ throw std::runtime_error("already running");
+ else
+ d_running = true;
+
+ d_sfg->d_detail->reset();
+ d_top_block->d_detail->flatten(d_sfg);
+ d_sfg->d_detail->validate();
+ d_sfg->d_detail->setup_connections();
+
+ d_graphs = d_sfg->d_detail->partition();
+ if (GR_RUNTIME_IMPL_DEBUG)
+ std::cout << "Flow graph has " << d_graphs.size()
+ << " sub-graphs." << std::endl;
+
+ d_threads.clear();
+ for (std::vector<gr_block_vector_t>::iterator p = d_graphs.begin();
+ p != d_graphs.end(); p++) {
+ gr_scheduler_thread_sptr thread = gr_make_scheduler_thread(*p);
+ thread->start();
+ d_threads.push_back(thread);
+ }
+}
+
+void
+gr_runtime_impl::stop()
+{
+ if (!d_running)
+ return;
+
+ for (gr_scheduler_thread_viter_t p = d_threads.begin();
+ p != d_threads.end(); p++)
+ (*p)->stop();
+
+ d_running = false;
+}
+
+void
+gr_runtime_impl::wait()
+{
+ for (gr_scheduler_thread_viter_t p = d_threads.begin();
+ p != d_threads.end(); p++) {
+ while(1) {
+ (*p)->join(NULL);
+ if (!(*p)->state() == omni_thread::STATE_TERMINATED)
+ break;
+ }
+ }
+}
+
+gr_scheduler_thread_sptr gr_make_scheduler_thread(gr_block_vector_t graph)
+{
+ return gr_scheduler_thread_sptr(new gr_scheduler_thread(graph));
+}
+
+gr_scheduler_thread::gr_scheduler_thread(gr_block_vector_t graph) :
+ omni_thread(NULL, PRIORITY_NORMAL),
+ d_sts(gr_make_single_threaded_scheduler(graph))
+{
+}
+
+gr_scheduler_thread::~gr_scheduler_thread()
+{
+}
+
+void gr_scheduler_thread::start()
+{
+ start_undetached();
+}
+
+void *gr_scheduler_thread::run_undetached(void *arg)
+{
+ d_sts->run();
+ return 0;
+}
+
+void gr_scheduler_thread::stop()
+{
+ d_sts->stop();
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_runtime_impl.h b/gnuradio-core/src/lib/runtime/gr_runtime_impl.h
new file mode 100644
index 000000000..54977ef97
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_runtime_impl.h
@@ -0,0 +1,74 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, 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_IMPL_H
+#define INCLUDED_GR_RUNTIME_IMPL_H
+
+#include <gr_runtime_types.h>
+#include <gr_block.h>
+#include <omnithread.h>
+#include <gr_single_threaded_scheduler.h>
+
+class gr_scheduler_thread;
+typedef boost::shared_ptr<gr_scheduler_thread> gr_scheduler_thread_sptr;
+typedef std::vector<gr_scheduler_thread_sptr> gr_scheduler_thread_vector_t;
+typedef std::vector<gr_scheduler_thread_sptr>::iterator gr_scheduler_thread_viter_t;
+
+gr_scheduler_thread_sptr gr_make_scheduler_thread(gr_block_vector_t graph);
+
+class gr_scheduler_thread : public omni_thread
+{
+private:
+ gr_scheduler_thread(gr_block_vector_t graph);
+ friend gr_scheduler_thread_sptr gr_make_scheduler_thread(gr_block_vector_t graph);
+
+ gr_single_threaded_scheduler_sptr d_sts;
+
+public:
+ ~gr_scheduler_thread();
+ virtual void *run_undetached(void *arg);
+ void start();
+ void stop();
+};
+
+class gr_runtime_impl
+{
+private:
+ gr_runtime_impl(gr_hier_block2_sptr top_block);
+ friend class gr_runtime;
+
+ bool d_running;
+ gr_hier_block2_sptr d_top_block;
+ gr_simple_flowgraph_sptr d_sfg;
+ std::vector<gr_block_vector_t> d_graphs;
+ gr_scheduler_thread_vector_t d_threads;
+
+ void start();
+ void stop();
+ void wait();
+
+public:
+ ~gr_runtime_impl();
+
+};
+
+#endif /* INCLUDED_GR_RUNTIME_IMPL_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_runtime_types.h b/gnuradio-core/src/lib/runtime/gr_runtime_types.h
index 55cbabe18..dfa0ce94f 100644
--- a/gnuradio-core/src/lib/runtime/gr_runtime_types.h
+++ b/gnuradio-core/src/lib/runtime/gr_runtime_types.h
@@ -20,8 +20,8 @@
* Boston, MA 02110-1301, USA.
*/
-#ifndef INCLUDED_GR_RUNTIME_H
-#define INCLUDED_GR_RUNTIME_H
+#ifndef INCLUDED_GR_RUNTIME_TYPES_H
+#define INCLUDED_GR_RUNTIME_TYPES_H
#include <gr_types.h>
@@ -29,16 +29,24 @@
* typedefs for smart pointers we use throughout the runtime system
*/
+class gr_basic_block;
class gr_block;
class gr_block_detail;
+class gr_hier_block2;
class gr_io_signature;
class gr_buffer;
class gr_buffer_reader;
+class gr_simple_flowgraph;
+class gr_runtime;
-typedef boost::shared_ptr<gr_block> gr_block_sptr;
-typedef boost::shared_ptr<gr_block_detail> gr_block_detail_sptr;
-typedef boost::shared_ptr<gr_io_signature> gr_io_signature_sptr;
-typedef boost::shared_ptr<gr_buffer> gr_buffer_sptr;
-typedef boost::shared_ptr<gr_buffer_reader> gr_buffer_reader_sptr;
+typedef boost::shared_ptr<gr_basic_block> gr_basic_block_sptr;
+typedef boost::shared_ptr<gr_block> gr_block_sptr;
+typedef boost::shared_ptr<gr_block_detail> gr_block_detail_sptr;
+typedef boost::shared_ptr<gr_hier_block2> gr_hier_block2_sptr;
+typedef boost::shared_ptr<gr_io_signature> gr_io_signature_sptr;
+typedef boost::shared_ptr<gr_buffer> gr_buffer_sptr;
+typedef boost::shared_ptr<gr_buffer_reader> gr_buffer_reader_sptr;
+typedef boost::shared_ptr<gr_runtime> gr_runtime_sptr;
+typedef boost::shared_ptr<gr_simple_flowgraph> gr_simple_flowgraph_sptr;
-#endif /* INCLUDED_GR_RUNTIME_H */
+#endif /* INCLUDED_GR_RUNTIME_TYPES_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_simple_flowgraph.cc b/gnuradio-core/src/lib/runtime/gr_simple_flowgraph.cc
new file mode 100644
index 000000000..21aeb587c
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_simple_flowgraph.cc
@@ -0,0 +1,67 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_simple_flowgraph.h>
+#include <gr_simple_flowgraph_detail.h>
+#include <iostream>
+
+#define GR_SIMPLE_FLOWGRAPH_DEBUG 0
+
+gr_simple_flowgraph_sptr gr_make_simple_flowgraph()
+{
+ return gr_simple_flowgraph_sptr(new gr_simple_flowgraph());
+}
+
+gr_simple_flowgraph::gr_simple_flowgraph() :
+d_detail(new gr_simple_flowgraph_detail())
+{
+}
+
+gr_simple_flowgraph::~gr_simple_flowgraph()
+{
+ delete d_detail;
+}
+
+void
+gr_simple_flowgraph::define_component(const std::string &name, gr_block_sptr block)
+{
+ if (GR_SIMPLE_FLOWGRAPH_DEBUG)
+ std::cout << "Defining block " << block << " as " << name << std::endl;
+ d_detail->define_component(name, block);
+}
+
+void
+gr_simple_flowgraph::connect(const std::string &src_name, int src_port,
+ const std::string &dst_name, int dst_port)
+{
+ d_detail->connect(src_name, src_port, dst_name, dst_port);
+}
+
+void
+gr_simple_flowgraph::validate()
+{
+ d_detail->validate();
+}
diff --git a/gnuradio-core/src/lib/runtime/gr_simple_flowgraph.h b/gnuradio-core/src/lib/runtime/gr_simple_flowgraph.h
new file mode 100644
index 000000000..ca2c505e5
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_simple_flowgraph.h
@@ -0,0 +1,52 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, 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_SIMPLE_FLOWGRAPH_H
+#define INCLUDED_GR_SIMPLE_FLOWGRAPH_H
+
+#include <gr_block.h>
+#include <boost/shared_ptr.hpp>
+#include <string>
+
+gr_simple_flowgraph_sptr gr_make_simple_flowgraph();
+
+class gr_simple_flowgraph_detail;
+
+class gr_simple_flowgraph
+{
+private:
+ friend class gr_runtime_impl;
+ friend gr_simple_flowgraph_sptr gr_make_simple_flowgraph();
+ gr_simple_flowgraph();
+
+ gr_simple_flowgraph_detail *d_detail;
+
+public:
+ ~gr_simple_flowgraph();
+
+ void define_component(const std::string &name, gr_block_sptr block);
+ void connect(const std::string &src, int src_port,
+ const std::string &dst, int dst_port);
+ void validate();
+};
+
+#endif /* INCLUDED_GR_SIMPLE_FLOWGRAPH_H */
diff --git a/gnuradio-core/src/lib/runtime/gr_simple_flowgraph.i b/gnuradio-core/src/lib/runtime/gr_simple_flowgraph.i
new file mode 100644
index 000000000..c3654fe50
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_simple_flowgraph.i
@@ -0,0 +1,45 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, 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.
+ */
+
+class gr_simple_flowgraph;
+typedef boost::shared_ptr<gr_simple_flowgraph> gr_simple_flowgraph_sptr;
+%template(gr_simple_flowgraph_sptr) boost::shared_ptr<gr_simple_flowgraph>;
+%rename(simple_flowgraph) gr_make_simple_flowgraph;
+%ignore gr_simple_flowgraph;
+
+gr_simple_flowgraph_sptr gr_make_simple_flowgraph();
+
+class gr_simple_flowgraph
+{
+private:
+ gr_simple_flowgraph();
+
+public:
+ ~gr_simple_flowgraph();
+ void define_component(const std::string name, gr_block_sptr block)
+ throw (std::invalid_argument);
+ void connect(const std::string &src, int src_port,
+ const std::string &dst, int dst_port)
+ throw (std::invalid_argument);
+ void validate()
+ throw (std::runtime_error);
+};
diff --git a/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.cc b/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.cc
new file mode 100644
index 000000000..2698bc6d8
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.cc
@@ -0,0 +1,471 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gr_simple_flowgraph.h>
+#include <gr_simple_flowgraph_detail.h>
+#include <gr_io_signature.h>
+#include <gr_block_detail.h>
+#include <gr_buffer.h>
+#include <iostream>
+#include <stdexcept>
+
+#define GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG 0
+
+gr_edge_sptr
+gr_make_edge(const std::string &src_name, int src_port,
+ const std::string &dst_name, int dst_port)
+{
+ return gr_edge_sptr(new gr_edge(src_name, src_port, dst_name, dst_port));
+}
+
+gr_edge::gr_edge(const std::string &src_name, int src_port, const std::string &dst_name, int dst_port)
+ : d_src(src_name, src_port),
+ d_dst(dst_name, dst_port)
+{
+}
+
+gr_edge::~gr_edge()
+{
+}
+
+gr_simple_flowgraph_detail::gr_simple_flowgraph_detail() :
+d_components(),
+d_edges()
+{
+}
+
+gr_simple_flowgraph_detail::~gr_simple_flowgraph_detail()
+{
+}
+
+void
+gr_simple_flowgraph_detail::reset()
+{
+ // Boost shared pointers will deallocate as needed
+ d_edges.clear();
+ d_components.clear();
+}
+
+gr_block_sptr
+gr_simple_flowgraph_detail::lookup_block(const std::string &name)
+{
+ gr_component_miter_t p = d_components.find(name);
+ if (p != d_components.end())
+ return p->second;
+ else
+ return gr_block_sptr();
+}
+
+void
+gr_simple_flowgraph_detail::define_component(const std::string &name, gr_block_sptr block)
+{
+ if (!block)
+ throw std::invalid_argument("null block passed");
+
+ if (!lookup_block(name))
+ d_components[name] = block;
+ else
+ throw std::invalid_argument("name already in use");
+}
+
+void
+gr_simple_flowgraph_detail::connect(const std::string &src_name, int src_port,
+ const std::string &dst_name, int dst_port)
+{
+ gr_block_sptr src_block = lookup_block(src_name);
+ gr_block_sptr dst_block = lookup_block(dst_name);
+
+ if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+ std::cout << "Connecting " << src_name << ":" << src_port << "->"
+ << dst_name << ":" << dst_port << std::endl;
+
+ if (!src_block)
+ throw std::invalid_argument("unknown src name");
+ if (!dst_block)
+ throw std::invalid_argument("unknown dst name");
+
+ check_valid_port(src_block->output_signature(), src_port);
+ check_valid_port(dst_block->input_signature(), dst_port);
+ check_dst_not_used(dst_name, dst_port);
+ check_type_match(src_block, src_port, dst_block, dst_port);
+
+ d_edges.push_back(gr_make_edge(src_name, src_port, dst_name, dst_port));
+}
+
+void
+gr_simple_flowgraph_detail::check_valid_port(gr_io_signature_sptr sig, int port)
+{
+ if (port < 0)
+ throw std::invalid_argument("negative port number");
+ if (sig->max_streams() >= 0 && port >= sig->max_streams())
+ throw std::invalid_argument("port number exceeds max");
+}
+
+void
+gr_simple_flowgraph_detail::check_dst_not_used(const std::string &name, int port)
+{
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++)
+ if ((*p)->dst_name() == name && (*p)->dst_port() == port)
+ throw std::invalid_argument("dst already in use");
+}
+
+void
+gr_simple_flowgraph_detail::check_type_match(gr_block_sptr src_block, int src_port,
+ gr_block_sptr dst_block, int dst_port)
+{
+ int src_size = src_block->output_signature()->sizeof_stream_item(src_port);
+ int dst_size = dst_block->input_signature()->sizeof_stream_item(dst_port);
+
+ if (src_size != dst_size)
+ throw std::invalid_argument("type size mismatch");
+}
+
+void
+gr_simple_flowgraph_detail::validate()
+{
+ for (gr_component_miter_t p = d_components.begin(); p != d_components.end(); p++) {
+ std::vector<int> used_ports;
+ int ninputs, noutputs;
+
+ used_ports = calc_used_ports(p->first, true); // inputs
+ ninputs = used_ports.size();
+ check_contiguity(p->second, used_ports, true); // inputs
+
+ used_ports = calc_used_ports(p->first, false); // outputs
+ noutputs = used_ports.size();
+ check_contiguity(p->second, used_ports, false); // outputs
+
+ if (!(p->second->check_topology(ninputs, noutputs)))
+ throw std::runtime_error("check topology failed");
+ }
+}
+
+std::vector<int>
+gr_simple_flowgraph_detail::calc_used_ports(const std::string &name, bool check_inputs)
+{
+ if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+ std::cout << "Calculating used " << (check_inputs ? "input " : "output ")
+ << "ports...";
+
+ std::vector<int> tmp, result;
+ std::insert_iterator<std::vector<int> > inserter(result, result.begin());
+
+ gr_edge_vector_t edges = calc_connections(name, check_inputs);
+
+ for (gr_edge_viter_t p = edges.begin(); p != edges.end(); p++) {
+ if (check_inputs == true)
+ tmp.push_back((*p)->dst_port());
+ else
+ tmp.push_back((*p)->src_port());
+ }
+
+ // remove duplicates
+ std::sort(tmp.begin(), tmp.end());
+ std::unique_copy(tmp.begin(), tmp.end(), inserter);
+
+ if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+ std::cout << result.size() << std::endl;
+
+ return result;
+}
+
+gr_edge_vector_t
+gr_simple_flowgraph_detail::calc_connections(const std::string &name, bool check_inputs)
+{
+ gr_edge_vector_t result;
+
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
+ if (check_inputs) {
+ if ((*p)->dst_name() == name)
+ result.push_back(*p);
+ }
+ else {
+ if ((*p)->src_name() == name)
+ result.push_back(*p);
+ }
+ }
+
+ return result; // assumes no duplicates
+}
+
+void
+gr_simple_flowgraph_detail::check_contiguity(gr_block_sptr block,
+ const std::vector<int> &used_ports,
+ bool check_inputs)
+{
+ if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+ std::cout << "Checking " << (check_inputs ? "input " : "output ")
+ << "contiguity...";
+
+ gr_io_signature_sptr sig =
+ check_inputs ? block->input_signature() : block->output_signature();
+
+ int nports = used_ports.size();
+ int min_ports = sig->min_streams();
+
+ if (nports == 0) {
+ if (min_ports == 0) {
+ if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+ std::cout << "ok." << std::endl;
+ return;
+ }
+ else {
+ if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+ std::cout << "needs " << min_ports << ", only has "
+ << nports << std::endl;
+
+ throw std::runtime_error("insufficient ports");
+ }
+ }
+
+ if (used_ports[nports-1]+1 != nports) {
+ for (int i = 0; i < nports; i++) {
+ if (used_ports[i] != i) {
+ if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+ std::cout << "missing " << (check_inputs ? "input ":"output ")
+ << i << std::endl;
+
+ throw std::runtime_error("missing input assignment");
+ }
+ }
+ }
+
+ if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+ std::cout << "ok." << std::endl;
+}
+
+void
+gr_simple_flowgraph_detail::setup_connections()
+{
+ // Assign block details to component blocks
+ for (gr_component_miter_t p = d_components.begin(); p != d_components.end(); p++) {
+ if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+ std::cout << "Allocating output buffers for " << p->first << "..." << std::endl;
+
+ int ninputs = calc_used_ports(p->first, true).size();
+ int noutputs = calc_used_ports(p->first, false).size();
+ gr_block_detail_sptr detail = gr_make_block_detail(ninputs, noutputs);
+ for (int i = 0; i < noutputs; i++)
+ detail->set_output(i, allocate_buffer(p->first, i));
+ p->second->set_detail(detail);
+ }
+
+ // Connect inputs to outputs for each block
+ for(gr_component_miter_t p = d_components.begin(); p != d_components.end(); p++) {
+ // Get its detail and edges that feed into it
+ gr_block_detail_sptr detail = p->second->detail();
+ gr_edge_vector_t in_edges = calc_upstream_edges(p->first);
+
+ if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+ if (in_edges.size() > 0)
+ std::cout << "Connecting inputs to " << p->first << "..." << std::endl;
+
+ // For each edge that feeds into it
+ for (gr_edge_viter_t e = in_edges.begin(); e != in_edges.end(); e++) {
+ // Set the input buffer on the destination port to the output
+ // buffer on the source port
+ int dst_port = (*e)->dst_port();
+ int src_port = (*e)->src_port();
+ gr_block_sptr src_block = lookup_block((*e)->src_name());
+ gr_buffer_sptr src_buffer = src_block->detail()->output(src_port);
+
+ if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+ std::cout << "Setting input on " << (*e)->dst_name()
+ << ":" << dst_port << std::endl;
+
+ detail->set_input(dst_port, gr_buffer_add_reader(src_buffer, p->second->history()-1));
+ }
+ }
+}
+
+gr_buffer_sptr
+gr_simple_flowgraph_detail::allocate_buffer(const std::string &name, int port)
+{
+ gr_block_sptr block = lookup_block(name);
+ int item_size = block->output_signature()->sizeof_stream_item(port);
+ int nitems = s_fixed_buffer_size/item_size;
+
+ // Make sure there are at least twice the output_multiple no. of items
+ if (nitems < 2*block->output_multiple()) // Note: this means output_multiple()
+ nitems = 2*block->output_multiple(); // can't be changed by block dynamically
+
+ // If any downstream blocks are decimators and/or have a large output_multiple,
+ // ensure we have a buffer at least twice their decimation factor*output_multiple
+ gr_block_vector_t blocks = calc_downstream_blocks(name, port);
+ for (gr_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
+ int decimation = (int)(1.0/(*p)->relative_rate());
+ int multiple = (*p)->output_multiple();
+ int history = (*p)->history();
+ nitems = std::max(nitems, 2*(decimation*multiple+history));
+ }
+
+ if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+ std::cout << "Allocating buffer for port " << port << " with "
+ << nitems << " items of size " << item_size << std::endl;
+
+ return gr_make_buffer(nitems, item_size);
+}
+
+gr_block_vector_t
+gr_simple_flowgraph_detail::calc_downstream_blocks(const std::string &name, int port)
+{
+ gr_block_vector_t tmp, result;
+ std::insert_iterator<gr_block_vector_t> inserter(result, result.begin());
+
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++)
+ if ((*p)->src_name() == name && (*p)->src_port() == port)
+ tmp.push_back(lookup_block((*p)->dst_name()));
+
+ // Remove duplicates
+ sort(tmp.begin(), tmp.end());
+ unique_copy(tmp.begin(), tmp.end(), inserter);
+ return result;
+}
+
+gr_edge_vector_t
+gr_simple_flowgraph_detail::calc_upstream_edges(const std::string &name)
+{
+ gr_edge_vector_t result;
+
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++)
+ if ((*p)->dst_name() == name)
+ result.push_back(*p);
+
+ return result; // Assume no duplicates
+}
+
+gr_block_vector_t
+gr_simple_flowgraph_detail::calc_used_blocks()
+{
+ std::vector<std::string> tmp, tmp_unique;
+ std::insert_iterator<std::vector<std::string> > inserter(tmp_unique, tmp_unique.begin());
+ gr_block_vector_t result;
+
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
+ tmp.push_back((*p)->src_name());
+ tmp.push_back((*p)->dst_name());
+ }
+
+ sort(tmp.begin(), tmp.end());
+ unique_copy(tmp.begin(), tmp.end(), inserter);
+
+ for (std::vector<std::string>::iterator p = tmp_unique.begin();
+ p != tmp_unique.end(); p++)
+ result.push_back(lookup_block(*p));
+
+ if (GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG)
+ std::cout << "Flowgraph uses " << result.size()
+ << " distinct blocks." << std::endl;
+
+ return result;
+}
+
+std::vector<gr_block_vector_t>
+gr_simple_flowgraph_detail::partition()
+{
+ std::vector<gr_block_vector_t> result;
+ gr_block_vector_t blocks = calc_used_blocks();
+ gr_block_vector_t graph;
+
+ while (blocks.size() > 0) {
+ graph = calc_reachable_blocks(blocks[0], blocks);
+ assert(graph.size());
+ result.push_back(topological_sort(graph));
+
+ for (gr_block_viter_t p = graph.begin(); p != graph.end(); p++)
+ blocks.erase(find(blocks.begin(), blocks.end(), *p));
+ }
+
+ return result;
+}
+
+gr_block_vector_t
+gr_simple_flowgraph_detail::calc_reachable_blocks(gr_block_sptr block, gr_block_vector_t &blocks)
+{
+ gr_block_vector_t result;
+
+ // Mark all blocks as unvisited
+ for (gr_block_viter_t p = blocks.begin(); p != blocks.end(); p++)
+ (*p)->detail()->set_color(gr_block_detail::WHITE);
+
+ // Recursively mark all reachable blocks
+ reachable_dfs_visit(block, blocks);
+
+ // Collect all the blocks that have been visited
+ for (gr_block_viter_t p = blocks.begin(); p != blocks.end(); p++)
+ if ((*p)->detail()->color() == gr_block_detail::BLACK)
+ result.push_back(*p);
+
+ return result;
+}
+
+// Recursively mark all reachable blocks from given block and block list
+void
+gr_simple_flowgraph_detail::reachable_dfs_visit(gr_block_sptr block, gr_block_vector_t &blocks)
+{
+ // Mark the current one as visited
+ block->detail()->set_color(gr_block_detail::BLACK);
+
+ // Recurse into adjacent vertices
+ gr_block_vector_t adjacent = calc_adjacent_blocks(block, blocks);
+
+ for (gr_block_viter_t p = adjacent.begin(); p != adjacent.end(); p++)
+ if ((*p)->detail()->color() == gr_block_detail::WHITE)
+ reachable_dfs_visit(*p, blocks);
+}
+
+// Return a list of block adjacent to a given block along any edge
+gr_block_vector_t
+gr_simple_flowgraph_detail::calc_adjacent_blocks(gr_block_sptr block, gr_block_vector_t &blocks)
+{
+ gr_block_vector_t tmp, result;
+ std::insert_iterator<gr_block_vector_t> inserter(result, result.begin());
+
+ // Find any blocks that are inputs or outputs
+ for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
+ if (lookup_block((*p)->src_name()) == block)
+ tmp.push_back(lookup_block((*p)->dst_name()));
+ if (lookup_block((*p)->dst_name()) == block)
+ tmp.push_back(lookup_block((*p)->src_name()));
+ }
+
+ // Remove duplicates
+ sort(tmp.begin(), tmp.end());
+ unique_copy(tmp.begin(), tmp.end(), inserter);
+ return result;
+}
+
+gr_block_vector_t
+gr_simple_flowgraph_detail::topological_sort(gr_block_vector_t &blocks)
+{
+ gr_block_vector_t result;
+
+ // NOP for now
+ result = blocks;
+
+ return result;
+}
+
diff --git a/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.h b/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.h
new file mode 100644
index 000000000..368a0619f
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.h
@@ -0,0 +1,128 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, 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_SIMPLE_FLOWGRAPH_DETAIL_H
+#define INCLUDED_GR_SIMPLE_FLOWGRAPH_DETAIL_H
+
+#include <gr_block.h>
+#include <map>
+
+#define GR_FIXED_BUFFER_SIZE (32*(1L<<10))
+
+typedef std::map<std::string, gr_block_sptr> gr_component_map_t;
+typedef std::map<std::string, gr_block_sptr>::iterator gr_component_miter_t;
+
+class gr_endpoint
+{
+private:
+ std::string d_name;
+ int d_port;
+
+public:
+ gr_endpoint(const std::string &name, int port) { d_name = name; d_port = port; }
+ const std::string &name() const { return d_name; }
+ int port() const { return d_port; }
+};
+
+class gr_edge;
+typedef boost::shared_ptr<gr_edge> gr_edge_sptr;
+gr_edge_sptr gr_make_edge(const std::string &src_name, int src_port,
+ const std::string &dst_name, int dst_port);
+
+class gr_edge
+{
+private:
+ friend gr_edge_sptr gr_make_edge(const std::string &src_name, int src_port,
+ const std::string &dst_name, int dst_port);
+ gr_edge(const std::string &name, int src_port,
+ const std::string &name, int dst_port);
+
+ gr_endpoint d_src;
+ gr_endpoint d_dst;
+
+public:
+ ~gr_edge();
+ const std::string src_name() const { return d_src.name(); }
+ const std::string dst_name() const { return d_dst.name(); }
+ int src_port() const { return d_src.port(); }
+ int dst_port() const { return d_dst.port(); }
+};
+
+typedef std::vector<gr_edge_sptr> gr_edge_vector_t;
+typedef std::vector<gr_edge_sptr>::iterator gr_edge_viter_t;
+
+class gr_simple_flowgraph_detail
+{
+private:
+ friend class gr_simple_flowgraph;
+ friend class gr_runtime_impl;
+
+ gr_simple_flowgraph_detail();
+
+ gr_component_map_t d_components;
+ gr_edge_vector_t d_edges;
+ static const unsigned int s_fixed_buffer_size = GR_FIXED_BUFFER_SIZE;
+
+ void reset();
+ void define_component(const std::string &name, gr_block_sptr block);
+ void connect(const std::string &src, int src_port,
+ const std::string &dst, int dst_port);
+ gr_block_sptr lookup_block(const std::string &name);
+ void check_valid_port(gr_io_signature_sptr sig, int port);
+ void check_dst_not_used(const std::string &name, int port);
+ void check_type_match(gr_block_sptr src_block, int src_port,
+ gr_block_sptr dst_block, int dst_port);
+ void validate();
+ gr_edge_vector_t calc_connections(const std::string &name, bool check_inputs); // false=use outputs
+ std::vector<int> calc_used_ports(const std::string &name, bool check_inputs);
+ void check_contiguity(gr_block_sptr block, const std::vector<int> &used_ports,
+ bool check_inputs);
+ void setup_connections();
+ gr_buffer_sptr allocate_buffer(const std::string &name, int port);
+ gr_block_vector_t calc_downstream_blocks(const std::string &name, int port);
+ gr_edge_vector_t calc_upstream_edges(const std::string &name);
+ gr_block_vector_t calc_used_blocks();
+ std::vector<gr_block_vector_t> partition();
+ gr_block_vector_t calc_reachable_blocks(gr_block_sptr block, gr_block_vector_t &blocks);
+ gr_block_vector_t topological_sort(gr_block_vector_t &blocks);
+ void reachable_dfs_visit(gr_block_sptr block, gr_block_vector_t &blocks);
+ gr_block_vector_t calc_adjacent_blocks(gr_block_sptr block, gr_block_vector_t &blocks);
+
+public:
+ ~gr_simple_flowgraph_detail();
+};
+
+inline std::ostream&
+operator <<(std::ostream& os, const gr_block_sptr p)
+{
+ os << "<gr_block " << p->name() << " (" << p->unique_id() << ")>";
+ return os;
+}
+
+inline std::ostream&
+operator <<(std::ostream &os, const gr_endpoint endp)
+{
+ os << endp.name() << ":" << endp.port();
+ return os;
+}
+
+#endif /* INCLUDED_GR_SIMPLE_FLOWGRAPH_H */
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_block.cc b/gnuradio-core/src/lib/runtime/qa_gr_block.cc
index 4773a6eaa..630d72749 100644
--- a/gnuradio-core/src/lib/runtime/qa_gr_block.cc
+++ b/gnuradio-core/src/lib/runtime/qa_gr_block.cc
@@ -25,7 +25,6 @@
#endif
#include <qa_gr_block.h>
#include <gr_block.h>
-#include <gr_runtime_types.h>
#include <gr_io_signature.h>
#include <gr_null_sink.h>
#include <gr_null_source.h>
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_hier_block2.cc b/gnuradio-core/src/lib/runtime/qa_gr_hier_block2.cc
new file mode 100644
index 000000000..766ea2f6b
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_hier_block2.cc
@@ -0,0 +1,46 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <qa_gr_hier_block2.h>
+#include <gr_hier_block2.h>
+#include <gr_io_signature.h>
+#include <gr_null_source.h>
+#include <gr_null_sink.h>
+
+void qa_gr_hier_block2::test_make()
+{
+ gr_hier_block2_sptr src1(gr_make_hier_block2("test",
+ gr_make_io_signature(1, 1, sizeof(int)),
+ gr_make_io_signature(1, 1, sizeof(int))));
+
+ CPPUNIT_ASSERT(src1);
+ CPPUNIT_ASSERT_EQUAL(std::string("test"), src1->name());
+ CPPUNIT_ASSERT_EQUAL(1, src1->input_signature()->max_streams());
+ CPPUNIT_ASSERT_EQUAL(1, src1->output_signature()->min_streams());
+ CPPUNIT_ASSERT_EQUAL(1, src1->output_signature()->max_streams());
+ CPPUNIT_ASSERT_EQUAL(sizeof(int),
+ src1->output_signature()->sizeof_stream_item(0));
+}
diff --git a/gnuradio-core/src/lib/runtime/qa_gr_hier_block2.h b/gnuradio-core/src/lib/runtime/qa_gr_hier_block2.h
new file mode 100644
index 000000000..a6bd8d97b
--- /dev/null
+++ b/gnuradio-core/src/lib/runtime/qa_gr_hier_block2.h
@@ -0,0 +1,43 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006 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 2, 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_QA_GR_HIER_BLOCK2_H
+#define INCLUDED_QA_GR_HIER_BLOCK2_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+#include <stdexcept>
+
+class qa_gr_hier_block2 : public CppUnit::TestCase
+{
+ CPPUNIT_TEST_SUITE(qa_gr_hier_block2);
+
+ CPPUNIT_TEST(test_make);
+
+ CPPUNIT_TEST_SUITE_END();
+
+private:
+ void test_make();
+ void test_derived();
+};
+
+#endif /* INCLUDED_QA_GR_HIER_BLOCK2_H */
diff --git a/gnuradio-core/src/lib/runtime/qa_runtime.cc b/gnuradio-core/src/lib/runtime/qa_runtime.cc
index 165a34703..ca0c71d3c 100644
--- a/gnuradio-core/src/lib/runtime/qa_runtime.cc
+++ b/gnuradio-core/src/lib/runtime/qa_runtime.cc
@@ -33,6 +33,7 @@
#include <qa_gr_vmcircbuf.h>
#include <qa_gr_io_signature.h>
#include <qa_gr_block.h>
+#include <qa_gr_hier_block2.h>
#include <qa_gr_buffer.h>
CppUnit::TestSuite *
@@ -43,6 +44,7 @@ qa_runtime::suite ()
s->addTest (qa_gr_vmcircbuf::suite ());
s->addTest (qa_gr_io_signature::suite ());
s->addTest (qa_gr_block::suite ());
+ s->addTest (qa_gr_hier_block2::suite ());
s->addTest (qa_gr_buffer::suite ());
return s;
diff --git a/gnuradio-core/src/lib/runtime/runtime.i b/gnuradio-core/src/lib/runtime/runtime.i
index f2fd36437..8e6c01f9a 100644
--- a/gnuradio-core/src/lib/runtime/runtime.i
+++ b/gnuradio-core/src/lib/runtime/runtime.i
@@ -26,6 +26,9 @@
#include <gr_buffer.h>
#include <gr_block.h>
#include <gr_block_detail.h>
+#include <gr_hier_block2.h>
+#include <gr_runtime.h>
+#include <gr_simple_flowgraph.h>
#include <gr_single_threaded_scheduler.h>
#include <gr_message.h>
#include <gr_msg_handler.h>
@@ -37,9 +40,12 @@
%include <gr_io_signature.i>
%include <gr_buffer.i>
+%include <gr_basic_block.i>
%include <gr_block.i>
%include <gr_block_detail.i>
+%include <gr_hier_block2.i>
%include <gr_swig_block_magic.i>
+%include <gr_simple_flowgraph.i>
%include <gr_single_threaded_scheduler.i>
%include <gr_message.i>
%include <gr_msg_handler.i>
@@ -47,3 +53,4 @@
%include <gr_dispatcher.i>
%include <gr_error_handler.i>
%include <gr_realtime.i>
+%include <gr_runtime.i>