diff options
author | Sebastian Koslowski <koslowski@kit.edu> | 2015-10-12 16:45:05 +0200 |
---|---|---|
committer | Sebastian Koslowski <koslowski@kit.edu> | 2015-11-13 22:49:37 +0100 |
commit | 19944f6328f1a852ed3384e750cb2b61da50d5bf (patch) | |
tree | fbbe9b612560a7b4350e2064bc001dfa85ec630f /grc | |
parent | 5c544a06e2d129a5ac0d2cfe6fc0b4d32e8a1849 (diff) |
grc: auto-generate missing hier_blocks
Diffstat (limited to 'grc')
-rw-r--r-- | grc/base/Platform.py | 2 | ||||
-rw-r--r-- | grc/blocks/options.xml | 8 | ||||
-rw-r--r-- | grc/python/FlowGraph.py | 21 | ||||
-rw-r--r-- | grc/python/Platform.py | 53 |
4 files changed, 82 insertions, 2 deletions
diff --git a/grc/base/Platform.py b/grc/base/Platform.py index db2bb76888..0cc3fcf1dd 100644 --- a/grc/base/Platform.py +++ b/grc/base/Platform.py @@ -122,7 +122,7 @@ class Platform(_Element): # get block instance and add it to the list of blocks block = self.Block(self._flow_graph, n) key = block.get_key() - if key in self.get_block_keys(): # test against repeated keys + if key in self._blocks: print >> sys.stderr, 'Warning: Block with key "%s" already exists.\n\tIgnoring: %s' % (key, xml_file) else: # store the block self._blocks[key] = block diff --git a/grc/blocks/options.xml b/grc/blocks/options.xml index 09cc74d151..937cfe82ea 100644 --- a/grc/blocks/options.xml +++ b/grc/blocks/options.xml @@ -207,6 +207,14 @@ part#slurp #end if</hide> <tab>Advanced</tab> </param> + <param> + <name>Hier Block Source Path</name> + <key>hier_block_src_path</key> + <value>.:</value> + <type>string</type> + <hide>part</hide> + <tab>Advanced</tab> + </param> <check>not $window_size or len($window_size) == 2</check> <check>not $window_size or 300 <= $(window_size)[0] <= 4096</check> <check>not $window_size or 300 <= $(window_size)[1] <= 4096</check> diff --git a/grc/python/FlowGraph.py b/grc/python/FlowGraph.py index 49530af8a3..9b55cb6d43 100644 --- a/grc/python/FlowGraph.py +++ b/grc/python/FlowGraph.py @@ -30,9 +30,11 @@ _bussrc_searcher = re.compile('^(bus_source)$') _bus_struct_sink_searcher = re.compile('^(bus_structure_sink)$') _bus_struct_src_searcher = re.compile('^(bus_structure_source)$') + class FlowGraph(_FlowGraph, _GUIFlowGraph): def __init__(self, **kwargs): + self.grc_file_path = '' _FlowGraph.__init__(self, **kwargs) _GUIFlowGraph.__init__(self) self._eval_cache = dict() @@ -232,7 +234,6 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph): return bussrc - def rewrite(self): """ Flag the namespace to be renewed. @@ -299,3 +300,21 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph): #evaluate e = self._eval(expr, self.n, self.n_hash) return e + + def get_new_block(self, key): + """Try to auto-generate the block from file if missing""" + block = _FlowGraph.get_new_block(self, key) + if not block: + platform = self.get_parent() + # we're before the initial fg rewrite(), so no evaluated values! + # --> use raw value instead + path_param = self._options_block.get_param('hier_block_src_path') + file_path = platform.find_file_in_paths( + filename=key + '.' + platform.get_key(), + paths=path_param.get_value(), + cwd=self.grc_file_path + ) + if file_path: # grc file found. load and get block + platform.load_and_generate_flow_graph(file_path) + block = _FlowGraph.get_new_block(self, key) # can be None + return block diff --git a/grc/python/Platform.py b/grc/python/Platform.py index 21fd7ef8d2..1d932761d8 100644 --- a/grc/python/Platform.py +++ b/grc/python/Platform.py @@ -24,6 +24,7 @@ from gnuradio import gr from .. base.Platform import Platform as _Platform from .. gui.Platform import Platform as _GUIPlatform +from .. gui import Messages from . import extract_docs from .FlowGraph import FlowGraph as _FlowGraph @@ -84,6 +85,7 @@ class Platform(_Platform, _GUIPlatform): self, prefs_file=PREFS_FILE ) + self._auto_hier_block_generate_chain = set() @staticmethod def _move_old_pref_file(): @@ -111,6 +113,57 @@ class Platform(_Platform, _GUIPlatform): ) return block + @staticmethod + def find_file_in_paths(filename, paths, cwd): + """Checks the provided paths relative to cwd for a certain filename""" + if not os.path.isdir(cwd): + cwd = os.path.dirname(cwd) + if isinstance(paths, str): + paths = (p for p in paths.split(':') if p) + + for path in paths: + path = os.path.expanduser(path) + if not os.path.isabs(path): + path = os.path.normpath(os.path.join(cwd, path)) + file_path = os.path.join(path, filename) + if os.path.exists(os.path.normpath(file_path)): + return file_path + + def load_and_generate_flow_graph(self, file_path): + """Loads a flowgraph from file and generates it""" + Messages.set_indent(len(self._auto_hier_block_generate_chain)) + Messages.send('>>> Loading: %r\n' % file_path) + if file_path in self._auto_hier_block_generate_chain: + Messages.send(' >>> Warning: cyclic hier_block dependency\n') + return False + self._auto_hier_block_generate_chain.add(file_path) + try: + flow_graph = self.get_new_flow_graph() + flow_graph.grc_file_path = file_path + # other, nested higiter_blocks might be auto-loaded here + flow_graph.import_data(self.parse_flow_graph(file_path)) + flow_graph.rewrite() + flow_graph.validate() + if not flow_graph.is_valid(): + raise Exception('Flowgraph invalid') + except Exception as e: + Messages.send('>>> Load Error: %r: %s\n' % (file_path, str(e))) + return False + finally: + self._auto_hier_block_generate_chain.discard(file_path) + Messages.set_indent(len(self._auto_hier_block_generate_chain)) + + try: + Messages.send('>>> Generating: %r\n' % file_path) + generator = self.get_generator()(flow_graph, file_path) + generator.write() + except Exception as e: + Messages.send('>>> Generate Error: %r: %s\n' % (file_path, str(e))) + return False + + self.load_block_xml(generator.get_file_path_xml()) + return True + ############################################## # Constructors ############################################## |