2 Copyright 2008 Free Software Foundation, Inc.
3 This file is part of GNU Radio
5 GNU Radio Companion is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 GNU Radio Companion is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 ##@package grc.elements.Block
24 from grc.Utils import odict
25 from grc.elements.Element import Element
26 from grc.elements.Param import Param
27 from grc.elements.Port import Port
29 from Cheetah.Template import Template
30 from UserDict import UserDict
32 class TemplateArg(UserDict):
34 A cheetah template argument created from a param.
35 The str of this class evaluates to the param's to code method.
36 The use of this class as a dictionary (enum only) will reveal the enum opts.
37 The eval method can return the param evaluated to a raw python data type.
40 def __init__(self, param):
41 UserDict.__init__(self)
44 for key in param.get_opt_keys():
45 self[key] = str(param.get_opt(key))
48 return str(self._param.to_code())
51 return self._param.evaluate()
55 def __init__(self, flow_graph, n):
57 Make a new block from nested data.
58 @param flow graph the parent element
59 @param n the nested odict
60 @return block a new block
65 category = Utils.exists_or_else(n, 'category', '')
66 params = Utils.listify(n, 'param')
67 sources = Utils.listify(n, 'source')
68 sinks = Utils.listify(n, 'sink')
70 Element.__init__(self, flow_graph)
74 self._category = category
75 #create the param objects
76 self._params = odict()
78 self._params['id'] = self.get_parent().get_parent().Param(
86 self._params['_enabled'] = self.get_parent().get_parent().Param(
96 for param in map(lambda n: self.get_parent().get_parent().Param(self, n), params):
98 #test against repeated keys
99 try: assert(key not in self.get_param_keys())
100 except AssertionError: self._exit_with_error('Key "%s" already exists in params'%key)
102 self._params[key] = param
103 #create the source objects
104 self._sources = odict()
105 for source in map(lambda n: self.get_parent().get_parent().Source(self, n), sources):
106 key = source.get_key()
107 #test against repeated keys
108 try: assert(key not in self.get_source_keys())
109 except AssertionError: self._exit_with_error('Key "%s" already exists in sources'%key)
111 self._sources[key] = source
112 #create the sink objects
113 self._sinks = odict()
114 for sink in map(lambda n: self.get_parent().get_parent().Sink(self, n), sinks):
116 #test against repeated keys
117 try: assert(key not in self.get_sink_keys())
118 except AssertionError: self._exit_with_error('Key "%s" already exists in sinks'%key)
120 self._sinks[key] = sink
126 Call test on all children.
128 map(lambda c: c.test(), self.get_params() + self.get_sinks() + self.get_sources())
130 def get_enabled(self):
132 Get the enabled state of the block.
133 @return true for enabled
135 try: return eval(self.get_param('_enabled').get_value())
138 def set_enabled(self, enabled):
140 Set the enabled state of the block.
141 @param enabled true for enabled
143 self.get_param('_enabled').set_value(str(enabled))
148 All ports and params must be valid.
149 All checks must evaluate to true.
151 if not self.get_enabled(): return
152 for c in self.get_params() + self.get_sinks() + self.get_sources():
153 try: assert(c.is_valid())
154 except AssertionError:
155 for msg in c.get_error_messages():
156 self._add_error_message('%s: %s'%(c, msg))
158 def __str__(self): return 'Block - %s - %s(%s)'%(self.get_id(), self.get_name(), self.get_key())
160 def get_id(self): return self.get_param('id').get_value()
162 def is_block(self): return True
164 def get_doc(self): return self._doc
166 def get_name(self): return self._name
168 def get_key(self): return self._key
170 def get_category(self): return self._category
172 def get_doc(self): return ''
174 def get_ports(self): return self.get_sources() + self.get_sinks()
176 ##############################################
178 ##############################################
179 def get_param_keys(self): return self._params.keys()
180 def get_param(self, key): return self._params[key]
181 def get_params(self): return self._params.values()
183 ##############################################
185 ##############################################
186 def get_sink_keys(self): return self._sinks.keys()
187 def get_sink(self, key): return self._sinks[key]
188 def get_sinks(self): return self._sinks.values()
190 ##############################################
192 ##############################################
193 def get_source_keys(self): return self._sources.keys()
194 def get_source(self, key): return self._sources[key]
195 def get_sources(self): return self._sources.values()
197 def get_connections(self):
198 return sum([port.get_connections() for port in self.get_ports()], [])
200 def resolve_dependencies(self, tmpl):
202 Resolve a paramater dependency with cheetah templates.
203 @param tmpl the string with dependencies
204 @return the resolved value
207 if '$' not in tmpl: return tmpl
208 n = dict((p.get_key(), TemplateArg(p)) for p in self.get_params())
209 try: return str(Template(tmpl, n))
210 except Exception, e: return "-------->\n%s: %s\n<--------"%(e, tmpl)
212 ##############################################
213 ## Import/Export Methods
214 ##############################################
215 def export_data(self):
217 Export this block's params to nested data.
218 @return a nested data odict
221 n['key'] = self.get_key()
222 n['param'] = map(lambda p: p.export_data(), self.get_params())
225 def import_data(self, n):
227 Import this block's params from nested data.
228 Any param keys that do not exist will be ignored.
229 @param n the nested data odict
231 params_n = Utils.listify(n, 'param')
232 for param_n in params_n:
233 #key and value must exist in the n data
234 if 'key' in param_n.keys() and 'value' in param_n.keys():
236 value = param_n['value']
237 #the key must exist in this block's params
238 if key in self.get_param_keys():
239 self.get_param(key).set_value(value)