From 9988664127b367fa8fee4409f8460673d6f265e1 Mon Sep 17 00:00:00 2001 From: jblum Date: Tue, 23 Jun 2009 20:38:18 +0000 Subject: Merging r11186:11273 from grc branch. Fixes, features, and reorganization for grc. Minor fixes and features for wxgui forms. git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@11274 221aa14e-8319-0410-a670-987f0aec2ac5 --- grc/python/FlowGraph.py | 155 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 grc/python/FlowGraph.py (limited to 'grc/python/FlowGraph.py') diff --git a/grc/python/FlowGraph.py b/grc/python/FlowGraph.py new file mode 100644 index 000000000..47089a305 --- /dev/null +++ b/grc/python/FlowGraph.py @@ -0,0 +1,155 @@ +""" +Copyright 2008, 2009 Free Software Foundation, Inc. +This file is part of GNU Radio + +GNU Radio Companion is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +GNU Radio Companion is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA +""" + +import expr_utils +from .. base.FlowGraph import FlowGraph as _FlowGraph +from Block import Block +from Connection import Connection +import re + +_variable_matcher = re.compile('^(variable\w*)$') +_parameter_matcher = re.compile('^(parameter)$') + +class FlowGraph(_FlowGraph): + + _eval_cache = dict() + def _eval(self, code, namespace, namespace_hash): + """ + Evaluate the code with the given namespace. + @param code a string with python code + @param namespace a dict representing the namespace + @param namespace_hash a unique hash for the namespace + @return the resultant object + """ + my_hash = hash(code) ^ namespace_hash + #cache if does not exist + if not self._eval_cache.has_key(my_hash): + self._eval_cache[my_hash] = eval(code, namespace, namespace) + #return from cache + return self._eval_cache[my_hash] + + def _get_io_signature(self, pad_key): + """ + Get an io signature for this flow graph. + The pad key determines the directionality of the io signature. + @param pad_key a string of pad_source or pad_sink + @return a dict with: type, nports, vlen, size + """ + pads = filter(lambda b: b.get_key() == pad_key, self.get_enabled_blocks()) + if not pads: return { + 'nports': '0', + 'type': '', + 'vlen': '0', + 'size': '0', + } + pad = pads[0] #take only the first, user should not have more than 1 + #load io signature + return { + 'nports': str(pad.get_param('nports').get_evaluated()), + 'type': str(pad.get_param('type').get_evaluated()), + 'vlen': str(pad.get_param('vlen').get_evaluated()), + 'size': pad.get_param('type').get_opt('size'), + } + + def get_input_signature(self): + """ + Get the io signature for the input side of this flow graph. + The io signature with be "0", "0" if no pad source is present. + @return a string tuple of type, num_ports, port_size + """ + return self._get_io_signature('pad_source') + + def get_output_signature(self): + """ + Get the io signature for the output side of this flow graph. + The io signature with be "0", "0" if no pad sink is present. + @return a string tuple of type, num_ports, port_size + """ + return self._get_io_signature('pad_sink') + + def get_imports(self): + """ + Get a set of all import statments in this flow graph namespace. + @return a set of import statements + """ + imports = sum([block.get_imports() for block in self.get_enabled_blocks()], []) + imports = sorted(set(imports)) + return imports + + def get_variables(self): + """ + Get a list of all variables in this flow graph namespace. + Exclude paramterized variables. + @return a sorted list of variable blocks in order of dependency (indep -> dep) + """ + variables = filter(lambda b: _variable_matcher.match(b.get_key()), self.get_enabled_blocks()) + #map var id to variable block + id2var = dict([(var.get_id(), var) for var in variables]) + #map var id to variable code + #variable code is a concatenation of all param code (without the id param) + id2expr = dict([(var.get_id(), var.get_var_make()) for var in variables]) + #sort according to dependency + sorted_ids = expr_utils.sort_variables(id2expr) + #create list of sorted variable blocks + variables = [id2var[id] for id in sorted_ids] + return variables + + def get_parameters(self): + """ + Get a list of all paramterized variables in this flow graph namespace. + @return a list of paramterized variables + """ + parameters = filter(lambda b: _parameter_matcher.match(b.get_key()), self.get_enabled_blocks()) + return parameters + + def evaluate(self, expr): + """ + Evaluate the expression. + @param expr the string expression + @throw Exception bad expression + @return the evaluated data + """ + if self.is_flagged(): + self.deflag() + #reload namespace + n = dict() + #load imports + for imp in self.get_imports(): + try: exec imp in n + except: pass + #load parameters + np = dict() + for parameter in self.get_parameters(): + try: + e = eval(parameter.get_param('value').to_code(), n, n) + np[parameter.get_id()] = e + except: pass + n.update(np) #merge param namespace + #load variables + for variable in self.get_variables(): + try: + e = eval(variable.get_param('value').to_code(), n, n) + n[variable.get_id()] = e + except: pass + #make namespace public + self.n = n + self.n_hash = hash(str(n)) + #evaluate + e = self._eval(expr, self.n, self.n_hash) + return e -- cgit From 25c5d91fb7c4b54f1e7d77fd9af213a3675a8339 Mon Sep 17 00:00:00 2001 From: jblum Date: Mon, 6 Jul 2009 02:28:52 +0000 Subject: Merged r11309:11357 from grc branch. Adds notebook cabability to grc and its wxgui windows/controls. git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@11358 221aa14e-8319-0410-a670-987f0aec2ac5 --- grc/python/FlowGraph.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'grc/python/FlowGraph.py') diff --git a/grc/python/FlowGraph.py b/grc/python/FlowGraph.py index 47089a305..8cad8be49 100644 --- a/grc/python/FlowGraph.py +++ b/grc/python/FlowGraph.py @@ -99,16 +99,7 @@ class FlowGraph(_FlowGraph): @return a sorted list of variable blocks in order of dependency (indep -> dep) """ variables = filter(lambda b: _variable_matcher.match(b.get_key()), self.get_enabled_blocks()) - #map var id to variable block - id2var = dict([(var.get_id(), var) for var in variables]) - #map var id to variable code - #variable code is a concatenation of all param code (without the id param) - id2expr = dict([(var.get_id(), var.get_var_make()) for var in variables]) - #sort according to dependency - sorted_ids = expr_utils.sort_variables(id2expr) - #create list of sorted variable blocks - variables = [id2var[id] for id in sorted_ids] - return variables + return expr_utils.sort_objects(variables, lambda v: v.get_id(), lambda v: v.get_var_make()) def get_parameters(self): """ -- cgit From 152fcbc219cd2e4f6df7b38843844bc85fdf2bc2 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sun, 30 Aug 2009 10:34:10 -0700 Subject: Switched the python classes to inherit from the base and gui classes. Use only **kwargs so all contructor parameters must be passed with keys. Moved gui input forms classes from base to gui param module. --- grc/python/FlowGraph.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'grc/python/FlowGraph.py') diff --git a/grc/python/FlowGraph.py b/grc/python/FlowGraph.py index 8cad8be49..96188b816 100644 --- a/grc/python/FlowGraph.py +++ b/grc/python/FlowGraph.py @@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA import expr_utils from .. base.FlowGraph import FlowGraph as _FlowGraph +from .. gui.FlowGraph import FlowGraph as _GUIFlowGraph from Block import Block from Connection import Connection import re @@ -26,7 +27,11 @@ import re _variable_matcher = re.compile('^(variable\w*)$') _parameter_matcher = re.compile('^(parameter)$') -class FlowGraph(_FlowGraph): +class FlowGraph(_FlowGraph, _GUIFlowGraph): + + def __init__(self, **kwargs): + _FlowGraph.__init__(self, **kwargs) + _GUIFlowGraph.__init__(self) _eval_cache = dict() def _eval(self, code, namespace, namespace_hash): -- cgit From 30513fdc9afa3d8e9d4dce4214299d89aed3c409 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Wed, 2 Sep 2009 13:16:47 -0700 Subject: Removed the flagging api and usage from the base classes. Far better to flag the namespace for renewing once in the flowgraph.py --- grc/python/FlowGraph.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'grc/python/FlowGraph.py') diff --git a/grc/python/FlowGraph.py b/grc/python/FlowGraph.py index 96188b816..6b2936c75 100644 --- a/grc/python/FlowGraph.py +++ b/grc/python/FlowGraph.py @@ -32,8 +32,8 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph): def __init__(self, **kwargs): _FlowGraph.__init__(self, **kwargs) _GUIFlowGraph.__init__(self) + self._eval_cache = dict() - _eval_cache = dict() def _eval(self, code, namespace, namespace_hash): """ Evaluate the code with the given namespace. @@ -114,6 +114,13 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph): parameters = filter(lambda b: _parameter_matcher.match(b.get_key()), self.get_enabled_blocks()) return parameters + def rewrite(self): + """ + Flag the namespace to be renewed. + """ + self._renew_eval_ns = True + _FlowGraph.rewrite(self) + def evaluate(self, expr): """ Evaluate the expression. @@ -121,8 +128,8 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph): @throw Exception bad expression @return the evaluated data """ - if self.is_flagged(): - self.deflag() + if self._renew_eval_ns: + self._renew_eval_ns = False #reload namespace n = dict() #load imports -- cgit From 4cc3667b348d58ef4fb30f0ecbe494cdb109fc83 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sat, 5 Sep 2009 00:54:56 -0700 Subject: better error msg for empty statements --- grc/python/FlowGraph.py | 1 + 1 file changed, 1 insertion(+) (limited to 'grc/python/FlowGraph.py') diff --git a/grc/python/FlowGraph.py b/grc/python/FlowGraph.py index 6b2936c75..4dd18a81f 100644 --- a/grc/python/FlowGraph.py +++ b/grc/python/FlowGraph.py @@ -42,6 +42,7 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph): @param namespace_hash a unique hash for the namespace @return the resultant object """ + if not code: raise Exception, 'Cannot evaluate empty statement.' my_hash = hash(code) ^ namespace_hash #cache if does not exist if not self._eval_cache.has_key(my_hash): -- cgit From a4a1ada03e5da936d90a5d6e3bd31943a5ad9513 Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 3 Dec 2009 10:42:49 -0500 Subject: Allow for multiple io pads per hier flow graph. Each io pad can have a different io signature. Uses the iosignaturev for hier implementation. Backwards compadible with exception: Pad blocks that used multiple ports must be replaced with multiple pad blocks as the new pad io blocks only support one port per block. --- grc/python/FlowGraph.py | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) (limited to 'grc/python/FlowGraph.py') diff --git a/grc/python/FlowGraph.py b/grc/python/FlowGraph.py index 4dd18a81f..24e4aac3b 100644 --- a/grc/python/FlowGraph.py +++ b/grc/python/FlowGraph.py @@ -50,44 +50,36 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph): #return from cache return self._eval_cache[my_hash] - def _get_io_signature(self, pad_key): + def _get_io_signaturev(self, pad_key): """ - Get an io signature for this flow graph. + Get a list of io signatures for this flow graph. The pad key determines the directionality of the io signature. @param pad_key a string of pad_source or pad_sink - @return a dict with: type, nports, vlen, size + @return a list of dicts with: type, label, vlen, size """ pads = filter(lambda b: b.get_key() == pad_key, self.get_enabled_blocks()) - if not pads: return { - 'nports': '0', - 'type': '', - 'vlen': '0', - 'size': '0', - } - pad = pads[0] #take only the first, user should not have more than 1 + sorted_pads = sorted(pads, lambda x, y: cmp(x.get_id(), y.get_id())) #load io signature - return { - 'nports': str(pad.get_param('nports').get_evaluated()), + return [{ + 'label': str(pad.get_param('label').get_evaluated()), 'type': str(pad.get_param('type').get_evaluated()), 'vlen': str(pad.get_param('vlen').get_evaluated()), 'size': pad.get_param('type').get_opt('size'), - } + } for pad in sorted_pads] - def get_input_signature(self): + def get_input_signaturev(self): """ Get the io signature for the input side of this flow graph. - The io signature with be "0", "0" if no pad source is present. - @return a string tuple of type, num_ports, port_size + @return a list of io signature structures """ - return self._get_io_signature('pad_source') + return self._get_io_signaturev('pad_source') - def get_output_signature(self): + def get_output_signaturev(self): """ Get the io signature for the output side of this flow graph. - The io signature with be "0", "0" if no pad sink is present. - @return a string tuple of type, num_ports, port_size + @return a list of io signature structures """ - return self._get_io_signature('pad_sink') + return self._get_io_signaturev('pad_sink') def get_imports(self): """ -- cgit From 61830989ce554e6dfac41bba2ced7006c424e0bc Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Sun, 6 Dec 2009 23:18:27 -0500 Subject: removed unused import statements, thanks pyflakes --- grc/python/FlowGraph.py | 2 -- 1 file changed, 2 deletions(-) (limited to 'grc/python/FlowGraph.py') diff --git a/grc/python/FlowGraph.py b/grc/python/FlowGraph.py index 4dd18a81f..054e17df2 100644 --- a/grc/python/FlowGraph.py +++ b/grc/python/FlowGraph.py @@ -20,8 +20,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA import expr_utils from .. base.FlowGraph import FlowGraph as _FlowGraph from .. gui.FlowGraph import FlowGraph as _GUIFlowGraph -from Block import Block -from Connection import Connection import re _variable_matcher = re.compile('^(variable\w*)$') -- cgit From a4ac44d7adbd9c6cdd107ec7985e294fea81845a Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 21 Apr 2011 11:02:28 -0700 Subject: grc: fix hier block generation w/ multiple pad blocks --- grc/python/FlowGraph.py | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'grc/python/FlowGraph.py') diff --git a/grc/python/FlowGraph.py b/grc/python/FlowGraph.py index b2d406bbd..89a169355 100644 --- a/grc/python/FlowGraph.py +++ b/grc/python/FlowGraph.py @@ -1,5 +1,5 @@ """ -Copyright 2008, 2009 Free Software Foundation, Inc. +Copyright 2008-2011 Free Software Foundation, Inc. This file is part of GNU Radio GNU Radio Companion is free software; you can redistribute it and/or @@ -48,15 +48,16 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph): #return from cache return self._eval_cache[my_hash] - def _get_io_signaturev(self, pad_key): + def get_io_signaturev(self, direction): """ Get a list of io signatures for this flow graph. - The pad key determines the directionality of the io signature. - @param pad_key a string of pad_source or pad_sink + @param direction a string of 'in' or 'out' @return a list of dicts with: type, label, vlen, size """ - pads = filter(lambda b: b.get_key() == pad_key, self.get_enabled_blocks()) - sorted_pads = sorted(pads, lambda x, y: cmp(x.get_id(), y.get_id())) + sorted_pads = { + 'in': self.get_pad_sources(), + 'out': self.get_pad_sinks(), + }[direction] #load io signature return [{ 'label': str(pad.get_param('label').get_evaluated()), @@ -65,19 +66,21 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph): 'size': pad.get_param('type').get_opt('size'), } for pad in sorted_pads] - def get_input_signaturev(self): + def get_pad_sources(self): """ - Get the io signature for the input side of this flow graph. - @return a list of io signature structures + Get a list of pad source blocks sorted by id order. + @return a list of pad source blocks in this flow graph """ - return self._get_io_signaturev('pad_source') + pads = filter(lambda b: b.get_key() == 'pad_source', self.get_enabled_blocks()) + return sorted(pads, lambda x, y: cmp(x.get_id(), y.get_id())) - def get_output_signaturev(self): + def get_pad_sinks(self): """ - Get the io signature for the output side of this flow graph. - @return a list of io signature structures + Get a list of pad sink blocks sorted by id order. + @return a list of pad sink blocks in this flow graph """ - return self._get_io_signaturev('pad_sink') + pads = filter(lambda b: b.get_key() == 'pad_sink', self.get_enabled_blocks()) + return sorted(pads, lambda x, y: cmp(x.get_id(), y.get_id())) def get_imports(self): """ -- cgit From 6fb32f05d01c23e1953fe874a33f37bc44758d9e Mon Sep 17 00:00:00 2001 From: Josh Blum Date: Thu, 4 Oct 2012 18:49:34 -0700 Subject: grc: added optional flag to pad source and sink --- grc/python/FlowGraph.py | 1 + 1 file changed, 1 insertion(+) (limited to 'grc/python/FlowGraph.py') diff --git a/grc/python/FlowGraph.py b/grc/python/FlowGraph.py index 89a169355..efe362760 100644 --- a/grc/python/FlowGraph.py +++ b/grc/python/FlowGraph.py @@ -64,6 +64,7 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph): 'type': str(pad.get_param('type').get_evaluated()), 'vlen': str(pad.get_param('vlen').get_evaluated()), 'size': pad.get_param('type').get_opt('size'), + 'optional': bool(pad.get_param('optional').get_evaluated()), } for pad in sorted_pads] def get_pad_sources(self): -- cgit From 52ca5e2765b7a4532d26502b5b76b7c85c5019d7 Mon Sep 17 00:00:00 2001 From: Tim O'Shea Date: Fri, 7 Dec 2012 09:28:41 -0800 Subject: core: added gr_tuntap_pdu, gr_socket_pdu, and msg passing enhancements --- grc/python/FlowGraph.py | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'grc/python/FlowGraph.py') diff --git a/grc/python/FlowGraph.py b/grc/python/FlowGraph.py index efe362760..376c2e337 100644 --- a/grc/python/FlowGraph.py +++ b/grc/python/FlowGraph.py @@ -58,6 +58,8 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph): 'in': self.get_pad_sources(), 'out': self.get_pad_sinks(), }[direction] + # we only want stream ports + sorted_pads = filter(lambda b: b.get_param('type').get_evaluated() != 'message', sorted_pads); #load io signature return [{ 'label': str(pad.get_param('label').get_evaluated()), @@ -83,6 +85,14 @@ class FlowGraph(_FlowGraph, _GUIFlowGraph): pads = filter(lambda b: b.get_key() == 'pad_sink', self.get_enabled_blocks()) return sorted(pads, lambda x, y: cmp(x.get_id(), y.get_id())) + def get_msg_pad_sources(self): + ps = self.get_pad_sources(); + return filter(lambda b: b.get_param('type').get_evaluated() == 'message', ps); + + def get_msg_pad_sinks(self): + ps = self.get_pad_sinks(); + return filter(lambda b: b.get_param('type').get_evaluated() == 'message', ps); + def get_imports(self): """ Get a set of all import statments in this flow graph namespace. -- cgit