[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Commit-gnuradio] [gnuradio] 18/18: Merge branch 'maint_grcwg' into refa
From: |
git |
Subject: |
[Commit-gnuradio] [gnuradio] 18/18: Merge branch 'maint_grcwg' into refactoring |
Date: |
Sun, 24 Apr 2016 19:19:38 +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 a03a3903153c8b495041eda48d8502084a2c92bb
Merge: 1763162 2a68b68
Author: Sebastian Koslowski <address@hidden>
Date: Thu Apr 21 16:04:56 2016 +0200
Merge branch 'maint_grcwg' into refactoring
grc/blocks/epy_block.xml | 25 ++++++++++++++++++-------
grc/core/Block.py | 6 +++---
grc/gui/FlowGraph.py | 11 +++++++----
3 files changed, 28 insertions(+), 14 deletions(-)
diff --cc grc/core/Block.py
index 6708986,0000000..cb4eb0d
mode 100644,000000..100644
--- a/grc/core/Block.py
+++ b/grc/core/Block.py
@@@ -1,846 -1,0 +1,846 @@@
+"""
+Copyright 2008-2015 Free Software Foundation, Inc.
+This file is part of GNU Radio
+
+GNU Radio Companion is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+GNU Radio Companion is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+"""
+
+import collections
+import itertools
+
+from Cheetah.Template import Template
+
+from .utils import epy_block_io, odict
+from . Constants import (
+ BLOCK_FLAG_NEED_QT_GUI, BLOCK_FLAG_NEED_WX_GUI,
+ ADVANCED_PARAM_TAB, DEFAULT_PARAM_TAB,
+ BLOCK_FLAG_THROTTLE, BLOCK_FLAG_DISABLE_BYPASS,
+ BLOCK_ENABLED, BLOCK_BYPASSED, BLOCK_DISABLED
+)
+from . Element import Element
+from . FlowGraph import _variable_matcher
+
+
+def _get_keys(lst):
+ return [elem.get_key() for elem in lst]
+
+
+def _get_elem(lst, key):
+ try:
+ return lst[_get_keys(lst).index(key)]
+ except ValueError:
+ raise ValueError('Key "{}" not found in {}.'.format(key,
_get_keys(lst)))
+
+
+class Block(Element):
+
+ is_block = True
+
+ def __init__(self, flow_graph, n):
+ """
+ Make a new block from nested data.
+
+ Args:
+ flow: graph the parent element
+ n: the nested odict
+
+ Returns:
+ block a new block
+ """
+ # Grab the data
+ self._doc = (n.find('doc') or '').strip('\n').replace('\\\n', '')
+ self._imports = map(lambda i: i.strip(), n.findall('import'))
+ self._make = n.find('make')
+ self._var_make = n.find('var_make')
+ self._checks = n.findall('check')
+ self._callbacks = n.findall('callback')
+ self._bus_structure_source = n.find('bus_structure_source') or ''
+ self._bus_structure_sink = n.find('bus_structure_sink') or ''
+ self.port_counters = [itertools.count(), itertools.count()]
+
+ # Build the block
+ Element.__init__(self, flow_graph)
+
+ # Grab the data
+ params = n.findall('param')
+ sources = n.findall('source')
+ sinks = n.findall('sink')
+ self._name = n.find('name')
+ self._key = n.find('key')
+ self._category = n.find('category') or ''
+ self._flags = n.find('flags') or ''
+ # Backwards compatibility
+ if n.find('throttle') and BLOCK_FLAG_THROTTLE not in self._flags:
+ self._flags += BLOCK_FLAG_THROTTLE
+ self._grc_source = n.find('grc_source') or ''
+ self._block_wrapper_path = n.find('block_wrapper_path')
+ self._bussify_sink = n.find('bus_sink')
+ self._bussify_source = n.find('bus_source')
+ self._var_value = n.find('var_value') or '$value'
+
+ # Get list of param tabs
+ n_tabs = n.find('param_tab_order') or None
+ self._param_tab_labels = n_tabs.findall('tab') if n_tabs is not None
else [DEFAULT_PARAM_TAB]
+
+ # Create the param objects
+ self._params = list()
+
+ # Add the id param
+ self.get_params().append(self.get_parent().get_parent().Param(
+ block=self,
+ n=odict({
+ 'name': 'ID',
+ 'key': 'id',
+ 'type': 'id',
+ })
+ ))
+ self.get_params().append(self.get_parent().get_parent().Param(
+ block=self,
+ n=odict({
+ 'name': 'Enabled',
+ 'key': '_enabled',
+ 'type': 'raw',
+ 'value': 'True',
+ 'hide': 'all',
+ })
+ ))
+ for param in itertools.imap(lambda n:
self.get_parent().get_parent().Param(block=self, n=n), params):
+ key = param.get_key()
+ # Test against repeated keys
+ if key in self.get_param_keys():
+ raise Exception('Key "{}" already exists in
params'.format(key))
+ # Store the param
+ self.get_params().append(param)
+ # Create the source objects
+ self._sources = list()
+ for source in map(lambda n:
self.get_parent().get_parent().Port(block=self, n=n, dir='source'), sources):
+ key = source.get_key()
+ # Test against repeated keys
+ if key in self.get_source_keys():
+ raise Exception('Key "{}" already exists in
sources'.format(key))
+ # Store the port
+ self.get_sources().append(source)
+ self.back_ofthe_bus(self.get_sources())
+ # Create the sink objects
+ self._sinks = list()
+ for sink in map(lambda n:
self.get_parent().get_parent().Port(block=self, n=n, dir='sink'), sinks):
+ key = sink.get_key()
+ # Test against repeated keys
+ if key in self.get_sink_keys():
+ raise Exception('Key "{}" already exists in
sinks'.format(key))
+ # Store the port
+ self.get_sinks().append(sink)
+ self.back_ofthe_bus(self.get_sinks())
+ self.current_bus_structure = {'source': '', 'sink': ''}
+
+ # Virtual source/sink and pad source/sink blocks are
+ # indistinguishable from normal GR blocks. Make explicit
+ # checks for them here since they have no work function or
+ # buffers to manage.
+ is_virtual_or_pad = self._key in (
+ "virtual_source", "virtual_sink", "pad_source", "pad_sink")
+ is_variable = self._key.startswith('variable')
+
+ # Disable blocks that are virtual/pads or variables
+ if is_virtual_or_pad or is_variable:
+ self._flags += BLOCK_FLAG_DISABLE_BYPASS
+
+ if not (is_virtual_or_pad or is_variable or self._key == 'options'):
+ self.get_params().append(self.get_parent().get_parent().Param(
+ block=self,
+ n=odict({'name': 'Block Alias',
+ 'key': 'alias',
+ 'type': 'string',
+ 'hide': 'part',
+ 'tab': ADVANCED_PARAM_TAB
+ })
+ ))
+
+ if (len(sources) or len(sinks)) and not is_virtual_or_pad:
+ self.get_params().append(self.get_parent().get_parent().Param(
+ block=self,
+ n=odict({'name': 'Core Affinity',
+ 'key': 'affinity',
+ 'type': 'int_vector',
+ 'hide': 'part',
+ 'tab': ADVANCED_PARAM_TAB
+ })
+ ))
+ if len(sources) and not is_virtual_or_pad:
+ self.get_params().append(self.get_parent().get_parent().Param(
+ block=self,
+ n=odict({'name': 'Min Output Buffer',
+ 'key': 'minoutbuf',
+ 'type': 'int',
+ 'hide': 'part',
+ 'value': '0',
+ 'tab': ADVANCED_PARAM_TAB
+ })
+ ))
+ self.get_params().append(self.get_parent().get_parent().Param(
+ block=self,
+ n=odict({'name': 'Max Output Buffer',
+ 'key': 'maxoutbuf',
+ 'type': 'int',
+ 'hide': 'part',
+ 'value': '0',
+ 'tab': ADVANCED_PARAM_TAB
+ })
+ ))
+
+ self.get_params().append(self.get_parent().get_parent().Param(
+ block=self,
+ n=odict({'name': 'Comment',
+ 'key': 'comment',
+ 'type': '_multiline',
+ 'hide': 'part',
+ 'value': '',
+ 'tab': ADVANCED_PARAM_TAB
+ })
+ ))
+
+ self._epy_source_hash = -1 # for epy blocks
+ self._epy_reload_error = None
+
+ if self._bussify_sink:
+ self.bussify({'name': 'bus', 'type': 'bus'}, 'sink')
+ if self._bussify_source:
+ self.bussify({'name': 'bus', 'type': 'bus'}, 'source')
+
+ def get_bus_structure(self, direction):
+ if direction == 'source':
+ bus_structure = self._bus_structure_source
+ else:
+ bus_structure = self._bus_structure_sink
+
+ bus_structure = self.resolve_dependencies(bus_structure)
+
+ if not bus_structure:
+ return '' # TODO: Don't like empty strings. should change this
to None eventually
+
+ try:
+ clean_bus_structure = self.get_parent().evaluate(bus_structure)
+ return clean_bus_structure
+ except:
+ return ''
+
+ def validate(self):
+ """
+ Validate this block.
+ Call the base class validate.
+ Evaluate the checks: each check must evaluate to True.
+ """
+ Element.validate(self)
+ # Evaluate the checks
+ for check in self._checks:
+ check_res = self.resolve_dependencies(check)
+ try:
+ if not self.get_parent().evaluate(check_res):
+ self.add_error_message('Check "{}" failed.'.format(check))
+ except:
+ self.add_error_message('Check "{}" did not
evaluate.'.format(check))
+
+ # For variables check the value (only if var_value is used
+ if _variable_matcher.match(self.get_key()) and self._var_value !=
'$value':
+ value = self._var_value
+ try:
+ value = self.get_var_value()
+ self.get_parent().evaluate(value)
+ except Exception as err:
+ self.add_error_message('Value "{}" cannot be
evaluated:\n{}'.format(value, err))
+
+ # check if this is a GUI block and matches the selected generate
option
+ current_generate_option =
self.get_parent().get_option('generate_options')
+
+ def check_generate_mode(label, flag, valid_options):
+ block_requires_mode = (
+ flag in self.get_flags() or
+ self.get_name().upper().startswith(label)
+ )
+ if block_requires_mode and current_generate_option not in
valid_options:
+ self.add_error_message("Can't generate this block in mode: {}
".format(
+ repr(current_generate_option)))
+
+ 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.get_param('_source_code').add_error_message(str(self._epy_reload_error))
+
+ def rewrite(self):
+ """
+ Add and remove ports to adjust for the nports.
+ """
+ Element.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()):
+ for i, master_port in enumerate(ports):
+ nports = master_port.get_nports() or 1
+ num_ports = 1 + len(master_port.get_clones())
+ if master_port.get_hide():
+ for connection in master_port.get_connections():
+ self.get_parent().remove_element(connection)
+ if not nports and num_ports == 1: # Not a master port and no
left-over clones
+ continue
+ # Remove excess cloned ports
+ for port in master_port.get_clones()[nports-1:]:
+ # Remove excess connections
+ for connection in port.get_connections():
+ self.get_parent().remove_element(connection)
+ master_port.remove_clone(port)
+ ports.remove(port)
+ # Add more cloned ports
+ for j in range(num_ports, nports):
+ port = master_port.add_clone()
+ ports.insert(ports.index(master_port) + j, port)
+
+ self.back_ofthe_bus(ports)
+ # Renumber non-message/message ports
+ domain_specific_port_index = collections.defaultdict(int)
+ for port in filter(lambda p: p.get_key().isdigit(), ports):
+ domain = port.get_domain()
+ port._key = str(domain_specific_port_index[domain])
+ domain_specific_port_index[domain] += 1
+
+ def port_controller_modify(self, direction):
+ """
+ Change the port controller.
+
+ Args:
+ direction: +1 or -1
+
+ Returns:
+ true for change
+ """
+ changed = False
+ # Concat the nports string from the private nports settings of all
ports
+ nports_str = ' '.join([port._nports for port in self.get_ports()])
+ # Modify all params whose keys appear in the nports string
+ for param in self.get_params():
+ if param.is_enum() or param.get_key() not in nports_str:
+ continue
+ # Try to increment the port controller by direction
+ try:
+ value = param.get_evaluated()
+ value = value + direction
+ if 0 < value:
+ param.set_value(value)
+ changed = True
+ except:
+ pass
+ return changed
+
+ def get_doc(self):
+ platform = self.get_parent().get_parent()
+ documentation = platform.block_docstrings.get(self._key, {})
+ from_xml = self._doc.strip()
+ if from_xml:
+ documentation[''] = from_xml
+ return documentation
+
+ def get_imports(self, raw=False):
+ """
+ Resolve all import statements.
+ Split each import statement at newlines.
+ Combine all import statments into a list.
+ Filter empty imports.
+
+ Returns:
+ a list of import statements
+ """
+ if raw:
+ return self._imports
+ return filter(lambda i: i, sum(map(lambda i:
self.resolve_dependencies(i).split('\n'), self._imports), []))
+
+ def get_make(self, raw=False):
+ if raw:
+ return self._make
+ return self.resolve_dependencies(self._make)
+
+ def get_var_make(self):
+ return self.resolve_dependencies(self._var_make)
+
+ def get_var_value(self):
+ return self.resolve_dependencies(self._var_value)
+
+ def get_callbacks(self):
+ """
+ Get a list of function callbacks for this block.
+
+ Returns:
+ a list of strings
+ """
+ def make_callback(callback):
+ callback = self.resolve_dependencies(callback)
+ if 'self.' in callback:
+ return callback
+ return 'self.{}.{}'.format(self.get_id(), callback)
+ return map(make_callback, self._callbacks)
+
+ def is_virtual_sink(self):
+ return self.get_key() == 'virtual_sink'
+
+ 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)
++ src_hash = hash((self.get_id(), 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(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(
++ 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))
+
+ params = {}
+ 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:
+ try:
+ param = params[key]
+ param.set_default(value)
+ except KeyError: # need to make a new param
+ 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 = []
+ 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))
+ 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.get_sinks(), blk_io.sinks, 'sink')
+ update_ports('out', self.get_sources(), blk_io.sources, 'source')
+ self.rewrite()
+
+ def back_ofthe_bus(self, portlist):
+ portlist.sort(key=lambda p: p._type == 'bus')
+
+ def filter_bus_port(self, ports):
+ buslist = [p for p in ports if p._type == 'bus']
+ return buslist or ports
+
+ # Main functions to get and set the block state
+ # Also kept get_enabled and set_enabled to keep compatibility
+ def get_state(self):
+ """
+ Gets the block's current state.
+
+ Returns:
+ ENABLED - 0
+ BYPASSED - 1
+ DISABLED - 2
+ """
+ try:
+ return int(eval(self.get_param('_enabled').get_value()))
+ except:
+ return BLOCK_ENABLED
+
+ def set_state(self, state):
+ """
+ Sets the state for the block.
+
+ Args:
+ ENABLED - 0
+ BYPASSED - 1
+ DISABLED - 2
+ """
+ if state in [BLOCK_ENABLED, BLOCK_BYPASSED, BLOCK_DISABLED]:
+ self.get_param('_enabled').set_value(str(state))
+ else:
+ self.get_param('_enabled').set_value(str(BLOCK_ENABLED))
+
+ # Enable/Disable Aliases
+ def get_enabled(self):
+ """
+ Get the enabled state of the block.
+
+ Returns:
+ true for enabled
+ """
+ return not (self.get_state() == BLOCK_DISABLED)
+
+ def set_enabled(self, enabled):
+ """
+ Set the enabled state of the block.
+
+ Args:
+ enabled: true for enabled
+
+ Returns:
+ True if block changed state
+ """
+ old_state = self.get_state()
+ new_state = BLOCK_ENABLED if enabled else BLOCK_DISABLED
+ self.set_state(new_state)
+ return old_state != new_state
+
+ # Block bypassing
+ def get_bypassed(self):
+ """
+ Check if the block is bypassed
+ """
+ return self.get_state() == BLOCK_BYPASSED
+
+ def set_bypassed(self):
+ """
+ Bypass the block
+
+ Returns:
+ True if block chagnes state
+ """
+ if self.get_state() != BLOCK_BYPASSED and self.can_bypass():
+ self.set_state(BLOCK_BYPASSED)
+ return True
+ return False
+
+ def can_bypass(self):
+ """ Check the number of sinks and sources and see if this block can
be bypassed """
+ # Check to make sure this is a single path block
+ # Could possibly support 1 to many blocks
+ if len(self.get_sources()) != 1 or len(self.get_sinks()) != 1:
+ return False
+ if not (self.get_sources()[0].get_type() ==
self.get_sinks()[0].get_type()):
+ return False
+ if self.bypass_disabled():
+ return False
+ return True
+
+ def __str__(self):
+ return 'Block - {} - {}({})'.format(self.get_id(), self.get_name(),
self.get_key())
+
+ def get_id(self):
+ return self.get_param('id').get_value()
+
+ def get_name(self):
+ return self._name
+
+ def get_key(self):
+ return self._key
+
+ def get_category(self):
+ return self._category
+
+ def set_category(self, cat):
+ self._category = cat
+
+ def get_ports(self):
+ return self.get_sources() + self.get_sinks()
+
+ def get_ports_gui(self):
+ return self.filter_bus_port(self.get_sources()) +
self.filter_bus_port(self.get_sinks())
+
+ def get_children(self):
+ return self.get_ports() + self.get_params()
+
+ def get_children_gui(self):
+ return self.get_ports_gui() + self.get_params()
+
+ def get_block_wrapper_path(self):
+ return self._block_wrapper_path
+
+ def get_comment(self):
+ return self.get_param('comment').get_value()
+
+ def get_flags(self):
+ return self._flags
+
+ def throtteling(self):
+ return BLOCK_FLAG_THROTTLE in self._flags
+
+ def bypass_disabled(self):
+ return BLOCK_FLAG_DISABLE_BYPASS in self._flags
+
+ ##############################################
+ # Access Params
+ ##############################################
+ def get_param_tab_labels(self):
+ return self._param_tab_labels
+
+ def get_param_keys(self):
+ return _get_keys(self._params)
+
+ def get_param(self, key):
+ return _get_elem(self._params, key)
+
+ def get_params(self):
+ return self._params
+
+ def has_param(self, key):
+ try:
+ _get_elem(self._params, key)
+ return True
+ except:
+ return False
+
+ ##############################################
+ # Access Sinks
+ ##############################################
+ def get_sink_keys(self):
+ return _get_keys(self._sinks)
+
+ def get_sink(self, key):
+ return _get_elem(self._sinks, key)
+
+ def get_sinks(self):
+ return self._sinks
+
+ def get_sinks_gui(self):
+ return self.filter_bus_port(self.get_sinks())
+
+ ##############################################
+ # Access Sources
+ ##############################################
+ def get_source_keys(self):
+ return _get_keys(self._sources)
+
+ def get_source(self, key):
+ return _get_elem(self._sources, key)
+
+ def get_sources(self):
+ return self._sources
+
+ def get_sources_gui(self):
+ return self.filter_bus_port(self.get_sources())
+
+ def get_connections(self):
+ return sum([port.get_connections() for port in self.get_ports()], [])
+
+ def resolve_dependencies(self, tmpl):
+ """
+ Resolve a paramater dependency with cheetah templates.
+
+ Args:
+ tmpl: the string with dependencies
+
+ Returns:
+ the resolved value
+ """
+ tmpl = str(tmpl)
+ if '$' not in tmpl:
+ return tmpl
+ n = dict((param.get_key(), param.template_arg)
+ for param in self.get_params()) # TODO: cache that
+ try:
+ return str(Template(tmpl, n))
+ except Exception as err:
+ return "Template error: {}\n {}".format(tmpl, err)
+
+ ##############################################
+ # Controller Modify
+ ##############################################
+ def type_controller_modify(self, direction):
+ """
+ Change the type controller.
+
+ Args:
+ direction: +1 or -1
+
+ Returns:
+ true for change
+ """
+ changed = False
+ type_param = None
+ for param in filter(lambda p: p.is_enum(), self.get_params()):
+ children = self.get_ports() + self.get_params()
+ # Priority to the type controller
+ if param.get_key() in ' '.join(map(lambda p: p._type, children)):
type_param = param
+ # Use param if type param is unset
+ if not type_param:
+ type_param = param
+ if type_param:
+ # Try to increment the enum by direction
+ try:
+ keys = type_param.get_option_keys()
+ old_index = keys.index(type_param.get_value())
+ new_index = (old_index + direction + len(keys)) % len(keys)
+ type_param.set_value(keys[new_index])
+ changed = True
+ except:
+ pass
+ return changed
+
+ def form_bus_structure(self, direc):
+ if direc == 'source':
+ get_p = self.get_sources
+ get_p_gui = self.get_sources_gui
+ bus_structure = self.get_bus_structure('source')
+ else:
+ get_p = self.get_sinks
+ get_p_gui = self.get_sinks_gui
+ bus_structure = self.get_bus_structure('sink')
+
+ struct = [range(len(get_p()))]
+ if True in map(lambda a: isinstance(a.get_nports(), int), get_p()):
+ structlet = []
+ last = 0
+ for j in [i.get_nports() for i in get_p() if
isinstance(i.get_nports(), int)]:
+ structlet.extend(map(lambda a: a+last, range(j)))
+ last = structlet[-1] + 1
+ struct = [structlet]
+ if bus_structure:
+
+ struct = bus_structure
+
+ self.current_bus_structure[direc] = struct
+ return struct
+
+ def bussify(self, n, direc):
+ if direc == 'source':
+ get_p = self.get_sources
+ get_p_gui = self.get_sources_gui
+ bus_structure = self.get_bus_structure('source')
+ else:
+ get_p = self.get_sinks
+ get_p_gui = self.get_sinks_gui
+ bus_structure = self.get_bus_structure('sink')
+
+ for elt in get_p():
+ for connect in elt.get_connections():
+ self.get_parent().remove_element(connect)
+
+ if ('bus' not in map(lambda a: a.get_type(), get_p())) and
len(get_p()) > 0:
+ struct = self.form_bus_structure(direc)
+ self.current_bus_structure[direc] = struct
+ if get_p()[0].get_nports():
+ n['nports'] = str(1)
+
+ for i in range(len(struct)):
+ n['key'] = str(len(get_p()))
+ n = odict(n)
+ port = self.get_parent().get_parent().Port(block=self, n=n,
dir=direc)
+ get_p().append(port)
+ elif 'bus' in map(lambda a: a.get_type(), get_p()):
+ for elt in get_p_gui():
+ get_p().remove(elt)
+ self.current_bus_structure[direc] = ''
+
+ ##############################################
+ # Import/Export Methods
+ ##############################################
+ def export_data(self):
+ """
+ Export this block's params to nested data.
+
+ Returns:
+ a nested data odict
+ """
+ n = odict()
+ n['key'] = self.get_key()
+ n['param'] = map(lambda p: p.export_data(), sorted(self.get_params(),
key=str))
+ if 'bus' in map(lambda a: a.get_type(), self.get_sinks()):
+ n['bus_sink'] = str(1)
+ if 'bus' in map(lambda a: a.get_type(), self.get_sources()):
+ n['bus_source'] = str(1)
+ return n
+
+ def get_hash(self):
+ return hash(tuple(map(hash, self.get_params())))
+
+ def import_data(self, n):
+ """
+ Import this block's params from nested data.
+ Any param keys that do not exist will be ignored.
+ Since params can be dynamically created based another param,
+ call rewrite, and repeat the load until the params stick.
+ This call to rewrite will also create any dynamic ports
+ that are needed for the connections creation phase.
+
+ Args:
+ n: the nested data odict
+ """
+ my_hash = 0
+ while self.get_hash() != my_hash:
+ params_n = n.findall('param')
+ for param_n in params_n:
+ key = param_n.find('key')
+ value = param_n.find('value')
+ # The key must exist in this block's params
+ if key in self.get_param_keys():
+ self.get_param(key).set_value(value)
+ # Store hash and call rewrite
+ my_hash = self.get_hash()
+ self.rewrite()
+ bussinks = n.findall('bus_sink')
+ if len(bussinks) > 0 and not self._bussify_sink:
+ self.bussify({'name': 'bus', 'type': 'bus'}, 'sink')
+ elif len(bussinks) > 0:
+ self.bussify({'name': 'bus', 'type': 'bus'}, 'sink')
+ self.bussify({'name': 'bus', 'type': 'bus'}, 'sink')
+ bussrcs = n.findall('bus_source')
+ if len(bussrcs) > 0 and not self._bussify_source:
+ self.bussify({'name': 'bus', 'type': 'bus'}, 'source')
+ elif len(bussrcs) > 0:
+ self.bussify({'name': 'bus', 'type': 'bus'}, 'source')
+ self.bussify({'name': 'bus', 'type': 'bus'}, 'source')
- [Commit-gnuradio] [gnuradio] branch master updated (bdf8517 -> a03a390), git, 2016/04/24
- [Commit-gnuradio] [gnuradio] 15/18: grc-refactoring: fix gui mode errors, no empty import on fg init, some renames, git, 2016/04/24
- [Commit-gnuradio] [gnuradio] 06/18: grc-refactor: rename grc/model/ to grc/core/, git, 2016/04/24
- [Commit-gnuradio] [gnuradio] 08/18: grc-refactor: Platform.py fixes, FlowGraphProxy, git, 2016/04/24
- [Commit-gnuradio] [gnuradio] 02/18: grc-refactor: clean-up grc directory, git, 2016/04/24
- [Commit-gnuradio] [gnuradio] 09/18: grc-refactor: move Messages to core, git, 2016/04/24
- [Commit-gnuradio] [gnuradio] 07/18: grc-refactor: cmake fixes and more reorganizing, git, 2016/04/24
- [Commit-gnuradio] [gnuradio] 13/18: grc-refactoring: move template arg to param, git, 2016/04/24
- [Commit-gnuradio] [gnuradio] 14/18: grc-refactor: fix fg load, git, 2016/04/24
- [Commit-gnuradio] [gnuradio] 12/18: grc-refactor: remove (hopefully) all deps to GR in core/ and gui/, git, 2016/04/24
- [Commit-gnuradio] [gnuradio] 18/18: Merge branch 'maint_grcwg' into refactoring,
git <=
- [Commit-gnuradio] [gnuradio] 11/18: grc-refactor: move gui prefs to gui, git, 2016/04/24
- [Commit-gnuradio] [gnuradio] 05/18: grc-refactor: fixes, type-testing-flags, FlowGraph.py, (more), git, 2016/04/24
- [Commit-gnuradio] [gnuradio] 01/18: grc-refactor: move grc.base to grc.python.base, git, 2016/04/24
- [Commit-gnuradio] [gnuradio] 10/18: grc-refactor: Platform.py, git, 2016/04/24
- [Commit-gnuradio] [gnuradio] 17/18: grc-refactor: CMake fixes, start-up script cleaned up, git, 2016/04/24
- [Commit-gnuradio] [gnuradio] 16/18: Merge remote-tracking branch 'upstream/master' into refactoring, git, 2016/04/24
- [Commit-gnuradio] [gnuradio] 04/18: grc-refactor: Cleaning up code style to match PEP8., git, 2016/04/24
- [Commit-gnuradio] [gnuradio] 03/18: grc-refactor: Moved code from grc.model.base to grc.model, git, 2016/04/24