summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Koslowski <koslowski@kit.edu>2016-06-09 14:44:22 +0200
committerSebastian Koslowski <koslowski@kit.edu>2016-06-10 14:41:52 +0200
commit435e2b16c903b4a9d16d40ffba649698c4ded190 (patch)
treea99691a8877b7fc911c9d4b223d26b0f3fa5921b
parent6375ebf0eb2b619e1a31ec8b8babc3ad0f968dd2 (diff)
grc-refactor: rewrite tree-api in core
-rw-r--r--grc/core/Block.py65
-rw-r--r--grc/core/Connection.py14
-rw-r--r--grc/core/Element.py54
-rw-r--r--grc/core/FlowGraph.py56
-rw-r--r--grc/core/Param.py34
-rw-r--r--grc/core/Platform.py8
-rw-r--r--grc/core/Port.py45
-rw-r--r--grc/core/generator/FlowGraphProxy.py2
-rw-r--r--grc/core/generator/Generator.py9
-rw-r--r--grc/core/generator/flow_graph.tmpl4
-rw-r--r--grc/gui/ActionHandler.py5
-rw-r--r--grc/gui/Block.py4
-rw-r--r--grc/gui/FlowGraph.py12
-rw-r--r--grc/gui/NotebookPage.py4
-rw-r--r--grc/gui/Param.py2
-rw-r--r--grc/gui/ParamWidgets.py8
-rw-r--r--grc/gui/Port.py26
17 files changed, 191 insertions, 161 deletions
diff --git a/grc/core/Block.py b/grc/core/Block.py
index b607f908fb..ff7f041dc0 100644
--- a/grc/core/Block.py
+++ b/grc/core/Block.py
@@ -63,18 +63,18 @@ class Block(Element):
Returns:
block a new block
"""
- Element.__init__(self, flow_graph)
+ Element.__init__(self, parent=flow_graph)
self._name = n['name']
self._key = n['key']
self._category = n.get('category', '')
self._flags = n.get('flags', '')
+ self._doc = n.get('doc', '').strip('\n').replace('\\\n', '')
# Backwards compatibility
if n.get('throttle') and BLOCK_FLAG_THROTTLE not in self._flags:
self._flags += BLOCK_FLAG_THROTTLE
- self._doc = n.get('doc', '').strip('\n').replace('\\\n', '')
self._imports = [i.strip() for i in n.get('import', [])]
self._make = n.get('make')
self._var_make = n.get('var_make')
@@ -90,7 +90,6 @@ class Block(Element):
sinks_n = n.get('sink', [])
# Get list of param tabs
- n_tabs = n.get('param_tab_order', {})
self._param_tab_labels = n.get('param_tab_order', {}).get('tab') or [DEFAULT_PARAM_TAB]
self._params = []
self._init_params(
@@ -106,22 +105,12 @@ class Block(Element):
self._epy_source_hash = -1 # for epy blocks
self._epy_reload_error = None
- self.back_ofthe_bus(self._sources)
- self.back_ofthe_bus(self._sinks)
- self.current_bus_structure = {'source': '', 'sink': ''}
- self._bus_structure_source = n.get('bus_structure_source', '')
- self._bus_structure_sink = n.get('bus_structure_sink', '')
- self._bussify_sink = n.get('bus_sink')
- self._bussify_source = n.get('bus_source')
- if self._bussify_sink:
- self.bussify({'name': 'bus', 'type': 'bus'}, 'sink')
- if self._bussify_source:
- self.bussify({'name': 'bus', 'type': 'bus'}, 'source')
+ self._init_bus_ports(n)
def _add_param(self, key, name, value='', type='raw', **kwargs):
n = {'key': key, 'name': name, 'value': value, 'type': type}
n.update(kwargs)
- param = self.get_parent().get_parent().Param(block=self, n=n)
+ param = self.parent_platform.Param(block=self, n=n)
self._params.append(param)
def _init_params(self, params_n, has_sources, has_sinks):
@@ -157,7 +146,7 @@ class Block(Element):
param_keys = set(param.get_key() for param in self._params)
for param_n in params_n:
- param = self.get_parent().get_parent().Param(block=self, n=param_n)
+ param = self.parent_platform.Param(block=self, n=param_n)
key = param.get_key()
if key in param_keys:
raise Exception('Key "{}" already exists in params'.format(key))
@@ -168,7 +157,7 @@ class Block(Element):
value='', tab=ADVANCED_PARAM_TAB)
def _init_ports(self, ports_n, direction):
- port_cls = self.get_parent().get_parent().Port
+ port_cls = self.parent_platform.Port
ports = []
port_keys = set()
for port_n in ports_n:
@@ -191,7 +180,7 @@ class Block(Element):
for check in self._checks:
check_res = self.resolve_dependencies(check)
try:
- if not self.get_parent().evaluate(check_res):
+ if not self.parent.evaluate(check_res):
self.add_error_message('Check "{}" failed.'.format(check))
except:
self.add_error_message('Check "{}" did not evaluate.'.format(check))
@@ -201,12 +190,12 @@ class Block(Element):
value = self._var_value
try:
value = self.get_var_value()
- self.get_parent().evaluate(value)
+ self.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')
+ current_generate_option = self.parent.get_option('generate_options')
def check_generate_mode(label, flag, valid_options):
block_requires_mode = (
@@ -237,14 +226,14 @@ class Block(Element):
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)
+ self.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)
+ self.parent.remove_element(connection)
master_port.remove_clone(port)
ports.remove(port)
# Add more cloned ports
@@ -261,8 +250,7 @@ class Block(Element):
domain_specific_port_index[domain] += 1
def get_doc(self):
- platform = self.get_parent().get_parent()
- documentation = platform.block_docstrings.get(self._key, {})
+ documentation = self.parent_platform.block_docstrings.get(self._key, {})
from_xml = self._doc.strip()
if from_xml:
documentation[''] = from_xml
@@ -280,8 +268,8 @@ class Block(Element):
"""
if raw:
return self._imports
- return [i for i in sum([self.resolve_dependencies(i).split('\n')
- for i in self._imports], []) if i]
+ return [i for i in sum((self.resolve_dependencies(i).split('\n')
+ for i in self._imports), []) if i]
def get_make(self, raw=False):
if raw:
@@ -319,8 +307,8 @@ class Block(Element):
###########################################################################
def rewrite_epy_block(self):
- flowgraph = self.get_parent()
- platform = flowgraph.get_parent()
+ flowgraph = self.parent_flowgraph
+ platform = self.parent_block
param_blk = self.get_param('_io_cache')
param_src = self.get_param('_source_code')
@@ -743,7 +731,7 @@ class Block(Element):
return '' # TODO: Don't like empty strings. should change this to None eventually
try:
- clean_bus_structure = self.get_parent().evaluate(bus_structure)
+ clean_bus_structure = self.parent.evaluate(bus_structure)
return clean_bus_structure
except:
return ''
@@ -798,15 +786,13 @@ class Block(Element):
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)
+ self.parent.remove_element(connect)
if ('bus' not in [a.get_type() for a in get_p()]) and len(get_p()) > 0:
struct = self.form_bus_structure(direc)
@@ -817,9 +803,22 @@ class Block(Element):
for i in range(len(struct)):
n['key'] = str(len(get_p()))
n = dict(n)
- port = self.get_parent().get_parent().Port(block=self, n=n, dir=direc)
+ port = self.parent.parent.Port(block=self, n=n, dir=direc)
get_p().append(port)
elif 'bus' in [a.get_type() for a in get_p()]:
for elt in get_p_gui():
get_p().remove(elt)
self.current_bus_structure[direc] = ''
+
+ def _init_bus_ports(self, n):
+ self.back_ofthe_bus(self._sources)
+ self.back_ofthe_bus(self._sinks)
+ self.current_bus_structure = {'source': '', 'sink': ''}
+ self._bus_structure_source = n.get('bus_structure_source', '')
+ self._bus_structure_sink = n.get('bus_structure_sink', '')
+ self._bussify_sink = n.get('bus_sink')
+ self._bussify_source = n.get('bus_source')
+ if self._bussify_sink:
+ self.bussify({'name': 'bus', 'type': 'bus'}, 'sink')
+ if self._bussify_source:
+ self.bussify({'name': 'bus', 'type': 'bus'}, 'source')
diff --git a/grc/core/Connection.py b/grc/core/Connection.py
index a15fe6a2e8..2309d159c8 100644
--- a/grc/core/Connection.py
+++ b/grc/core/Connection.py
@@ -24,7 +24,7 @@ import collections
from six.moves import range
from . import Constants
-from .Element import Element
+from .Element import Element, lazyproperty
class Connection(Element):
@@ -94,7 +94,7 @@ class Connection(Element):
The ports must match in type.
"""
Element.validate(self)
- platform = self.get_parent().get_parent()
+ platform = self.parent_platform
source_domain = self.source_port.get_domain()
sink_domain = self.sink_port.get_domain()
@@ -131,13 +131,13 @@ class Connection(Element):
"""
return self.source_block.get_enabled() and self.sink_block.get_enabled()
- @property
+ @lazyproperty
def source_block(self):
- return self.source_port.get_parent()
+ return self.source_port.parent_block
- @property
+ @lazyproperty
def sink_block(self):
- return self.sink_port.get_parent()
+ return self.sink_port.parent_block
##############################################
# Import/Export Methods
@@ -171,6 +171,6 @@ class Connection(Element):
for i in range(len(sources)):
try:
- self.get_parent().connect(sources[i], sinks[i])
+ self.parent_flowgraph.connect(sources[i], sinks[i])
except:
pass
diff --git a/grc/core/Element.py b/grc/core/Element.py
index e697d293fb..a046d6beb4 100644
--- a/grc/core/Element.py
+++ b/grc/core/Element.py
@@ -17,11 +17,26 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
"""
+import weakref
+
+
+class lazyproperty(object):
+ def __init__(self, func):
+ self.func = func
+
+ def __get__(self, instance, cls):
+ if instance is None:
+ return self
+ else:
+ value = self.func(instance)
+ setattr(instance, self.func.__name__, value)
+ return value
+
class Element(object):
def __init__(self, parent=None):
- self._parent = parent
+ self._parent = weakref.ref(parent) if parent else lambda: None
self._error_messages = []
##################################################
@@ -33,6 +48,7 @@ class Element(object):
Call this base method before adding error messages in the subclass.
"""
del self._error_messages[:]
+
for child in self.get_children():
child.validate()
@@ -88,8 +104,40 @@ class Element(object):
##############################################
# Tree-like API
##############################################
- def get_parent(self):
- return self._parent
+ @property
+ def parent(self):
+ return self._parent()
+
+ def get_parent_of_type(self, cls):
+ parent = self.parent
+ if parent is None:
+ return None
+ elif isinstance(parent, cls):
+ return parent
+ else:
+ return parent.get_parent_of_type(cls)
+
+ @lazyproperty
+ def parent_platform(self):
+ from .Platform import Platform
+ return self.get_parent_of_type(Platform)
+
+ @lazyproperty
+ def parent_flowgraph(self):
+ from .FlowGraph import FlowGraph
+ return self.get_parent_of_type(FlowGraph)
+
+ @lazyproperty
+ def parent_block(self):
+ from .Block import Block
+ return self.get_parent_of_type(Block)
+
+ def reset_parents(self):
+ """Reset all lazy properties"""
+ # todo: use case?
+ for name, obj in vars(Element):
+ if isinstance(obj, lazyproperty):
+ delattr(self, name)
def get_children(self):
return list()
diff --git a/grc/core/FlowGraph.py b/grc/core/FlowGraph.py
index a17d820539..16842595c8 100644
--- a/grc/core/FlowGraph.py
+++ b/grc/core/FlowGraph.py
@@ -54,25 +54,20 @@ class FlowGraph(Element):
the flow graph object
"""
Element.__init__(self, platform)
- self._elements = []
self._timestamp = time.ctime()
+ self._options_block = self.parent_platform.get_new_block(self, 'options')
- self.platform = platform # todo: make this a lazy prop
- self.blocks = []
+ self.blocks = [self._options_block]
self.connections = []
self._eval_cache = {}
self.namespace = {}
self.grc_file_path = ''
- self._options_block = self.new_block('options')
def __str__(self):
return 'FlowGraph - {}({})'.format(self.get_option('title'), self.get_option('id'))
- ##############################################
- # TODO: Move these to new generator package
- ##############################################
def get_imports(self):
"""
Get a set of all import statements in this flow graph namespace.
@@ -199,19 +194,6 @@ class FlowGraph(Element):
raise KeyError('No block with ID {!r}'.format(id))
def get_elements(self):
- """
- Get a list of all the elements.
- Always ensure that the options block is in the list (only once).
-
- Returns:
- the element list
- """
- options_block_count = self.blocks.count(self._options_block)
- if not options_block_count:
- self.blocks.append(self._options_block)
- for _ in range(options_block_count-1):
- self.blocks.remove(self._options_block)
-
return self.blocks + self.connections
get_children = get_elements
@@ -220,7 +202,6 @@ class FlowGraph(Element):
"""
Flag the namespace to be renewed.
"""
-
self.renew_namespace()
for child in chain(self.blocks, self.connections):
child.rewrite()
@@ -297,8 +278,10 @@ class FlowGraph(Element):
Returns:
the new block or None if not found
"""
+ if key == 'options':
+ return self._options_block
try:
- block = self.platform.get_new_block(self, key)
+ block = self.parent_platform.get_new_block(self, key)
self.blocks.append(block)
except KeyError:
block = None
@@ -317,7 +300,7 @@ class FlowGraph(Element):
the new connection
"""
- connection = self.platform.Connection(
+ connection = self.parent_platform.Connection(
flow_graph=self, porta=porta, portb=portb)
self.connections.append(connection)
return connection
@@ -329,9 +312,12 @@ class FlowGraph(Element):
If the element is a block, remove its connections.
If the element is a connection, just remove the connection.
"""
+ if element is self._options_block:
+ return
+
if element.is_port:
# Found a port, set to parent signal block
- element = element.get_parent()
+ element = element.parent
if element in self.blocks:
# Remove block, remove all involved connections
@@ -370,7 +356,7 @@ class FlowGraph(Element):
n['block'] = [b.export_data() for b in blocks]
n['connection'] = [c.export_data() for c in connections]
instructions = collections.OrderedDict()
- instructions['created'] = '.'.join(self.get_parent().config.version_parts)
+ instructions['created'] = '.'.join(self.parent.config.version_parts)
instructions['format'] = FLOW_GRAPH_FILE_FORMAT_VERSION
return {'flow_graph': n, '_instructions': instructions}
@@ -397,22 +383,22 @@ class FlowGraph(Element):
self._timestamp = fg_n.get('timestamp', time.ctime())
# build the blocks
- self._options_block = self.new_block('options')
+ self.blocks.append(self._options_block)
for block_n in fg_n.get('block', []):
key = block_n['key']
- block = self._options_block if key == 'options' else self.new_block(key)
+ block = self.new_block(key)
if not block:
# we're before the initial fg update(), so no evaluated values!
# --> use raw value instead
path_param = self._options_block.get_param('hier_block_src_path')
- file_path = self.platform.find_file_in_paths(
+ file_path = self.parent_platform.find_file_in_paths(
filename=key + '.grc',
paths=path_param.get_value(),
cwd=self.grc_file_path
)
if file_path: # grc file found. load and get block
- self.platform.load_and_generate_flow_graph(file_path)
+ self.parent_platform.load_and_generate_flow_graph(file_path)
block = self.new_block(key) # can be None
if not block: # looks like this block key cannot be found
@@ -488,22 +474,22 @@ class FlowGraph(Element):
if 'bus' in [a.get_type() for a in get_p_gui()]:
if len(get_p_gui()) > len(bus_structure):
- times = list(range(len(bus_structure), len(get_p_gui())))
+ times = range(len(bus_structure), len(get_p_gui()))
for i in times:
for connect in get_p_gui()[-1].get_connections():
- block.get_parent().remove_element(connect)
+ block.parent.remove_element(connect)
get_p().remove(get_p_gui()[-1])
elif len(get_p_gui()) < len(bus_structure):
n = {'name': 'bus', 'type': 'bus'}
if any(isinstance(a.get_nports(), int) for a in get_p()):
n['nports'] = str(1)
- times = list(range(len(get_p_gui()), len(bus_structure)))
+ times = range(len(get_p_gui()), len(bus_structure))
for i in times:
n['key'] = str(len(get_p()))
n = dict(n)
- port = block.get_parent().get_parent().Port(
+ port = block.parent.parent.Port(
block=block, n=n, dir=direc)
get_p().append(port)
@@ -576,14 +562,14 @@ def _initialize_dummy_block(block, block_n):
for param_n in block_n.get('param', []):
if param_n['key'] not in block.get_param_keys():
new_param_n = {'key': param_n['key'], 'name': param_n['key'], 'type': 'string'}
- params = block.get_parent().get_parent().Param(block=block, n=new_param_n)
+ params = block.parent_platform.Param(block=block, n=new_param_n)
block.get_params().append(params)
def _dummy_block_add_port(block, key, dir):
""" This is so ugly... Add a port to a dummy-field block """
port_n = {'name': '?', 'key': key, 'type': ''}
- port = block.get_parent().get_parent().Port(block=block, n=port_n, dir=dir)
+ port = block.parent_platform.Port(block=block, n=port_n, dir=dir)
if port.is_source:
block.get_sources().append(port)
else:
diff --git a/grc/core/Param.py b/grc/core/Param.py
index a9d495d5a4..b21cbcddf1 100644
--- a/grc/core/Param.py
+++ b/grc/core/Param.py
@@ -84,7 +84,7 @@ class Option(Element):
self._opts = dict()
opts = n.get('opt', [])
# Test against opts when non enum
- if not self.get_parent().is_enum() and opts:
+ if not self.parent.is_enum() and opts:
raise Exception('Options for non-enum types cannot have sub-options')
# Extract opts
for opt in opts:
@@ -304,17 +304,17 @@ class Param(Element):
Returns:
hide the hide property string
"""
- hide = self.get_parent().resolve_dependencies(self._hide).strip()
+ hide = self.parent.resolve_dependencies(self._hide).strip()
if hide:
return hide
# Hide ID in non variable blocks
- if self.get_key() == 'id' and not _show_id_matcher.match(self.get_parent().get_key()):
+ if self.get_key() == 'id' and not _show_id_matcher.match(self.parent.get_key()):
return 'part'
# Hide port controllers for type and nports
- if self.get_key() in ' '.join([' '.join([p._type, p._nports]) for p in self.get_parent().get_ports()]):
+ if self.get_key() in ' '.join([' '.join([p._type, p._nports]) for p in self.parent.get_ports()]):
return 'part'
# Hide port controllers for vlen, when == 1
- if self.get_key() in ' '.join(p._vlen for p in self.get_parent().get_ports()):
+ if self.get_key() in ' '.join(p._vlen for p in self.parent.get_ports()):
try:
if int(self.get_evaluated()) == 1:
return 'part'
@@ -369,7 +369,7 @@ class Param(Element):
elif t in ('raw', 'complex', 'real', 'float', 'int', 'hex', 'bool'):
# Raise exception if python cannot evaluate this value
try:
- e = self.get_parent().get_parent().evaluate(v)
+ e = self.parent_flowgraph.evaluate(v)
except Exception as e:
raise Exception('Value "{}" cannot be evaluated:\n{}'.format(v, e))
# Raise an exception if the data is invalid
@@ -404,7 +404,7 @@ class Param(Element):
v = '()'
# Raise exception if python cannot evaluate this value
try:
- e = self.get_parent().get_parent().evaluate(v)
+ e = self.parent.parent.evaluate(v)
except Exception as e:
raise Exception('Value "{}" cannot be evaluated:\n{}'.format(v, e))
# Raise an exception if the data is invalid
@@ -435,7 +435,7 @@ class Param(Element):
elif t in ('string', 'file_open', 'file_save', '_multiline', '_multiline_python_external'):
# Do not check if file/directory exists, that is a runtime issue
try:
- e = self.get_parent().get_parent().evaluate(v)
+ e = self.parent.parent.evaluate(v)
if not isinstance(e, str):
raise Exception()
except:
@@ -466,16 +466,16 @@ class Param(Element):
elif t == 'stream_id':
# Get a list of all stream ids used in the virtual sinks
ids = [param.get_value() for param in filter(
- lambda p: p.get_parent().is_virtual_sink(),
+ lambda p: p.parent.is_virtual_sink(),
self.get_all_params(t),
)]
# Check that the virtual sink's stream id is unique
- if self.get_parent().is_virtual_sink():
+ if self.parent.is_virtual_sink():
# Id should only appear once, or zero times if block is disabled
if ids.count(v) > 1:
raise Exception('Stream ID "{}" is not unique.'.format(v))
# Check that the virtual source's steam id is found
- if self.get_parent().is_virtual_source():
+ if self.parent.is_virtual_source():
if v not in ids:
raise Exception('Stream ID "{}" is not found.'.format(v))
return v
@@ -523,7 +523,7 @@ class Param(Element):
if not v:
# Allow for empty grid pos
return ''
- e = self.get_parent().get_parent().evaluate(v)
+ e = self.parent_flowgraph.evaluate(v)
if not isinstance(e, (list, tuple)) or len(e) != 4 or not all([isinstance(ei, int) for ei in e]):
raise Exception('A grid position must be a list of 4 integers.')
row, col, row_span, col_span = e
@@ -535,7 +535,7 @@ class Param(Element):
raise Exception('Row and column span must be greater than zero.')
# Get hostage cell parent
try:
- my_parent = self.get_parent().get_param('notebook').evaluate()
+ my_parent = self.parent.get_param('notebook').evaluate()
except:
my_parent = ''
# Calculate hostage cells
@@ -558,7 +558,7 @@ class Param(Element):
return ''
# Get a list of all notebooks
- notebook_blocks = [b for b in self.get_parent().get_parent().get_enabled_blocks() if b.get_key() == 'notebook']
+ notebook_blocks = [b for b in self.parent_flowgraph.get_enabled_blocks() if b.get_key() == 'notebook']
# Check for notebook param syntax
try:
notebook_id, page_index = map(str.strip, v.split(','))
@@ -634,7 +634,7 @@ class Param(Element):
a list of params
"""
params = []
- for block in self.get_parent().get_parent().get_enabled_blocks():
+ for block in self.parent_flowgraph.get_enabled_blocks():
params.extend(p for p in block.get_params() if p.get_type() == type)
return params
@@ -658,13 +658,13 @@ class Param(Element):
self._default = str(value)
def get_type(self):
- return self.get_parent().resolve_dependencies(self._type)
+ return self.parent.resolve_dependencies(self._type)
def get_tab_label(self):
return self._tab_label
def get_name(self):
- return self.get_parent().resolve_dependencies(self._name).strip()
+ return self.parent.resolve_dependencies(self._name).strip()
def get_key(self):
return self._key
diff --git a/grc/core/Platform.py b/grc/core/Platform.py
index 403c6c87b4..2c0b83dca4 100644
--- a/grc/core/Platform.py
+++ b/grc/core/Platform.py
@@ -68,10 +68,6 @@ class Platform(Element):
self._block_dtd = Constants.BLOCK_DTD
self._default_flow_graph = Constants.DEFAULT_FLOW_GRAPH
- # Create a dummy flow graph for the blocks
- self._flow_graph = Element(self)
- self._flow_graph.connections = []
-
self.blocks = {}
self._blocks_n = {}
self._category_trees_n = []
@@ -80,6 +76,10 @@ class Platform(Element):
self._auto_hier_block_generate_chain = set()
+ # Create a dummy flow graph for the blocks
+ self._flow_graph = Element.__new__(FlowGraph)
+ Element.__init__(self._flow_graph, self)
+ self._flow_graph.connections = []
self.load_blocks()
def __str__(self):
diff --git a/grc/core/Port.py b/grc/core/Port.py
index b0753910e6..99b5a25508 100644
--- a/grc/core/Port.py
+++ b/grc/core/Port.py
@@ -43,7 +43,7 @@ def _get_source_from_virtual_source_port(vsp, traversed=[]):
Recursively resolve source ports over the virtual connections.
Keep track of traversed sources to avoid recursive loops.
"""
- if not vsp.get_parent().is_virtual_source():
+ if not vsp.parent.is_virtual_source():
return vsp
if vsp in traversed:
raise Exception('Loop found when resolving virtual source {}'.format(vsp))
@@ -51,10 +51,10 @@ def _get_source_from_virtual_source_port(vsp, traversed=[]):
return _get_source_from_virtual_source_port(
_get_source_from_virtual_sink_port(
list(filter( # Get all virtual sinks with a matching stream id
- lambda vs: vs.get_param('stream_id').get_value() == vsp.get_parent().get_param('stream_id').get_value(),
+ lambda vs: vs.get_param('stream_id').get_value() == vsp.parent.get_param('stream_id').get_value(),
list(filter( # Get all enabled blocks that are also virtual sinks
lambda b: b.is_virtual_sink(),
- vsp.get_parent().get_parent().get_enabled_blocks(),
+ vsp.parent.parent.get_enabled_blocks(),
)),
))[0].get_sinks()[0]
), traversed + [vsp],
@@ -81,7 +81,7 @@ def _get_sink_from_virtual_sink_port(vsp, traversed=[]):
Recursively resolve sink ports over the virtual connections.
Keep track of traversed sinks to avoid recursive loops.
"""
- if not vsp.get_parent().is_virtual_sink():
+ if not vsp.parent.is_virtual_sink():
return vsp
if vsp in traversed:
raise Exception('Loop found when resolving virtual sink {}'.format(vsp))
@@ -89,10 +89,10 @@ def _get_sink_from_virtual_sink_port(vsp, traversed=[]):
return _get_sink_from_virtual_sink_port(
_get_sink_from_virtual_source_port(
filter( # Get all virtual source with a matching stream id
- lambda vs: vs.get_param('stream_id').get_value() == vsp.get_parent().get_param('stream_id').get_value(),
+ lambda vs: vs.get_param('stream_id').get_value() == vsp.parent.get_param('stream_id').get_value(),
list(filter( # Get all enabled blocks that are also virtual sinks
lambda b: b.is_virtual_source(),
- vsp.get_parent().get_parent().get_enabled_blocks(),
+ vsp.parent.parent.get_enabled_blocks(),
)),
)[0].get_sources()[0]
), traversed + [vsp],
@@ -160,7 +160,7 @@ class Port(Element):
Element.validate(self)
if self.get_type() not in self.get_types():
self.add_error_message('Type "{}" is not a possible type.'.format(self.get_type()))
- platform = self.get_parent().get_parent().get_parent()
+ platform = self.parent.parent.parent
if self.get_domain() not in platform.domains:
self.add_error_message('Domain key "{}" is not registered.'.format(self.get_domain()))
if not self.get_enabled_connections() and not self.get_optional():
@@ -188,7 +188,7 @@ class Port(Element):
self._vlen = ''
Element.rewrite(self)
- hide = self.get_parent().resolve_dependencies(self._hide).strip().lower()
+ hide = self.parent.resolve_dependencies(self._hide).strip().lower()
self._hide_evaluated = False if hide in ('false', 'off', '0') else bool(hide)
# Update domain if was deduced from (dynamic) port type
@@ -201,9 +201,9 @@ class Port(Element):
self._key = '0' # Is rectified in rewrite()
def resolve_virtual_source(self):
- if self.get_parent().is_virtual_sink():
+ if self.parent.is_virtual_sink():
return _get_source_from_virtual_sink_port(self)
- if self.get_parent().is_virtual_source():
+ if self.parent.is_virtual_source():
return _get_source_from_virtual_source_port(self)
def resolve_empty_type(self):
@@ -236,9 +236,9 @@ class Port(Element):
Returns:
the vector length or 1
"""
- vlen = self.get_parent().resolve_dependencies(self._vlen)
+ vlen = self.parent.resolve_dependencies(self._vlen)
try:
- return int(self.get_parent().get_parent().evaluate(vlen))
+ return int(self.parent.parent.evaluate(vlen))
except:
return 1
@@ -254,9 +254,9 @@ class Port(Element):
if self._nports == '':
return ''
- nports = self.get_parent().resolve_dependencies(self._nports)
+ nports = self.parent.resolve_dependencies(self._nports)
try:
- return max(1, int(self.get_parent().get_parent().evaluate(nports)))
+ return max(1, int(self.parent.parent.evaluate(nports)))
except:
return 1
@@ -325,7 +325,7 @@ class Port(Element):
n['key'] = '99999' if self._key.isdigit() else n['name']
# Clone
- port = self.__class__(self.get_parent(), n, self._dir)
+ port = self.__class__(self.parent, n, self._dir)
self._clones.append(port)
return port
@@ -345,7 +345,7 @@ class Port(Element):
def get_name(self):
number = ''
if self.get_type() == 'bus':
- busses = [a for a in self.get_parent().get_ports_gui() if a._dir == self._dir]
+ busses = [a for a in self.parent.get_ports_gui() if a._dir == self._dir]
number = str(busses.index(self)) + '#' + str(len(self.get_associated_ports()))
return self._name + number
@@ -361,7 +361,7 @@ class Port(Element):
return self._dir == 'source'
def get_type(self):
- return self.get_parent().resolve_dependencies(self._type)
+ return self.parent_block.resolve_dependencies(self._type)
def get_domain(self):
return self._domain
@@ -376,7 +376,7 @@ class Port(Element):
Returns:
a list of connection objects
"""
- connections = self.get_parent().get_parent().connections
+ connections = self.parent_flowgraph.connections
connections = [c for c in connections if c.source_port is self or c.sink_port is self]
return connections
@@ -393,12 +393,13 @@ class Port(Element):
if not self.get_type() == 'bus':
return [self]
else:
+ flowgraph = self.parent_flowgraph
if self.is_source:
- get_ports = self.get_parent().get_sources
- bus_structure = self.get_parent().current_bus_structure['source']
+ get_ports = flowgraph.get_sources
+ bus_structure = flowgraph.current_bus_structure['source']
else:
- get_ports = self.get_parent().get_sinks
- bus_structure = self.get_parent().current_bus_structure['sink']
+ get_ports = flowgraph.get_sinks
+ bus_structure = flowgraph.current_bus_structure['sink']
ports = [i for i in get_ports() if not i.get_type() == 'bus']
if bus_structure:
diff --git a/grc/core/generator/FlowGraphProxy.py b/grc/core/generator/FlowGraphProxy.py
index c673c5b005..a23c6d84ab 100644
--- a/grc/core/generator/FlowGraphProxy.py
+++ b/grc/core/generator/FlowGraphProxy.py
@@ -117,7 +117,7 @@ class FlowGraphProxy(object):
# using the block param 'type' instead of the port domain here
# to emphasize that hier block generation is domain agnostic
is_message_pad = pad.get_param('type').get_evaluated() == "message"
- if port.get_parent() == pad:
+ if port.parent == pad:
if is_message_pad:
key = pad.get_param('label').get_value()
else:
diff --git a/grc/core/generator/Generator.py b/grc/core/generator/Generator.py
index 97729b3ada..c3308d6c32 100644
--- a/grc/core/generator/Generator.py
+++ b/grc/core/generator/Generator.py
@@ -175,7 +175,7 @@ class TopBlockGenerator(object):
for connection in virtual:
source = connection.source.resolve_virtual_source()
sink = connection.sink_port
- resolved = fg.get_parent().Connection(flow_graph=fg, porta=source, portb=sink)
+ resolved = fg.parent.Connection(flow_graph=fg, porta=source, portb=sink)
connections.append(resolved)
# Remove the virtual connection
connections.remove(connection)
@@ -202,7 +202,7 @@ class TopBlockGenerator(object):
# Ignore disabled connections
continue
sink_port = sink.sink_port
- connection = fg.get_parent().Connection(flow_graph=fg, porta=source_port, portb=sink_port)
+ connection = fg.parent.Connection(flow_graph=fg, porta=source_port, portb=sink_port)
connections.append(connection)
# Remove this sink connection
connections.remove(sink)
@@ -215,7 +215,7 @@ class TopBlockGenerator(object):
c.source_block.get_id(), c.sink_block.get_id()
))
- connection_templates = fg.get_parent().connection_templates
+ connection_templates = fg.parent.connection_templates
msgs = [c for c in fg.get_enabled_connections() if c.is_msg()]
# List of variable names
@@ -265,9 +265,8 @@ class HierBlockGenerator(TopBlockGenerator):
file_path: where to write the py file (the xml goes into HIER_BLOCK_LIB_DIR)
"""
TopBlockGenerator.__init__(self, flow_graph, file_path)
- platform = flow_graph.get_parent()
- hier_block_lib_dir = platform.config.hier_block_lib_dir
+ hier_block_lib_dir = flow_graph.parent_platform.config.hier_block_lib_dir
if not os.path.exists(hier_block_lib_dir):
os.mkdir(hier_block_lib_dir)
diff --git a/grc/core/generator/flow_graph.tmpl b/grc/core/generator/flow_graph.tmpl
index 21bcb601a2..c86808455b 100644
--- a/grc/core/generator/flow_graph.tmpl
+++ b/grc/core/generator/flow_graph.tmpl
@@ -241,11 +241,11 @@ gr.io_signaturev($(len($io_sigs)), $(len($io_sigs)), [$(', '.join($size_strs))])
## However, port names for IO pads should be self.
########################################################
#def make_port_sig($port)
- #if $port.get_parent().get_key() in ('pad_source', 'pad_sink')
+ #if $port.parent.get_key() in ('pad_source', 'pad_sink')
#set block = 'self'
#set key = $flow_graph.get_pad_port_global_key($port)
#else
- #set block = 'self.' + $port.get_parent().get_id()
+ #set block = 'self.' + $port.parent.get_id()
#set key = $port.get_key()
#end if
#if not $key.isdigit()
diff --git a/grc/gui/ActionHandler.py b/grc/gui/ActionHandler.py
index 3c6b57b482..8d4dc7841f 100644
--- a/grc/gui/ActionHandler.py
+++ b/grc/gui/ActionHandler.py
@@ -384,12 +384,11 @@ class ActionHandler:
# Window stuff
##################################################
elif action == Actions.ABOUT_WINDOW_DISPLAY:
- platform = flow_graph.get_parent()
- Dialogs.AboutDialog(platform.config)
+ Dialogs.AboutDialog(self.platform.config)
elif action == Actions.HELP_WINDOW_DISPLAY:
Dialogs.HelpDialog()
elif action == Actions.TYPES_WINDOW_DISPLAY:
- Dialogs.TypesDialog(flow_graph.get_parent())
+ Dialogs.TypesDialog(self.platform)
elif action == Actions.ERRORS_WINDOW_DISPLAY:
Dialogs.ErrorsDialog(flow_graph)
elif action == Actions.TOGGLE_CONSOLE_WINDOW:
diff --git a/grc/gui/Block.py b/grc/gui/Block.py
index a6c31cd473..49bba4f3db 100644
--- a/grc/gui/Block.py
+++ b/grc/gui/Block.py
@@ -181,7 +181,7 @@ class Block(Element, _Block):
# Show the flow graph complexity on the top block if enabled
if Actions.TOGGLE_SHOW_FLOWGRAPH_COMPLEXITY.get_active() and self.get_key() == "options":
- complexity = calculate_flowgraph_complexity(self.get_parent())
+ complexity = calculate_flowgraph_complexity(self.parent)
markups.append(
'<span foreground="#444" size="medium" font_desc="{font}">'
'<b>Complexity: {num}bal</b></span>'.format(num=num_to_str(complexity), font=BLOCK_FONT)
@@ -201,7 +201,7 @@ class Block(Element, _Block):
width, height = layout.get_pixel_size()
if width and height:
padding = BLOCK_LABEL_PADDING
- pixmap = self.get_parent().new_pixmap(width + 2 * padding,
+ pixmap = self.parent.new_pixmap(width + 2 * padding,
height + 2 * padding)
gc = pixmap.new_gc()
gc.set_foreground(Colors.COMMENT_BACKGROUND_COLOR)
diff --git a/grc/gui/FlowGraph.py b/grc/gui/FlowGraph.py
index 37a233f825..8e4a26ea7e 100644
--- a/grc/gui/FlowGraph.py
+++ b/grc/gui/FlowGraph.py
@@ -88,12 +88,12 @@ class FlowGraph(Element, _Flowgraph):
return block_id
def install_external_editor(self, param):
- target = (param.get_parent().get_id(), param.get_key())
+ target = (param.parent_block.get_id(), param.get_key())
if target in self._external_updaters:
editor = self._external_updaters[target]
else:
- config = self.get_parent().config
+ config = self.parent_platform.config
editor = (find_executable(config.editor) or
Dialogs.ChooseEditorDialog(config))
if not editor:
@@ -112,7 +112,7 @@ class FlowGraph(Element, _Flowgraph):
# Problem launching the editor. Need to select a new editor.
Messages.send('>>> Error opening an external editor. Please select a different editor.\n')
# Reset the editor to force the user to select a new one.
- self.get_parent().config.editor = ''
+ self.parent_platform.config.editor = ''
def handle_external_editor_change(self, new_value, target):
try:
@@ -452,9 +452,9 @@ class FlowGraph(Element, _Flowgraph):
for selected in selected_elements:
if selected in elements: continue
selected_elements.remove(selected)
- if self._old_selected_port and self._old_selected_port.get_parent() not in elements:
+ if self._old_selected_port and self._old_selected_port.parent not in elements:
self._old_selected_port = None
- if self._new_selected_port and self._new_selected_port.get_parent() not in elements:
+ if self._new_selected_port and self._new_selected_port.parent not in elements:
self._new_selected_port = None
#update highlighting
for element in elements:
@@ -532,7 +532,7 @@ class FlowGraph(Element, _Flowgraph):
#update the selected port information
if selected_element.is_port:
if not coor_m: selected_port = selected_element
- selected_element = selected_element.get_parent()
+ selected_element = selected_element.parent_block
selected.add(selected_element)
#place at the end of the list
self.get_elements().remove(element)
diff --git a/grc/gui/NotebookPage.py b/grc/gui/NotebookPage.py
index 757dcbc0f8..4745035aff 100644
--- a/grc/gui/NotebookPage.py
+++ b/grc/gui/NotebookPage.py
@@ -49,7 +49,7 @@ class NotebookPage(Gtk.HBox):
self.saved = True
# import the file
- initial_state = flow_graph.get_parent().parse_flow_graph(file_path)
+ initial_state = flow_graph.parent_platform.parse_flow_graph(file_path)
flow_graph.import_data(initial_state)
self.state_cache = StateCache(initial_state)
@@ -97,7 +97,7 @@ class NotebookPage(Gtk.HBox):
Returns:
generator
"""
- platform = self.flow_graph.get_parent()
+ platform = self.flow_graph.parent_platform
return platform.Generator(self.flow_graph, self.file_path)
def _handle_button(self, button):
diff --git a/grc/gui/Param.py b/grc/gui/Param.py
index 137c5e057b..a630f5faa3 100644
--- a/grc/gui/Param.py
+++ b/grc/gui/Param.py
@@ -62,7 +62,7 @@ class Param(Element, _Param):
return input_widget_cls(self, *args, **kwargs)
def format_label_markup(self, have_pending_changes=False):
- block = self.get_parent()
+ block = self.parent
# fixme: using non-public attribute here
has_callback = \
hasattr(block, 'get_callbacks') and \
diff --git a/grc/gui/ParamWidgets.py b/grc/gui/ParamWidgets.py
index e0979e19f3..fbbfa93d1d 100644
--- a/grc/gui/ParamWidgets.py
+++ b/grc/gui/ParamWidgets.py
@@ -173,8 +173,7 @@ class PythonEditorParam(InputParam):
self.pack_start(button, True)
def open_editor(self, widget=None):
- flowgraph = self.param.get_parent().get_parent()
- flowgraph.install_external_editor(self.param)
+ self.param.parent_flowgraph.install_external_editor(self.param)
def get_text(self):
pass # we never update the value from here
@@ -274,9 +273,8 @@ class FileParam(EntryParam):
if self.param.get_key() == 'qt_qss_theme':
dirname = os.path.dirname(dirname) # trim filename
if not os.path.exists(dirname):
- platform = self.param.get_parent().get_parent().get_parent()
- dirname = os.path.join(platform.config.install_prefix,
- '/share/gnuradio/themes')
+ config = self.param.parent_platform.config
+ dirname = os.path.join(config.install_prefix, '/share/gnuradio/themes')
if not os.path.exists(dirname):
dirname = os.getcwd() # fix bad paths
diff --git a/grc/gui/Port.py b/grc/gui/Port.py
index 0fa35573c1..8c4500f960 100644
--- a/grc/gui/Port.py
+++ b/grc/gui/Port.py
@@ -67,8 +67,8 @@ class Port(_Port, Element):
#get current rotation
rotation = self.get_rotation()
#get all sibling ports
- ports = self.get_parent().get_sources_gui() \
- if self.is_source else self.get_parent().get_sinks_gui()
+ ports = self.parent.get_sources_gui() \
+ if self.is_source else self.parent.get_sinks_gui()
ports = [p for p in ports if not p.get_hide()]
#get the max width
self.W = max([port.W for port in ports] + [PORT_MIN_WIDTH])
@@ -85,10 +85,10 @@ class Port(_Port, Element):
index = len(ports)-index-1
port_separation = PORT_SEPARATION \
- if not self.get_parent().has_busses[self.is_source] \
+ if not self.parent.has_busses[self.is_source] \
else max([port.H for port in ports]) + PORT_SPACING
- offset = (self.get_parent().H - (len(ports)-1)*port_separation - self.H)/2
+ offset = (self.parent.H - (len(ports)-1)*port_separation - self.H)/2
#create areas and connector coordinates
if (self.is_sink and rotation == 0) or (self.is_source and rotation == 180):
x = -W
@@ -96,7 +96,7 @@ class Port(_Port, Element):
self.add_area((x, y), (W, self.H))
self._connector_coordinate = (x-1, y+self.H/2)
elif (self.is_source and rotation == 0) or (self.is_sink and rotation == 180):
- x = self.get_parent().W
+ x = self.parent.W
y = port_separation*index+offset
self.add_area((x, y), (W, self.H))
self._connector_coordinate = (x+1+W, y+self.H/2)
@@ -106,7 +106,7 @@ class Port(_Port, Element):
self.add_area((x, y), (self.H, W))
self._connector_coordinate = (x+self.H/2, y-1)
elif (self.is_sink and rotation == 90) or (self.is_source and rotation == 270):
- y = self.get_parent().W
+ y = self.parent.W
x = port_separation*index+offset
self.add_area((x, y), (self.H, W))
self._connector_coordinate = (x+self.H/2, y+1+W)
@@ -125,7 +125,7 @@ class Port(_Port, Element):
"""
border_color = (
Colors.HIGHLIGHT_COLOR if self.is_highlighted() else
- Colors.MISSING_BLOCK_BORDER_COLOR if self.get_parent().is_dummy_block else
+ Colors.MISSING_BLOCK_BORDER_COLOR if self.parent.is_dummy_block else
Colors.BORDER_COLOR
)
Element.draw(self, widget, cr, border_color, self._bg_color)
@@ -186,7 +186,7 @@ class Port(_Port, Element):
Returns:
the parent's rotation
"""
- return self.get_parent().get_rotation()
+ return self.parent.get_rotation()
def move(self, delta_coor):
"""
@@ -195,7 +195,7 @@ class Port(_Port, Element):
Args:
delta_corr: the (delta_x, delta_y) tuple
"""
- self.get_parent().move(delta_coor)
+ self.parent.move(delta_coor)
def rotate(self, direction):
"""
@@ -204,7 +204,7 @@ class Port(_Port, Element):
Args:
direction: degrees to rotate
"""
- self.get_parent().rotate(direction)
+ self.parent.rotate(direction)
def get_coordinate(self):
"""
@@ -213,7 +213,7 @@ class Port(_Port, Element):
Returns:
the parents coordinate
"""
- return self.get_parent().get_coordinate()
+ return self.parent.get_coordinate()
def set_highlighted(self, highlight):
"""
@@ -222,7 +222,7 @@ class Port(_Port, Element):
Args:
highlight: true to enable highlighting
"""
- self.get_parent().set_highlighted(highlight)
+ self.parent.set_highlighted(highlight)
def is_highlighted(self):
"""
@@ -231,7 +231,7 @@ class Port(_Port, Element):
Returns:
the parent's highlighting status
"""
- return self.get_parent().is_highlighted()
+ return self.parent.is_highlighted()
def _label_hidden(self):
"""