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
23 from grc.Utils import odict
24 from grc.elements.Element import Element
25 from grc.elements.Param import Param
26 from grc.elements.Port import Port
28 from Cheetah.Template import Template
29 from UserDict import UserDict
31 class TemplateArg(UserDict):
33 A cheetah template argument created from a param.
34 The str of this class evaluates to the param's to code method.
35 The use of this class as a dictionary (enum only) will reveal the enum opts.
36 The eval method can return the param evaluated to a raw python data type.
39 def __init__(self, param):
40 UserDict.__init__(self)
43 for key in param.get_opt_keys():
44 self[key] = str(param.get_opt(key))
47 return str(self._param.to_code())
50 return self._param.evaluate()
54 def __init__(self, flow_graph, n):
56 Make a new block from nested data.
57 @param flow graph the parent element
58 @param n the nested odict
59 @return block a new block
64 category = Utils.exists_or_else(n, 'category', '')
65 params = Utils.listify(n, 'param')
66 sources = Utils.listify(n, 'source')
67 sinks = Utils.listify(n, 'sink')
69 Element.__init__(self, flow_graph)
73 self._category = category
74 #create the param objects
75 self._params = odict()
77 self._params['id'] = self.get_parent().get_parent().Param(
85 self._params['_enabled'] = self.get_parent().get_parent().Param(
95 for param in map(lambda n: self.get_parent().get_parent().Param(self, n), params):
97 #test against repeated keys
98 try: assert(key not in self.get_param_keys())
99 except AssertionError: self._exit_with_error('Key "%s" already exists in params'%key)
101 self._params[key] = param
102 #create the source objects
103 self._sources = odict()
104 for source in map(lambda n: self.get_parent().get_parent().Source(self, n), sources):
105 key = source.get_key()
106 #test against repeated keys
107 try: assert(key not in self.get_source_keys())
108 except AssertionError: self._exit_with_error('Key "%s" already exists in sources'%key)
110 self._sources[key] = source
111 #create the sink objects
112 self._sinks = odict()
113 for sink in map(lambda n: self.get_parent().get_parent().Sink(self, n), sinks):
115 #test against repeated keys
116 try: assert(key not in self.get_sink_keys())
117 except AssertionError: self._exit_with_error('Key "%s" already exists in sinks'%key)
119 self._sinks[key] = sink
125 Call test on all children.
127 map(lambda c: c.test(), self.get_params() + self.get_sinks() + self.get_sources())
129 def get_enabled(self):
131 Get the enabled state of the block.
132 @return true for enabled
134 try: return eval(self.get_param('_enabled').get_value())
137 def set_enabled(self, enabled):
139 Set the enabled state of the block.
140 @param enabled true for enabled
142 self.get_param('_enabled').set_value(str(enabled))
147 All ports and params must be valid.
148 All checks must evaluate to true.
150 if not self.get_enabled(): return
151 for c in self.get_params() + self.get_sinks() + self.get_sources():
152 try: assert(c.is_valid())
153 except AssertionError:
154 for msg in c.get_error_messages():
155 self._add_error_message('%s: %s'%(c, msg))
157 def __str__(self): return 'Block - %s - %s(%s)'%(self.get_id(), self.get_name(), self.get_key())
159 def get_id(self): return self.get_param('id').get_value()
161 def is_block(self): return True
163 def get_doc(self): return self._doc
165 def get_name(self): return self._name
167 def get_key(self): return self._key
169 def get_category(self): return self._category
171 def get_doc(self): return ''
173 def get_ports(self): return self.get_sources() + self.get_sinks()
175 ##############################################
177 ##############################################
178 def get_param_keys(self): return self._params.keys()
179 def get_param(self, key): return self._params[key]
180 def get_params(self): return self._params.values()
182 ##############################################
184 ##############################################
185 def get_sink_keys(self): return self._sinks.keys()
186 def get_sink(self, key): return self._sinks[key]
187 def get_sinks(self): return self._sinks.values()
189 ##############################################
191 ##############################################
192 def get_source_keys(self): return self._sources.keys()
193 def get_source(self, key): return self._sources[key]
194 def get_sources(self): return self._sources.values()
196 def get_connections(self):
197 return sum([port.get_connections() for port in self.get_ports()], [])
199 def resolve_dependencies(self, tmpl):
201 Resolve a paramater dependency with cheetah templates.
202 @param tmpl the string with dependencies
203 @return the resolved value
206 if '$' not in tmpl: return tmpl
207 n = dict((p.get_key(), TemplateArg(p)) for p in self.get_params())
208 try: return str(Template(tmpl, n))
209 except Exception, e: return "-------->\n%s: %s\n<--------"%(e, tmpl)
211 ##############################################
212 ## Import/Export Methods
213 ##############################################
214 def export_data(self):
216 Export this block's params to nested data.
217 @return a nested data odict
220 n['key'] = self.get_key()
221 n['param'] = map(lambda p: p.export_data(), self.get_params())
224 def import_data(self, n):
226 Import this block's params from nested data.
227 Any param keys that do not exist will be ignored.
228 @param n the nested data odict
230 params_n = Utils.listify(n, 'param')
231 for param_n in params_n:
232 #key and value must exist in the n data
233 if 'key' in param_n.keys() and 'value' in param_n.keys():
235 value = param_n['value']
236 #the key must exist in this block's params
237 if key in self.get_param_keys():
238 self.get_param(key).set_value(value)