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
21 from ... utils import odict
22 from Element import Element
23 from Param import Param
26 from Cheetah.Template import Template
27 from UserDict import UserDict
29 class TemplateArg(UserDict):
31 A cheetah template argument created from a param.
32 The str of this class evaluates to the param's to code method.
33 The use of this class as a dictionary (enum only) will reveal the enum opts.
34 The eval method can return the param evaluated to a raw python data type.
37 def __init__(self, param):
38 UserDict.__init__(self)
41 for key in param.get_opt_keys():
42 self[key] = str(param.get_opt(key))
45 return str(self._param.to_code())
48 return self._param.evaluate()
52 def __init__(self, flow_graph, n):
54 Make a new block from nested data.
55 @param flow graph the parent element
56 @param n the nested odict
57 @return block a new block
60 Element.__init__(self, flow_graph)
62 params = utils.listify(n, 'param')
63 sources = utils.listify(n, 'source')
64 sinks = utils.listify(n, 'sink')
65 self._name = n['name']
67 self._category = utils.exists_or_else(n, 'category', '')
68 self._block_wrapper_path = n['block_wrapper_path']
69 #create the param objects
70 self._params = odict()
72 self._params['id'] = self.get_parent().get_parent().Param(
80 self._params['_enabled'] = self.get_parent().get_parent().Param(
90 for param in map(lambda n: self.get_parent().get_parent().Param(self, n), params):
92 #test against repeated keys
93 try: assert(key not in self.get_param_keys())
94 except AssertionError: self._exit_with_error('Key "%s" already exists in params'%key)
96 self._params[key] = param
97 #create the source objects
98 self._sources = odict()
99 for source in map(lambda n: self.get_parent().get_parent().Source(self, n), sources):
100 key = source.get_key()
101 #test against repeated keys
102 try: assert(key not in self.get_source_keys())
103 except AssertionError: self._exit_with_error('Key "%s" already exists in sources'%key)
105 self._sources[key] = source
106 #create the sink objects
107 self._sinks = odict()
108 for sink in map(lambda n: self.get_parent().get_parent().Sink(self, n), sinks):
110 #test against repeated keys
111 try: assert(key not in self.get_sink_keys())
112 except AssertionError: self._exit_with_error('Key "%s" already exists in sinks'%key)
114 self._sinks[key] = sink
120 Call test on all children.
122 map(lambda c: c.test(), self.get_params() + self.get_sinks() + self.get_sources())
124 def get_enabled(self):
126 Get the enabled state of the block.
127 @return true for enabled
129 try: return eval(self.get_param('_enabled').get_value())
132 def set_enabled(self, enabled):
134 Set the enabled state of the block.
135 @param enabled true for enabled
137 self.get_param('_enabled').set_value(str(enabled))
142 All ports and params must be valid.
143 All checks must evaluate to true.
145 for c in self.get_params() + self.get_ports() + self.get_connections():
146 try: assert(c.is_valid())
147 except AssertionError:
148 for msg in c.get_error_messages():
149 self._add_error_message('>>> %s:\n\t%s'%(c, msg))
151 def __str__(self): return 'Block - %s - %s(%s)'%(self.get_id(), self.get_name(), self.get_key())
153 def get_id(self): return self.get_param('id').get_value()
154 def is_block(self): return True
155 def get_name(self): return self._name
156 def get_key(self): return self._key
157 def get_category(self): return self._category
158 def get_doc(self): return ''
159 def get_ports(self): return self.get_sources() + self.get_sinks()
160 def get_block_wrapper_path(self): return self._block_wrapper_path
162 ##############################################
164 ##############################################
165 def get_param_keys(self): return self._params.keys()
166 def get_param(self, key): return self._params[key]
167 def get_params(self): return self._params.values()
169 ##############################################
171 ##############################################
172 def get_sink_keys(self): return self._sinks.keys()
173 def get_sink(self, key): return self._sinks[key]
174 def get_sinks(self): return self._sinks.values()
176 ##############################################
178 ##############################################
179 def get_source_keys(self): return self._sources.keys()
180 def get_source(self, key): return self._sources[key]
181 def get_sources(self): return self._sources.values()
183 def get_connections(self):
184 return sum([port.get_connections() for port in self.get_ports()], [])
186 def resolve_dependencies(self, tmpl):
188 Resolve a paramater dependency with cheetah templates.
189 @param tmpl the string with dependencies
190 @return the resolved value
193 if '$' not in tmpl: return tmpl
194 n = dict((p.get_key(), TemplateArg(p)) for p in self.get_params())
195 try: return str(Template(tmpl, n))
196 except Exception, e: return "-------->\n%s: %s\n<--------"%(e, tmpl)
198 ##############################################
200 ##############################################
201 def type_controller_modify(self, direction):
203 Change the type controller.
204 @param direction +1 or -1
205 @return true for change
209 for param in filter(lambda p: p.is_enum(), self.get_params()):
210 children = self.get_ports() + self.get_params()
211 #priority to the type controller
212 if param.get_key() in ' '.join(map(lambda p: p._type, children)): type_param = param
213 #use param if type param is unset
214 if not type_param: type_param = param
216 #try to increment the enum by direction
218 keys = type_param.get_option_keys()
219 old_index = keys.index(type_param.get_value())
220 new_index = (old_index + direction + len(keys))%len(keys)
221 type_param.set_value(keys[new_index])
226 def port_controller_modify(self, direction):
228 Change the port controller.
229 @param direction +1 or -1
230 @return true for change
234 ##############################################
235 ## Import/Export Methods
236 ##############################################
237 def export_data(self):
239 Export this block's params to nested data.
240 @return a nested data odict
243 n['key'] = self.get_key()
244 n['param'] = map(lambda p: p.export_data(), self.get_params())
247 def import_data(self, n):
249 Import this block's params from nested data.
250 Any param keys that do not exist will be ignored.
251 @param n the nested data odict
253 params_n = utils.listify(n, 'param')
254 for param_n in params_n:
255 #key and value must exist in the n data
256 if 'key' in param_n.keys() and 'value' in param_n.keys():
258 value = param_n['value']
259 #the key must exist in this block's params
260 if key in self.get_param_keys():
261 self.get_param(key).set_value(value)