summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Koslowski <koslowski@kit.edu>2015-10-12 16:45:05 +0200
committerSebastian Koslowski <koslowski@kit.edu>2015-11-13 22:49:37 +0100
commit19944f6328f1a852ed3384e750cb2b61da50d5bf (patch)
treefbbe9b612560a7b4350e2064bc001dfa85ec630f
parent5c544a06e2d129a5ac0d2cfe6fc0b4d32e8a1849 (diff)
grc: auto-generate missing hier_blocks
-rw-r--r--grc/base/Platform.py2
-rw-r--r--grc/blocks/options.xml8
-rw-r--r--grc/python/FlowGraph.py21
-rw-r--r--grc/python/Platform.py53
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 &lt;= $(window_size)[0] &lt;= 4096</check>
<check>not $window_size or 300 &lt;= $(window_size)[1] &lt;= 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
##############################################