From 5cc562c0cb8fd5ce44a16e082d5891d9ca9b339f Mon Sep 17 00:00:00 2001
From: Seth Hitefield <sdhitefield@gmail.com>
Date: Fri, 31 Jul 2015 15:29:56 -0400
Subject: grc: fix for block bypass where the next block is a virtual sink and
 moved bypass code in generator

---
 grc/python/Generator.py    | 53 +++++++++++++++++++++++++++++++++++++++++++---
 grc/python/flow_graph.tmpl |  9 +-------
 2 files changed, 51 insertions(+), 11 deletions(-)

(limited to 'grc/python')

diff --git a/grc/python/Generator.py b/grc/python/Generator.py
index 98b671dde5..38a505264a 100644
--- a/grc/python/Generator.py
+++ b/grc/python/Generator.py
@@ -166,18 +166,65 @@ class TopBlockGenerator(object):
             except:
                 pass
             return code
+
         blocks = expr_utils.sort_objects(
             self._flow_graph.get_enabled_blocks(),
             lambda b: b.get_id(), _get_block_sort_text
         )
-        # list of regular blocks (all blocks minus the special ones)
+        # List of regular blocks (all blocks minus the special ones)
         blocks = filter(lambda b: b not in (imports + parameters), blocks)
-        # list of connections where each endpoint is enabled (sorted by domains, block names)
-        connections = filter(lambda c: not (c.is_bus() or c.is_msg()), self._flow_graph.get_enabled_connections())
+
+        # Filter out virtual sink connections
+        cf = lambda c: not (c.is_bus() or c.is_msg() or c.get_sink().get_parent().is_virtual_sink())
+        connections = filter(cf, self._flow_graph.get_enabled_connections())
+
+        # Get the virtual blocks and resolve their conenctions
+        virtual = filter(lambda c: c.get_source().get_parent().is_virtual_source(), connections)
+        for connection in virtual:
+            source = connection.get_source().resolve_virtual_source()
+            sink = connection.get_sink()
+            resolved = self._flow_graph.get_parent().Connection(flow_graph=self._flow_graph, porta=source, portb=sink)
+            connections.append(resolved)
+            # Remove the virtual connection
+            connections.remove(connection)
+
+        # Bypassing blocks: Need to find all the enabled connections for the block using
+        # the *connections* object rather than get_connections(). Create new connections
+        # that bypass the selected block and remove the existing ones. This allows adjacent
+        # bypassed blocks to see the newly created connections to downstream blocks,
+        # allowing them to correctly construct bypass connections.
+        bypassed_blocks = self._flow_graph.get_bypassed_blocks()
+        for block in bypassed_blocks:
+            # Get the upstream connection (off of the sink ports)
+            # Use *connections* not get_connections()
+            get_source_connection = lambda c: c.get_sink() == block.get_sinks()[0]
+            source_connection = filter(get_source_connection, connections)
+            # The source connection should never have more than one element.
+            assert (len(source_connection) == 1)
+
+            # Get the source of the connection.
+            source_port = source_connection[0].get_source()
+
+            # Loop through all the downstream connections
+            get_sink_connections = lambda c: c.get_source() == block.get_sources()[0]
+            for sink in filter(get_sink_connections, connections):
+                if not sink.get_enabled():
+                    # Ignore disabled connections
+                    continue
+                sink_port = sink.get_sink()
+                connection = self._flow_graph.get_parent().Connection(flow_graph=self._flow_graph, porta=source_port, portb=sink_port)
+                connections.append(connection)
+                # Remove this sink connection
+                connections.remove(sink)
+            # Remove the source connection
+            connections.remove(source_connection[0])
+
+        # List of connections where each endpoint is enabled (sorted by domains, block names)
         connections.sort(key=lambda c: (
             c.get_source().get_domain(), c.get_sink().get_domain(),
             c.get_source().get_parent().get_id(), c.get_sink().get_parent().get_id()
         ))
+
         connection_templates = self._flow_graph.get_parent().get_connection_templates()
         msgs = filter(lambda c: c.is_msg(), self._flow_graph.get_enabled_connections())
         # list of variable names
diff --git a/grc/python/flow_graph.tmpl b/grc/python/flow_graph.tmpl
index 3dd772b6ee..3cc16e7e14 100644
--- a/grc/python/flow_graph.tmpl
+++ b/grc/python/flow_graph.tmpl
@@ -255,15 +255,8 @@ gr.io_signaturev($(len($io_sigs)), $(len($io_sigs)), [$(', '.join($size_strs))])
 #for $con in $connections
     #set global $source = $con.get_source()
     #set global $sink = $con.get_sink()
-    ##resolve virtual sources to the actual sources
-    #if $source.get_parent().is_virtual_source()
-        #set global $source = $source.resolve_virtual_source()
-    #end if
-    ##do not generate connections with virtual sinks
-    #if not $sink.get_parent().is_virtual_sink()
-        #include source=$connection_templates[($source.get_domain(), $sink.get_domain())]
+    #include source=$connection_templates[($source.get_domain(), $sink.get_domain())]
 
-    #end if
 #end for
 
 ########################################################
-- 
cgit v1.2.3