commit-gnuradio
[Top][All Lists]
Advanced

[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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]