[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] [gnuradio] 03/06: grc: refactor/enhance hier block gen
From: |
git |
Subject: |
[Commit-gnuradio] [gnuradio] 03/06: grc: refactor/enhance hier block generation |
Date: |
Tue, 9 Dec 2014 20:02:14 +0000 (UTC) |
This is an automated email from the git hooks/post-receive script.
jcorgan pushed a commit to branch master
in repository gnuradio.
commit ac726bdd0aac71cbd85c7dcb11c718cd7e2732d7
Author: Sebastian Koslowski <address@hidden>
Date: Wed Sep 17 12:36:58 2014 -0400
grc: refactor/enhance hier block generation
---
grc/blocks/pad_sink.xml | 4 +-
grc/blocks/pad_source.xml | 4 +-
grc/python/FlowGraph.py | 80 ++++++++++++--------
grc/python/Generator.py | 177 ++++++++++++++++++++++-----------------------
grc/python/flow_graph.tmpl | 14 +++-
5 files changed, 151 insertions(+), 128 deletions(-)
diff --git a/grc/blocks/pad_sink.xml b/grc/blocks/pad_sink.xml
index 37e132c..b022fa3 100644
--- a/grc/blocks/pad_sink.xml
+++ b/grc/blocks/pad_sink.xml
@@ -7,9 +7,7 @@
<block>
<name>Pad Sink</name>
<key>pad_sink</key>
- <make>#if str($type) == "message"
-None;self.message_port_register_hier_in($label)
-#end if</make>
+ <make></make>
<param>
<name>Label</name>
<key>label</key>
diff --git a/grc/blocks/pad_source.xml b/grc/blocks/pad_source.xml
index 745e48c..c0fb19e 100644
--- a/grc/blocks/pad_source.xml
+++ b/grc/blocks/pad_source.xml
@@ -7,9 +7,7 @@
<block>
<name>Pad Source</name>
<key>pad_source</key>
- <make>#if str($type) == "message"
-None;self.message_port_register_hier_out($label)
-#end if</make>
+ <make></make>
<param>
<name>Label</name>
<key>label</key>
diff --git a/grc/python/FlowGraph.py b/grc/python/FlowGraph.py
index daec2d4..977200d 100644
--- a/grc/python/FlowGraph.py
+++ b/grc/python/FlowGraph.py
@@ -58,34 +58,62 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph):
#return from cache
return self._eval_cache[my_hash]
- def get_io_signaturev(self, direction):
+ def get_hier_block_stream_io(self, direction):
"""
- Get a list of io signatures for this flow graph.
+ Get a list of stream io signatures for this flow graph.
Args:
direction: a string of 'in' or 'out'
Returns:
- a list of dicts with: type, label, vlen, size
+ a list of dicts with: type, label, vlen, size, optional
"""
- sorted_pads = {
- 'in': self.get_pad_sources(),
- 'out': self.get_pad_sinks(),
- }[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()),
- 'type': str(pad.get_param('type').get_evaluated()),
- 'vlen': str(pad.get_param('vlen').get_value()),
- 'size': pad.get_param('type').get_opt('size'),
- 'optional': bool(pad.get_param('optional').get_evaluated()),
- } for pad in expanded_pads]
+ return filter(lambda p: p['type'] != "message",
+ self.get_hier_block_io(direction))
+
+ def get_hier_block_message_io(self, direction):
+ """
+ Get a list of message io signatures for this flow graph.
+
+ Args:
+ direction: a string of 'in' or 'out'
+
+ Returns:
+ a list of dicts with: type, label, vlen, size, optional
+ """
+ return filter(lambda p: p['type'] == "message",
+ self.get_hier_block_io(direction))
+
+ def get_hier_block_io(self, direction):
+ """
+ Get a list of io ports for this flow graph.
+
+ Args:
+ direction: a string of 'in' or 'out'
+
+ Returns:
+ a list of dicts with: type, label, vlen, size, optional
+ """
+ pads = self.get_pad_sources() if direction in ('sink', 'in') else \
+ self.get_pad_sinks() if direction in ('source', 'out') else []
+ ports = []
+ for pad in pads:
+ master = {
+ 'label': str(pad.get_param('label').get_evaluated()),
+ 'type': str(pad.get_param('type').get_evaluated()),
+ 'vlen': str(pad.get_param('vlen').get_value()),
+ 'size': pad.get_param('type').get_opt('size'),
+ 'optional': bool(pad.get_param('optional').get_evaluated()),
+ }
+ num_ports = pad.get_param('num_streams').get_evaluated()
+ if num_ports > 1:
+ for i in xrange(num_ports):
+ clone = master.copy()
+ clone['label'] += str(i)
+ ports.append(clone)
+ else:
+ ports.append(master)
+ return ports
def get_pad_sources(self):
"""
@@ -118,20 +146,14 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph):
key_offset = 0
pads = self.get_pad_sources() if port.is_source() else
self.get_pad_sinks()
for pad in pads:
+ if pad.get_param('type').get_evaluated() == "message":
+ continue
if port.get_parent() == pad:
return str(key_offset + int(port.get_key()))
# assuming we have either only sources or sinks
key_offset += len(pad.get_ports())
return -1
- def get_msg_pad_sources(self):
- ps = self.get_pad_sources();
- return filter(lambda b: b.get_param('type').get_evaluated() ==
'message', ps);
-
- def get_msg_pad_sinks(self):
- ps = self.get_pad_sinks();
- return filter(lambda b: b.get_param('type').get_evaluated() ==
'message', ps);
-
def get_imports(self):
"""
Get a set of all import statments in this flow graph namespace.
diff --git a/grc/python/Generator.py b/grc/python/Generator.py
index 35cb2d9..24d943d 100644
--- a/grc/python/Generator.py
+++ b/grc/python/Generator.py
@@ -34,6 +34,8 @@ from . import expr_utils
class Generator(object):
+ """Adaptor for various generators (uses generate_options)"""
+
def __init__(self, flow_graph, file_path):
"""
Initialize the generator object.
@@ -53,6 +55,7 @@ class Generator(object):
return self._generate_options
def __getattr__(self, item):
+ """get all other attrib from actual generator object"""
return getattr(self._generator, item)
@@ -60,7 +63,7 @@ class TopBlockGenerator(object):
def __init__(self, flow_graph, file_path):
"""
- Initialize the generator object.
+ Initialize the top block generator object.
Args:
flow_graph: the flow graph object
@@ -77,9 +80,11 @@ class TopBlockGenerator(object):
filename = self._flow_graph.get_option('id') + '.py'
self._file_path = os.path.join(dirname, filename)
- def get_file_path(self): return self._file_path
+ def get_file_path(self):
+ return self._file_path
def write(self):
+ """generate output and write it to files"""
#do throttle warning
throttling_blocks = filter(lambda b: b.throttle(),
self._flow_graph.get_enabled_blocks())
if not throttling_blocks and self._generate_options != 'hb':
@@ -165,7 +170,7 @@ class TopBlockGenerator(object):
#list of variable names
var_ids = [var.get_id() for var in parameters + variables]
#prepend self.
- replace_dict = dict([(var_id, 'self.%s'%var_id) for var_id in var_ids])
+ replace_dict = dict([(var_id, 'self.%s' % var_id) for var_id in
var_ids])
#list of callbacks
callbacks = [
expr_utils.expr_replace(cb, replace_dict)
@@ -197,119 +202,113 @@ class TopBlockGenerator(object):
class HierBlockGenerator(TopBlockGenerator):
+ """Extends the top block generator to also generate a block XML file"""
def __init__(self, flow_graph, file_path):
- TopBlockGenerator.__init__(self, flow_graph, file_path)
+ """
+ Initialize the hier block generator object.
+ Args:
+ flow_graph: the flow graph object
+ file_path: where to write the py file (the xml goes into
HIER_BLOCK_LIB_DIR)
+ """
+ TopBlockGenerator.__init__(self, flow_graph, file_path)
self._mode = HIER_BLOCK_FILE_MODE
-
- dirname = HIER_BLOCKS_LIB_DIR
- filename = self._flow_graph.get_option('id')
-
- self._file_path = os.path.join(dirname, filename + '.py')
+ self._file_path = os.path.join(HIER_BLOCKS_LIB_DIR,
+ self._flow_graph.get_option('id') +
'.py')
self._file_path_xml = self._file_path + '.xml'
- def get_file_path(self): return self._file_path
- def get_file_path_xml(self): return self._file_path_xml
+ def get_file_path_xml(self):
+ return self._file_path_xml
def write(self):
+ """generate output and write it to files"""
TopBlockGenerator.write(self)
ParseXML.to_file(self._build_block_n_from_flow_graph_io(),
self.get_file_path_xml())
ParseXML.validate_dtd(self.get_file_path_xml(), BLOCK_DTD)
def _build_block_n_from_flow_graph_io(self):
- flow_graph = self._flow_graph
- python_file = self.get_file_path()
+ """
+ Generate a block XML nested data from the flow graph IO
+ Returns:
+ a xml node tree
+ """
#extract info from the flow graph
- input_sigs = flow_graph.get_io_signaturev('in')
- output_sigs = flow_graph.get_io_signaturev('out')
- 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')
- block_desc = flow_graph.get_option('description')
- block_author = flow_graph.get_option('author')
+ block_key = self._flow_graph.get_option('id')
+ parameters = self._flow_graph.get_parameters()
+
+ def var_or_value(name):
+ if name in map(lambda p: p.get_id(), parameters):
+ return "$"+name
+ return name
+
#build the nested data
block_n = odict()
- block_n['name'] = block_name
+ block_n['name'] = self._flow_graph.get_option('title') or \
+ self._flow_graph.get_option('id').replace('_', ' ').title()
block_n['key'] = block_key
- block_n['category'] = block_category
- block_n['import'] = 'execfile("%s")'%python_file
+ block_n['category'] = self._flow_graph.get_option('category')
+ block_n['import'] = 'execfile("{0}")'.format(self.get_file_path())
#make data
- if parameters: block_n['make'] = '%s(\n %s,\n)'%(
- block_key,
- ',\n '.join(['%s=$%s'%(param.get_id(), param.get_id()) for
param in parameters]),
- )
- else: block_n['make'] = '%s()'%block_key
+ if parameters:
+ block_n['make'] = '{cls}(\n {kwargs},\n)'.format(
+ cls=block_key,
+ kwargs=',\n '.join(
+ '{key}=${key}'.format(key=param.get_id()) for param in
parameters
+ ),
+ )
+ else:
+ block_n['make'] = '{cls}()'.format(cls=block_key)
#callback data
- block_n['callback'] = ['set_%s($%s)'%(param.get_id(), param.get_id())
for param in parameters]
- #param data
- params_n = list()
+ block_n['callback'] = [
+ 'set_{key}(${key})'.format(key=param.get_id()) for param in
parameters
+ ]
+
+ # Parameters
+ block_n['param'] = list()
for param in parameters:
param_n = odict()
param_n['name'] = param.get_param('label').get_value() or
param.get_id()
param_n['key'] = param.get_id()
param_n['value'] = param.get_param('value').get_value()
param_n['type'] = 'raw'
- 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()
- sink_n['name'] = input_sig['label']
- sink_n['type'] = input_sig['type']
- sink_n['vlen'] = var_or_value(input_sig['vlen'], parameters)
- if input_sig['optional']: sink_n['optional'] = '1'
- block_n['sink'].append(sink_n)
- #sink data msg ports
- for input_sig in input_msgp:
- sink_n = odict()
- sink_n['name'] = input_sig.get_param("label").get_value();
- sink_n['type'] = "message"
- sink_n['optional'] = input_sig.get_param("optional").get_value();
- block_n['sink'].append(sink_n)
- #source data stream ports
- block_n['source'] = list()
+ block_n['param'].append(param_n)
+
+ # bus stuff
+ if self._flow_graph.get_bussink():
+ block_n['bus_sink'] = '1'
+ if self._flow_graph.get_bussrc():
+ block_n['bus_source'] = '1'
+
+ # sink/source ports
+ for direction in ('sink', 'source'):
+ block_n[direction] = list()
+ for port in self._flow_graph.get_hier_block_io(direction):
+ port_n = odict()
+ port_n['name'] = port['label']
+ port_n['type'] = port['type']
+ if port['type'] != "message":
+ port_n['vlen'] = var_or_value(port['vlen'])
+ if port['optional']:
+ port_n['optional'] = '1'
+ block_n[direction].append(port_n)
+
+ # more bus stuff
+ bus_struct_sink = self._flow_graph.get_bus_structure_sink()
if bus_struct_sink:
- block_n['bus_structure_sink'] =
bus_struct_sink[0].get_param('struct').get_value();
+ block_n['bus_structure_sink'] =
bus_struct_sink[0].get_param('struct').get_value()
+ bus_struct_src = self._flow_graph.get_bus_structure_src()
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']
- source_n['type'] = output_sig['type']
- source_n['vlen'] = var_or_value(output_sig['vlen'], parameters)
- if output_sig['optional']: source_n['optional'] = '1'
- block_n['source'].append(source_n)
- #source data msg ports
- for output_sig in output_msgp:
- source_n = odict()
- source_n['name'] = output_sig.get_param("label").get_value();
- source_n['type'] = "message"
- source_n['optional'] =
output_sig.get_param("optional").get_value();
- block_n['source'].append(source_n)
- #doc data
- block_n['doc'] = "%s\n%s\n%s"%(block_author, block_desc, python_file)
- block_n['grc_source'] = "%s"%(flow_graph.grc_file_path)
- #write the block_n to file
- n = {'block': block_n}
- return n
+ block_n['bus_structure_source'] =
bus_struct_src[0].get_param('struct').get_value()
+ # documentation
+ block_n['doc'] = "\n".join(field for field in (
+ self._flow_graph.get_option('author'),
+ self._flow_graph.get_option('description'),
+ self.get_file_path()
+ ) if field)
+ block_n['grc_source'] = str(self._flow_graph.grc_file_path)
-def var_or_value(name, parameters):
- if name in map(lambda p: p.get_id(), parameters):
- return "$"+name
- return name
-
+ n = {'block': block_n}
+ return n
diff --git a/grc/python/flow_graph.tmpl b/grc/python/flow_graph.tmpl
index bee9c68..b07c296 100644
--- a/grc/python/flow_graph.tmpl
+++ b/grc/python/flow_graph.tmpl
@@ -90,8 +90,8 @@ class $(class_name)(gr.top_block):
def __init__($param_str):
gr.top_block.__init__(self, "$title")
#elif $generate_options == 'hb'
- #set $in_sigs = $flow_graph.get_io_signaturev('in')
- #set $out_sigs = $flow_graph.get_io_signaturev('out')
+ #set $in_sigs = $flow_graph.get_hier_block_stream_io('in')
+ #set $out_sigs = $flow_graph.get_hier_block_stream_io('out')
class $(class_name)(gr.hier_block2):
#def make_io_sig($io_sigs)
#set $size_strs = ['%s*%s'%(io_sig['size'], io_sig['vlen']) for io_sig in
$io_sigs]
@@ -110,6 +110,12 @@ gr.io_signaturev($(len($io_sigs)), $(len($io_sigs)), [$(',
'.join($size_strs))])
$make_io_sig($in_sigs),
$make_io_sig($out_sigs),
)
+ #for $pad in $flow_graph.get_hier_block_message_io('in')
+ self.message_port_register_hier_out("$pad['label']")
+ #end for
+ #for $pad in $flow_graph.get_hier_block_message_io('out')
+ self.message_port_register_hier_in("$pad['label']")
+ #end for
#end if
########################################################
##Create Parameters
@@ -208,11 +214,11 @@ gr.io_signaturev($(len($io_sigs)), $(len($io_sigs)),
[$(', '.join($size_strs))])
#end for
########################################################
-##Create Asynch Message Connections
+##Create Message Connections
########################################################
#if $messages2
$DIVIDER
- # Asynch Message Connections
+ # Message Connections
$DIVIDER
#end if
#for $msg in $messages2
- [Commit-gnuradio] [gnuradio] branch master updated (56f6953 -> 971d13a), git, 2014/12/09
- [Commit-gnuradio] [gnuradio] 04/06: Merge branch 'maint', git, 2014/12/09
- [Commit-gnuradio] [gnuradio] 02/06: grc: move convert hier into a child generator, git, 2014/12/09
- [Commit-gnuradio] [gnuradio] 05/06: Merge remote-tracking branch 'gnuradio-wg-grc/master_grcwg', git, 2014/12/09
- [Commit-gnuradio] [gnuradio] 06/06: runtime: TSBs can now act as sources, git, 2014/12/09
- [Commit-gnuradio] [gnuradio] 03/06: grc: refactor/enhance hier block generation,
git <=
- [Commit-gnuradio] [gnuradio] 01/06: Merge branch 'maint_grcwg' into master_grcwg, git, 2014/12/09