setup special wxgui connect on sinks, needs testing
authorJosh Blum <josh@joshknows.com>
Wed, 7 Oct 2009 16:48:24 +0000 (09:48 -0700)
committerJosh Blum <josh@joshknows.com>
Wed, 7 Oct 2009 16:48:24 +0000 (09:48 -0700)
gr-wxgui/src/python/common.py
gr-wxgui/src/python/constsink_gl.py
gr-wxgui/src/python/fftsink_gl.py
gr-wxgui/src/python/histosink_gl.py
gr-wxgui/src/python/numbersink2.py
gr-wxgui/src/python/scopesink_gl.py
gr-wxgui/src/python/waterfallsink_gl.py

index fe080aa4ad08470ff164afe4f841e32df3abc0de..dca41c9a3ec1d0f11fa8e48f4b784c29f498e1be 100644 (file)
@@ -19,6 +19,9 @@
 # Boston, MA 02110-1301, USA.
 #
 
+##################################################
+# conditional disconnections of wx flow graph
+##################################################
 import wx
 
 def bind_to_visible_event(win, callback):
@@ -51,14 +54,14 @@ def bind_to_visible_event(win, callback):
 
 from gnuradio import gr
 
-def special_connect(source, sink, hb, win, size):
+def conditional_connect(source, sink, hb, win, size):
        nulls = list()
        cache = [None]
        def callback(visible, init=False):
                if visible == cache[0]: return
                cache[0] = visible
                if not init: hb.lock()
-               print 'visible', visible
+               print 'visible', visible, source, sink
                if visible:
                        if not init:
                                hb.disconnect(source, nulls[0])
@@ -75,6 +78,24 @@ def special_connect(source, sink, hb, win, size):
        callback(False, init=True) #initially connect
        bind_to_visible_event(win, callback)
 
+class wxgui_hb(object):
+       def wxgui_connect(self, *points):
+               """
+               Use wxgui connect when the first point is the self source of the hb.
+               The win property of this object should be set to the wx window.
+               When this method tries to connect self to the next point,
+               it will conditionally make this connection based on the visibility state.
+               """
+               try:
+                       assert points[0] == self or points[0][0] == self
+                       conditional_connect(
+                               points[0], points[1],
+                               win=self.win, hb=self,
+                               size=self._hb.input_signature().sizeof_stream_item(0),
+                       )
+                       if len(points[1:]) > 1: self.connect(*points[1:])
+               except (AssertionError, IndexError): self.connect(*points)
+
 #A macro to apply an index to a key
 index_key = lambda key, i: "%s_%d"%(key, i+1)
 
index b3a1625b09b5ab412ce3f239c285d4c2c58a91ad..91bc65d9fb6a3142492b44a4cdc8cc553072e3dc 100644 (file)
@@ -31,7 +31,7 @@ from constants import *
 ##################################################
 # Constellation sink block (wrapper for old wxgui)
 ##################################################
-class const_sink_c(gr.hier_block2):
+class const_sink_c(gr.hier_block2, common.wxgui_hb):
        """
        A constellation block with a gui window.
        """
@@ -94,8 +94,6 @@ class const_sink_c(gr.hier_block2):
                agc = gr.feedforward_agc_cc(16, 1)
                msgq = gr.msg_queue(2)
                sink = gr.message_sink(gr.sizeof_gr_complex*const_size, msgq, True)
-               #connect
-               self.connect(self, self._costas, self._retime, agc, sd, sink)
                #controller
                def setter(p, k, x): p[k] = x
                self.controller = pubsub()
@@ -131,5 +129,7 @@ class const_sink_c(gr.hier_block2):
                        sample_rate_key=SAMPLE_RATE_KEY,
                )
                common.register_access_methods(self, self.win)
+               #connect
+               self.wxgui_connect(self, self._costas, self._retime, agc, sd, sink)
 
 
index 4edb11b4aad72af99b4b1526ca06aec8b03901f0..9d683d69795c3cf7f7fe320a5fb5dd262a215347 100644 (file)
@@ -31,7 +31,7 @@ from constants import *
 ##################################################
 # FFT sink block (wrapper for old wxgui)
 ##################################################
-class _fft_sink_base(gr.hier_block2):
+class _fft_sink_base(gr.hier_block2, common.wxgui_hb):
        """
        An fft block with real/complex inputs and a gui window.
        """
@@ -105,8 +105,7 @@ class _fft_sink_base(gr.hier_block2):
                setattr(self.win, 'set_baseband_freq', getattr(self, 'set_baseband_freq')) #BACKWARDS
                setattr(self.win, 'set_peak_hold', getattr(self, 'set_peak_hold')) #BACKWARDS
                #connect
-               common.special_connect(self, fft, hb=self, win=self.win, size=self._item_size)
-               self.connect(fft, sink)
+               self.wxgui_connect(self, fft, sink)
 
 class fft_sink_f(_fft_sink_base):
        _fft_chain = blks2.logpwrfft_f
index db6606e413c14cbd94274bba1e8c572997f22b42..509f746be68a9e763c0d6c6f6ac83e073546d39d 100644 (file)
@@ -31,7 +31,7 @@ from constants import *
 ##################################################
 # histo sink block (wrapper for old wxgui)
 ##################################################
-class histo_sink_f(gr.hier_block2):
+class histo_sink_f(gr.hier_block2, common.wxgui_hb):
        """
        A histogram block and a gui window.
        """
@@ -56,8 +56,6 @@ class histo_sink_f(gr.hier_block2):
                histo = gr.histo_sink_f(msgq)
                histo.set_num_bins(num_bins)
                histo.set_frame_size(frame_size)
-               #connect
-               self.connect(self, histo)
                #controller
                self.controller = pubsub()
                self.controller.subscribe(NUM_BINS_KEY, histo.set_num_bins)
@@ -79,6 +77,8 @@ class histo_sink_f(gr.hier_block2):
                        msg_key=MSG_KEY,
                )
                common.register_access_methods(self, self.win)
+               #connect
+               self.wxgui_connect(self, histo)
 
 # ----------------------------------------------------------------
 # Standalone test app
index 7f853e6a4f3f7b73b2acda44b0d8d1f0d87d5c3b..011acdfd5e93e01b8c7907c9d264b40e5bcd7f66 100644 (file)
@@ -31,7 +31,7 @@ from constants import *
 ##################################################
 # Number sink block (wrapper for old wxgui)
 ##################################################
-class _number_sink_base(gr.hier_block2):
+class _number_sink_base(gr.hier_block2, common.wxgui_hb):
        """
        An decimator block with a number window display
        """
@@ -81,8 +81,6 @@ class _number_sink_base(gr.hier_block2):
                        avg = gr.single_pole_iir_filter_cc(1.0)
                msgq = gr.msg_queue(2)
                sink = gr.message_sink(self._item_size, msgq, True)
-               #connect
-               self.connect(self, sd, mult, add, avg, sink)
                #controller
                self.controller = pubsub()
                self.controller.subscribe(SAMPLE_RATE_KEY, sd.set_sample_rate)
@@ -118,6 +116,8 @@ class _number_sink_base(gr.hier_block2):
                common.register_access_methods(self, self.controller)
                #backwards compadibility
                self.set_show_gauge = self.win.show_gauges
+               #connect
+               self.wxgui_connect(self, sd, mult, add, avg, sink)
 
 class number_sink_f(_number_sink_base):
        _item_size = gr.sizeof_float
index a5e3ca3ce32fc7f9c40fd305d5c7fd4bd2d709e5..2882488e3dabcfa341c2eaf165b0b0d3a32bd888 100644 (file)
@@ -34,7 +34,7 @@ class ac_couple_block(gr.hier_block2):
        Mute the low pass filter to disable ac coupling.
        """
 
-       def __init__(self, controller, ac_couple_key, ac_couple, sample_rate_key):
+       def __init__(self, controller, ac_couple_key, sample_rate_key):
                gr.hier_block2.__init__(
                        self,
                        "ac_couple",
@@ -52,13 +52,13 @@ class ac_couple_block(gr.hier_block2):
                controller.subscribe(ac_couple_key, lambda x: mute.set_mute(not x))
                controller.subscribe(sample_rate_key, lambda x: lpf.set_taps(0.05))
                #initialize
-               controller[ac_couple_key] = ac_couple
+               controller[ac_couple_key] = controller[ac_couple_key]
                controller[sample_rate_key] = controller[sample_rate_key]
 
 ##################################################
 # Scope sink block (wrapper for old wxgui)
 ##################################################
-class _scope_sink_base(gr.hier_block2):
+class _scope_sink_base(gr.hier_block2, common.wxgui_hb):
        """
        A scope block with a gui window.
        """
@@ -102,25 +102,10 @@ class _scope_sink_base(gr.hier_block2):
                self.controller.publish(TRIGGER_SLOPE_KEY, scope.get_trigger_slope)
                self.controller.subscribe(TRIGGER_CHANNEL_KEY, scope.set_trigger_channel)
                self.controller.publish(TRIGGER_CHANNEL_KEY, scope.get_trigger_channel)
-               #connect
-               if self._real:
-                       for i in range(num_inputs):
-                               self.connect(
-                                       (self, i),
-                                       ac_couple_block(self.controller, common.index_key(AC_COUPLE_KEY, i), ac_couple, SAMPLE_RATE_KEY),
-                                       (scope, i),
-                               )
-               else:
-                       for i in range(num_inputs):
-                               c2f = gr.complex_to_float() 
-                               self.connect((self, i), c2f)
-                               for j in range(2):
-                                       self.connect(
-                                               (c2f, j), 
-                                               ac_couple_block(self.controller, common.index_key(AC_COUPLE_KEY, 2*i+j), ac_couple, SAMPLE_RATE_KEY),
-                                               (scope, 2*i+j),
-                                       )
-                       num_inputs *= 2
+               actual_num_inputs = self._real and num_inputs or num_inputs*2
+               #init ac couple
+               for i in range(actual_num_inputs):
+                       self.controller[common.index_key(AC_COUPLE_KEY, i)] = ac_couple
                #start input watcher
                common.input_watcher(msgq, self.controller, MSG_KEY)
                #create window
@@ -130,7 +115,7 @@ class _scope_sink_base(gr.hier_block2):
                        size=size,
                        title=title,
                        frame_rate=frame_rate,
-                       num_inputs=num_inputs,
+                       num_inputs=actual_num_inputs,
                        sample_rate_key=SAMPLE_RATE_KEY,
                        t_scale=t_scale,
                        v_scale=v_scale,
@@ -144,6 +129,24 @@ class _scope_sink_base(gr.hier_block2):
                        msg_key=MSG_KEY,
                )
                common.register_access_methods(self, self.win)
+               #connect
+               if self._real:
+                       for i in range(num_inputs):
+                               self.wxgui_connect(
+                                       (self, i),
+                                       ac_couple_block(self.controller, common.index_key(AC_COUPLE_KEY, i), SAMPLE_RATE_KEY),
+                                       (scope, i),
+                               )
+               else:
+                       for i in range(num_inputs):
+                               c2f = gr.complex_to_float() 
+                               self.wxgui_connect((self, i), c2f)
+                               for j in range(2):
+                                       self.connect(
+                                               (c2f, j), 
+                                               ac_couple_block(self.controller, common.index_key(AC_COUPLE_KEY, 2*i+j), SAMPLE_RATE_KEY),
+                                               (scope, 2*i+j),
+                                       )
 
 class scope_sink_f(_scope_sink_base):
        _item_size = gr.sizeof_float
index 2d4c959f8a8f14baafb64409092c807513409ac4..37844399ed6337e1a9fdf992c3dc0b63b2b98b1c 100644 (file)
@@ -31,7 +31,7 @@ from constants import *
 ##################################################
 # Waterfall sink block (wrapper for old wxgui)
 ##################################################
-class _waterfall_sink_base(gr.hier_block2):
+class _waterfall_sink_base(gr.hier_block2, common.wxgui_hb):
        """
        An fft block with real/complex inputs and a gui window.
        """
@@ -73,8 +73,6 @@ 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, fft, sink)
                #controller
                self.controller = pubsub()
                self.controller.subscribe(AVERAGE_KEY, fft.set_average)
@@ -110,6 +108,8 @@ class _waterfall_sink_base(gr.hier_block2):
                )
                common.register_access_methods(self, self.win)
                setattr(self.win, 'set_baseband_freq', getattr(self, 'set_baseband_freq')) #BACKWARDS
+               #connect
+               self.wxgui_connect(self, fft, sink)
 
 class waterfall_sink_f(_waterfall_sink_base):
        _fft_chain = blks2.logpwrfft_f