From df4f5820cea5c8786f118bf94adb950afe6b2aab Mon Sep 17 00:00:00 2001 From: Sebastian Koslowski <koslowski@kit.edu> Date: Wed, 11 Nov 2015 18:48:28 +0100 Subject: grc: some clean-up --- grc/python/Generator.py | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'grc/python/Generator.py') diff --git a/grc/python/Generator.py b/grc/python/Generator.py index f064c7528f..ddd32ca355 100644 --- a/grc/python/Generator.py +++ b/grc/python/Generator.py @@ -24,6 +24,7 @@ import tempfile import shlex import codecs from distutils.spawn import find_executable + from Cheetah.Template import Template from .. gui import Messages @@ -152,11 +153,12 @@ class TopBlockGenerator(object): """ output = list() - title = self._flow_graph.get_option('title') or self._flow_graph.get_option('id').replace('_', ' ').title() - imports = self._flow_graph.get_imports() - variables = self._flow_graph.get_variables() - parameters = self._flow_graph.get_parameters() - monitors = self._flow_graph.get_monitors() + fg = self._flow_graph + title = fg.get_option('title') or fg.get_option('id').replace('_', ' ').title() + imports = fg.get_imports() + variables = fg.get_variables() + parameters = fg.get_parameters() + monitors = fg.get_monitors() # list of blocks not including variables and imports and parameters and disabled def _get_block_sort_text(block): @@ -172,7 +174,7 @@ class TopBlockGenerator(object): return code blocks = expr_utils.sort_objects( - filter(lambda b: b.get_enabled() and not b.get_bypassed(), self._flow_graph.iter_blocks()), + filter(lambda b: b.get_enabled() and not b.get_bypassed(), fg.iter_blocks()), lambda b: b.get_id(), _get_block_sort_text ) # List of regular blocks (all blocks minus the special ones) @@ -186,14 +188,14 @@ class TopBlockGenerator(object): # Filter out virtual sink connections cf = lambda c: not (c.is_bus() or c.is_msg() or c.get_sink().get_parent().is_virtual_sink()) - connections = filter(cf, self._flow_graph.get_enabled_connections()) + connections = filter(cf, fg.get_enabled_connections()) - # Get the virtual blocks and resolve their conenctions + # Get the virtual blocks and resolve their connections virtual = filter(lambda c: c.get_source().get_parent().is_virtual_source(), connections) for connection in virtual: source = connection.get_source().resolve_virtual_source() sink = connection.get_sink() - resolved = self._flow_graph.get_parent().Connection(flow_graph=self._flow_graph, porta=source, portb=sink) + resolved = fg.get_parent().Connection(flow_graph=fg, porta=source, portb=sink) connections.append(resolved) # Remove the virtual connection connections.remove(connection) @@ -203,7 +205,7 @@ class TopBlockGenerator(object): # that bypass the selected block and remove the existing ones. This allows adjacent # bypassed blocks to see the newly created connections to downstream blocks, # allowing them to correctly construct bypass connections. - bypassed_blocks = self._flow_graph.get_bypassed_blocks() + bypassed_blocks = fg.get_bypassed_blocks() for block in bypassed_blocks: # Get the upstream connection (off of the sink ports) # Use *connections* not get_connections() @@ -222,7 +224,7 @@ class TopBlockGenerator(object): # Ignore disabled connections continue sink_port = sink.get_sink() - connection = self._flow_graph.get_parent().Connection(flow_graph=self._flow_graph, porta=source_port, portb=sink_port) + connection = fg.get_parent().Connection(flow_graph=fg, porta=source_port, portb=sink_port) connections.append(connection) # Remove this sink connection connections.remove(sink) @@ -235,8 +237,8 @@ class TopBlockGenerator(object): c.get_source().get_parent().get_id(), c.get_sink().get_parent().get_id() )) - connection_templates = self._flow_graph.get_parent().get_connection_templates() - msgs = filter(lambda c: c.is_msg(), self._flow_graph.get_enabled_connections()) + connection_templates = fg.get_parent().get_connection_templates() + msgs = filter(lambda c: c.is_msg(), fg.get_enabled_connections()) # list of variable names var_ids = [var.get_id() for var in parameters + variables] # prepend self. @@ -244,7 +246,7 @@ class TopBlockGenerator(object): # list of callbacks callbacks = [ expr_utils.expr_replace(cb, replace_dict) - for cb in sum([block.get_callbacks() for block in self._flow_graph.get_enabled_blocks()], []) + for cb in sum([block.get_callbacks() for block in fg.get_enabled_blocks()], []) ] # map var id to callbacks var_id2cbs = dict([ @@ -255,7 +257,7 @@ class TopBlockGenerator(object): namespace = { 'title': title, 'imports': imports, - 'flow_graph': self._flow_graph, + 'flow_graph': fg, 'variables': variables, 'parameters': parameters, 'monitors': monitors, -- cgit v1.2.3 From 635bb2d62420001e4a0c34b3898aa259775e43b8 Mon Sep 17 00:00:00 2001 From: Sebastian Koslowski <koslowski@kit.edu> Date: Wed, 2 Dec 2015 17:45:06 +0100 Subject: grc: add embedded python modules --- grc/blocks/epy_module.xml | 33 +++++++++++++++++++++++++++++++++ grc/gui/Param.py | 2 +- grc/python/FlowGraph.py | 22 ++++++++++++++++++---- grc/python/Generator.py | 8 ++++++-- grc/python/Param.py | 2 +- 5 files changed, 59 insertions(+), 8 deletions(-) create mode 100644 grc/blocks/epy_module.xml (limited to 'grc/python/Generator.py') diff --git a/grc/blocks/epy_module.xml b/grc/blocks/epy_module.xml new file mode 100644 index 0000000000..6d6d71804c --- /dev/null +++ b/grc/blocks/epy_module.xml @@ -0,0 +1,33 @@ +<?xml version="1.0"?> +<block> + <name>Python Module</name> + <key>epy_module</key> + <category>Misc</category> + <import>import $id # embedded python module</import> + <make></make> + <param> + <name>Code</name> + <key>source_code</key> + <value># this module will be imported in the into your flowgraph</value> + <type>_multiline_python_external</type> + <hide>part</hide> + </param> + <doc>This block lets you embed a python module in your flowgraph. + +Code you put in this module is accessible in other blocks using the ID of this +block. Example: + +If you put + + a = 2 + + def double(arg): + return 2 * arg + +in a Python Module Block with the ID 'stuff' you can use code like + + stuff.a # evals to 2 + stuff.double(3) # evals to 6 + +to set parameters of other blocks in your flowgraph.</doc> +</block> diff --git a/grc/gui/Param.py b/grc/gui/Param.py index 515c345a73..6884d6530a 100644 --- a/grc/gui/Param.py +++ b/grc/gui/Param.py @@ -345,7 +345,7 @@ class FileParam(EntryParam): PARAM_MARKUP_TMPL="""\ #set $foreground = $param.is_valid() and 'black' or 'red' -<span foreground="$foreground" font_desc="$font"><b>$encode($param.get_name()): </b>$encode(repr($param))</span>""" +<span foreground="$foreground" font_desc="$font"><b>$encode($param.get_name()): </b>$encode(repr($param).replace('\\n',' '))</span>""" PARAM_LABEL_MARKUP_TMPL="""\ #set $foreground = $modified and 'blue' or $param.is_valid() and 'black' or 'red' diff --git a/grc/python/FlowGraph.py b/grc/python/FlowGraph.py index bedf9ccf33..686dae70fa 100644 --- a/grc/python/FlowGraph.py +++ b/grc/python/FlowGraph.py @@ -17,6 +17,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA """ import re +import imp from operator import methodcaller from . import expr_utils @@ -203,6 +204,12 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph): self.iter_enabled_blocks()) return monitors + def get_python_modules(self): + """Iterate over custom code block ID and Source""" + for block in self.iter_enabled_blocks(): + if block.get_key() == 'epy_module': + yield block.get_id(), block.get_param('source_code').get_value() + def get_bussink(self): bussink = filter(lambda b: _bussink_searcher.search(b.get_key()), self.get_enabled_blocks()) @@ -213,8 +220,6 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph): return False - - def get_bussrc(self): bussrc = filter(lambda b: _bussrc_searcher.search(b.get_key()), self.get_enabled_blocks()) @@ -278,9 +283,18 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph): #reload namespace n = dict() #load imports - for imp in self.get_imports(): - try: exec imp in n + for code in self.get_imports(): + try: exec code in n except: pass + + for id, code in self.get_python_modules(): + try: + module = imp.new_module(id) + exec code in module.__dict__ + n[id] = module + except: + pass + #load parameters np = dict() for parameter in self.get_parameters(): diff --git a/grc/python/Generator.py b/grc/python/Generator.py index ddd32ca355..d688beba15 100644 --- a/grc/python/Generator.py +++ b/grc/python/Generator.py @@ -181,10 +181,14 @@ class TopBlockGenerator(object): blocks = filter(lambda b: b not in (imports + parameters), blocks) for block in blocks: - if block.get_key() == 'epy_block': - file_path = os.path.join(self._dirname, block.get_id() + '.py') + key = block.get_key() + file_path = os.path.join(self._dirname, block.get_id() + '.py') + if key == 'epy_block': src = block.get_param('_source_code').get_value() output.append((file_path, src)) + elif key == 'epy_module': + src = block.get_param('source_code').get_value() + output.append((file_path, src)) # Filter out virtual sink connections cf = lambda c: not (c.is_bus() or c.is_msg() or c.get_sink().get_parent().is_virtual_sink()) diff --git a/grc/python/Param.py b/grc/python/Param.py index 746f677e46..e60f613f00 100644 --- a/grc/python/Param.py +++ b/grc/python/Param.py @@ -31,7 +31,7 @@ from Constants import VECTOR_TYPES, COMPLEX_TYPES, REAL_TYPES, INT_TYPES from gnuradio import eng_notation _check_id_matcher = re.compile('^[a-z|A-Z]\w*$') -_show_id_matcher = re.compile('^(variable\w*|parameter|options|notebook)$') +_show_id_matcher = re.compile('^(variable\w*|parameter|options|notebook|epy_module)$') #blacklist certain ids, its not complete, but should help -- cgit v1.2.3