diff options
author | Sebastian Koslowski <koslowski@kit.edu> | 2016-04-27 12:35:12 +0200 |
---|---|---|
committer | Sebastian Koslowski <koslowski@kit.edu> | 2016-04-27 16:47:08 +0200 |
commit | 031a9dc18326ce1f4328c8edf131cba5904c3b13 (patch) | |
tree | a0a350eb696802e82d8facb37dc132ff5c7a97a6 | |
parent | 26de50e62da7116754c0175c32c4179de2d13672 (diff) |
grc: auto-add callbacks for epy block params
-rw-r--r-- | grc/blocks/epy_block.xml | 9 | ||||
-rw-r--r-- | grc/core/Block.py | 10 | ||||
-rw-r--r-- | grc/core/utils/epy_block_io.py | 37 |
3 files changed, 45 insertions, 11 deletions
diff --git a/grc/blocks/epy_block.xml b/grc/blocks/epy_block.xml index d443d29c31..3fd5aa84f1 100644 --- a/grc/blocks/epy_block.xml +++ b/grc/blocks/epy_block.xml @@ -25,7 +25,8 @@ be the parameters. All of them are required to have default values! import numpy as np from gnuradio import gr -class blk(gr.sync_block): + +class blk(gr.sync_block): # other base classes are basic_block, decim_block, interp_block """Embedded Python Block example - a simple multiply const""" def __init__(self, example_param=1.0): # only default arguments here @@ -36,11 +37,13 @@ class blk(gr.sync_block): in_sig=[np.complex64], out_sig=[np.complex64] ) - self.factor = example_param + # if an attribute with the same name as a parameter is found, + # a callback is registered (properties work, too). + self.example_param = example_param def work(self, input_items, output_items): """example: multiply with constant""" - output_items[0][:] = input_items[0] * self.factor + output_items[0][:] = input_items[0] * self.example_param return len(output_items[0]) </value> <type>_multiline_python_external</type> diff --git a/grc/core/Block.py b/grc/core/Block.py index cb4eb0db61..106e4bc89a 100644 --- a/grc/core/Block.py +++ b/grc/core/Block.py @@ -418,8 +418,11 @@ class Block(Element): except Exception as e: self._epy_reload_error = ValueError(str(e)) try: # Load last working block io - blk_io = epy_block_io.BlockIO(*eval(param_blk.get_value())) - except: + blk_io_args = eval(param_blk.get_value()) + if len(blk_io_args) == 6: + blk_io_args += ([],) # add empty callbacks + blk_io = epy_block_io.BlockIO(*blk_io_args) + except Exception: return else: self._epy_reload_error = None # Clear previous errors @@ -432,7 +435,8 @@ class Block(Element): 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)) + '{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): diff --git a/grc/core/utils/epy_block_io.py b/grc/core/utils/epy_block_io.py index df3a4bbc3e..76b50051db 100644 --- a/grc/core/utils/epy_block_io.py +++ b/grc/core/utils/epy_block_io.py @@ -11,7 +11,7 @@ TYPE_MAP = { 'int8': 'byte', 'uint8': 'byte', } -BlockIO = collections.namedtuple('BlockIO', 'name cls params sinks sources doc') +BlockIO = collections.namedtuple('BlockIO', 'name cls params sinks sources doc callbacks') def _ports(sigs, msgs): @@ -51,6 +51,7 @@ def extract(cls): cls = _find_block_class(cls, gr.gateway.gateway_block) spec = inspect.getargspec(cls.__init__) + init_args = spec.args[1:] defaults = map(repr, spec.defaults or ()) doc = cls.__doc__ or cls.__init__.__doc__ or '' cls_name = cls.__name__ @@ -64,14 +65,23 @@ def extract(cls): raise RuntimeError("Can't create an instance of your block: " + str(e)) name = instance.name() - params = list(zip(spec.args[1:], defaults)) + + params = list(zip(init_args, defaults)) + + def settable(attr): + try: + return callable(getattr(cls, attr).fset) # check for a property with setter + except AttributeError: + return attr in instance.__dict__ # not dir() - only the instance attribs + + callbacks = [attr for attr in dir(instance) if attr in init_args and settable(attr)] sinks = _ports(instance.in_sig(), pmt.to_python(instance.message_ports_in())) sources = _ports(instance.out_sig(), pmt.to_python(instance.message_ports_out())) - return BlockIO(name, cls_name, params, sinks, sources, doc) + return BlockIO(name, cls_name, params, sinks, sources, doc, callbacks) if __name__ == '__main__': @@ -81,7 +91,7 @@ from gnuradio import gr import pmt class blk(gr.sync_block): - def __init__(self, param1=None, param2=None): + def __init__(self, param1=None, param2=None, param3=None): "Test Docu" gr.sync_block.__init__( self, @@ -91,8 +101,25 @@ class blk(gr.sync_block): ) self.message_port_register_in(pmt.intern('msg_in')) self.message_port_register_out(pmt.intern('msg_out')) + self.param1 = param1 + self._param2 = param2 + self._param3 = param3 + + @property + def param2(self): + return self._param2 + + @property + def param3(self): + return self._param3 + + @param3.setter + def param3(self, value): + self._param3 = value def work(self, inputs_items, output_items): return 10 """ - print extract(blk_code) + from pprint import pprint + pprint(dict(extract(blk_code)._asdict())) + |