summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas McCarthy <namccart@gmail.com>2013-07-07 18:08:20 -0400
committerJohnathan Corgan <johnathan@corganlabs.com>2013-07-08 07:19:33 -0700
commitcd99526b5d1c8b1130ac1ba87e21f96c621b1bdc (patch)
tree12836648bf75868b17b04a2c3ead9c1b6fa2d4c5
parent2dc1b6f2ed0cabd2bccbcc58487e93be4295df84 (diff)
grc: add bus ports
Bus ports allow ganging together of block input or output ports into a single display item for connection to other bus ports.
-rw-r--r--grc/base/Block.py123
-rw-r--r--grc/base/Connection.py22
-rw-r--r--grc/base/FlowGraph.py73
-rw-r--r--grc/base/ParseXML.py1
-rw-r--r--grc/base/Port.py30
-rw-r--r--grc/base/flow_graph.dtd4
-rw-r--r--grc/blocks/bus_sink.xml27
-rw-r--r--grc/blocks/bus_source.xml27
-rw-r--r--grc/blocks/bus_structure_sink.xml18
-rw-r--r--grc/blocks/bus_structure_source.xml18
-rw-r--r--grc/blocks/pad_sink.xml9
-rw-r--r--grc/blocks/pad_source.xml10
-rw-r--r--grc/gui/ActionHandler.py19
-rw-r--r--grc/gui/Actions.py10
-rw-r--r--grc/gui/Bars.py1
-rw-r--r--grc/gui/Block.py13
-rw-r--r--grc/gui/Connection.py18
-rw-r--r--grc/gui/Element.py3
-rw-r--r--grc/gui/FlowGraph.py14
-rw-r--r--grc/gui/Port.py25
-rw-r--r--grc/gui/Utils.py6
-rw-r--r--grc/python/Block.py31
-rw-r--r--grc/python/Connection.py6
-rw-r--r--grc/python/Constants.py1
-rw-r--r--grc/python/FlowGraph.py80
-rw-r--r--grc/python/Generator.py2
-rw-r--r--grc/python/Port.py8
-rw-r--r--grc/python/block.dtd6
-rw-r--r--grc/python/convert_hier.py12
29 files changed, 589 insertions, 28 deletions
diff --git a/grc/base/Block.py b/grc/base/Block.py
index 223f3183b7..1fb0db9ad8 100644
--- a/grc/base/Block.py
+++ b/grc/base/Block.py
@@ -22,6 +22,7 @@ from Element import Element
from Cheetah.Template import Template
from UserDict import UserDict
+from .. gui import Actions
class TemplateArg(UserDict):
"""
@@ -63,6 +64,7 @@ class Block(Element):
block a new block
"""
#build the block
+
Element.__init__(self, flow_graph)
#grab the data
params = n.findall('param')
@@ -73,6 +75,10 @@ class Block(Element):
self._category = n.find('category') or ''
self._grc_source = n.find('grc_source') or ''
self._block_wrapper_path = n.find('block_wrapper_path')
+ self._bussify_sink = n.find('bus_sink')
+ self._bussify_source = n.find('bus_source')
+
+
#create the param objects
self._params = list()
#add the id param
@@ -110,6 +116,7 @@ class Block(Element):
raise Exception, 'Key "%s" already exists in sources'%key
#store the port
self.get_sources().append(source)
+ self.back_ofthe_bus(self.get_sources())
#create the sink objects
self._sinks = list()
for sink in map(lambda n: self.get_parent().get_parent().Port(block=self, n=n, dir='sink'), sinks):
@@ -119,7 +126,21 @@ class Block(Element):
raise Exception, 'Key "%s" already exists in sinks'%key
#store the port
self.get_sinks().append(sink)
+ self.back_ofthe_bus(self.get_sinks())
+ self.current_bus_structure = {'source':'','sink':''};
+
+ def back_ofthe_bus(self, portlist):
+ portlist.sort(key=lambda a: a.get_type() == 'bus');
+
+
+ def filter_bus_port(self, ports):
+ buslist = [i for i in ports if i.get_type() == 'bus'];
+ if len(buslist) == 0:
+ return ports;
+ else:
+ return buslist;
+
def get_enabled(self):
"""
Get the enabled state of the block.
@@ -148,7 +169,12 @@ class Block(Element):
def get_category(self): return self._category
def get_doc(self): return ''
def get_ports(self): return self.get_sources() + self.get_sinks()
+ def get_ports_gui(self): return self.filter_bus_port(self.get_sources()) + self.filter_bus_port(self.get_sinks());
+
+
+
def get_children(self): return self.get_ports() + self.get_params()
+ def get_children_gui(self): return self.get_ports_gui() + self.get_params()
def get_block_wrapper_path(self): return self._block_wrapper_path
##############################################
@@ -164,6 +190,7 @@ class Block(Element):
def get_sink_keys(self): return _get_keys(self._sinks)
def get_sink(self, key): return _get_elem(self._sinks, key)
def get_sinks(self): return self._sinks
+ def get_sinks_gui(self): return self.filter_bus_port(self.get_sinks())
##############################################
# Access Sources
@@ -171,6 +198,9 @@ class Block(Element):
def get_source_keys(self): return _get_keys(self._sources)
def get_source(self, key): return _get_elem(self._sources, key)
def get_sources(self): return self._sources
+ def get_sources_gui(self): return self.filter_bus_port(self.get_sources());
+
+
def get_connections(self):
return sum([port.get_connections() for port in self.get_ports()], [])
@@ -188,6 +218,7 @@ class Block(Element):
tmpl = str(tmpl)
if '$' not in tmpl: return tmpl
n = dict((p.get_key(), TemplateArg(p)) for p in self.get_params())
+
try: return str(Template(tmpl, n))
except Exception, e: return "-------->\n%s: %s\n<--------"%(e, tmpl)
@@ -235,6 +266,77 @@ class Block(Element):
"""
return False
+
+ def form_bus_structure(self, direc):
+ if direc == 'source':
+ get_p = self.get_sources;
+ get_p_gui = self.get_sources_gui;
+ bus_structure = self.get_bus_structure('source');
+ else:
+ get_p = self.get_sinks;
+ get_p_gui = self.get_sinks_gui
+ bus_structure = self.get_bus_structure('sink');
+
+ struct = [range(len(get_p()))];
+ if True in map(lambda a: isinstance(a.get_nports(), int), get_p()):
+
+
+ structlet = [];
+ last = 0;
+ for j in [i.get_nports() for i in get_p() if isinstance(i.get_nports(), int)]:
+ structlet.extend(map(lambda a: a+last, range(j)));
+ last = structlet[-1] + 1;
+ struct = [structlet];
+ if bus_structure:
+
+ struct = bus_structure
+
+ self.current_bus_structure[direc] = struct;
+ return struct
+
+ def bussify(self, n, direc):
+ if direc == 'source':
+ get_p = self.get_sources;
+ get_p_gui = self.get_sources_gui;
+ bus_structure = self.get_bus_structure('source');
+ else:
+ get_p = self.get_sinks;
+ get_p_gui = self.get_sinks_gui
+ bus_structure = self.get_bus_structure('sink');
+
+
+ for elt in get_p():
+ for connect in elt.get_connections():
+ self.get_parent().remove_element(connect);
+
+
+
+
+
+
+ if (not 'bus' in map(lambda a: a.get_type(), get_p())) and len(get_p()) > 0:
+
+ struct = self.form_bus_structure(direc);
+ self.current_bus_structure[direc] = struct;
+ if get_p()[0].get_nports():
+ n['nports'] = str(1);
+
+ for i in range(len(struct)):
+ n['key'] = str(len(get_p()));
+ n = odict(n);
+ port = self.get_parent().get_parent().Port(block=self, n=n, dir=direc);
+ get_p().append(port);
+
+
+
+
+ elif 'bus' in map(lambda a: a.get_type(), get_p()):
+ for elt in get_p_gui():
+ get_p().remove(elt);
+ self.current_bus_structure[direc] = ''
+
+
+
##############################################
## Import/Export Methods
##############################################
@@ -246,8 +348,14 @@ class Block(Element):
a nested data odict
"""
n = odict()
+
+
n['key'] = self.get_key()
n['param'] = map(lambda p: p.export_data(), self.get_params())
+ if 'bus' in map(lambda a: a.get_type(), self.get_sinks()):
+ n['bus_sink'] = str(1);
+ if 'bus' in map(lambda a: a.get_type(), self.get_sources()):
+ n['bus_source'] = str(1);
return n
def import_data(self, n):
@@ -262,6 +370,7 @@ class Block(Element):
Args:
n: the nested data odict
"""
+
get_hash = lambda: hash(tuple(map(hash, self.get_params())))
my_hash = 0
while get_hash() != my_hash:
@@ -275,3 +384,17 @@ class Block(Element):
#store hash and call rewrite
my_hash = get_hash()
self.rewrite()
+ bussinks = n.findall('bus_sink');
+ if len(bussinks) > 0 and not self._bussify_sink:
+ self.bussify({'name':'bus','type':'bus'}, 'sink')
+ elif len(bussinks) > 0:
+ self.bussify({'name':'bus','type':'bus'}, 'sink')
+ self.bussify({'name':'bus','type':'bus'}, 'sink')
+
+ bussrcs = n.findall('bus_source');
+ if len(bussrcs) > 0 and not self._bussify_source:
+ self.bussify({'name':'bus','type':'bus'}, 'source')
+ elif len(bussrcs) > 0:
+ self.bussify({'name':'bus','type':'bus'}, 'source')
+ self.bussify({'name':'bus','type':'bus'}, 'source')
+
diff --git a/grc/base/Connection.py b/grc/base/Connection.py
index b9afe1434d..654eedb357 100644
--- a/grc/base/Connection.py
+++ b/grc/base/Connection.py
@@ -43,13 +43,31 @@ class Connection(Element):
if port.is_sink(): sink = port
if not source: raise ValueError('Connection could not isolate source')
if not sink: raise ValueError('Connection could not isolate sink')
+
+ busses = len(filter(lambda a: a.get_type() == 'bus', [source, sink]))%2
+ if not busses == 0: raise ValueError('busses must get with busses')
+
+ if not len(source.get_associated_ports()) == len(sink.get_associated_ports()):
+ raise ValueError('port connections must have same cardinality');
#ensure that this connection (source -> sink) is unique
for connection in self.get_parent().get_connections():
if connection.get_source() is source and connection.get_sink() is sink:
raise Exception('This connection between source and sink is not unique.')
self._source = source
self._sink = sink
-
+
+ if source.get_type() == 'bus':
+
+ sources = source.get_associated_ports();
+ sinks = sink.get_associated_ports();
+
+ for i in range(len(sources)):
+ try:
+ flow_graph.connect(sources[i], sinks[i]);
+ except:
+ pass
+
+
def __str__(self):
return 'Connection (\n\t%s\n\t\t%s\n\t%s\n\t\t%s\n)'%(
self.get_source().get_parent(),
@@ -71,6 +89,8 @@ class Connection(Element):
if source_type != sink_type:
self.add_error_message('Source type "%s" does not match sink type "%s".'%(source_type, sink_type))
+
+
def get_enabled(self):
"""
Get the enabled state of this connection.
diff --git a/grc/base/FlowGraph.py b/grc/base/FlowGraph.py
index e8c49466d0..a35afa363b 100644
--- a/grc/base/FlowGraph.py
+++ b/grc/base/FlowGraph.py
@@ -56,6 +56,48 @@ class FlowGraph(Element):
if not filter(lambda b: b.get_id() == id, self.get_blocks()): return id
def __str__(self): return 'FlowGraph - %s(%s)'%(self.get_option('title'), self.get_option('id'))
+ def rewrite(self):
+ def refactor_bus_structure():
+
+ for block in self.get_blocks():
+ for direc in ['source', 'sink']:
+ if direc == 'source':
+ get_p = block.get_sources;
+ get_p_gui = block.get_sources_gui;
+ bus_structure = block.form_bus_structure('source');
+ else:
+ get_p = block.get_sinks;
+ get_p_gui = block.get_sinks_gui
+ bus_structure = block.form_bus_structure('sink');
+
+ if 'bus' in map(lambda a: a.get_type(), get_p_gui()):
+
+
+
+ if len(get_p_gui()) > len(bus_structure):
+ times = range(len(bus_structure), len(get_p_gui()));
+ for i in times:
+ for connect in get_p_gui()[-1].get_connections():
+ block.get_parent().remove_element(connect);
+ get_p().remove(get_p_gui()[-1]);
+ elif len(get_p_gui()) < len(bus_structure):
+ n = {'name':'bus','type':'bus'};
+ if True in map(lambda a: isinstance(a.get_nports(), int), get_p()):
+ n['nports'] = str(1);
+
+ times = range(len(get_p_gui()), len(bus_structure));
+
+ for i in times:
+ n['key'] = str(len(get_p()));
+ n = odict(n);
+ port = block.get_parent().get_parent().Port(block=block, n=n, dir=direc);
+ get_p().append(port);
+
+
+
+ for child in self.get_children(): child.rewrite()
+ refactor_bus_structure();
+
def get_option(self, key):
"""
@@ -76,7 +118,15 @@ class FlowGraph(Element):
## Access Elements
##############################################
def get_block(self, id): return filter(lambda b: b.get_id() == id, self.get_blocks())[0]
- def get_blocks(self): return filter(lambda e: e.is_block(), self.get_elements())
+ def get_blocks_unordered(self): return filter(lambda e: e.is_block(), self.get_elements())
+ def get_blocks(self):
+ blocks = self.get_blocks_unordered();
+ for i in range(len(blocks)):
+ if blocks[i].get_key() == 'variable':
+ blk = blocks[i];
+ blocks.remove(blk);
+ blocks.insert(1, blk);
+ return blocks;
def get_connections(self): return filter(lambda e: e.is_connection(), self.get_elements())
def get_children(self): return self.get_elements()
def get_elements(self):
@@ -123,10 +173,15 @@ class FlowGraph(Element):
Returns:
the new block or None if not found
"""
+
if key not in self.get_parent().get_block_keys(): return None
block = self.get_parent().get_new_block(self, key)
- self.get_elements().append(block)
- return block
+ self.get_elements().append(block);
+ if block._bussify_sink:
+ block.bussify({'name':'bus','type':'bus'}, 'sink')
+ if block._bussify_source:
+ block.bussify({'name':'bus','type':'bus'}, 'source')
+ return block;
def connect(self, porta, portb):
"""
@@ -140,7 +195,10 @@ class FlowGraph(Element):
Returns:
the new connection
"""
+
connection = self.get_parent().Connection(flow_graph=self, porta=porta, portb=portb)
+
+
self.get_elements().append(connection)
return connection
@@ -151,6 +209,7 @@ class FlowGraph(Element):
If the element is a block, remove its connections.
If the element is a connection, just remove the connection.
"""
+
if element not in self.get_elements(): return
#found a port, set to parent signal block
if element.is_port():
@@ -159,7 +218,14 @@ class FlowGraph(Element):
if element.is_block():
for port in element.get_ports():
map(self.remove_element, port.get_connections())
+ if element.is_connection():
+ if element.is_bus():
+ cons_list = []
+ for i in map(lambda a: a.get_connections(), element.get_source().get_associated_ports()):
+ cons_list.extend(i);
+ map(self.remove_element, cons_list);
self.get_elements().remove(element)
+
def evaluate(self, expr):
"""
@@ -214,6 +280,7 @@ class FlowGraph(Element):
#only load the block when the block key was valid
if block: block.import_data(block_n)
else: Messages.send_error_load('Block key "%s" not found in %s'%(key, self.get_parent()))
+
#build the connections
for connection_n in connections_n:
#try to make the connection
diff --git a/grc/base/ParseXML.py b/grc/base/ParseXML.py
index 0d19f6b212..e8f9b0583e 100644
--- a/grc/base/ParseXML.py
+++ b/grc/base/ParseXML.py
@@ -78,6 +78,7 @@ def _from_file(xml):
#delistify if the length of values is 1
for key, values in nested_data.iteritems():
if len(values) == 1: nested_data[key] = values[0]
+
return odict({tag: nested_data})
def to_file(nested_data, xml_file):
diff --git a/grc/base/Port.py b/grc/base/Port.py
index 0e58f583c3..1b2acb0582 100644
--- a/grc/base/Port.py
+++ b/grc/base/Port.py
@@ -38,6 +38,7 @@ class Port(Element):
self._type = n['type']
self._dir = dir
+
def validate(self):
"""
Validate the port.
@@ -62,7 +63,14 @@ class Port(Element):
def is_port(self): return True
def get_color(self): return '#FFFFFF'
- def get_name(self): return self._name
+ def get_name(self):
+ number = ''
+ if self.get_type() == 'bus':
+ busses = filter(lambda a: a._dir == self._dir, self.get_parent().get_ports_gui());
+
+ number = str(busses.index(self)) + '#' + str(len(self.get_associated_ports()));
+ return self._name + number
+
def get_key(self): return self._key
def is_sink(self): return self._dir == 'sink'
def is_source(self): return self._dir == 'source'
@@ -87,3 +95,23 @@ class Port(Element):
a list of connection objects
"""
return filter(lambda c: c.get_enabled(), self.get_connections())
+
+ def get_associated_ports(self):
+ if not self.get_type() == 'bus':
+ return [self];
+ else:
+ if self.is_source():
+ get_p = self.get_parent().get_sources;
+ bus_structure = self.get_parent().current_bus_structure['source'];
+ direc = 'source'
+ else:
+ get_p = self.get_parent().get_sinks;
+ bus_structure = self.get_parent().current_bus_structure['sink'];
+ direc = 'sink'
+
+ ports = [i for i in get_p() if not i.get_type() == 'bus'];
+ if bus_structure:
+ busses = [i for i in get_p() if i.get_type() == 'bus'];
+ bus_index = busses.index(self);
+ ports = filter(lambda a: ports.index(a) in bus_structure[bus_index], ports);
+ return ports;
diff --git a/grc/base/flow_graph.dtd b/grc/base/flow_graph.dtd
index 74f48f10ab..becfc21e9b 100644
--- a/grc/base/flow_graph.dtd
+++ b/grc/base/flow_graph.dtd
@@ -24,10 +24,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<!ELEMENT flow_graph (timestamp?, block*, connection*)> <!-- optional timestamp -->
<!ELEMENT timestamp (#PCDATA)>
<!-- Block -->
-<!ELEMENT block (key, param*)>
+<!ELEMENT block (key, param*, bus_sink?, bus_source?)>
<!ELEMENT param (key, value)>
<!ELEMENT key (#PCDATA)>
<!ELEMENT value (#PCDATA)>
+<!ELEMENT bus_sink (#PCDATA)>
+<!ELEMENT bus_source (#PCDATA)>
<!-- Connection -->
<!ELEMENT connection (source_block_id, sink_block_id, source_key, sink_key)>
<!ELEMENT source_block_id (#PCDATA)>
diff --git a/grc/blocks/bus_sink.xml b/grc/blocks/bus_sink.xml
new file mode 100644
index 0000000000..273b4c517a
--- /dev/null
+++ b/grc/blocks/bus_sink.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Bus Sink
+###################################################
+ -->
+<block>
+ <name>Bus Sink</name>
+ <key>bus_sink</key>
+ <make>$yesno.yesno</make>
+
+ <param>
+ <name>On/Off</name>
+ <key>yesno</key>
+ <type>enum</type>
+ <option>
+ <name>On</name>
+ <key>on</key>
+ <opt>yesno:True</opt>
+ </option>
+ <option>
+ <name>Off</name>
+ <key>off</key>
+ <opt>yesno:False</opt>
+ </option>
+ </param>
+</block>
diff --git a/grc/blocks/bus_source.xml b/grc/blocks/bus_source.xml
new file mode 100644
index 0000000000..15e4a9f31b
--- /dev/null
+++ b/grc/blocks/bus_source.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Bus Sink
+###################################################
+ -->
+<block>
+ <name>Bus Source</name>
+ <key>bus_source</key>
+ <make>$yesno.yesno</make>
+
+ <param>
+ <name>On/Off</name>
+ <key>yesno</key>
+ <type>enum</type>
+ <option>
+ <name>On</name>
+ <key>on</key>
+ <opt>yesno:True</opt>
+ </option>
+ <option>
+ <name>Off</name>
+ <key>off</key>
+ <opt>yesno:False</opt>
+ </option>
+ </param>
+</block>
diff --git a/grc/blocks/bus_structure_sink.xml b/grc/blocks/bus_structure_sink.xml
new file mode 100644
index 0000000000..df16657282
--- /dev/null
+++ b/grc/blocks/bus_structure_sink.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Bus Sink
+###################################################
+ -->
+<block>
+ <name>Bus Sink Structure</name>
+ <key>bus_structure_sink</key>
+ <make>None</make>
+
+ <param>
+ <name>Structure</name>
+ <key>struct</key>
+ <value></value>
+ <type>raw</type>
+ </param>
+</block>
diff --git a/grc/blocks/bus_structure_source.xml b/grc/blocks/bus_structure_source.xml
new file mode 100644
index 0000000000..27652ca3b3
--- /dev/null
+++ b/grc/blocks/bus_structure_source.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<!--
+###################################################
+##Bus Sink
+###################################################
+ -->
+<block>
+ <name>Bus Source Structure</name>
+ <key>bus_structure_source</key>
+ <make>None</make>
+
+ <param>
+ <name>Structure</name>
+ <key>struct</key>
+ <value></value>
+ <type>raw</type>
+ </param>
+</block>
diff --git a/grc/blocks/pad_sink.xml b/grc/blocks/pad_sink.xml
index f0e10a3391..37e132c34c 100644
--- a/grc/blocks/pad_sink.xml
+++ b/grc/blocks/pad_sink.xml
@@ -62,6 +62,13 @@ None;self.message_port_register_hier_in($label)
<value>1</value>
<type>int</type>
</param>
+
+ <param>
+ <name>Num Streams</name>
+ <key>num_streams</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
<param>
<name>Optional</name>
<key>optional</key>
@@ -78,10 +85,12 @@ None;self.message_port_register_hier_in($label)
</option>
</param>
<check>$vlen &gt; 0</check>
+ <check>$num_streams &gt; 0</check>
<sink>
<name>in</name>
<type>$type</type>
<vlen>$vlen</vlen>
+ <nports>$num_streams</nports>
</sink>
<doc>
The inputs of this block will become the outputs to this flow graph when it is instantiated as a hierarchical block.
diff --git a/grc/blocks/pad_source.xml b/grc/blocks/pad_source.xml
index a56a65dcc3..b6faebfc68 100644
--- a/grc/blocks/pad_source.xml
+++ b/grc/blocks/pad_source.xml
@@ -62,6 +62,14 @@ None;self.message_port_register_hier_out($label)
<value>1</value>
<type>int</type>
</param>
+
+ <param>
+ <name>Num Streams</name>
+ <key>num_streams</key>
+ <value>1</value>
+ <type>int</type>
+ </param>
+
<param>
<name>Optional</name>
<key>optional</key>
@@ -78,10 +86,12 @@ None;self.message_port_register_hier_out($label)
</option>
</param>
<check>$vlen &gt; 0</check>
+ <check>$num_streams &gt; 0</check>
<source>
<name>out</name>
<type>$type</type>
<vlen>$vlen</vlen>
+ <nports>$num_streams</nports>
</source>
<doc>
The outputs of this block will become the inputs to this flow graph when it is instantiated as a hierarchical block.
diff --git a/grc/gui/ActionHandler.py b/grc/gui/ActionHandler.py
index add32dbdac..fa3e960d26 100644
--- a/grc/gui/ActionHandler.py
+++ b/grc/gui/ActionHandler.py
@@ -447,6 +447,23 @@ class ActionHandler:
for b in self.get_flow_graph().get_selected_blocks():
if b._grc_source:
self.main_window.new_page(b._grc_source, show=True);
+ elif action == Actions.BUSSIFY_SOURCES:
+ n = {'name':'bus', 'type':'bus'}
+ for b in self.get_flow_graph().get_selected_blocks():
+ b.bussify(n, 'source');
+ self.get_flow_graph()._old_selected_port = None;
+ self.get_flow_graph()._new_selected_port = None;
+ Actions.ELEMENT_CREATE();
+
+ elif action == Actions.BUSSIFY_SINKS:
+ n = {'name':'bus', 'type':'bus'}
+ for b in self.get_flow_graph().get_selected_blocks():
+ b.bussify(n, 'sink')
+ self.get_flow_graph()._old_selected_port = None;
+ self.get_flow_graph()._new_selected_port = None;
+ Actions.ELEMENT_CREATE();
+
+
else: print '!!! Action "%s" not handled !!!'%action
##################################################
# Global Actions for all States
@@ -466,6 +483,8 @@ class ActionHandler:
Actions.BLOCK_DISABLE.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
Actions.BLOCK_CREATE_HIER.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
Actions.OPEN_HIER.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
+ Actions.BUSSIFY_SOURCES.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
+ Actions.BUSSIFY_SINKS.set_sensitive(bool(self.get_flow_graph().get_selected_blocks()))
Actions.RELOAD_BLOCKS.set_sensitive(True)
#set the exec and stop buttons
self.update_exec_stop()
diff --git a/grc/gui/Actions.py b/grc/gui/Actions.py
index 9225b0bd52..5832e08bf0 100644
--- a/grc/gui/Actions.py
+++ b/grc/gui/Actions.py
@@ -295,3 +295,13 @@ OPEN_HIER = Action(
tooltip='Open the source of the selected hierarchical block',
stock_id=gtk.STOCK_JUMP_TO,
)
+BUSSIFY_SOURCES = Action(
+ label='Toggle So_urce Bus',
+ tooltip='Gang source ports into a single bus port',
+ stock_id=gtk.STOCK_JUMP_TO,
+)
+BUSSIFY_SINKS = Action(
+ label='Toggle S_ink Bus',
+ tooltip='Gang sink ports into a single bus port',
+ stock_id=gtk.STOCK_JUMP_TO,
+)
diff --git a/grc/gui/Bars.py b/grc/gui/Bars.py
index d95d23f1fe..770e705ffc 100644
--- a/grc/gui/Bars.py
+++ b/grc/gui/Bars.py
@@ -52,6 +52,7 @@ TOOLBAR_LIST = (
None,
Actions.RELOAD_BLOCKS,
Actions.OPEN_HIER,
+ Actions.BUSSIFY_SOURCES,
)
##The list of actions and categories for the menu bar.
diff --git a/grc/gui/Block.py b/grc/gui/Block.py
index 11e66bff85..e69fe1a418 100644
--- a/grc/gui/Block.py
+++ b/grc/gui/Block.py
@@ -124,6 +124,7 @@ class Block(Element):
def create_shapes(self):
"""Update the block, parameters, and ports when a change occurs."""
+
Element.create_shapes(self)
if self.is_horizontal(): self.add_area((0, 0), (self.W, self.H))
elif self.is_vertical(): self.add_area((0, 0), (self.H, self.W))
@@ -173,7 +174,10 @@ class Block(Element):
self.H = max(*(
[self.label_height+2*BLOCK_LABEL_PADDING] + [2*PORT_BORDER_SEPARATION + \
sum([port.H + PORT_SEPARATION for port in ports]) - PORT_SEPARATION
- for ports in (self.get_sources(), self.get_sinks())]
+ for ports in (self.get_sources_gui(), self.get_sinks_gui())] +
+ [4*PORT_BORDER_SEPARATION + \
+ sum([(port.H) + PORT_SEPARATION for port in ports]) - PORT_SEPARATION
+ for ports in ([i for i in self.get_sources_gui() if i.get_type() == 'bus'], [i for i in self.get_sinks_gui() if i.get_type() == 'bus'])]
))
def draw(self, gc, window):
@@ -196,7 +200,10 @@ class Block(Element):
elif self.is_vertical():
window.draw_drawable(gc, self.vertical_label, 0, 0, x+(self.H-self.label_height)/2, y+BLOCK_LABEL_PADDING, -1, -1)
#draw ports
- for port in self.get_ports(): port.draw(gc, window)
+
+
+ for port in self.get_ports_gui():
+ port.draw(gc, window)
def what_is_selected(self, coor, coor_m=None):
"""
@@ -209,7 +216,7 @@ class Block(Element):
Returns:
this block, a port, or None
"""
- for port in self.get_ports():
+ for port in self.get_ports_gui():
port_selected = port.what_is_selected(coor, coor_m)
if port_selected: return port_selected
return Element.what_is_selected(self, coor, coor_m)
diff --git a/grc/gui/Connection.py b/grc/gui/Connection.py
index 5d24fefded..4f46e73ea9 100644
--- a/grc/gui/Connection.py
+++ b/grc/gui/Connection.py
@@ -62,7 +62,10 @@ class Connection(Element):
self._sink_coor = None
self._source_coor = None
#get the source coordinate
- connector_length = self.get_source().get_connector_length()
+ try:
+ connector_length = self.get_source().get_connector_length()
+ except:
+ return
self.x1, self.y1 = Utils.get_rotated_coordinate((connector_length, 0), self.get_source().get_rotation())
#get the sink coordinate
connector_length = self.get_sink().get_connector_length() + CONNECTOR_ARROW_HEIGHT
@@ -133,7 +136,11 @@ class Connection(Element):
source = self.get_source()
#check for changes
if self._sink_rot != sink.get_rotation() or self._source_rot != source.get_rotation(): self.create_shapes()
- elif self._sink_coor != sink.get_coordinate() or self._source_coor != source.get_coordinate(): self._update_after_move()
+ elif self._sink_coor != sink.get_coordinate() or self._source_coor != source.get_coordinate():
+ try:
+ self._update_after_move()
+ except:
+ return
#cache values
self._sink_rot = sink.get_rotation()
self._source_rot = source.get_rotation()
@@ -145,5 +152,8 @@ class Connection(Element):
else: border_color = Colors.CONNECTION_DISABLED_COLOR
Element.draw(self, gc, window, bg_color=None, border_color=border_color)
#draw arrow on sink port
- gc.set_foreground(self._arrow_color)
- window.draw_polygon(gc, True, self._arrow)
+ try:
+ gc.set_foreground(self._arrow_color)
+ window.draw_polygon(gc, True, self._arrow)
+ except:
+ return
diff --git a/grc/gui/Element.py b/grc/gui/Element.py
index eac59d88eb..cd97a3fb21 100644
--- a/grc/gui/Element.py
+++ b/grc/gui/Element.py
@@ -69,7 +69,7 @@ class Element(object):
Create labels (if applicable) and call on all children.
Call this base method before creating labels in the element.
"""
- for child in self.get_children(): child.create_labels()
+ for child in self.get_children():child.create_labels()
def create_shapes(self):
"""
@@ -89,6 +89,7 @@ class Element(object):
border_color: the color for lines and rectangle borders
bg_color: the color for the inside of the rectangle
"""
+
X,Y = self.get_coordinate()
for (rX,rY),(W,H) in self._areas_list:
aX = X + rX
diff --git a/grc/gui/FlowGraph.py b/grc/gui/FlowGraph.py
index 3f17c47bc8..a238ed166a 100644
--- a/grc/gui/FlowGraph.py
+++ b/grc/gui/FlowGraph.py
@@ -65,6 +65,8 @@ class FlowGraph(Element):
Actions.BLOCK_PARAM_MODIFY,
Actions.BLOCK_CREATE_HIER,
Actions.OPEN_HIER,
+ Actions.BUSSIFY_SOURCES,
+ Actions.BUSSIFY_SINKS,
]: self._context_menu.append(action.create_menu_item())
###########################################################################
@@ -141,6 +143,7 @@ class FlowGraph(Element):
Args:
clipboard: the nested data of blocks, connections
"""
+
selected = set()
(x_min, y_min), blocks_n, connections_n = clipboard
old_id2block = dict()
@@ -158,18 +161,23 @@ class FlowGraph(Element):
#set params
params_n = block_n.findall('param')
for param_n in params_n:
+
param_key = param_n.find('key')
param_value = param_n.find('value')
#setup id parameter
if param_key == 'id':
old_id2block[param_value] = block
#if the block id is not unique, get a new block id
- if param_value in [block.get_id() for block in self.get_blocks()]:
+ if param_value in [bluck.get_id() for bluck in self.get_blocks()]:
param_value = self._get_unique_id(param_value)
+
+
#set value to key
+
block.get_param(param_key).set_value(param_value)
#move block to offset coordinate
block.move((x_off, y_off))
+
#update before creating connections
self.update()
#create connections
@@ -333,9 +341,13 @@ class FlowGraph(Element):
Call the top level rewrite and validate.
Call the top level create labels and shapes.
"""
+
self.rewrite()
+
self.validate()
+
self.create_labels()
+
self.create_shapes()
##########################################################################
diff --git a/grc/gui/Port.py b/grc/gui/Port.py
index 7b4c27dd5f..2ccc394971 100644
--- a/grc/gui/Port.py
+++ b/grc/gui/Port.py
@@ -45,15 +45,22 @@ class Port(Element):
def create_shapes(self):
"""Create new areas and labels for the port."""
Element.create_shapes(self)
+
#get current rotation
rotation = self.get_rotation()
#get all sibling ports
- if self.is_source(): ports = self.get_parent().get_sources()
- elif self.is_sink(): ports = self.get_parent().get_sinks()
+ if self.is_source(): ports = self.get_parent().get_sources_gui()
+ elif self.is_sink(): ports = self.get_parent().get_sinks_gui()
#get the max width
self.W = max([port.W for port in ports] + [PORT_MIN_WIDTH])
#get a numeric index for this port relative to its sibling ports
- index = ports.index(self)
+ try:
+ index = ports.index(self)
+ except:
+ if hasattr(self, '_connector_length'):
+ del self._connector_length;
+ return
+
length = len(ports)
#reverse the order of ports for these rotations
if rotation in (180, 270): index = length-index-1
@@ -81,7 +88,15 @@ class Port(Element):
self._connector_coordinate = (x+self.H/2, y+1+self.W)
#the connector length
self._connector_length = CONNECTOR_EXTENSION_MINIMAL + CONNECTOR_EXTENSION_INCREMENT*index
-
+
+ def modify_height(self, start_height):
+ type_dict = {'bus':(lambda a: a * 3)};
+
+ if self.get_type() in type_dict:
+ return type_dict[self.get_type()](start_height);
+ else:
+ return start_height;
+
def create_labels(self):
"""Create the labels for the socket."""
Element.create_labels(self)
@@ -91,6 +106,7 @@ class Port(Element):
layout.set_markup(Utils.parse_template(PORT_MARKUP_TMPL, port=self))
self.w, self.h = layout.get_pixel_size()
self.W, self.H = 2*PORT_LABEL_PADDING+self.w, 2*PORT_LABEL_PADDING+self.h
+ self.H = self.modify_height(self.H);
#create the pixmap
pixmap = self.get_parent().get_parent().new_pixmap(self.w, self.h)
gc = pixmap.new_gc()
@@ -111,6 +127,7 @@ class Port(Element):
gc: the graphics context
window: the gtk window to draw on
"""
+
Element.draw(
self, gc, window, bg_color=self._bg_color,
border_color=self.is_highlighted() and Colors.HIGHLIGHT_COLOR or Colors.BORDER_COLOR,
diff --git a/grc/gui/Utils.py b/grc/gui/Utils.py
index b68c19c4e1..407c875a87 100644
--- a/grc/gui/Utils.py
+++ b/grc/gui/Utils.py
@@ -101,4 +101,10 @@ def parse_template(tmpl_str, **kwargs):
a string of the parsed template
"""
kwargs['encode'] = gobject.markup_escape_text
+ #try:
+ # cat = str(Template(tmpl_str, kwargs))
+ #except TypeError:
+ # print 'guppy'
+ # print tmpl_str
+ # print str(kwargs['param'].get_error_messages())
return str(Template(tmpl_str, kwargs))
diff --git a/grc/python/Block.py b/grc/python/Block.py
index 806de46724..d365c43319 100644
--- a/grc/python/Block.py
+++ b/grc/python/Block.py
@@ -31,6 +31,8 @@ class Block(_Block, _GUIBlock):
##for make sink to keep track of indexes
_sink_count = 0
+
+
def __init__(self, flow_graph, n):
"""
Make a new block from nested data.
@@ -50,6 +52,8 @@ class Block(_Block, _GUIBlock):
self._checks = n.findall('check')
self._callbacks = n.findall('callback')
self._throttle = n.find('throttle') or ''
+ self._bus_structure_source = n.find('bus_structure_source') or ''
+ self._bus_structure_sink = n.find('bus_structure_sink') or ''
#build the block
_Block.__init__(
self,
@@ -58,6 +62,21 @@ class Block(_Block, _GUIBlock):
)
_GUIBlock.__init__(self)
+ def get_bus_structure(self, direction):
+ if direction == 'source':
+ bus_structure = self._bus_structure_source;
+ else:
+ bus_structure = self._bus_structure_sink;
+
+ bus_structure = self.resolve_dependencies(bus_structure);
+
+ if not bus_structure: return ''
+ try:
+ clean_bus_structure = self.get_parent().evaluate(bus_structure)
+ return clean_bus_structure
+
+ except: return ''
+
def throttle(self): return bool(self._throttle)
def validate(self):
@@ -84,10 +103,11 @@ class Block(_Block, _GUIBlock):
def rectify(ports):
#restore integer contiguity after insertion
#rectify the port names with the index
+ self.back_ofthe_bus(ports);
for i, port in enumerate(ports):
port._key = str(i)
port._name = port._n['name']
- if len(ports) > 1: port._name += str(i)
+ if len(ports) > 1 and not port._type == 'bus': port._name += str(i)
def insert_port(get_ports, get_port, key):
prev_port = get_port(str(int(key)-1))
@@ -121,14 +141,19 @@ class Block(_Block, _GUIBlock):
#remove excess ports and connections
if nports < num_ports:
for key in reversed(map(str, range(index_first+nports, index_first+num_ports))):
- remove_port(get_ports, get_port, key)
+ remove_port(get_ports, get_port, key);
+
+
continue
#add more ports
if nports > num_ports:
for key in map(str, range(index_first+num_ports, index_first+nports)):
insert_port(get_ports, get_port, key)
+
+
continue
-
+
+
def port_controller_modify(self, direction):
"""
Change the port controller.
diff --git a/grc/python/Connection.py b/grc/python/Connection.py
index 341dd2d821..97bf61d590 100644
--- a/grc/python/Connection.py
+++ b/grc/python/Connection.py
@@ -33,7 +33,9 @@ class Connection(_Connection, _GUIConnection):
def is_message(self):
return self.get_source().get_type() == self.get_sink().get_type() == 'message'
-
+
+ def is_bus(self):
+ return self.get_source().get_type() == self.get_sink().get_type() == 'bus'
def validate(self):
"""
Validate the connections.
@@ -44,3 +46,5 @@ class Connection(_Connection, _GUIConnection):
sink_size = Constants.TYPE_TO_SIZEOF[self.get_sink().get_type()] * self.get_sink().get_vlen()
if source_size != sink_size:
self.add_error_message('Source IO size "%s" does not match sink IO size "%s".'%(source_size, sink_size))
+
+
diff --git a/grc/python/Constants.py b/grc/python/Constants.py
index b8dc9a96a1..5666a2378b 100644
--- a/grc/python/Constants.py
+++ b/grc/python/Constants.py
@@ -59,6 +59,7 @@ CORE_TYPES = ( #name, key, sizeof, color
('Integer 8', 's8', 1, '#FF66FF'),
('Message Queue', 'msg', 0, '#777777'),
('Async Message', 'message', 0, '#C0C0C0'),
+ ('Bus Connection', 'bus', 0, '#FFFFFF'),
('Wildcard', '', 0, '#FFFFFF'),
)
diff --git a/grc/python/FlowGraph.py b/grc/python/FlowGraph.py
index 1080006cf5..89acfd89ef 100644
--- a/grc/python/FlowGraph.py
+++ b/grc/python/FlowGraph.py
@@ -20,11 +20,17 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
import expr_utils
from .. base.FlowGraph import FlowGraph as _FlowGraph
from .. gui.FlowGraph import FlowGraph as _GUIFlowGraph
+from .. base.odict import odict
import re
_variable_matcher = re.compile('^(variable\w*)$')
_parameter_matcher = re.compile('^(parameter)$')
_monitors_searcher = re.compile('(ctrlport_monitor)')
+_bussink_searcher = re.compile('^(bus_sink)$')
+_bussrc_searcher = re.compile('^(bus_source)$')
+_bus_struct_sink_searcher = re.compile('^(bus_structure_sink)$')
+_bus_struct_src_searcher = re.compile('^(bus_structure_source)$')
+
class FlowGraph(_FlowGraph, _GUIFlowGraph):
@@ -48,6 +54,7 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph):
if not code: raise Exception, 'Cannot evaluate empty statement.'
my_hash = hash(code) ^ namespace_hash
#cache if does not exist
+
if not self._eval_cache.has_key(my_hash):
self._eval_cache[my_hash] = eval(code, namespace, namespace)
#return from cache
@@ -69,6 +76,10 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph):
}[direction]
# we only want stream ports
sorted_pads = filter(lambda b: b.get_param('type').get_evaluated() != 'message', sorted_pads);
+ expanded_pads = [];
+ for i in sorted_pads:
+ for j in range(i.get_param('num_streams').get_evaluated()):
+ expanded_pads.append(i);
#load io signature
return [{
'label': str(pad.get_param('label').get_evaluated()),
@@ -76,7 +87,7 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph):
'vlen': str(pad.get_param('vlen').get_evaluated()),
'size': pad.get_param('type').get_opt('size'),
'optional': bool(pad.get_param('optional').get_evaluated()),
- } for pad in sorted_pads]
+ } for pad in expanded_pads]
def get_pad_sources(self):
"""
@@ -145,12 +156,73 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph):
monitors = filter(lambda b: _monitors_searcher.search(b.get_key()), self.get_enabled_blocks())
return monitors
+ def get_bussink(self):
+ bussink = filter(lambda b: _bussink_searcher.search(b.get_key()), self.get_enabled_blocks())
+
+ for i in bussink:
+ for j in i.get_params():
+ if j.get_name() == 'On/Off' and j.get_value() == 'on':
+ return True;
+
+ return False
+
+
+
+ def get_bussrc(self):
+ bussrc = filter(lambda b: _bussrc_searcher.search(b.get_key()), self.get_enabled_blocks())
+
+ for i in bussrc:
+ for j in i.get_params():
+ if j.get_name() == 'On/Off' and j.get_value() == 'on':
+ return True;
+
+ return False
+
+ def get_bus_structure_sink(self):
+ bussink = filter(lambda b: _bus_struct_sink_searcher.search(b.get_key()), self.get_enabled_blocks())
+
+ return bussink
+
+ def get_bus_structure_src(self):
+ bussrc = filter(lambda b: _bus_struct_src_searcher.search(b.get_key()), self.get_enabled_blocks())
+
+ return bussrc
+
+
def rewrite(self):
"""
Flag the namespace to be renewed.
"""
+
+
+
+
+ def reconnect_bus_blocks():
+ for block in self.get_blocks():
+
+ if 'bus' in map(lambda a: a.get_type(), block.get_sources_gui()):
+
+
+ for i in range(len(block.get_sources_gui())):
+ if len(block.get_sources_gui()[i].get_connections()) > 0:
+ source = block.get_sources_gui()[i]
+ sink = []
+
+ for j in range(len(source.get_connections())):
+ sink.append(source.get_connections()[j].get_sink());
+
+
+ for elt in source.get_connections():
+ self.remove_element(elt);
+ for j in sink:
+ self.connect(source, j);
self._renew_eval_ns = True
- _FlowGraph.rewrite(self)
+ _FlowGraph.rewrite(self);
+ reconnect_bus_blocks();
+
+
+
+
def evaluate(self, expr):
"""
@@ -163,6 +235,8 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph):
Returns:
the evaluated data
"""
+
+
if self._renew_eval_ns:
self._renew_eval_ns = False
#reload namespace
@@ -188,6 +262,8 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph):
#make namespace public
self.n = n
self.n_hash = hash(str(n))
+
#evaluate
e = self._eval(expr, self.n, self.n_hash)
+
return e
diff --git a/grc/python/Generator.py b/grc/python/Generator.py
index 77abc45281..47fe1d98fd 100644
--- a/grc/python/Generator.py
+++ b/grc/python/Generator.py
@@ -123,7 +123,7 @@ Add a Misc->Throttle block to your flow graph to avoid CPU congestion.''')
#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
- connections = filter(lambda c: not (c.is_msg() or c.is_message()), self._flow_graph.get_enabled_connections())
+ connections = filter(lambda c: not (c.is_bus() or c.is_msg() or c.is_message()), self._flow_graph.get_enabled_connections())
messages = filter(lambda c: c.is_msg(), self._flow_graph.get_enabled_connections())
messages2 = filter(lambda c: c.is_message(), self._flow_graph.get_enabled_connections())
#list of variable names
diff --git a/grc/python/Port.py b/grc/python/Port.py
index d4afa6cf77..8ebf5c7b05 100644
--- a/grc/python/Port.py
+++ b/grc/python/Port.py
@@ -110,7 +110,8 @@ class Port(_Port, _GUIPort):
self._nports = n.find('nports') or ''
self._vlen = n.find('vlen') or ''
self._optional = bool(n.find('optional'))
-
+
+
def get_types(self): return Constants.TYPE_TO_SIZEOF.keys()
def is_type_empty(self): return not self._n['type']
@@ -174,6 +175,9 @@ class Port(_Port, _GUIPort):
try: return int(self.get_parent().get_parent().evaluate(vlen))
except: return 1
+
+
+
def get_nports(self):
"""
Get the number of ports.
@@ -191,6 +195,8 @@ class Port(_Port, _GUIPort):
if 0 < nports: return nports
except: return 1
+
+
def get_optional(self): return bool(self._optional)
def get_color(self):
diff --git a/grc/python/block.dtd b/grc/python/block.dtd
index 292ea06cb6..99d38a0d46 100644
--- a/grc/python/block.dtd
+++ b/grc/python/block.dtd
@@ -25,7 +25,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Top level element.
A block contains a name, ...parameters list, and list of IO ports.
-->
-<!ELEMENT block (name, key, category?, throttle?, import*, var_make?, make, callback*, param*, check*, sink*, source*, doc?, grc_source?)>
+<!ELEMENT block (name, key, category?, throttle?, import*, var_make?, make, callback*, param*, bus_sink?, bus_source?, check*, sink*, source*, bus_structure_sink?, bus_structure_source?, doc?, grc_source?)>
<!--
Sub level elements.
-->
@@ -44,11 +44,15 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
<!ELEMENT name (#PCDATA)>
<!ELEMENT key (#PCDATA)>
<!ELEMENT check (#PCDATA)>
+<!ELEMENT bus_sink (#PCDATA)>
+<!ELEMENT bus_source (#PCDATA)>
<!ELEMENT opt (#PCDATA)>
<!ELEMENT type (#PCDATA)>
<!ELEMENT hide (#PCDATA)>
<!ELEMENT vlen (#PCDATA)>
<!ELEMENT nports (#PCDATA)>
+<!ELEMENT bus_structure_sink (#PCDATA)>
+<!ELEMENT bus_structure_source (#PCDATA)>
<!ELEMENT var_make (#PCDATA)>
<!ELEMENT make (#PCDATA)>
<!ELEMENT value (#PCDATA)>
diff --git a/grc/python/convert_hier.py b/grc/python/convert_hier.py
index 508ec63b2b..de76827541 100644
--- a/grc/python/convert_hier.py
+++ b/grc/python/convert_hier.py
@@ -28,6 +28,10 @@ def convert_hier(flow_graph, python_file):
input_msgp = flow_graph.get_msg_pad_sources();
output_msgp = flow_graph.get_msg_pad_sinks();
parameters = flow_graph.get_parameters()
+ bussink = flow_graph.get_bussink()
+ bussrc = flow_graph.get_bussrc()
+ bus_struct_sink = flow_graph.get_bus_structure_sink()
+ bus_struct_src = flow_graph.get_bus_structure_src()
block_key = flow_graph.get_option('id')
block_name = flow_graph.get_option('title') or flow_graph.get_option('id').replace('_', ' ').title()
block_category = flow_graph.get_option('category')
@@ -58,6 +62,10 @@ def convert_hier(flow_graph, python_file):
params_n.append(param_n)
block_n['param'] = params_n
#sink data stream ports
+ if bussink:
+ block_n['bus_sink'] = '1';
+ if bussrc:
+ block_n['bus_source'] = '1';
block_n['sink'] = list()
for input_sig in input_sigs:
sink_n = odict()
@@ -75,6 +83,10 @@ def convert_hier(flow_graph, python_file):
block_n['sink'].append(sink_n)
#source data stream ports
block_n['source'] = list()
+ if bus_struct_sink:
+ block_n['bus_structure_sink'] = bus_struct_sink[0].get_param('struct').get_value();
+ if bus_struct_src:
+ block_n['bus_structure_source'] = bus_struct_src[0].get_param('struct').get_value();
for output_sig in output_sigs:
source_n = odict()
source_n['name'] = output_sig['label']