summaryrefslogtreecommitdiff
path: root/grc/core
diff options
context:
space:
mode:
authorSebastian Koslowski <koslowski@kit.edu>2016-04-05 22:03:43 +0200
committerSebastian Koslowski <koslowski@kit.edu>2016-05-27 21:58:27 +0200
commit1937f756fd4027ace86316fc6fb1433cd832e6eb (patch)
treef4dfcf25ae5033db66484498c1864eb002c0aed3 /grc/core
parentcc02c4b22a2e17eddfc05863a9f17fb9a5778361 (diff)
grc: separate core and OOT block trees via the category of each block
Each block get assigned a module based on the root of its category. The category is set via a block_tree.xml or else from its <category> tag. The category root is only interpreted as module name if it is in square brackets. Else the default module 'Others' is used.
Diffstat (limited to 'grc/core')
-rw-r--r--grc/core/Block.py9
-rw-r--r--grc/core/Constants.py1
-rw-r--r--grc/core/Platform.py82
-rw-r--r--grc/core/utils/odict.py4
4 files changed, 42 insertions, 54 deletions
diff --git a/grc/core/Block.py b/grc/core/Block.py
index f67d990857..8a683a2b6b 100644
--- a/grc/core/Block.py
+++ b/grc/core/Block.py
@@ -79,7 +79,8 @@ class Block(Element):
sinks = n.findall('sink')
self._name = n.find('name')
self._key = n.find('key')
- self._category = n.find('category') or ''
+ category = (n.find('category') or '').split('/')
+ self.category = [cat.strip() for cat in category if cat.strip()]
self._flags = n.find('flags') or ''
# Backwards compatibility
if n.find('throttle') and BLOCK_FLAG_THROTTLE not in self._flags:
@@ -594,12 +595,6 @@ class Block(Element):
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()
diff --git a/grc/core/Constants.py b/grc/core/Constants.py
index 462049cc73..eeb1d7f848 100644
--- a/grc/core/Constants.py
+++ b/grc/core/Constants.py
@@ -37,6 +37,7 @@ FLOW_GRAPH_FILE_FORMAT_VERSION = 1
# Param tabs
DEFAULT_PARAM_TAB = "General"
ADVANCED_PARAM_TAB = "Advanced"
+DEFAULT_BLOCK_MODULE_NAME = '(no module specified)'
# Port domains
GR_STREAM_DOMAIN = "gr_stream"
diff --git a/grc/core/Platform.py b/grc/core/Platform.py
index 5bcf79c4b2..9b25e67d65 100644
--- a/grc/core/Platform.py
+++ b/grc/core/Platform.py
@@ -67,15 +67,15 @@ class Platform(Element):
self._flow_graph = Element(self)
self._flow_graph.connections = []
- self.blocks = None
- self._blocks_n = None
- self._category_trees_n = None
+ self.blocks = odict()
+ self._blocks_n = odict()
+ self._block_categories = {}
self.domains = {}
self.connection_templates = {}
self._auto_hier_block_generate_chain = set()
- self.load_blocks()
+ self.build_block_library()
def __str__(self):
return 'Platform - {}({})'.format(self.config.key, self.config.name)
@@ -133,16 +133,17 @@ class Platform(Element):
self.load_block_xml(generator.get_file_path_xml())
return True
- def load_blocks(self):
+ def build_block_library(self):
"""load the blocks and block tree from the search paths"""
self._docstring_extractor.start()
# Reset
- self.blocks = odict()
- self._blocks_n = odict()
- self._category_trees_n = list()
+ self.blocks.clear()
+ self._blocks_n.clear()
+ self._block_categories.clear()
self.domains.clear()
self.connection_templates.clear()
ParseXML.xml_failures.clear()
+
# Try to parse and load blocks
for xml_file in self.iter_xml_files():
try:
@@ -158,6 +159,19 @@ class Platform(Element):
except Exception as e:
print >> sys.stderr, 'Warning: XML parsing failed:\n\t%r\n\tIgnoring: %s' % (e, xml_file)
+ # Add blocks to block tree
+ for key, block in self.blocks.iteritems():
+ category = self._block_categories.get(key, block.category)
+ # Blocks with empty categories are hidden
+ if not category:
+ continue
+ root = category[0]
+ if root.startswith('[') and root.endswith(']'):
+ category[0] = root[1:-1]
+ else:
+ category.insert(0, Constants.DEFAULT_BLOCK_MODULE_NAME)
+ block.category = category
+
self._docstring_extractor.finish()
# self._docstring_extractor.wait()
@@ -195,8 +209,19 @@ class Platform(Element):
def load_category_tree_xml(self, xml_file):
"""Validate and parse category tree file and add it to list"""
ParseXML.validate_dtd(xml_file, Constants.BLOCK_TREE_DTD)
- n = ParseXML.from_file(xml_file).find('cat')
- self._category_trees_n.append(n)
+ xml = ParseXML.from_file(xml_file)
+ path = []
+
+ def load_category(cat_n):
+ path.append(cat_n.find('name').strip())
+ for block_key in cat_n.findall('block'):
+ if block_key not in self._block_categories:
+ self._block_categories[block_key] = list(path)
+ for sub_cat_n in cat_n.findall('cat'):
+ load_category(sub_cat_n)
+ path.pop()
+
+ load_category(xml.find('cat'))
def load_domain_xml(self, xml_file):
"""Load a domain properties and connection templates from XML"""
@@ -241,43 +266,6 @@ class Platform(Element):
else:
self.connection_templates[key] = connection_n.find('make') or ''
- def load_block_tree(self, block_tree):
- """
- Load a block tree with categories and blocks.
- Step 1: Load all blocks from the xml specification.
- Step 2: Load blocks with builtin category specifications.
-
- Args:
- block_tree: the block tree object
- """
- # Recursive function to load categories and blocks
- def load_category(cat_n, parent=None):
- # Add this category
- parent = (parent or []) + [cat_n.find('name')]
- block_tree.add_block(parent)
- # Recursive call to load sub categories
- map(lambda c: load_category(c, parent), cat_n.findall('cat'))
- # Add blocks in this category
- for block_key in cat_n.findall('block'):
- if block_key not in self.blocks:
- print >> sys.stderr, 'Warning: Block key "{}" not found when loading category tree.'.format(block_key)
- continue
- block = self.blocks[block_key]
- # If it exists, the block's category shall not be overridden by the xml tree
- if not block.get_category():
- block.set_category(parent)
-
- # Recursively load the category trees and update the categories for each block
- for category_tree_n in self._category_trees_n:
- load_category(category_tree_n)
-
- # Add blocks to block tree
- for block in self.blocks.itervalues():
- # Blocks with empty categories are hidden
- if not block.get_category():
- continue
- block_tree.add_block(block.get_category(), block)
-
def _save_docstring_extraction_result(self, key, docstrings):
docs = {}
for match, docstring in docstrings.iteritems():
diff --git a/grc/core/utils/odict.py b/grc/core/utils/odict.py
index 20970e947c..85927e869f 100644
--- a/grc/core/utils/odict.py
+++ b/grc/core/utils/odict.py
@@ -109,3 +109,7 @@ class odict(DictMixin):
if isinstance(obj, list):
return obj
return [obj]
+
+ def clear(self):
+ self._data.clear()
+ del self._keys[:] \ No newline at end of file