summaryrefslogtreecommitdiff
path: root/grc/python/Port.py
diff options
context:
space:
mode:
Diffstat (limited to 'grc/python/Port.py')
-rw-r--r--grc/python/Port.py57
1 files changed, 50 insertions, 7 deletions
diff --git a/grc/python/Port.py b/grc/python/Port.py
index c2bfd9ccc..d0ef51b48 100644
--- a/grc/python/Port.py
+++ b/grc/python/Port.py
@@ -1,5 +1,5 @@
"""
-Copyright 2008-2011 Free Software Foundation, Inc.
+Copyright 2008-2012 Free Software Foundation, Inc.
This file is part of GNU Radio
GNU Radio Companion is free software; you can redistribute it and/or
@@ -24,7 +24,7 @@ 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.
+ 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())
@@ -50,6 +50,35 @@ def _get_source_from_virtual_source_port(vsp, traversed=[]):
)
except: raise Exception, 'Could not resolve source for virtual source port %s'%vsp
+def _get_sink_from_virtual_source_port(vsp):
+ """
+ Resolve the sink port that is connected to the given virtual source port.
+ Use the get sink from virtual sink to recursively resolve subsequent ports.
+ """
+ try: return _get_sink_from_virtual_sink_port(
+ vsp.get_enabled_connections()[0].get_sink()) # Could have many connections, but use first
+ except: raise Exception, 'Could not resolve source for virtual source port %s'%vsp
+
+def _get_sink_from_virtual_sink_port(vsp, traversed=[]):
+ """
+ Recursively resolve sink ports over the virtual connections.
+ Keep track of traversed sinks to avoid recursive loops.
+ """
+ if not vsp.get_parent().is_virtual_sink(): return vsp
+ if vsp in traversed: raise Exception, 'Loop found when resolving virtual sink %s'%vsp
+ try: return _get_sink_from_virtual_sink_port(
+ _get_sink_from_virtual_source_port(
+ filter(#get all virtual source with a matching stream id
+ lambda vs: vs.get_param('stream_id').get_value() == vsp.get_parent().get_param('stream_id').get_value(),
+ filter(#get all enabled blocks that are also virtual sinks
+ lambda b: b.is_virtual_source(),
+ vsp.get_parent().get_parent().get_enabled_blocks(),
+ ),
+ )[0].get_sources()[0]
+ ), traversed + [vsp],
+ )
+ except: raise Exception, 'Could not resolve source for virtual sink port %s'%vsp
+
class Port(_Port, _GUIPort):
def __init__(self, block, n, dir):
@@ -81,6 +110,8 @@ class Port(_Port, _GUIPort):
def get_types(self): return Constants.TYPE_TO_SIZEOF.keys()
+ def is_type_empty(self): return not self._n['type']
+
def validate(self):
_Port.validate(self)
if not self.get_enabled_connections() and not self.get_optional():
@@ -99,18 +130,30 @@ class Port(_Port, _GUIPort):
Handle the port cloning for virtual blocks.
"""
_Port.rewrite(self)
- if self.get_parent().is_virtual_sink() or self.get_parent().is_virtual_source():
+ if self.is_type_empty():
try: #clone type and vlen
- source = self.resolve_virtual_source()
+ source = self.resolve_empty_type()
self._type = str(source.get_type())
self._vlen = str(source.get_vlen())
except: #reset type and vlen
self._type = ''
self._vlen = ''
- def resolve_virtual_source(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 resolve_empty_type(self):
+ if self.is_sink():
+ try:
+ src = _get_source_from_virtual_sink_port(self)
+ if not src.is_type_empty(): return src
+ except: pass
+ sink = _get_sink_from_virtual_sink_port(self)
+ if not sink.is_type_empty(): return sink
+ if self.is_source():
+ try:
+ src = _get_source_from_virtual_source_port(self)
+ if not src.is_type_empty(): return src
+ except: pass
+ sink = _get_sink_from_virtual_source_port(self)
+ if not sink.is_type_empty(): return sink
def get_vlen(self):
"""