Merge commit '25a8' from git@gnuradio.org:jblum
[debian/gnuradio] / grc / python / Port.py
index 2f7af855c53ecbb85243d70121a872fd735210ef..6965371df8a9e922dbeb808d78da53bf93c81a59 100644 (file)
@@ -18,32 +18,39 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 """
 
 from .. base.Port import Port as _Port
+from .. gui.Port import Port as _GUIPort
 import Constants
 
 def _get_source_from_virtual_sink_port(vsp):
+       """
+       Resolve the source port that is connected to the given virtual sink port.
+       Use the get source from virtual source to recursively resolve subsequent ports. 
+       """
        try: return _get_source_from_virtual_source_port(
                vsp.get_enabled_connections()[0].get_source())
-       except: raise Exception, 'Could not resolve source for virtual sink port', vsp
-
-def _get_source_from_virtual_source_port(vsp):
-       if not vsp.is_virtual_source(): return vsp
+       except: raise Exception, 'Could not resolve source for virtual sink port %s'%vsp
+
+def _get_source_from_virtual_source_port(vsp, traversed=[]):
+       """
+       Recursively resolve source ports over the virtual connections.
+       Keep track of traversed sources to avoid recursive loops.
+       """
+       if not vsp.get_parent().is_virtual_source(): return vsp
+       if vsp in traversed: raise Exception, 'Loop found when resolving virtual source %s'%vsp
        try: return _get_source_from_virtual_source_port(
                _get_source_from_virtual_sink_port(
-                       filter(
+                       filter(#get all virtual sinks with a matching stream id
                                lambda vs: vs.get_param('stream_id').get_value() == vsp.get_parent().get_param('stream_id').get_value(),
-                               filter(
-                                       lambda b: b.get_key() == 'virtual_sink',
+                               filter(#get all enabled blocks that are also virtual sinks
+                                       lambda b: b.is_virtual_sink(),
                                        vsp.get_parent().get_parent().get_enabled_blocks(),
                                ),
-                       )[0].get_sink(vsp.get_key())
-               )
+                       )[0].get_sinks()[0]
+               ), traversed + [vsp],
        )
-       except: raise Exception, 'Could not resolve source for virtual source port', vsp
+       except: raise Exception, 'Could not resolve source for virtual source port %s'%vsp
 
-class Port(_Port):
-
-       ##possible port types
-       TYPES = ['complex', 'float', 'int', 'short', 'byte', 'msg']
+class Port(_Port, _GUIPort):
 
        def __init__(self, block, n, dir):
                """
@@ -67,10 +74,13 @@ class Port(_Port):
                        n=n,
                        dir=dir,
                )
+               _GUIPort.__init__(self)
                self._nports = n.find('nports') or ''
                self._vlen = n.find('vlen') or ''
                self._optional = bool(n.find('optional'))
 
+       def get_types(self): return ('complex', 'float', 'int', 'short', 'byte', 'msg', '')
+
        def validate(self):
                _Port.validate(self)
                try: assert self.get_enabled_connections() or self.get_optional()
@@ -89,7 +99,7 @@ class Port(_Port):
                Handle the port cloning for virtual blocks.
                """
                _Port.rewrite(self)
-               if self.is_virtual_sink() or self.is_virtual_source():
+               if self.get_parent().is_virtual_sink() or self.get_parent().is_virtual_source():
                        try: #clone type and vlen
                                source = self.resolve_virtual_source()
                                self._type = str(source.get_type())
@@ -98,11 +108,9 @@ class Port(_Port):
                                self._type = ''
                                self._vlen = ''
 
-       def is_virtual_sink(self): return self.get_parent().get_key() == 'virtual_sink'
-       def is_virtual_source(self): return self.get_parent().get_key() == 'virtual_source'
        def resolve_virtual_source(self):
-               if self.is_virtual_sink(): return _get_source_from_virtual_sink_port(self)
-               if self.is_virtual_source(): return _get_source_from_virtual_source_port(self)
+               if self.get_parent().is_virtual_sink(): return _get_source_from_virtual_sink_port(self)
+               if self.get_parent().is_virtual_source(): return _get_source_from_virtual_source_port(self)
 
        def get_vlen(self):
                """