commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r6169 - in gnuradio/trunk/gnuradio-core/src: lib/runti


From: jcorgan
Subject: [Commit-gnuradio] r6169 - in gnuradio/trunk/gnuradio-core/src: lib/runtime python/gnuradio/gr
Date: Thu, 23 Aug 2007 12:46:20 -0600 (MDT)

Author: jcorgan
Date: 2007-08-23 12:46:20 -0600 (Thu, 23 Aug 2007)
New Revision: 6169

Added:
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.h
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_flowgraph.cc
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_flowgraph.h
   gnuradio/trunk/gnuradio-core/src/lib/runtime/qa_gr_flowgraph.cc
   gnuradio/trunk/gnuradio-core/src/lib/runtime/qa_gr_flowgraph.h
Removed:
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_simple_flowgraph.cc
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_simple_flowgraph.h
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.cc
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.h
Modified:
   gnuradio/trunk/gnuradio-core/src/lib/runtime/Makefile.am
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_basic_block.cc
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_basic_block.h
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_block.h
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_block_detail.cc
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_block_detail.h
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_runtime_impl.cc
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_runtime_impl.h
   gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_runtime_types.h
   gnuradio/trunk/gnuradio-core/src/lib/runtime/qa_runtime.cc
   gnuradio/trunk/gnuradio-core/src/python/gnuradio/gr/qa_hier_block2.py
Log:
Merge r6160:6168 from jcorgan/fg into trunk.

Refactors gr_simple_flowgraph into gr_flowgraph and gr_flat_flowgraph.

Adds cppunit-based QA.

Trial fix for ticket:164 included for free.



Modified: gnuradio/trunk/gnuradio-core/src/lib/runtime/Makefile.am
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/Makefile.am    2007-08-23 
17:25:53 UTC (rev 6168)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/Makefile.am    2007-08-23 
18:46:20 UTC (rev 6169)
@@ -31,8 +31,8 @@
 
 libruntime_la_SOURCES =                        \
        gr_basic_block.cc                       \
-       gr_simple_flowgraph.cc                  \
-       gr_simple_flowgraph_detail.cc           \
+       gr_flowgraph.cc                         \
+       gr_flat_flowgraph.cc                    \
        gr_block.cc                             \
        gr_block_detail.cc                      \
        gr_hier_block2.cc                       \
@@ -66,14 +66,15 @@
        qa_gr_block.cc                          \
        qa_gr_hier_block2.cc                    \
        qa_gr_buffer.cc                         \
+       qa_gr_flowgraph.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_flowgraph.h                          \
+       gr_flat_flowgraph.h                     \
        gr_block.h                              \
        gr_block_detail.h                       \
        gr_hier_block2.h                        \
@@ -109,6 +110,7 @@
        gr_vmcircbuf_sysv_shm.h                 \
        gr_vmcircbuf_createfilemapping.h        \
        qa_gr_block.h                           \
+       qa_gr_flowgraph.h                       \
        qa_gr_hier_block2.h                     \
        qa_gr_buffer.h                          \
        qa_gr_io_signature.h                    \
@@ -135,3 +137,5 @@
        gr_sync_interpolator.i          \
        gr_swig_block_magic.i           \
        runtime.i
+
+MOSTLYCLEANFILES = *~ *.loT

Modified: gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_basic_block.cc
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_basic_block.cc      
2007-08-23 17:25:53 UTC (rev 6168)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_basic_block.cc      
2007-08-23 18:46:20 UTC (rev 6169)
@@ -42,7 +42,8 @@
   : d_name(name),
     d_input_signature(input_signature),
     d_output_signature(output_signature),
-    d_unique_id(s_next_id++)
+    d_unique_id(s_next_id++),
+    d_color(WHITE)
 {
     s_ncurrently_allocated++;
 }

Modified: gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_basic_block.h
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_basic_block.h       
2007-08-23 17:25:53 UTC (rev 6168)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_basic_block.h       
2007-08-23 18:46:20 UTC (rev 6169)
@@ -41,10 +41,16 @@
 class gr_basic_block : public boost::enable_shared_from_this<gr_basic_block>
 {
 protected:
+    friend class gr_flowgraph;
+    friend class gr_flat_flowgraph; // TODO: will be redundant
+
+    enum vcolor { WHITE, GREY, BLACK };
+
     std::string          d_name;
     gr_io_signature_sptr d_input_signature;
     gr_io_signature_sptr d_output_signature;
     long                 d_unique_id;
+    vcolor               d_color;
 
     //! Protected constructor prevents instantiation by non-derived classes
     gr_basic_block(const std::string &name,
@@ -61,6 +67,12 @@
         d_output_signature = iosig;
     }
 
+    /*!
+     * \brief Allow the flowgraph to set for sorting and partitioning
+     */
+    void set_color(vcolor color) { d_color = color; }
+    vcolor color() const { return d_color; }
+
 public:
     virtual ~gr_basic_block();
     long unique_id() const { return d_unique_id; }

Modified: gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_block.h
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_block.h     2007-08-23 
17:25:53 UTC (rev 6168)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_block.h     2007-08-23 
18:46:20 UTC (rev 6169)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004 Free Software Foundation, Inc.
+ * Copyright 2004,2007 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -214,4 +214,9 @@
 typedef std::vector<gr_block_sptr> gr_block_vector_t;
 typedef std::vector<gr_block_sptr>::iterator gr_block_viter_t;
 
+inline gr_block_sptr make_gr_block_sptr(gr_basic_block_sptr p)
+{
+  return boost::dynamic_pointer_cast<gr_block, gr_basic_block>(p);
+}
+
 #endif /* INCLUDED_GR_BLOCK_H */

Modified: gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_block_detail.cc
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_block_detail.cc     
2007-08-23 17:25:53 UTC (rev 6168)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_block_detail.cc     
2007-08-23 18:46:20 UTC (rev 6169)
@@ -38,8 +38,7 @@
 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_color (gr_block_detail::WHITE)
+    d_done (false)
 {
   s_ncurrently_allocated++;
 }

Modified: gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_block_detail.h
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_block_detail.h      
2007-08-23 17:25:53 UTC (rev 6168)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_block_detail.h      
2007-08-23 18:46:20 UTC (rev 6169)
@@ -75,13 +75,6 @@
 
   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:
@@ -90,7 +83,6 @@
   std::vector<gr_buffer_reader_sptr> d_input;
   std::vector<gr_buffer_sptr>       d_output;
   bool                               d_done;
-  vcolor                             d_color;
 
   gr_block_detail (unsigned int ninputs, unsigned int noutputs);
 

Copied: gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc (from 
rev 6168, 
gnuradio/branches/developers/jcorgan/fg/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc           
                (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc   
2007-08-23 18:46:20 UTC (rev 6169)
@@ -0,0 +1,223 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 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 3, 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_flat_flowgraph.h>
+#include <gr_block_detail.h>
+#include <gr_io_signature.h>
+#include <gr_buffer.h>
+#include <iostream>
+#include <map>
+
+#define GR_FLAT_FLOWGRAPH_DEBUG 0
+
+gr_flat_flowgraph_sptr
+gr_make_flat_flowgraph()
+{
+  return gr_flat_flowgraph_sptr(new gr_flat_flowgraph());
+}
+
+gr_flat_flowgraph::gr_flat_flowgraph()
+{
+}
+
+gr_flat_flowgraph::~gr_flat_flowgraph()
+{
+}
+
+void
+gr_flat_flowgraph::setup_connections()
+{
+  gr_basic_block_vector_t blocks = calc_used_blocks();
+
+  // Assign block details to blocks
+  for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++)
+    make_gr_block_sptr(*p)->set_detail(allocate_block_detail(*p));
+
+  // Connect inputs to outputs for each block
+  for(gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++)
+    connect_block_inputs(*p);
+}
+
+gr_block_detail_sptr
+gr_flat_flowgraph::allocate_block_detail(gr_basic_block_sptr block, 
gr_block_detail_sptr old_detail)
+{
+  int ninputs = calc_used_ports(block, true).size();
+  int noutputs = calc_used_ports(block, false).size();
+  gr_block_detail_sptr detail = gr_make_block_detail(ninputs, noutputs);
+
+  if (GR_FLAT_FLOWGRAPH_DEBUG)
+    std::cout << "Creating block detail for " << block << std::endl;
+
+  // Re-use or allocate output buffers
+  for (int i = 0; i < noutputs; i++) {
+    gr_buffer_sptr buffer;
+
+    if (!old_detail || i >= old_detail->noutputs()) {
+      if (GR_FLAT_FLOWGRAPH_DEBUG)
+       std::cout << "Allocating new buffer for output " << i << std::endl;
+      buffer = allocate_buffer(block, i);
+    }
+    else {
+      if (GR_FLAT_FLOWGRAPH_DEBUG)
+       std::cout << "Reusing old buffer for output " << i << std::endl;
+      buffer = old_detail->output(i);
+    }
+
+    detail->set_output(i, buffer);
+  }
+
+  return detail;
+}
+
+gr_buffer_sptr
+gr_flat_flowgraph::allocate_buffer(gr_basic_block_sptr block, int port)
+{
+  gr_block_sptr grblock = make_gr_block_sptr(block);
+  if (!grblock)
+    throw std::runtime_error("allocate_buffer found non-gr_block");
+  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*grblock->output_multiple())   // Note: this means 
output_multiple()
+    nitems = 2*grblock->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_basic_block_vector_t blocks = calc_downstream_blocks(block, port);
+
+  for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
+    gr_block_sptr dgrblock = make_gr_block_sptr(*p);
+    if (!dgrblock)
+      throw std::runtime_error("allocate_buffer found non-gr_block");
+
+    double decimation = (1.0/dgrblock->relative_rate());
+    int multiple      = dgrblock->output_multiple();
+    int history       = dgrblock->history();
+    nitems = std::max(nitems, 
static_cast<int>(2*(decimation*multiple+history)));
+  }
+
+  return gr_make_buffer(nitems, item_size);
+}
+
+void
+gr_flat_flowgraph::connect_block_inputs(gr_basic_block_sptr block)
+{
+  gr_block_sptr grblock = make_gr_block_sptr(block);
+  if (!grblock)
+    throw std::runtime_error("found non-gr_block");
+  
+  // Get its detail and edges that feed into it
+  gr_block_detail_sptr detail = grblock->detail();
+  gr_edge_vector_t in_edges = calc_upstream_edges(block);
+  
+  // For each edge that feeds into it
+  for (gr_edge_viter_t e = in_edges.begin(); e != in_edges.end(); e++) {
+    // Set the buffer reader 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_basic_block_sptr src_block = e->src().block();
+    gr_block_sptr src_grblock = make_gr_block_sptr(src_block);
+    if (!src_grblock)
+      throw std::runtime_error("found non-gr_block");
+    gr_buffer_sptr src_buffer = src_grblock->detail()->output(src_port);
+    
+    if (GR_FLAT_FLOWGRAPH_DEBUG)
+      std::cout << "Setting input " << dst_port << " from edge " << (*e) << 
std::endl;
+
+    detail->set_input(dst_port, gr_buffer_add_reader(src_buffer, 
grblock->history()-1));
+  }
+}
+
+void
+gr_flat_flowgraph::merge_connections(gr_flat_flowgraph_sptr old_ffg)
+{
+  std::map<gr_block_sptr, gr_block_detail_sptr> old_details;
+
+  // Allocate or reuse output buffers
+  for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) {
+    gr_block_sptr block = make_gr_block_sptr(*p);
+
+    gr_block_detail_sptr old_detail = block->detail();
+    block->set_detail(allocate_block_detail(block, old_detail));
+
+    // Save old detail for use in next step
+    old_details[block] = old_detail;
+  }
+
+  for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) {
+    gr_block_sptr block = make_gr_block_sptr(*p);
+
+    if (GR_FLAT_FLOWGRAPH_DEBUG)
+      std::cout << "merge: testing " << (*p) << "...";
+    
+    if (old_ffg->has_block_p(*p)) {
+      // Block exists in old flow graph
+      if (GR_FLAT_FLOWGRAPH_DEBUG)
+       std::cout << "used in old flow graph" << std::endl;
+      gr_block_detail_sptr detail = block->detail();
+
+      // Iterate through the inputs and see what needs to be done
+      for (int i = 0; i < detail->ninputs(); i++) {
+       if (GR_FLAT_FLOWGRAPH_DEBUG)
+         std::cout << "Checking input " << i << "...";
+       gr_edge edge = calc_upstream_edge(*p, i);
+
+       // Fish out old buffer reader and see if it matches correct buffer from 
edge list
+       gr_block_sptr src_block = make_gr_block_sptr(edge.src().block());
+       gr_block_detail_sptr src_detail = src_block->detail();
+       gr_buffer_sptr src_buffer = src_detail->output(edge.src().port());
+       gr_buffer_reader_sptr old_reader;
+       gr_block_detail_sptr old_detail = old_details[block];
+       if (old_detail && i < old_detail->ninputs())
+         old_reader = old_detail->input(i);
+       
+       // If there's a match, use it
+       if (old_reader && (src_buffer == old_reader->buffer())) {
+         if (GR_FLAT_FLOWGRAPH_DEBUG)
+           std::cout << "matched" << std::endl;
+         detail->set_input(i, old_reader);
+
+       }
+       else {
+         if (GR_FLAT_FLOWGRAPH_DEBUG)
+           std::cout << "needs a new reader" << std::endl;
+
+         // Create new buffer reader and assign
+         detail->set_input(i, gr_buffer_add_reader(src_buffer, 
block->history()-1));
+       }
+      }
+    }
+    else {
+      // Block is new, it just needs buffer readers at this point
+      if (GR_FLAT_FLOWGRAPH_DEBUG)
+       std::cout << "new block" << std::endl;
+      connect_block_inputs(block);
+    }
+  }  
+}
+

Copied: gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.h (from 
rev 6168, 
gnuradio/branches/developers/jcorgan/fg/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.h)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.h            
                (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.h    
2007-08-23 18:46:20 UTC (rev 6169)
@@ -0,0 +1,65 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2007 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 3, 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_FLAT_FLOWGRAPH_H
+#define INCLUDED_GR_FLAT_FLOWGRAPH_H
+
+#include <gr_flowgraph.h>
+#include <gr_block.h>
+
+// 32Kbyte buffer size between blocks
+#define GR_FIXED_BUFFER_SIZE (32*(1L<<10))
+
+// Create a shared pointer to a heap allocated gr_flat_flowgraph
+// (types defined in gr_runtime_types.h)
+gr_flat_flowgraph_sptr gr_make_flat_flowgraph();
+
+/*!
+ *\brief Class specializing gr_flat_flowgraph that has all nodes
+ * as gr_blocks, with no hierarchy
+ *
+ */
+class gr_flat_flowgraph : public gr_flowgraph
+{
+public:
+  friend gr_flat_flowgraph_sptr gr_make_flat_flowgraph();
+
+  // Destruct an arbitrary gr_flat_flowgraph
+  ~gr_flat_flowgraph();
+
+  // Wire gr_blocks together in new flat_flowgraph
+  void setup_connections();
+
+  // Merge applicable connections from existing flat flowgraph
+  void merge_connections(gr_flat_flowgraph_sptr sfg);
+
+private:
+  gr_flat_flowgraph();
+
+  static const unsigned int s_fixed_buffer_size = GR_FIXED_BUFFER_SIZE;
+  gr_block_detail_sptr allocate_block_detail(gr_basic_block_sptr block, 
+                                            gr_block_detail_sptr 
old_detail=gr_block_detail_sptr());
+  gr_buffer_sptr allocate_buffer(gr_basic_block_sptr block, int port);
+  void connect_block_inputs(gr_basic_block_sptr block);
+};
+
+#endif /* INCLUDED_GR_FLAT_FLOWGRAPH_H */

Copied: gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_flowgraph.cc (from rev 
6168, 
gnuradio/branches/developers/jcorgan/fg/gnuradio-core/src/lib/runtime/gr_flowgraph.cc)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_flowgraph.cc                
                (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_flowgraph.cc        
2007-08-23 18:46:20 UTC (rev 6169)
@@ -0,0 +1,436 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 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 3, 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_flowgraph.h>
+#include <gr_io_signature.h>
+#include <stdexcept>
+#include <iostream>
+
+#define GR_FLOWGRAPH_DEBUG 0
+
+gr_edge::~gr_edge()
+{
+}
+
+gr_flowgraph_sptr gr_make_flowgraph()
+{
+  return gr_flowgraph_sptr(new gr_flowgraph());
+}
+
+gr_flowgraph::gr_flowgraph()
+{
+}
+  
+gr_flowgraph::~gr_flowgraph()
+{
+}
+
+void
+gr_flowgraph::connect(const gr_endpoint &src, const gr_endpoint &dst)
+{
+  check_valid_port(src.block()->output_signature(), src.port());
+  check_valid_port(dst.block()->input_signature(), dst.port());
+  check_dst_not_used(dst);
+  check_type_match(src, dst);
+
+  // All ist klar, Herr Kommisar
+  d_edges.push_back(gr_edge(src,dst));
+}
+
+void
+gr_flowgraph::disconnect(const gr_endpoint &src, const gr_endpoint &dst)
+{
+  for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
+    if (src == p->src() && dst == p->dst()) {
+      d_edges.erase(p);
+      return;
+    }
+  }
+
+  throw std::invalid_argument("edge to disconnect not found");
+}
+
+void
+gr_flowgraph::validate()
+{
+  d_blocks = calc_used_blocks();
+
+  for (gr_basic_block_viter_t p = d_blocks.begin(); p != d_blocks.end(); p++) {
+    std::vector<int> used_ports;
+    int ninputs, noutputs;
+
+    if (GR_FLOWGRAPH_DEBUG)
+      std::cout << "Validating block: " << (*p) << std::endl;
+
+    used_ports = calc_used_ports(*p, true); // inputs
+    ninputs = used_ports.size();
+    check_contiguity(*p, used_ports, true); // inputs
+
+    used_ports = calc_used_ports(*p, false); // outputs
+    noutputs = used_ports.size();
+    check_contiguity(*p, used_ports, false); // outputs
+
+    if (!((*p)->check_topology(ninputs, noutputs)))
+      throw std::runtime_error("check topology failed");
+  }
+}
+
+void
+gr_flowgraph::clear()
+{
+  // Boost shared pointers will deallocate as needed
+  d_blocks.clear();
+  d_edges.clear();
+}
+
+void
+gr_flowgraph::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_flowgraph::check_dst_not_used(const gr_endpoint &dst)
+{
+  // A destination is in use if it is already on the edge list
+  for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++)
+    if (p->dst() == dst)
+      throw std::invalid_argument("dst already in use");
+}
+
+void
+gr_flowgraph::check_type_match(const gr_endpoint &src, const gr_endpoint &dst)
+{
+  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("itemsize mismatch between src and dst");
+}
+
+gr_basic_block_vector_t
+gr_flowgraph::calc_used_blocks()
+{
+  gr_basic_block_vector_t tmp, result;
+  std::insert_iterator<gr_basic_block_vector_t> inserter(result, 
result.begin());
+
+  // Collect all blocks in the edge list
+  for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
+    tmp.push_back(p->src().block());
+    tmp.push_back(p->dst().block());
+  }
+
+  // Return vector of unique blocks
+  sort(tmp.begin(), tmp.end());
+  unique_copy(tmp.begin(), tmp.end(), inserter);
+  return result;
+}
+
+std::vector<int>
+gr_flowgraph::calc_used_ports(gr_basic_block_sptr block, bool check_inputs)
+{
+  std::vector<int> tmp, result;
+  std::insert_iterator<std::vector<int> > inserter(result, result.begin());
+
+  // Collect all seen ports 
+  gr_edge_vector_t edges = calc_connections(block, 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());
+  }
+
+  // Return vector of unique values
+  std::sort(tmp.begin(), tmp.end());
+  std::unique_copy(tmp.begin(), tmp.end(), inserter);
+  return result;
+}
+
+gr_edge_vector_t
+gr_flowgraph::calc_connections(gr_basic_block_sptr block, 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().block() == block)
+       result.push_back(*p);
+    }
+    else {
+      if (p->src().block() == block)
+       result.push_back(*p);
+    }
+  }
+
+  return result; // assumes no duplicates
+}
+
+void
+gr_flowgraph::check_contiguity(gr_basic_block_sptr block,
+                              const std::vector<int> &used_ports,
+                              bool check_inputs)
+{
+  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)
+      return;
+    else
+      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)
+       throw std::runtime_error("missing input assignment");
+  }
+}
+
+gr_basic_block_vector_t
+gr_flowgraph::calc_downstream_blocks(gr_basic_block_sptr block, int port)
+{
+  gr_basic_block_vector_t tmp, result;
+  std::insert_iterator<gr_basic_block_vector_t> inserter(result, 
result.begin());
+
+  for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++)
+    if (p->src() == gr_endpoint(block, port))
+      tmp.push_back(p->dst().block());
+
+  // Remove duplicates
+  sort(tmp.begin(), tmp.end());
+  unique_copy(tmp.begin(), tmp.end(), inserter);
+  return result;
+}
+
+gr_basic_block_vector_t
+gr_flowgraph::calc_downstream_blocks(gr_basic_block_sptr block)
+{
+  gr_basic_block_vector_t tmp, result;
+  std::insert_iterator<gr_basic_block_vector_t> inserter(result, 
result.begin());
+
+  for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++)
+    if (p->src().block() == block)
+      tmp.push_back(p->dst().block());
+
+  // Remove duplicates
+  sort(tmp.begin(), tmp.end());
+  unique_copy(tmp.begin(), tmp.end(), inserter);
+  return result;
+}
+
+gr_edge_vector_t
+gr_flowgraph::calc_upstream_edges(gr_basic_block_sptr block)
+{
+  gr_edge_vector_t result;
+
+  for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++)
+    if (p->dst().block() == block)
+      result.push_back(*p);
+
+  return result; // Assume no duplicates
+}
+
+bool
+gr_flowgraph::has_block_p(gr_basic_block_sptr block)
+{
+  gr_basic_block_viter_t result;
+  result = std::find(d_blocks.begin(), d_blocks.end(), block);
+  return (result != d_blocks.end());
+}
+
+gr_edge
+gr_flowgraph::calc_upstream_edge(gr_basic_block_sptr block, int port)
+{
+  gr_edge result;
+
+  for (gr_edge_viter_t p = d_edges.begin(); p != d_edges.end(); p++) {
+    if (p->dst() == gr_endpoint(block, port)) {
+      result = (*p);
+      break;
+    }
+  }
+
+  return result;
+}
+
+std::vector<gr_basic_block_vector_t>
+gr_flowgraph::partition()
+{
+  std::vector<gr_basic_block_vector_t> result;
+  gr_basic_block_vector_t blocks = calc_used_blocks();
+  gr_basic_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_basic_block_viter_t p = graph.begin(); p != graph.end(); p++)
+      blocks.erase(find(blocks.begin(), blocks.end(), *p));
+  }
+
+  return result;
+}
+
+gr_basic_block_vector_t
+gr_flowgraph::calc_reachable_blocks(gr_basic_block_sptr block, 
gr_basic_block_vector_t &blocks)
+{
+  gr_basic_block_vector_t result;
+
+  // Mark all blocks as unvisited
+  for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++)
+    (*p)->set_color(gr_basic_block::WHITE);
+
+  // Recursively mark all reachable blocks
+  reachable_dfs_visit(block, blocks);
+
+  // Collect all the blocks that have been visited
+  for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++)
+    if ((*p)->color() == gr_basic_block::BLACK)
+      result.push_back(*p);
+
+  return result;
+}
+
+// Recursively mark all reachable blocks from given block and block list
+void 
+gr_flowgraph::reachable_dfs_visit(gr_basic_block_sptr block, 
gr_basic_block_vector_t &blocks)
+{
+  // Mark the current one as visited
+  block->set_color(gr_basic_block::BLACK);
+
+  // Recurse into adjacent vertices
+  gr_basic_block_vector_t adjacent = calc_adjacent_blocks(block, blocks);
+
+  for (gr_basic_block_viter_t p = adjacent.begin(); p != adjacent.end(); p++)
+    if ((*p)->color() == gr_basic_block::WHITE)
+      reachable_dfs_visit(*p, blocks);
+}
+
+// Return a list of block adjacent to a given block along any edge
+gr_basic_block_vector_t 
+gr_flowgraph::calc_adjacent_blocks(gr_basic_block_sptr block, 
gr_basic_block_vector_t &blocks)
+{
+  gr_basic_block_vector_t tmp, result;
+  std::insert_iterator<gr_basic_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 (p->src().block() == block)
+      tmp.push_back(p->dst().block());
+    if (p->dst().block() == block)
+      tmp.push_back(p->src().block());
+  }    
+
+  // Remove duplicates
+  sort(tmp.begin(), tmp.end());
+  unique_copy(tmp.begin(), tmp.end(), inserter);
+  return result;
+}
+
+gr_basic_block_vector_t
+gr_flowgraph::topological_sort(gr_basic_block_vector_t &blocks)
+{
+  gr_basic_block_vector_t tmp;
+  gr_basic_block_vector_t result;
+  tmp = sort_sources_first(blocks);
+
+  // Start 'em all white
+  for (gr_basic_block_viter_t p = tmp.begin(); p != tmp.end(); p++)
+    (*p)->set_color(gr_basic_block::WHITE);
+
+  for (gr_basic_block_viter_t p = tmp.begin(); p != tmp.end(); p++) {
+    if ((*p)->color() == gr_basic_block::WHITE)
+      topological_dfs_visit(*p, result);
+  }    
+
+  reverse(result.begin(), result.end());
+  return result;
+}
+
+gr_basic_block_vector_t
+gr_flowgraph::sort_sources_first(gr_basic_block_vector_t &blocks)
+{
+  gr_basic_block_vector_t sources, nonsources, result;
+
+  for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
+    if (source_p(*p))
+      sources.push_back(*p);
+    else
+      nonsources.push_back(*p);
+  }
+
+  for (gr_basic_block_viter_t p = sources.begin(); p != sources.end(); p++)
+    result.push_back(*p);
+
+  for (gr_basic_block_viter_t p = nonsources.begin(); p != nonsources.end(); 
p++)
+    result.push_back(*p);
+
+  return result;
+}
+
+bool
+gr_flowgraph::source_p(gr_basic_block_sptr block)
+{
+  return (calc_upstream_edges(block).size() == 0);
+}
+
+void
+gr_flowgraph::topological_dfs_visit(gr_basic_block_sptr block, 
gr_basic_block_vector_t &output)
+{
+  block->set_color(gr_basic_block::GREY);
+  gr_basic_block_vector_t blocks(calc_downstream_blocks(block));
+
+  for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
+    switch ((*p)->color()) {
+    case gr_basic_block::WHITE:           
+      topological_dfs_visit(*p, output);
+      break;
+
+    case gr_basic_block::GREY:            
+      throw std::runtime_error("flow graph has loops!");
+
+    case gr_basic_block::BLACK:
+      continue;
+
+    default:
+      throw std::runtime_error("invalid color on block!");
+    }
+  }
+
+  block->set_color(gr_basic_block::BLACK);
+  output.push_back(block);
+}
+

Copied: gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_flowgraph.h (from rev 
6168, 
gnuradio/branches/developers/jcorgan/fg/gnuradio-core/src/lib/runtime/gr_flowgraph.h)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_flowgraph.h                 
        (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_flowgraph.h 2007-08-23 
18:46:20 UTC (rev 6169)
@@ -0,0 +1,188 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2006,2007 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 3, 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_FLOWGRAPH_H
+#define INCLUDED_GR_FLOWGRAPH_H
+
+#include <gr_basic_block.h>
+#include <iostream>
+
+/*!
+ *\brief Class representing a specific input or output graph endpoint
+ *
+ */
+class gr_endpoint
+{
+private:
+  gr_basic_block_sptr d_basic_block;
+  int d_port;
+
+public:
+  gr_endpoint() : d_basic_block(), d_port(0) { }
+  gr_endpoint(gr_basic_block_sptr block, int port) { d_basic_block = block; 
d_port = port; }
+  gr_basic_block_sptr block() const { return d_basic_block; }
+  int port() const { return d_port; }
+
+  bool operator==(const gr_endpoint &other) const;
+};    
+
+inline bool gr_endpoint::operator==(const gr_endpoint &other) const
+{
+  return (d_basic_block == other.d_basic_block && 
+         d_port == other.d_port);
+}
+
+// Hold vectors of gr_endpoint objects
+typedef std::vector<gr_endpoint> gr_endpoint_vector_t;
+typedef std::vector<gr_endpoint>::iterator gr_endpoint_viter_t;
+
+/*!
+ *\brief Class representing a connection between to graph endpoints
+ *
+ */
+class gr_edge
+{
+public:
+  gr_edge() : d_src(), d_dst() { };
+  gr_edge(const gr_endpoint &src, const gr_endpoint &dst) : d_src(src), 
d_dst(dst) { }
+  ~gr_edge();
+
+  const gr_endpoint &src() const { return d_src; }
+  const gr_endpoint &dst() const { return d_dst; }
+
+private:
+  gr_endpoint d_src;
+  gr_endpoint d_dst;
+};
+
+// Hold vectors of gr_edge objects
+typedef std::vector<gr_edge> gr_edge_vector_t;
+typedef std::vector<gr_edge>::iterator gr_edge_viter_t;
+
+
+// Create a shared pointer to a heap allocated flowgraph
+// (types defined in gr_runtime_types.h)
+gr_flowgraph_sptr gr_make_flowgraph();
+
+/*!
+ *\brief Class representing a directed, acyclic graph of basic blocks
+ *
+ */
+class gr_flowgraph
+{
+public:
+  friend gr_flowgraph_sptr gr_make_flowgraph();
+
+  // Destruct an arbitrary flowgraph
+  ~gr_flowgraph();
+
+  // Connect two endpoints
+  void connect(const gr_endpoint &src, const gr_endpoint &dst);
+
+  // Disconnect two endpoints
+  void disconnect(const gr_endpoint &src, const gr_endpoint &dst);
+
+  // Connect an output port to an input port (convenience)
+  void connect(gr_basic_block_sptr src_block, int src_port,
+              gr_basic_block_sptr dst_block, int dst_port);
+
+  // Disconnect an input port from an output port (convenience)
+  void disconnect(gr_basic_block_sptr src_block, int src_port,
+                 gr_basic_block_sptr dst_block, int dst_port);
+
+  // Validate connectivity, raise exception if invalid
+  void validate();
+
+  // Clear existing flowgraph
+  void clear();
+
+  // Return vector of edges
+  const gr_edge_vector_t &edges() const { return d_edges; }
+
+  // Return vector of connected blocks
+  gr_basic_block_vector_t calc_used_blocks();
+
+  // Return vector of vectors of disjointly connected blocks, topologically
+  // sorted.
+  std::vector<gr_basic_block_vector_t> partition();
+
+protected:
+  gr_basic_block_vector_t d_blocks;
+  gr_edge_vector_t d_edges;
+
+  gr_flowgraph();
+  std::vector<int> calc_used_ports(gr_basic_block_sptr block, bool 
check_inputs); 
+  gr_basic_block_vector_t calc_downstream_blocks(gr_basic_block_sptr block, 
int port);
+  gr_edge_vector_t calc_upstream_edges(gr_basic_block_sptr block);
+  bool has_block_p(gr_basic_block_sptr block);
+  gr_edge calc_upstream_edge(gr_basic_block_sptr block, int port);
+
+private:
+
+  void check_valid_port(gr_io_signature_sptr sig, int port);
+  void check_dst_not_used(const gr_endpoint &dst);
+  void check_type_match(const gr_endpoint &src, const gr_endpoint &dst);
+  gr_edge_vector_t calc_connections(gr_basic_block_sptr block, bool 
check_inputs); // false=use outputs
+  void check_contiguity(gr_basic_block_sptr block, const std::vector<int> 
&used_ports, bool check_inputs);
+
+  gr_basic_block_vector_t calc_downstream_blocks(gr_basic_block_sptr block);
+  gr_basic_block_vector_t calc_reachable_blocks(gr_basic_block_sptr block, 
gr_basic_block_vector_t &blocks);
+  void reachable_dfs_visit(gr_basic_block_sptr block, gr_basic_block_vector_t 
&blocks);
+  gr_basic_block_vector_t calc_adjacent_blocks(gr_basic_block_sptr block, 
gr_basic_block_vector_t &blocks);
+  gr_basic_block_vector_t topological_sort(gr_basic_block_vector_t &blocks);
+  gr_basic_block_vector_t sort_sources_first(gr_basic_block_vector_t &blocks);
+  bool source_p(gr_basic_block_sptr block);
+  void topological_dfs_visit(gr_basic_block_sptr block, 
gr_basic_block_vector_t &output);
+};
+
+// Convenience functions
+inline
+void gr_flowgraph::connect(gr_basic_block_sptr src_block, int src_port,
+                     gr_basic_block_sptr dst_block, int dst_port)
+{
+  connect(gr_endpoint(src_block, src_port),
+         gr_endpoint(dst_block, dst_port));
+}
+
+inline
+void gr_flowgraph::disconnect(gr_basic_block_sptr src_block, int src_port,
+                        gr_basic_block_sptr dst_block, int dst_port)
+{
+  disconnect(gr_endpoint(src_block, src_port),
+            gr_endpoint(dst_block, dst_port));
+}
+
+inline std::ostream&
+operator <<(std::ostream &os, const gr_endpoint endp)
+{
+  os << endp.block() << ":" << endp.port();
+  return os;
+}
+
+inline std::ostream&
+operator <<(std::ostream &os, const gr_edge edge)
+{
+  os << edge.src() << "->" << edge.dst();
+  return os;
+}
+
+#endif /* INCLUDED_GR_FLOWGRAPH_H */

Modified: gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc       
2007-08-23 17:25:53 UTC (rev 6168)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc       
2007-08-23 18:46:20 UTC (rev 6169)
@@ -24,7 +24,6 @@
 #endif
 
 #include <gr_hier_block2_detail.h>
-#include <gr_simple_flowgraph.h>
 #include <gr_io_signature.h>
 #include <gr_runtime.h>
 #include <stdexcept>
@@ -35,7 +34,7 @@
 gr_hier_block2_detail::gr_hier_block2_detail(gr_hier_block2 *owner) :
   d_owner(owner), 
   d_parent_detail(0),
-  d_fg(gr_make_simple_flowgraph()),
+  d_fg(gr_make_flowgraph()),
   d_inputs(owner->input_signature()->max_streams()),
   d_outputs(owner->output_signature()->max_streams()),
   d_runtime()
@@ -228,22 +227,24 @@
 }
 
 void
-gr_hier_block2_detail::flatten(gr_simple_flowgraph_sptr sfg)
+gr_hier_block2_detail::flatten(gr_flat_flowgraph_sptr sfg)
 {
   if (GR_HIER_BLOCK2_DETAIL_DEBUG)
     std::cout << "flattening " << d_owner->name() << std::endl;
 
   // Add my edges to the flow graph, resolving references to actual endpoints
-  for (gr_edge_viter_t p = d_fg->d_detail->d_edges.begin(); p != 
d_fg->d_detail->d_edges.end(); p++) {
+  gr_edge_vector_t edges = d_fg->edges();
+
+  for (gr_edge_viter_t p = edges.begin(); p != edges.end(); p++) {
     if (GR_HIER_BLOCK2_DETAIL_DEBUG)
       std::cout << "Flattening edge " << (*p) << std::endl;
 
-    gr_endpoint src_endp = resolve_endpoint((*p)->src(), false);
-    gr_endpoint dst_endp = resolve_endpoint((*p)->dst(), true);
+    gr_endpoint src_endp = resolve_endpoint(p->src(), false);
+    gr_endpoint dst_endp = resolve_endpoint(p->dst(), true);
     sfg->connect(src_endp, dst_endp);
   }
 
-  gr_basic_block_vector_t blocks = d_fg->d_detail->calc_used_blocks();
+  gr_basic_block_vector_t blocks = d_fg->calc_used_blocks();
 
   // Recurse hierarchical children
   for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {

Modified: gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h        
2007-08-23 17:25:53 UTC (rev 6168)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h        
2007-08-23 18:46:20 UTC (rev 6169)
@@ -22,7 +22,7 @@
 #define INCLUDED_GR_HIER_BLOCK2_DETAIL_H
 
 #include <gr_hier_block2.h>
-#include <gr_simple_flowgraph_detail.h>
+#include <gr_flat_flowgraph.h>
 #include <boost/utility.hpp>
 
 class gr_hier_block2_detail : boost::noncopyable
@@ -37,7 +37,7 @@
     // Private implementation data
     gr_hier_block2 *d_owner;
     gr_hier_block2_detail *d_parent_detail;
-    gr_simple_flowgraph_sptr d_fg;
+    gr_flowgraph_sptr d_fg;
     gr_endpoint_vector_t d_inputs;
     gr_endpoint_vector_t d_outputs;
     gr_runtime *d_runtime;
@@ -51,7 +51,7 @@
     void connect_output(int my_port, int port, gr_basic_block_sptr block);
     void disconnect_input(int my_port, int port, gr_basic_block_sptr block);
     void disconnect_output(int my_port, int port, gr_basic_block_sptr block);
-    void flatten(gr_simple_flowgraph_sptr sfg);
+    void flatten(gr_flat_flowgraph_sptr sfg);
     gr_endpoint resolve_port(int port, bool is_input);
     gr_endpoint resolve_endpoint(const gr_endpoint &endp, bool is_input);
     void set_runtime(gr_runtime *runtime) { d_runtime = runtime; }

Modified: gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_runtime_impl.cc
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_runtime_impl.cc     
2007-08-23 17:25:53 UTC (rev 6168)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_runtime_impl.cc     
2007-08-23 18:46:20 UTC (rev 6169)
@@ -26,7 +26,7 @@
 
 #include <gr_runtime.h>
 #include <gr_runtime_impl.h>
-#include <gr_simple_flowgraph.h>
+#include <gr_flat_flowgraph.h>
 #include <gr_hier_block2.h>
 #include <gr_hier_block2_detail.h>
 #include <gr_local_sighandler.h>
@@ -42,6 +42,19 @@
 
 static gr_runtime_impl *s_runtime = 0;
 
+// Make a vector of gr_block from a vector of gr_basic_block
+static
+gr_block_vector_t
+make_gr_block_vector(gr_basic_block_vector_t &blocks)
+{
+  gr_block_vector_t result;
+  for (gr_basic_block_viter_t p = blocks.begin(); p != blocks.end(); p++) {
+    result.push_back(make_gr_block_sptr(*p));
+  }
+
+  return result;
+}
+
 // FIXME: This prevents using more than one gr_runtime instance
 void 
 runtime_sigint_handler(int signum)
@@ -56,7 +69,7 @@
 gr_runtime_impl::gr_runtime_impl(gr_hier_block2_sptr top_block, gr_runtime 
*owner) 
   : d_running(false),
     d_top_block(top_block),
-    d_sfg(gr_make_simple_flowgraph()),
+    d_ffg(gr_make_flat_flowgraph()),
     d_owner(owner)
 {
   s_runtime = this;
@@ -79,12 +92,12 @@
     throw std::runtime_error("already running");
 
   // Create new simple flow graph by flattening hierarchical block
-  d_sfg->d_detail->reset();
-  d_top_block->d_detail->flatten(d_sfg);
+  d_ffg->clear();
+  d_top_block->d_detail->flatten(d_ffg);
 
   // Validate new simple flow graph and wire it up
-  d_sfg->d_detail->validate();
-  d_sfg->d_detail->setup_connections();
+  d_ffg->validate();
+  d_ffg->setup_connections();
 
   // Execute scheduler threads
   start_threads();
@@ -96,10 +109,10 @@
   if (GR_RUNTIME_IMPL_DEBUG)
     std::cout << "start_threads: entered" << std::endl;
 
-  d_graphs = d_sfg->d_detail->partition();
-  for (std::vector<gr_block_vector_t>::iterator p = d_graphs.begin();
+  d_graphs = d_ffg->partition();
+  for (std::vector<gr_basic_block_vector_t>::iterator p = d_graphs.begin();
        p != d_graphs.end(); p++) {
-    gr_scheduler_thread *thread = new gr_scheduler_thread(*p);
+    gr_scheduler_thread *thread = new 
gr_scheduler_thread(make_gr_block_vector(*p));
     d_threads.push_back(thread);
     if (GR_RUNTIME_IMPL_DEBUG)
       std::cout << "start_threads: starting " << thread << std::endl;
@@ -188,14 +201,14 @@
     std::cout << "restart: threads stopped" << std::endl;
 
   // Create new simple flow graph 
-  gr_simple_flowgraph_sptr new_sfg = gr_make_simple_flowgraph();
-  d_top_block->d_detail->flatten(new_sfg);
-  new_sfg->validate();
-  new_sfg->d_detail->merge_connections(d_sfg);
+  gr_flat_flowgraph_sptr new_ffg = gr_make_flat_flowgraph();
+  d_top_block->d_detail->flatten(new_ffg);
+  new_ffg->validate();
+  new_ffg->merge_connections(d_ffg);
 
   if (GR_RUNTIME_IMPL_DEBUG)
     std::cout << "restart: replacing old flow graph with new" << std::endl;
-  d_sfg = new_sfg;
+  d_ffg = new_ffg;
 
   start_threads();
 }

Modified: gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_runtime_impl.h
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_runtime_impl.h      
2007-08-23 17:25:53 UTC (rev 6168)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_runtime_impl.h      
2007-08-23 18:46:20 UTC (rev 6169)
@@ -72,8 +72,8 @@
     
   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_flat_flowgraph_sptr         d_ffg;
+  std::vector<gr_basic_block_vector_t> d_graphs;
   gr_scheduler_thread_vector_t   d_threads;
   gr_runtime                    *d_owner;
   int                            d_lock_count;

Modified: gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_runtime_types.h
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_runtime_types.h     
2007-08-23 17:25:53 UTC (rev 6168)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_runtime_types.h     
2007-08-23 18:46:20 UTC (rev 6169)
@@ -1,6 +1,6 @@
 /* -*- c++ -*- */
 /*
- * Copyright 2004 Free Software Foundation, Inc.
+ * Copyright 2004,2007 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -36,17 +36,19 @@
 class gr_io_signature;
 class gr_buffer;
 class gr_buffer_reader;
-class gr_simple_flowgraph;
+class gr_flowgraph;
+class gr_flat_flowgraph;
 class gr_runtime;
 
 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_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;
+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_flowgraph>         gr_flowgraph_sptr;
+typedef boost::shared_ptr<gr_flat_flowgraph>    gr_flat_flowgraph_sptr;
 
 #endif /* INCLUDED_GR_RUNTIME_TYPES_H */

Deleted: gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_simple_flowgraph.cc

Deleted: gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_simple_flowgraph.h

Deleted: 
gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.cc

Deleted: 
gnuradio/trunk/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.h

Copied: gnuradio/trunk/gnuradio-core/src/lib/runtime/qa_gr_flowgraph.cc (from 
rev 6168, 
gnuradio/branches/developers/jcorgan/fg/gnuradio-core/src/lib/runtime/qa_gr_flowgraph.cc)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/qa_gr_flowgraph.cc             
                (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/qa_gr_flowgraph.cc     
2007-08-23 18:46:20 UTC (rev 6169)
@@ -0,0 +1,245 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 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 3, 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_flowgraph.h>
+#include <gr_flowgraph.h>
+#include <gr_nop.h>
+#include <gr_null_source.h>
+#include <gr_null_sink.h>
+
+void qa_gr_flowgraph::t0()
+{
+  gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+  CPPUNIT_ASSERT(fg);
+}
+
+void qa_gr_flowgraph::t1_connect()
+{
+  gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+  gr_block_sptr nop1 = gr_make_nop(sizeof(int));
+  gr_block_sptr nop2 = gr_make_nop(sizeof(int));
+
+  fg->connect(nop1, 0, nop2, 0);
+}
+
+void qa_gr_flowgraph::t2_connect_invalid_src_port_neg()
+{
+  gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+  gr_block_sptr nop1 = gr_make_nop(sizeof(int));
+  gr_block_sptr nop2 = gr_make_nop(sizeof(int));
+
+  CPPUNIT_ASSERT_THROW(fg->connect(nop1, -1, nop2, 0), std::invalid_argument);
+}
+
+void qa_gr_flowgraph::t3_connect_src_port_exceeds()
+{
+  gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+  gr_block_sptr src = gr_make_null_source(sizeof(int));
+  gr_block_sptr dst = gr_make_null_sink(sizeof(int));
+
+  CPPUNIT_ASSERT_THROW(fg->connect(src, 1, dst, 0), std::invalid_argument);
+}
+
+void qa_gr_flowgraph::t4_connect_invalid_dst_port_neg()
+{
+  gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+  gr_block_sptr nop1 = gr_make_nop(sizeof(int));
+  gr_block_sptr nop2 = gr_make_nop(sizeof(int));
+
+  CPPUNIT_ASSERT_THROW(fg->connect(nop1, 0, nop2, -1), std::invalid_argument);
+}
+
+void qa_gr_flowgraph::t5_connect_dst_port_exceeds()
+{
+  gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+  gr_block_sptr src = gr_make_null_source(sizeof(int));
+  gr_block_sptr dst = gr_make_null_sink(sizeof(int));
+
+  CPPUNIT_ASSERT_THROW(fg->connect(src, 0, dst, 1), std::invalid_argument);
+}
+
+void qa_gr_flowgraph::t6_connect_dst_in_use()
+{
+  gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+  gr_block_sptr src1 = gr_make_null_source(sizeof(int));
+  gr_block_sptr src2 = gr_make_null_source(sizeof(int));
+  gr_block_sptr dst = gr_make_null_sink(sizeof(int));
+
+  fg->connect(src1, 0, dst, 0);
+  CPPUNIT_ASSERT_THROW(fg->connect(src2, 0, dst, 0), std::invalid_argument);
+}
+
+void qa_gr_flowgraph::t7_connect_one_src_two_dst()
+{
+  gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+  gr_block_sptr src = gr_make_null_source(sizeof(int));
+  gr_block_sptr dst1 = gr_make_null_sink(sizeof(int));
+  gr_block_sptr dst2 = gr_make_null_sink(sizeof(int));
+
+  fg->connect(src, 0, dst1, 0);
+  fg->connect(src, 0, dst2, 0);
+}
+
+void qa_gr_flowgraph::t8_connect_type_mismatch()
+{
+  gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+  gr_block_sptr nop1 = gr_make_nop(sizeof(char));
+  gr_block_sptr nop2 = gr_make_nop(sizeof(int));
+
+  CPPUNIT_ASSERT_THROW(fg->connect(nop1, 0, nop2, 0), std::invalid_argument);
+}
+
+void qa_gr_flowgraph::t9_disconnect()
+{
+  gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+  gr_block_sptr nop1 = gr_make_nop(sizeof(int));
+  gr_block_sptr nop2 = gr_make_nop(sizeof(int));
+
+  fg->connect(nop1, 0, nop2, 0);
+  fg->disconnect(nop1, 0, nop2, 0);
+}
+
+void qa_gr_flowgraph::t10_disconnect_unconnected_block()
+{
+  gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+  gr_block_sptr nop1 = gr_make_nop(sizeof(int));
+  gr_block_sptr nop2 = gr_make_nop(sizeof(int));
+  gr_block_sptr nop3 = gr_make_nop(sizeof(int));
+
+  fg->connect(nop1, 0, nop2, 0);
+  CPPUNIT_ASSERT_THROW(fg->disconnect(nop1, 0, nop3, 0), 
std::invalid_argument);
+}
+
+void qa_gr_flowgraph::t11_disconnect_unconnected_port()
+{
+  gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+  gr_block_sptr nop1 = gr_make_nop(sizeof(int));
+  gr_block_sptr nop2 = gr_make_nop(sizeof(int));
+
+  fg->connect(nop1, 0, nop2, 0);
+  CPPUNIT_ASSERT_THROW(fg->disconnect(nop1, 0, nop2, 1), 
std::invalid_argument);
+}
+
+void qa_gr_flowgraph::t12_validate()
+{
+  gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+  gr_block_sptr nop1 = gr_make_nop(sizeof(int));
+  gr_block_sptr nop2 = gr_make_nop(sizeof(int));
+
+  fg->connect(nop1, 0, nop2, 0);
+  fg->validate();
+}
+
+void qa_gr_flowgraph::t13_validate_missing_input_assignment()
+{
+  gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+  gr_block_sptr nop1 = gr_make_nop(sizeof(int));
+  gr_block_sptr nop2 = gr_make_nop(sizeof(int));
+
+  fg->connect(nop1, 0, nop2, 0);
+  fg->connect(nop1, 0, nop2, 2);
+  CPPUNIT_ASSERT_THROW(fg->validate(), std::runtime_error);
+}
+
+void qa_gr_flowgraph::t14_validate_missing_output_assignment()
+{
+  gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+  gr_block_sptr nop1 = gr_make_nop(sizeof(int));
+  gr_block_sptr nop2 = gr_make_nop(sizeof(int));
+
+  fg->connect(nop1, 0, nop2, 0);
+  fg->connect(nop1, 2, nop2, 1);
+  CPPUNIT_ASSERT_THROW(fg->validate(), std::runtime_error);
+}
+
+void qa_gr_flowgraph::t15_clear()
+{
+  gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+  gr_block_sptr nop1 = gr_make_nop(sizeof(int));
+  gr_block_sptr nop2 = gr_make_nop(sizeof(int));
+
+  fg->connect(nop1, 0, nop2, 0);
+
+  CPPUNIT_ASSERT(fg->edges().size() == 1);
+  CPPUNIT_ASSERT(fg->calc_used_blocks().size() == 2);
+
+  fg->clear();
+
+  CPPUNIT_ASSERT(fg->edges().size() == 0);
+  CPPUNIT_ASSERT(fg->calc_used_blocks().size() == 0);
+}
+
+void qa_gr_flowgraph::t16_partition()
+{
+  gr_flowgraph_sptr fg = gr_make_flowgraph();
+
+  gr_block_sptr nop11 = gr_make_nop(sizeof(int));
+  gr_block_sptr nop12 = gr_make_nop(sizeof(int));
+  gr_block_sptr nop13 = gr_make_nop(sizeof(int));
+  gr_block_sptr nop14 = gr_make_nop(sizeof(int));
+
+  gr_block_sptr nop21 = gr_make_nop(sizeof(int));
+  gr_block_sptr nop22 = gr_make_nop(sizeof(int));
+  gr_block_sptr nop23 = gr_make_nop(sizeof(int));
+
+  gr_block_sptr nop31 = gr_make_nop(sizeof(int));
+  gr_block_sptr nop32 = gr_make_nop(sizeof(int));
+  
+  // Build disjoint graph #1
+  fg->connect(nop11, 0, nop12, 0);
+  fg->connect(nop12, 0, nop13, 0);
+  fg->connect(nop13, 0, nop14, 0);
+
+  // Build disjoint graph #2
+  fg->connect(nop21, 0, nop22, 0);
+  fg->connect(nop22, 0, nop23, 0);
+
+  // Build disjoint graph #3
+  fg->connect(nop31, 0, nop32, 0);
+
+  std::vector<gr_basic_block_vector_t> graphs = fg->partition();
+
+  CPPUNIT_ASSERT(graphs.size() == 3);
+  CPPUNIT_ASSERT(graphs[0].size() == 4);
+  CPPUNIT_ASSERT(graphs[1].size() == 3);
+  CPPUNIT_ASSERT(graphs[2].size() == 2);
+}

Copied: gnuradio/trunk/gnuradio-core/src/lib/runtime/qa_gr_flowgraph.h (from 
rev 6168, 
gnuradio/branches/developers/jcorgan/fg/gnuradio-core/src/lib/runtime/qa_gr_flowgraph.h)
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/qa_gr_flowgraph.h              
                (rev 0)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/qa_gr_flowgraph.h      
2007-08-23 18:46:20 UTC (rev 6169)
@@ -0,0 +1,75 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2007 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 3, 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_FLOWGRAPH_H
+#define INCLUDED_QA_GR_FLOWGRAPH_H
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestCase.h>
+#include <stdexcept>
+
+class qa_gr_flowgraph : public CppUnit::TestCase 
+{
+  CPPUNIT_TEST_SUITE(qa_gr_flowgraph);
+  
+  CPPUNIT_TEST(t0);
+  CPPUNIT_TEST(t1_connect);
+  CPPUNIT_TEST(t2_connect_invalid_src_port_neg);
+  CPPUNIT_TEST(t3_connect_src_port_exceeds);
+  CPPUNIT_TEST(t4_connect_invalid_dst_port_neg);
+  CPPUNIT_TEST(t5_connect_dst_port_exceeds);
+  CPPUNIT_TEST(t6_connect_dst_in_use);
+  CPPUNIT_TEST(t7_connect_one_src_two_dst);
+  CPPUNIT_TEST(t8_connect_type_mismatch);
+  CPPUNIT_TEST(t9_disconnect);
+  CPPUNIT_TEST(t10_disconnect_unconnected_block);
+  CPPUNIT_TEST(t11_disconnect_unconnected_port);
+  CPPUNIT_TEST(t12_validate);
+  CPPUNIT_TEST(t13_validate_missing_input_assignment);
+  CPPUNIT_TEST(t14_validate_missing_output_assignment);
+  CPPUNIT_TEST(t15_clear);
+  CPPUNIT_TEST(t16_partition);
+
+  CPPUNIT_TEST_SUITE_END();
+
+private:
+
+  void t0();
+  void t1_connect();
+  void t2_connect_invalid_src_port_neg();
+  void t3_connect_src_port_exceeds();
+  void t4_connect_invalid_dst_port_neg();
+  void t5_connect_dst_port_exceeds();
+  void t6_connect_dst_in_use();
+  void t7_connect_one_src_two_dst();
+  void t8_connect_type_mismatch();
+  void t9_disconnect();
+  void t10_disconnect_unconnected_block();
+  void t11_disconnect_unconnected_port();
+  void t12_validate();
+  void t13_validate_missing_input_assignment();
+  void t14_validate_missing_output_assignment();
+  void t15_clear();
+  void t16_partition();
+};
+
+#endif /* INCLUDED_QA_GR_FLOWGRAPH_H */

Modified: gnuradio/trunk/gnuradio-core/src/lib/runtime/qa_runtime.cc
===================================================================
--- gnuradio/trunk/gnuradio-core/src/lib/runtime/qa_runtime.cc  2007-08-23 
17:25:53 UTC (rev 6168)
+++ gnuradio/trunk/gnuradio-core/src/lib/runtime/qa_runtime.cc  2007-08-23 
18:46:20 UTC (rev 6169)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002 Free Software Foundation, Inc.
+ * Copyright 2002,2007 Free Software Foundation, Inc.
  * 
  * This file is part of GNU Radio
  * 
@@ -33,6 +33,7 @@
 #include <qa_gr_vmcircbuf.h>
 #include <qa_gr_io_signature.h>
 #include <qa_gr_block.h>
+#include <qa_gr_flowgraph.h>
 #include <qa_gr_hier_block2.h>
 #include <qa_gr_buffer.h>
 
@@ -44,6 +45,7 @@
   s->addTest (qa_gr_vmcircbuf::suite ());
   s->addTest (qa_gr_io_signature::suite ());
   s->addTest (qa_gr_block::suite ());
+  s->addTest (qa_gr_flowgraph::suite ());
   s->addTest (qa_gr_hier_block2::suite ());
   s->addTest (qa_gr_buffer::suite ());
   

Modified: gnuradio/trunk/gnuradio-core/src/python/gnuradio/gr/qa_hier_block2.py
===================================================================
--- gnuradio/trunk/gnuradio-core/src/python/gnuradio/gr/qa_hier_block2.py       
2007-08-23 17:25:53 UTC (rev 6168)
+++ gnuradio/trunk/gnuradio-core/src/python/gnuradio/gr/qa_hier_block2.py       
2007-08-23 18:46:20 UTC (rev 6169)
@@ -20,14 +20,6 @@
        self.assertEqual(1, hblock.output_signature().max_streams())
        self.assertEqual(gr.sizeof_int, 
hblock.output_signature().sizeof_stream_item(0))
 
-    def test_001_connect_internal(self):
-       hblock = gr.hier_block2("test_block", 
-                               gr.io_signature(1,1,gr.sizeof_int), 
-                               gr.io_signature(1,1,gr.sizeof_int))
-       nop1 = gr.nop(gr.sizeof_int)
-       nop2 = gr.nop(gr.sizeof_int)
-       hblock.connect(nop1, nop2)
-
     def test_002_connect_input(self):
        hblock = gr.hier_block2("test_block", 
                                gr.io_signature(1,1,gr.sizeof_int), 
@@ -35,7 +27,7 @@
        nop1 = gr.nop(gr.sizeof_int)
        hblock.connect(hblock, nop1)
 
-    def test_002a_connect_input_in_use(self):
+    def test_003_connect_input_in_use(self):
        hblock = gr.hier_block2("test_block", 
                                gr.io_signature(1,1,gr.sizeof_int), 
                                gr.io_signature(1,1,gr.sizeof_int))
@@ -45,14 +37,14 @@
        self.assertRaises(ValueError,
            lambda: hblock.connect(hblock, nop2))
 
-    def test_003_connect_output(self):
+    def test_004_connect_output(self):
        hblock = gr.hier_block2("test_block", 
                                gr.io_signature(1,1,gr.sizeof_int), 
                                gr.io_signature(1,1,gr.sizeof_int))
        nop1 = gr.nop(gr.sizeof_int)
        hblock.connect(nop1, hblock)
 
-    def test_003a_connect_output_in_use(self):
+    def test_005_connect_output_in_use(self):
        hblock = gr.hier_block2("test_block", 
                                gr.io_signature(1,1,gr.sizeof_int), 
                                gr.io_signature(1,1,gr.sizeof_int))
@@ -62,7 +54,7 @@
        self.assertRaises(ValueError,
            lambda: hblock.connect(nop2, hblock))
 
-    def test_004_connect_invalid_src_port_neg(self):
+    def test_006_connect_invalid_src_port_neg(self):
        hblock = gr.hier_block2("test_block", 
                                gr.io_signature(1,1,gr.sizeof_int), 
                                gr.io_signature(1,1,gr.sizeof_int))
@@ -78,7 +70,7 @@
        self.assertRaises(ValueError, 
            lambda: hblock.connect((hblock, 1), nop1))
 
-    def test_006_connect_invalid_dst_port_neg(self):
+    def test_007_connect_invalid_dst_port_neg(self):
        hblock = gr.hier_block2("test_block", 
                                gr.io_signature(1,1,gr.sizeof_int), 
                                gr.io_signature(1,1,gr.sizeof_int))
@@ -87,7 +79,7 @@
        self.assertRaises(ValueError, 
            lambda: hblock.connect(nop1, (nop2, -1)))
 
-    def test_007_connect_invalid_dst_port_exceeds(self):
+    def test_008_connect_invalid_dst_port_exceeds(self):
        hblock = gr.hier_block2("test_block", 
                                gr.io_signature(1,1,gr.sizeof_int), 
                                gr.io_signature(1,1,gr.sizeof_int))
@@ -96,54 +88,11 @@
        self.assertRaises(ValueError, 
            lambda: hblock.connect(nop1, (nop2, 1)))
 
-    def test_008_connect_dst_port_in_use(self):
-       hblock = gr.hier_block2("test_block", 
-                               gr.io_signature(1,1,gr.sizeof_int), 
-                               gr.io_signature(1,1,gr.sizeof_int))
-       nop1 = gr.nop(gr.sizeof_int)
-       nop2 = gr.nop(gr.sizeof_int)
-       hblock.connect(nop1, nop2);
-       self.assertRaises(ValueError, 
-           lambda: hblock.connect(nop1, nop2))
-
-    def test_009_connect_one_src_two_dst(self):
+    def test_009_check_topology(self):
        hblock = gr.top_block("test_block")
-       src = gr.null_source(gr.sizeof_int)
-       dst1 = gr.null_sink(gr.sizeof_int)
-       dst2 = gr.null_sink(gr.sizeof_int)
-       hblock.connect(src, dst1)
-       hblock.connect(src, dst2)
-
-    def test_010_connect_type_mismatch(self):
-       hblock = gr.top_block("test_block")
-       nop1 = gr.nop(gr.sizeof_char)
-       nop2 = gr.nop(gr.sizeof_int)
-       self.assertRaises(ValueError, 
-           lambda: hblock.connect(nop1, nop2))
-
-    def test_011_check_topology(self):
-       hblock = gr.top_block("test_block")
        hblock.check_topology(0, 0)
 
-    def test_012_disconnect(self):
-       hblock = gr.top_block("test_block") 
-       nop1 = gr.nop(gr.sizeof_int)
-       nop2 = gr.nop(gr.sizeof_int)
-       hblock.connect(nop1, nop2)
-        hblock.disconnect(nop1, nop2)
-
-    def test_013_disconnect_not_connected(self):
-       hblock = gr.hier_block2("test_block", 
-                               gr.io_signature(1,1,gr.sizeof_int), 
-                               gr.io_signature(1,1,gr.sizeof_int))
-       nop1 = gr.nop(gr.sizeof_int)
-       nop2 = gr.nop(gr.sizeof_int)
-       nop3 = gr.nop(gr.sizeof_int)
-       hblock.connect(nop1, nop2)
-       self.assertRaises(ValueError, 
-           lambda: hblock.disconnect(nop1, nop3))
-
-    def test_014_run(self):
+    def test_010_run(self):
         expected = (1.0, 2.0, 3.0, 4.0)
         hblock = gr.top_block("test_block")
         src = gr.vector_source_f(expected, False)
@@ -158,7 +107,7 @@
         self.assertEquals(expected, actual1)
         self.assertEquals(expected, actual2)
 
-    def test_015_disconnect_input(self):
+    def test_012_disconnect_input(self):
        hblock = gr.hier_block2("test_block", 
                                gr.io_signature(1,1,gr.sizeof_int), 
                                gr.io_signature(1,1,gr.sizeof_int))
@@ -166,7 +115,7 @@
        hblock.connect(hblock, nop1)
         hblock.disconnect(hblock, nop1)
    
-    def test_016_disconnect_input_not_connected(self):
+    def test_013_disconnect_input_not_connected(self):
        hblock = gr.hier_block2("test_block", 
                                gr.io_signature(1,1,gr.sizeof_int), 
                                gr.io_signature(1,1,gr.sizeof_int))
@@ -176,7 +125,7 @@
         self.assertRaises(ValueError,
             lambda: hblock.disconnect(hblock, nop2))
    
-    def test_017_disconnect_input_neg(self):
+    def test_014_disconnect_input_neg(self):
        hblock = gr.hier_block2("test_block", 
                                gr.io_signature(1,1,gr.sizeof_int), 
                                gr.io_signature(1,1,gr.sizeof_int))
@@ -185,7 +134,7 @@
         self.assertRaises(ValueError,
             lambda: hblock.disconnect((hblock, -1), nop1))
 
-    def test_018_disconnect_input_exceeds(self):
+    def test_015_disconnect_input_exceeds(self):
        hblock = gr.hier_block2("test_block", 
                                gr.io_signature(1,1,gr.sizeof_int), 
                                gr.io_signature(1,1,gr.sizeof_int))
@@ -194,7 +143,7 @@
         self.assertRaises(ValueError,
             lambda: hblock.disconnect((hblock, 1), nop1))
 
-    def test_019_disconnect_output(self):
+    def test_016_disconnect_output(self):
        hblock = gr.hier_block2("test_block", 
                                gr.io_signature(1,1,gr.sizeof_int), 
                                gr.io_signature(1,1,gr.sizeof_int))
@@ -202,7 +151,7 @@
        hblock.connect(nop1, hblock)
         hblock.disconnect(nop1, hblock)
    
-    def test_020_disconnect_output_not_connected(self):
+    def test_017_disconnect_output_not_connected(self):
        hblock = gr.hier_block2("test_block", 
                                gr.io_signature(1,1,gr.sizeof_int), 
                                gr.io_signature(1,1,gr.sizeof_int))
@@ -212,7 +161,7 @@
         self.assertRaises(ValueError,
             lambda: hblock.disconnect(nop2, hblock))
    
-    def test_021_disconnect_output_neg(self):
+    def test_018_disconnect_output_neg(self):
        hblock = gr.hier_block2("test_block", 
                                gr.io_signature(1,1,gr.sizeof_int), 
                                gr.io_signature(1,1,gr.sizeof_int))
@@ -221,7 +170,7 @@
         self.assertRaises(ValueError,
             lambda: hblock.disconnect(nop1, (hblock, -1)))
 
-    def test_022_disconnect_output_exceeds(self):
+    def test_019_disconnect_output_exceeds(self):
        hblock = gr.hier_block2("test_block", 
                                gr.io_signature(1,1,gr.sizeof_int), 
                                gr.io_signature(1,1,gr.sizeof_int))
@@ -230,7 +179,7 @@
         self.assertRaises(ValueError,
             lambda: hblock.disconnect(nop1, (hblock, 1)))
 
-    def test_023_run(self):
+    def test_020_run(self):
        hblock = gr.top_block("test_block")
        data = (1.0, 2.0, 3.0, 4.0)
        src = gr.vector_source_f(data, False)





reply via email to

[Prev in Thread] Current Thread [Next in Thread]