commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] [gnuradio] 46/101: grc: dynamic super-classing proof-o


From: git
Subject: [Commit-gnuradio] [gnuradio] 46/101: grc: dynamic super-classing proof-of-concept =)
Date: Thu, 16 Mar 2017 14:58:05 +0000 (UTC)

This is an automated email from the git hooks/post-receive script.

jcorgan pushed a commit to branch python3
in repository gnuradio.

commit 36f186bc46f528d95d9186955e91736d1fdb299e
Author: Sebastian Koslowski <address@hidden>
Date:   Thu Jul 14 14:32:20 2016 +0200

    grc: dynamic super-classing proof-of-concept =)
---
 grc/core/Block.py    | 187 ++++++++++++++++++++++++++-------------------------
 grc/core/Platform.py |  12 ++--
 grc/gui/Block.py     |   2 +-
 grc/gui/Element.py   |   7 ++
 grc/gui/Platform.py  |   3 +-
 grc/gui/Port.py      |   2 +-
 6 files changed, 115 insertions(+), 98 deletions(-)

diff --git a/grc/core/Block.py b/grc/core/Block.py
index 9bcb6e6..8ffb99b 100644
--- a/grc/core/Block.py
+++ b/grc/core/Block.py
@@ -304,97 +304,6 @@ class Block(Element):
     def is_virtual_source(self):
         return self.key == 'virtual_source'
 
-    ###########################################################################
-    # Custom rewrite functions
-    ###########################################################################
-
-    def rewrite_epy_block(self):
-        flowgraph = self.parent_flowgraph
-        platform = self.parent_platform
-        param_blk = self.params['_io_cache']
-        param_src = self.params['_source_code']
-
-        src = param_src.get_value()
-        src_hash = hash((self.get_id(), src))
-        if src_hash == self._epy_source_hash:
-            return
-
-        try:
-            blk_io = utils.epy_block_io.extract(src)
-
-        except Exception as e:
-            self._epy_reload_error = ValueError(str(e))
-            try:  # Load last working block io
-                blk_io_args = eval(param_blk.get_value())
-                if len(blk_io_args) == 6:
-                    blk_io_args += ([],)  # add empty callbacks
-                blk_io = utils.epy_block_io.BlockIO(*blk_io_args)
-            except Exception:
-                return
-        else:
-            self._epy_reload_error = None  # Clear previous errors
-            param_blk.set_value(repr(tuple(blk_io)))
-
-        # print "Rewriting embedded python block {!r}".format(self.get_id())
-
-        self._epy_source_hash = src_hash
-        self.name = blk_io.name or blk_io.cls
-        self._doc = blk_io.doc
-        self._imports[0] = 'import ' + self.get_id()
-        self._make = '{0}.{1}({2})'.format(self.get_id(), blk_io.cls, ', 
'.join(
-            '{0}=${{ {0} }}'.format(key) for key, _ in blk_io.params))
-        self._callbacks = ['{0} = ${{ {0} }}'.format(attr) for attr in 
blk_io.callbacks]
-
-        params = {}
-        for param in list(self.params):
-            if hasattr(param, '__epy_param__'):
-                params[param.key] = param
-                del self.params[param.key]
-
-        for key, value in blk_io.params:
-            try:
-                param = params[key]
-                param.set_default(value)
-            except KeyError:  # need to make a new param
-                name = key.replace('_', ' ').title()
-                n = dict(name=name, key=key, type='raw', value=value)
-                param = platform.Param(block=self, n=n)
-                setattr(param, '__epy_param__', True)
-            self.params[key] = param
-
-        def update_ports(label, ports, port_specs, direction):
-            ports_to_remove = list(ports)
-            iter_ports = iter(ports)
-            ports_new = []
-            port_current = next(iter_ports, None)
-            for key, port_type in port_specs:
-                reuse_port = (
-                    port_current is not None and
-                    port_current.get_type() == port_type and
-                    (key.isdigit() or port_current.key == key)
-                )
-                if reuse_port:
-                    ports_to_remove.remove(port_current)
-                    port, port_current = port_current, next(iter_ports, None)
-                else:
-                    n = dict(name=label + str(key), type=port_type, key=key)
-                    if port_type == 'message':
-                        n['name'] = key
-                        n['optional'] = '1'
-                    port = platform.Port(block=self, n=n, dir=direction)
-                ports_new.append(port)
-            # replace old port list with new one
-            del ports[:]
-            ports.extend(ports_new)
-            # remove excess port connections
-            for port in ports_to_remove:
-                for connection in port.get_connections():
-                    flowgraph.remove_element(connection)
-
-        update_ports('in', self.sinks, blk_io.sinks, 'sink')
-        update_ports('out', self.sources, blk_io.sources, 'source')
-        self.rewrite()
-
     @property
     def documentation(self):
         documentation = self.parent_platform.block_docstrings.get(self.key, {})
@@ -803,3 +712,99 @@ class Block(Element):
             self.bussify({'name': 'bus', 'type': 'bus'}, 'sink')
         if self._bussify_source:
             self.bussify({'name': 'bus', 'type': 'bus'}, 'source')
+
+
+class EPyBlock(Block):
+
+    def __init__(self, flow_graph, n):
+        super(EPyBlock, self).__init__(flow_graph, n)
+        self._epy_source_hash = -1  # for epy blocks
+        self._epy_reload_error = None
+
+
+    def rewrite_epy_block(self):
+        flowgraph = self.parent_flowgraph
+        platform = self.parent_platform
+        param_blk = self.params['_io_cache']
+        param_src = self.params['_source_code']
+
+        src = param_src.get_value()
+        src_hash = hash((self.get_id(), src))
+        if src_hash == self._epy_source_hash:
+            return
+
+        try:
+            blk_io = utils.epy_block_io.extract(src)
+
+        except Exception as e:
+            self._epy_reload_error = ValueError(str(e))
+            try:  # Load last working block io
+                blk_io_args = eval(param_blk.get_value())
+                if len(blk_io_args) == 6:
+                    blk_io_args += ([],)  # add empty callbacks
+                blk_io = utils.epy_block_io.BlockIO(*blk_io_args)
+            except Exception:
+                return
+        else:
+            self._epy_reload_error = None  # Clear previous errors
+            param_blk.set_value(repr(tuple(blk_io)))
+
+        # print "Rewriting embedded python block {!r}".format(self.get_id())
+
+        self._epy_source_hash = src_hash
+        self.name = blk_io.name or blk_io.cls
+        self._doc = blk_io.doc
+        self._imports[0] = 'import ' + self.get_id()
+        self._make = '{0}.{1}({2})'.format(self.get_id(), blk_io.cls, ', 
'.join(
+            '{0}=${{ {0} }}'.format(key) for key, _ in blk_io.params))
+        self._callbacks = ['{0} = ${{ {0} }}'.format(attr) for attr in 
blk_io.callbacks]
+
+        params = {}
+        for param in list(self.params):
+            if hasattr(param, '__epy_param__'):
+                params[param.key] = param
+                del self.params[param.key]
+
+        for key, value in blk_io.params:
+            try:
+                param = params[key]
+                param.set_default(value)
+            except KeyError:  # need to make a new param
+                name = key.replace('_', ' ').title()
+                n = dict(name=name, key=key, type='raw', value=value)
+                param = platform.Param(block=self, n=n)
+                setattr(param, '__epy_param__', True)
+            self.params[key] = param
+
+        def update_ports(label, ports, port_specs, direction):
+            ports_to_remove = list(ports)
+            iter_ports = iter(ports)
+            ports_new = []
+            port_current = next(iter_ports, None)
+            for key, port_type in port_specs:
+                reuse_port = (
+                    port_current is not None and
+                    port_current.get_type() == port_type and
+                    (key.isdigit() or port_current.key == key)
+                )
+                if reuse_port:
+                    ports_to_remove.remove(port_current)
+                    port, port_current = port_current, next(iter_ports, None)
+                else:
+                    n = dict(name=label + str(key), type=port_type, key=key)
+                    if port_type == 'message':
+                        n['name'] = key
+                        n['optional'] = '1'
+                    port = platform.Port(block=self, n=n, dir=direction)
+                ports_new.append(port)
+            # replace old port list with new one
+            del ports[:]
+            ports.extend(ports_new)
+            # remove excess port connections
+            for port in ports_to_remove:
+                for connection in port.get_connections():
+                    flowgraph.remove_element(connection)
+
+        update_ports('in', self.sinks, blk_io.sinks, 'sink')
+        update_ports('out', self.sources, blk_io.sources, 'source')
+        self.rewrite()
diff --git a/grc/core/Platform.py b/grc/core/Platform.py
index 10e75d7..e32bd91 100644
--- a/grc/core/Platform.py
+++ b/grc/core/Platform.py
@@ -32,7 +32,7 @@ from .Element import Element
 from .generator import Generator
 from .FlowGraph import FlowGraph
 from .Connection import Connection
-from .Block import Block
+from .Block import Block, EPyBlock
 from .Port import Port
 from .Param import Param
 
@@ -45,7 +45,10 @@ class Platform(Element):
     Generator = Generator
     FlowGraph = FlowGraph
     Connection = Connection
-    Block = Block
+    block_classes = {
+        None: Block,  # default
+        'epy_block': EPyBlock,
+    }
     Port = Port
     Param = Param
 
@@ -198,7 +201,7 @@ class Platform(Element):
         n = ParseXML.from_file(xml_file).get('block', {})
         n['block_wrapper_path'] = xml_file  # inject block wrapper path
         # Get block instance and add it to the list of blocks
-        block = self.Block(self._flow_graph, n)
+        block = self.block_classes[None](self._flow_graph, n)
         key = block.key
         if key in self.blocks:
             print('Warning: Block with key "{}" already exists.\n\tIgnoring: 
{}'.format(key, xml_file), file=sys.stderr)
@@ -309,4 +312,5 @@ class Platform(Element):
         return list(self.blocks.values())
 
     def get_new_block(self, flow_graph, key):
-        return self.Block(flow_graph, n=self._blocks_n[key])
+        cls = self.block_classes.get(key, self.block_classes[None])
+        return cls(flow_graph, n=self._blocks_n[key])
diff --git a/grc/gui/Block.py b/grc/gui/Block.py
index c5a9f06..b55e471 100644
--- a/grc/gui/Block.py
+++ b/grc/gui/Block.py
@@ -41,7 +41,7 @@ class Block(CoreBlock, Element):
         Block constructor.
         Add graphics related params to the block.
         """
-        CoreBlock.__init__(self, flow_graph, n)
+        super(self.__class__, self).__init__(flow_graph, n)
 
         self.states.update(_coordinate=(0, 0), _rotation=0)
         self.width = self.height = 0
diff --git a/grc/gui/Element.py b/grc/gui/Element.py
index b51a647..cdbf548 100644
--- a/grc/gui/Element.py
+++ b/grc/gui/Element.py
@@ -30,6 +30,13 @@ class Element(object):
     and methods to detect selection of those areas.
     """
 
+    @classmethod
+    def make_cls_with_base(cls, super_cls):
+        name = super_cls.__name__
+        bases = (super_cls,) + cls.__bases__[1:]
+        namespace = cls.__dict__.copy()
+        return type(name, bases, namespace)
+
     def __init__(self):
         """
         Make a new list of rectangular areas and lines, and set the coordinate 
and the rotation.
diff --git a/grc/gui/Platform.py b/grc/gui/Platform.py
index 25c7556..b8dd6aa 100644
--- a/grc/gui/Platform.py
+++ b/grc/gui/Platform.py
@@ -66,6 +66,7 @@ class Platform(CorePlatform):
     Config = Config
     FlowGraph = FlowGraph
     Connection = Connection
-    Block = Block
+    block_classes = {key: Block.make_cls_with_base(cls)
+                     for key, cls in CorePlatform.block_classes.items()}
     Port = Port
     Param = Param
diff --git a/grc/gui/Port.py b/grc/gui/Port.py
index d8a180b..4b3f6ed 100644
--- a/grc/gui/Port.py
+++ b/grc/gui/Port.py
@@ -37,7 +37,7 @@ class Port(_Port, Element):
         Port constructor.
         Create list of connector coordinates.
         """
-        _Port.__init__(self, block, n, dir)
+        super(Port, self).__init__(block, n, dir)
         Element.__init__(self)
         self._connector_coordinate = (0, 0)
         self._hovering = True



reply via email to

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