summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--grc/core/Block.py187
-rw-r--r--grc/core/Platform.py12
-rw-r--r--grc/gui/Block.py2
-rw-r--r--grc/gui/Element.py7
-rw-r--r--grc/gui/Platform.py3
-rw-r--r--grc/gui/Port.py2
6 files changed, 115 insertions, 98 deletions
diff --git a/grc/core/Block.py b/grc/core/Block.py
index 9bcb6e6f66..8ffb99b5bd 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 10e75d797d..e32bd9198a 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 c5a9f063a3..b55e471e37 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 b51a64735f..cdbf548941 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 25c755675c..b8dd6aa074 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 d8a180b7c8..4b3f6edb81 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