summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc86
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h12
-rwxr-xr-xgnuradio-core/src/python/gnuradio/gr/qa_hier_block2.py54
-rw-r--r--gr-wxgui/src/python/fftsink_gl.py3
-rw-r--r--gr-wxgui/src/python/scopesink_gl.py5
-rw-r--r--gr-wxgui/src/python/waterfallsink_gl.py3
6 files changed, 108 insertions, 55 deletions
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc
index d85d26749..fa52b7429 100644
--- a/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc
@@ -49,7 +49,7 @@ gr_hier_block2_detail::gr_hier_block2_detail(gr_hier_block2 *owner) :
throw std::runtime_error(msg.str());
}
- d_inputs = gr_endpoint_vector_t(max_inputs);
+ d_inputs = std::vector<gr_endpoint_vector_t>(max_inputs);
d_outputs = gr_endpoint_vector_t(max_outputs);
}
@@ -222,7 +222,6 @@ gr_hier_block2_detail::disconnect(gr_basic_block_sptr src, int src_port,
d_fg->disconnect(src, src_port, dst, dst_port);
}
-// FIXME: ticket:161 will be implemented here
void
gr_hier_block2_detail::connect_input(int my_port, int port, gr_basic_block_sptr block)
{
@@ -233,13 +232,16 @@ gr_hier_block2_detail::connect_input(int my_port, int port, gr_basic_block_sptr
throw std::invalid_argument(msg.str());
}
- if (d_inputs[my_port].block()) {
- msg << "external input port " << my_port << " already wired to "
- << d_inputs[my_port];
+ gr_endpoint_vector_t &endps = d_inputs[my_port];
+ gr_endpoint endp(block, port);
+
+ gr_endpoint_viter_t p = std::find(endps.begin(), endps.end(), endp);
+ if (p != endps.end()) {
+ msg << "external input port " << my_port << " already wired to " << endp;
throw std::invalid_argument(msg.str());
}
-
- d_inputs[my_port] = gr_endpoint(block, port);
+
+ endps.push_back(endp);
}
void
@@ -271,13 +273,16 @@ gr_hier_block2_detail::disconnect_input(int my_port, int port, gr_basic_block_sp
throw std::invalid_argument(msg.str());
}
- if (d_inputs[my_port].block() != block) {
- msg << "block " << block << " not assigned to input "
- << my_port << ", can't disconnect";
+ gr_endpoint_vector_t &endps = d_inputs[my_port];
+ gr_endpoint endp(block, port);
+
+ gr_endpoint_viter_t p = std::find(endps.begin(), endps.end(), endp);
+ if (p == endps.end()) {
+ msg << "external input port " << my_port << " not connected to " << endp;
throw std::invalid_argument(msg.str());
}
-
- d_inputs[my_port] = gr_endpoint();
+
+ endps.erase(p);
}
void
@@ -299,7 +304,7 @@ gr_hier_block2_detail::disconnect_output(int my_port, int port, gr_basic_block_s
d_outputs[my_port] = gr_endpoint();
}
-gr_endpoint
+gr_endpoint_vector_t
gr_hier_block2_detail::resolve_port(int port, bool is_input)
{
std::stringstream msg;
@@ -309,7 +314,7 @@ gr_hier_block2_detail::resolve_port(int port, bool is_input)
<< (is_input ? "input" : "output")
<< " of " << d_owner->name() << std::endl;
- gr_endpoint result;
+ gr_endpoint_vector_t result;
if (is_input) {
if (port < 0 || port >= (signed)d_inputs.size()) {
@@ -317,13 +322,18 @@ gr_hier_block2_detail::resolve_port(int port, bool is_input)
throw std::runtime_error(msg.str());
}
- if (d_inputs[port] == gr_endpoint()) {
+ if (d_inputs[port].empty()) {
msg << "hierarchical block '" << d_owner->name() << "' input " << port
<< " is not connected internally";
throw std::runtime_error(msg.str());
}
- result = resolve_endpoint(d_inputs[port], true);
+ gr_endpoint_vector_t &endps = d_inputs[port];
+ gr_endpoint_viter_t p;
+ for (p = endps.begin(); p != endps.end(); p++) {
+ gr_endpoint_vector_t tmp = resolve_endpoint(*p, true);
+ std::copy(tmp.begin(), tmp.end(), back_inserter(result));
+ }
}
else {
if (port < 0 || port >= (signed)d_outputs.size()) {
@@ -340,7 +350,7 @@ gr_hier_block2_detail::resolve_port(int port, bool is_input)
result = resolve_endpoint(d_outputs[port], false);
}
- if (!result.block()) {
+ if (result.empty()) {
msg << "unable to resolve "
<< (is_input ? "input port " : "output port ")
<< port;
@@ -359,16 +369,18 @@ gr_hier_block2_detail::disconnect_all()
d_outputs.clear();
}
-gr_endpoint
+gr_endpoint_vector_t
gr_hier_block2_detail::resolve_endpoint(const gr_endpoint &endp, bool is_input) const
{
std::stringstream msg;
+ gr_endpoint_vector_t result;
// Check if endpoint is a leaf node
if (cast_to_block_sptr(endp.block())) {
if (GR_HIER_BLOCK2_DETAIL_DEBUG)
std::cout << "Block " << endp.block() << " is a leaf node, returning." << std::endl;
- return endp;
+ result.push_back(endp);
+ return result;
}
// Check if endpoint is a hierarchical block
@@ -394,33 +406,41 @@ gr_hier_block2_detail::flatten_aux(gr_flat_flowgraph_sptr sfg) const
// Add my edges to the flow graph, resolving references to actual endpoints
gr_edge_vector_t edges = d_fg->edges();
-
- for (gr_edge_viter_t p = edges.begin(); p != edges.end(); p++) {
+ gr_edge_viter_t p;
+
+ for (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_vector_t src_endps = resolve_endpoint(p->src(), false);
+ gr_endpoint_vector_t dst_endps = resolve_endpoint(p->dst(), true);
- if (GR_HIER_BLOCK2_DETAIL_DEBUG) {
- std::cout << "src_endp = " << src_endp
- << ", dst_endp = " << dst_endp << std::endl;
+ gr_endpoint_viter_t s, d;
+ for (s = src_endps.begin(); s != src_endps.end(); s++) {
+ for (d = dst_endps.begin(); d != dst_endps.end(); d++) {
+ if (GR_HIER_BLOCK2_DETAIL_DEBUG)
+ std::cout << (*s) << "->" << (*d) << std::endl;
+ sfg->connect(*s, *d);
+ }
}
- sfg->connect(src_endp, dst_endp);
}
// Construct unique list of blocks used either in edges, inputs,
// outputs, or by themselves. I still hate STL.
gr_basic_block_vector_t blocks, tmp = d_fg->calc_used_blocks();
- std::vector<gr_basic_block_sptr>::const_iterator p; // Because flatten_aux is const
- for (p = d_blocks.begin(); p != d_blocks.end(); p++)
- tmp.push_back(*p);
+ std::vector<gr_basic_block_sptr>::const_iterator b; // Because flatten_aux is const
+ for (b = d_blocks.begin(); b != d_blocks.end(); b++)
+ tmp.push_back(*b);
+
+ std::vector<gr_endpoint_vector_t>::const_iterator ep; // Because flatten_aux is const
+ std::vector<gr_endpoint>::const_iterator e; // Because flatten_aux is const
+
+ for (ep = d_inputs.begin(); ep != d_inputs.end(); ep++)
+ for (e = (*ep).begin(); e != (*ep).end(); e++)
+ tmp.push_back((*e).block());
- std::vector<gr_endpoint>::const_iterator e; // Because flatten_aux is const
- for (e = d_inputs.begin(); e != d_inputs.end(); e++)
- tmp.push_back((*e).block());
for (e = d_outputs.begin(); e != d_outputs.end(); e++)
tmp.push_back((*e).block());
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h
index d31ae93e7..0e1f89fb4 100644
--- a/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.h
@@ -1,5 +1,6 @@
+/* -*- c++ -*- */
/*
- * Copyright 2006,2007 Free Software Foundation, Inc.
+ * Copyright 2006,2007,2009 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
@@ -48,16 +49,17 @@ private:
gr_hier_block2 *d_owner;
gr_hier_block2_detail *d_parent_detail;
gr_flowgraph_sptr d_fg;
- gr_endpoint_vector_t d_inputs;
- gr_endpoint_vector_t d_outputs;
+ std::vector<gr_endpoint_vector_t> d_inputs; // Multiple internal endpoints per external input
+ gr_endpoint_vector_t d_outputs; // Single internal endpoint per external output
gr_basic_block_vector_t d_blocks;
void connect_input(int my_port, int port, gr_basic_block_sptr block);
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);
- gr_endpoint resolve_port(int port, bool is_input);
- gr_endpoint resolve_endpoint(const gr_endpoint &endp, bool is_input) const;
+
+ gr_endpoint_vector_t resolve_port(int port, bool is_input);
+ gr_endpoint_vector_t resolve_endpoint(const gr_endpoint &endp, bool is_input) const;
};
#endif /* INCLUDED_GR_HIER_BLOCK2_DETAIL_H */
diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_hier_block2.py b/gnuradio-core/src/python/gnuradio/gr/qa_hier_block2.py
index 36739961e..8fa3d4af9 100755
--- a/gnuradio-core/src/python/gnuradio/gr/qa_hier_block2.py
+++ b/gnuradio-core/src/python/gnuradio/gr/qa_hier_block2.py
@@ -27,16 +27,6 @@ class test_hier_block2(gr_unittest.TestCase):
nop1 = gr.nop(gr.sizeof_int)
hblock.connect(hblock, nop1)
- 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))
- nop1 = gr.nop(gr.sizeof_int)
- nop2 = gr.nop(gr.sizeof_int)
- hblock.connect(hblock, nop1)
- self.assertRaises(ValueError,
- lambda: hblock.connect(hblock, nop2))
-
def test_004_connect_output(self):
hblock = gr.hier_block2("test_block",
gr.io_signature(1,1,gr.sizeof_int),
@@ -289,6 +279,50 @@ class test_hier_block2(gr_unittest.TestCase):
hb2.connect(hb2, gr.kludge_copy(gr.sizeof_char), dst)
tb.run()
self.assertEquals(dst.data(), (1,))
+
+ def test_031_multiple_internal_inputs(self):
+ tb = gr.top_block()
+ src = gr.vector_source_f([1.0,])
+ hb = gr.hier_block2("hb",
+ gr.io_signature(1, 1, gr.sizeof_float),
+ gr.io_signature(1, 1, gr.sizeof_float))
+ m1 = gr.multiply_const_ff(1.0)
+ m2 = gr.multiply_const_ff(2.0)
+ add = gr.add_ff()
+ hb.connect(hb, m1) # m1 is connected to hb external input #0
+ hb.connect(hb, m2) # m2 is also connected to hb external input #0
+ hb.connect(m1, (add, 0))
+ hb.connect(m2, (add, 1))
+ hb.connect(add, hb) # add is connected to hb external output #0
+ dst = gr.vector_sink_f()
+ tb.connect(src, hb, dst)
+ tb.run()
+ self.assertEquals(dst.data(), (3.0,))
+
+ def test_032_nested_multiple_internal_inputs(self):
+ tb = gr.top_block()
+ src = gr.vector_source_f([1.0,])
+ hb = gr.hier_block2("hb",
+ gr.io_signature(1, 1, gr.sizeof_float),
+ gr.io_signature(1, 1, gr.sizeof_float))
+ hb2 = gr.hier_block2("hb",
+ gr.io_signature(1, 1, gr.sizeof_float),
+ gr.io_signature(1, 1, gr.sizeof_float))
+
+ m1 = gr.multiply_const_ff(1.0)
+ m2 = gr.multiply_const_ff(2.0)
+ add = gr.add_ff()
+ hb2.connect(hb2, m1) # m1 is connected to hb2 external input #0
+ hb2.connect(hb2, m2) # m2 is also connected to hb2 external input #0
+ hb2.connect(m1, (add, 0))
+ hb2.connect(m2, (add, 1))
+ hb2.connect(add, hb2) # add is connected to hb2 external output #0
+ hb.connect(hb, hb2, hb) # hb as hb2 as nested internal block
+ dst = gr.vector_sink_f()
+ tb.connect(src, hb, dst)
+ tb.run()
+ self.assertEquals(dst.data(), (3.0,))
+
if __name__ == "__main__":
gr_unittest.main()
diff --git a/gr-wxgui/src/python/fftsink_gl.py b/gr-wxgui/src/python/fftsink_gl.py
index 30ebd3fde..3f0a93fc8 100644
--- a/gr-wxgui/src/python/fftsink_gl.py
+++ b/gr-wxgui/src/python/fftsink_gl.py
@@ -63,7 +63,6 @@ class _fft_sink_base(gr.hier_block2):
gr.io_signature(0, 0, 0),
)
#blocks
- copy = gr.kludge_copy(self._item_size)
fft = self._fft_chain(
sample_rate=sample_rate,
fft_size=fft_size,
@@ -75,7 +74,7 @@ class _fft_sink_base(gr.hier_block2):
msgq = gr.msg_queue(2)
sink = gr.message_sink(gr.sizeof_float*fft_size, msgq, True)
#connect
- self.connect(self, copy, fft, sink)
+ self.connect(self, fft, sink)
#controller
self.controller = pubsub()
self.controller.subscribe(AVERAGE_KEY, fft.set_average)
diff --git a/gr-wxgui/src/python/scopesink_gl.py b/gr-wxgui/src/python/scopesink_gl.py
index 6e9ff832a..b4ae0f339 100644
--- a/gr-wxgui/src/python/scopesink_gl.py
+++ b/gr-wxgui/src/python/scopesink_gl.py
@@ -42,13 +42,12 @@ class ac_couple_block(gr.hier_block2):
gr.io_signature(1, 1, gr.sizeof_float),
)
#blocks
- copy = gr.kludge_copy(gr.sizeof_float)
lpf = gr.single_pole_iir_filter_ff(0.0)
sub = gr.sub_ff()
mute = gr.mute_ff()
#connect
- self.connect(self, copy, sub, self)
- self.connect(copy, lpf, mute, (sub, 1))
+ self.connect(self, sub, self)
+ self.connect(self, lpf, mute, (sub, 1))
#subscribe
controller.subscribe(ac_couple_key, lambda x: mute.set_mute(not x))
controller.subscribe(sample_rate_key, lambda x: lpf.set_taps(2.0/x))
diff --git a/gr-wxgui/src/python/waterfallsink_gl.py b/gr-wxgui/src/python/waterfallsink_gl.py
index 344640af0..91c1c7eb5 100644
--- a/gr-wxgui/src/python/waterfallsink_gl.py
+++ b/gr-wxgui/src/python/waterfallsink_gl.py
@@ -63,7 +63,6 @@ class _waterfall_sink_base(gr.hier_block2):
gr.io_signature(0, 0, 0),
)
#blocks
- copy = gr.kludge_copy(self._item_size)
fft = self._fft_chain(
sample_rate=sample_rate,
fft_size=fft_size,
@@ -75,7 +74,7 @@ class _waterfall_sink_base(gr.hier_block2):
msgq = gr.msg_queue(2)
sink = gr.message_sink(gr.sizeof_float*fft_size, msgq, True)
#connect
- self.connect(self, copy, fft, sink)
+ self.connect(self, fft, sink)
#controller
self.controller = pubsub()
self.controller.subscribe(AVERAGE_KEY, fft.set_average)