diff options
author | Sebastian Koslowski <koslowski@kit.edu> | 2015-07-20 22:24:53 +0200 |
---|---|---|
committer | Sebastian Koslowski <koslowski@kit.edu> | 2015-11-11 21:39:32 +0100 |
commit | c9a5fabe17efe8af1c9435f746ed55c5f5790917 (patch) | |
tree | 77242850bfc2ebb159cb9c9d53eff9ea5459f8cb /grc/python/Block.py | |
parent | 8b14a84ef8b8a73db002153cb398f79f1343ebc2 (diff) |
grc: add embedded python block definition and support in GRC
Diffstat (limited to 'grc/python/Block.py')
-rw-r--r-- | grc/python/Block.py | 96 |
1 files changed, 95 insertions, 1 deletions
diff --git a/grc/python/Block.py b/grc/python/Block.py index 5289d5765e..accfd21913 100644 --- a/grc/python/Block.py +++ b/grc/python/Block.py @@ -21,11 +21,13 @@ import itertools import collections from .. base.Constants import BLOCK_FLAG_NEED_QT_GUI, BLOCK_FLAG_NEED_WX_GUI +from .. base.odict import odict + from .. base.Block import Block as _Block from .. gui.Block import Block as _GUIBlock from . FlowGraph import _variable_matcher -import extract_docs +from . import epy_block_io, extract_docs class Block(_Block, _GUIBlock): @@ -59,6 +61,9 @@ class Block(_Block, _GUIBlock): ) _GUIBlock.__init__(self) + self._epy_source_hash = -1 # for epy blocks + self._epy_reload_error = None + def get_bus_structure(self, direction): if direction == 'source': bus_structure = self._bus_structure_source; @@ -111,12 +116,16 @@ class Block(_Block, _GUIBlock): check_generate_mode('WX GUI', BLOCK_FLAG_NEED_WX_GUI, ('wx_gui',)) check_generate_mode('QT GUI', BLOCK_FLAG_NEED_QT_GUI, ('qt_gui', 'hb_qt_gui')) + if self._epy_reload_error: + self.add_error_message(str(self._epy_reload_error)) def rewrite(self): """ Add and remove ports to adjust for the nports. """ _Block.rewrite(self) + # Check and run any custom rewrite function for this block + getattr(self, 'rewrite_' + self._key, lambda: None)() # adjust nports, disconnect hidden ports for ports in (self.get_sources(), self.get_sinks()): @@ -216,3 +225,88 @@ class Block(_Block, _GUIBlock): def is_virtual_source(self): return self.get_key() == 'virtual_source' + + ########################################################################### + # Custom rewrite functions + ########################################################################### + + def rewrite_epy_block(self): + flowgraph = self.get_parent() + platform = flowgraph.get_parent() + param_blk = self.get_param('_io_cache') + param_src = self.get_param('_source_code') + + src = param_src.get_value() + src_hash = hash(src) + if src_hash == self._epy_source_hash: + return + + try: + blk_io = epy_block_io.extract(src) + + except Exception as e: + self._epy_reload_error = ValueError('Source code eval:\n' + str(e)) + try: # load last working block io + blk_io = epy_block_io.BlockIO(*eval(param_blk.get_value())) + except: + 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] = 'from {} import {}'.format(self.get_id(), blk_io.cls) + self._make = '{}({})'.format(blk_io.cls, ', '.join( + '{0}=${0}'.format(key) for key, _ in blk_io.params)) + + params = dict() + for param in list(self._params): + if hasattr(param, '__epy_param__'): + params[param.get_key()] = param + self._params.remove(param) + + for key, value in blk_io.params: + if key in params: + param = params[key] + if not param.value_is_default(): + param.set_value(value) + else: + name = key.replace('_', ' ').title() + n = odict(dict(name=name, key=key, type='raw', value=value)) + param = platform.Param(block=self, n=n) + setattr(param, '__epy_param__', True) + self._params.append(param) + + def update_ports(label, ports, port_specs, direction): + ports_to_remove = list(ports) + iter_ports = iter(ports) + ports_new = list() + 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.get_key() == key) + ) + if reuse_port: + ports_to_remove.remove(port_current) + port, port_current = port_current, next(iter_ports, None) + else: + n = odict(dict(name=label + str(key), type=port_type, key=key)) + 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.get_sinks(), blk_io.sinks, 'sink') + update_ports('out', self.get_sources(), blk_io.sources, 'source') + _Block.rewrite(self) |