Changeset 8986
- Timestamp:
- 07/23/08 17:32:23
- Files:
-
- grc/trunk/notes/todo.txt (modified) (1 diff)
- grc/trunk/src/grc_gnuradio/Generator.py (modified) (3 diffs)
- grc/trunk/src/grc_gnuradio/Param.py (modified) (1 diff)
- grc/trunk/src/grc_gnuradio/blocks/options.xml (modified) (1 diff)
- grc/trunk/src/grc_gnuradio/data/flow_graph.tmpl (modified) (2 diffs)
- grc/trunk/src/grc_gnuradio/expr_utils.py (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
grc/trunk/notes/todo.txt
r8985 r8986 13 13 -hotkeys in action descriptions 14 14 -log slider gui control 15 -variable resolution graph structure16 15 -recursive/nested categories 16 17 ############ Maybe: #################### 17 18 -icons for certain blocks, + for add 18 19 -zoom in/out 19 -hide io type s20 -hide io type params 20 21 21 22 ############ Problems: #################### 22 23 -catch error on open non-existant files 23 -variables dependent on variables that change24 -flow graph, try mouse DRAG_MOTION?25 24 26 25 ############ Suggestions: #################### grc/trunk/src/grc_gnuradio/Generator.py
r8956 r8986 26 26 import stat 27 27 from Cheetah.Template import Template 28 import expr_utils 28 29 29 30 ##The default binary to execute python files. … … 77 78 @return a string of python code 78 79 """ 79 #load the namespace80 80 imports = self._flow_graph.get_imports() 81 81 variables = self._flow_graph.get_variables() 82 #list of blocks not including variables and imports 82 83 blocks = sorted(self._flow_graph.get_blocks(), lambda x, y: cmp(x.get_id(), y.get_id())) 83 84 blocks = filter(lambda b: b not in (imports + variables) and b.get_enabled(), blocks) 85 #list of callbacks 86 callbacks = sum([block.get_callbacks() for block in self._flow_graph.get_blocks()], []) 87 #list of variable names 88 var_ids = [var.get_id() for var in variables] 89 #map var id to the expression (prepend self.) 90 var_id2expr = dict( 91 [(var.get_id(), expr_utils.expr_prepend(var.get_make().split('\n')[0], var_ids, 'self.')) 92 for var in variables] 93 ) 94 #create graph structure for variables 95 variable_graph = expr_utils.get_graph(var_id2expr) 96 #map var id to direct dependents 97 #for each var id, make a list of all 2nd order edges 98 #use all edges of that id that are not also 2nd order edges 99 #meaning: list variables the ONLY depend directly on this variable 100 #and not variables that also depend indirectly on this variable 101 var_id2deps = dict( 102 [(var_id, filter(lambda e: e not in sum([list(variable_graph.get_edges(edge)) 103 for edge in variable_graph.get_edges(var_id)], []), variable_graph.get_edges(var_id) 104 ) 105 ) 106 for var_id in var_ids] 107 ) 108 #map var id to callbacks 109 var_id2cbs = dict( 110 [(var_id, filter(lambda c: var_id in expr_utils.expr_split(c), callbacks)) 111 for var_id in var_ids] 112 ) 113 #load the namespace 84 114 namespace = { 85 115 'imports': imports, … … 88 118 'blocks': blocks, 89 119 'connections': self._flow_graph.get_connections(), 90 'callbacks': sum([block.get_callbacks() for block in self._flow_graph.get_blocks()], []),91 120 'gui_type': self._flow_graph.get_option('generate_options'), 121 'var_id2expr': var_id2expr, 122 'var_id2deps': var_id2deps, 123 'var_id2cbs': var_id2cbs, 92 124 } 93 125 #build the template grc/trunk/src/grc_gnuradio/Param.py
r8985 r8986 214 214 #add self. to variables 215 215 if self.get_parent().self_flag: 216 code_splits = expr_utils.expr_split(code)217 216 var_ids = [var.get_id() for var in self.get_parent().get_parent().get_variables()] 218 for i, cs in enumerate(code_splits): 219 if cs in var_ids: code_splits[i] = "self.%s"%cs 220 code = ''.join(code_splits) 217 code = expr_utils.expr_prepend(code, var_ids, 'self.') 221 218 return code 222 219 grc/trunk/src/grc_gnuradio/blocks/options.xml
r8939 r8986 71 71 The window size (width, height) must be between (300, 300) and (2048, 2048). 72 72 73 The generate options controls the type of code generated (wx-graphical or non-graphical). \73 The generate options controls the type of code generated. \ 74 74 Non-graphical flow graphs should avoid using graphical sinks or graphical variable controls. 75 76 The id of this block determines the name of the generated file and the name of the class. \ 77 For example, an id of my_block will generate the file my_block.py and class my_block(gr.... 75 78 </doc> 76 79 </block> grc/trunk/src/grc_gnuradio/data/flow_graph.tmpl
r8910 r8986 8 8 ##@param blocks the signal blocks 9 9 ##@param connections the connections 10 ##@param callbacks the block callback strings11 10 ##@param gui_type the type of gui (wx gui or no gui) 11 ##@param var_id2expr variable id map to expression 12 ##@param var_id2deps variable id map to direct dependencies 13 ##@param var_id2cbs variable id map to callback strings 12 14 ######################################################## 13 15 #import time … … 146 148 ######################################################## 147 149 ##Create Callbacks 148 ## Determine block callbacks that depend on the variable.149 ## Write a set method for this variable that calls the callbacks.150 ## Write a set method for this variable that calls the callbacks 151 ## and sets the direct variable dependencies. 150 152 ######################################################## 151 153 #for $var in $variables 152 154 #set $id = $var.get_id() 153 #set $var_callbacks = filter(lambda c: id in ''.join(c.split('(')[1:]), $callbacks)154 155 def set_$(id)(self, $id): 155 156 self.$id = $id 156 #for $callback in $var_callbacks 157 #for $dep in $var_id2deps[$id] 158 self.set_$(dep)($var_id2expr[$dep]) 159 #end for 160 #for $callback in $var_id2cbs[$id] 157 161 self.$callback 158 162 #end for grc/trunk/src/grc_gnuradio/expr_utils.py
r8885 r8986 24 24 VAR_CHARS = string.letters + string.digits + '_' 25 25 26 class graph(object): 27 """! 28 Simple graph structure held in a dictionary. 29 """ 30 31 def __init__(self): self._graph = dict() 32 33 def __str__(self): return str(self._graph) 34 35 def add_node(self, node_key): 36 if self._graph.has_key(node_key): return 37 self._graph[node_key] = set() 38 39 def remove_node(self, node_key): 40 if not self._graph.has_key(node_key): return 41 for edges in self._graph.values(): 42 if node_key in edges: edges.remove(node_key) 43 self._graph.pop(node_key) 44 45 def add_edge(self, src_node_key, dest_node_key): 46 self._graph[src_node_key].add(dest_node_key) 47 48 def remove_edge(self, src_node_key, dest_node_key): 49 self._graph[src_node_key].remove(dest_node_key) 50 51 def get_nodes(self): return self._graph.keys() 52 53 def get_edges(self, node_key): return self._graph[node_key] 54 26 55 def expr_split(expr): 27 56 """! … … 41 70 elif char in ("'", '"'): 42 71 toks.append(tok) 43 tok = char 72 tok = char 44 73 quote = char 45 74 else: … … 49 78 toks.append(tok) 50 79 return filter(lambda t: t, toks) 80 81 def expr_prepend(expr, vars, prepend): 82 """! 83 Search for vars in the expression and add the prepend. 84 @param expr an expression string 85 @param vars a list of variable names 86 @param prepend the prepend string 87 @return a new expression with the prepend 88 """ 89 expr_splits = expr_split(expr) 90 for i, es in enumerate(expr_splits): 91 if es in vars: expr_splits[i] = prepend + es 92 return ''.join(expr_splits) 51 93 52 94 def get_variable_dependencies(expr, vars): … … 60 102 return set(filter(lambda v: v in expr_toks, vars)) 61 103 104 def get_graph(exprs): 105 """! 106 Get a graph representing the variable dependencies 107 @param exprs a mapping of variable name to expression 108 @return a graph of variable deps 109 """ 110 vars = exprs.keys() 111 #get dependencies for each expression, load into graph 112 var_graph = graph() 113 for var in vars: var_graph.add_node(var) 114 for var, expr in exprs.iteritems(): 115 for dep in get_variable_dependencies(expr, vars): 116 var_graph.add_edge(dep, var) 117 return var_graph 118 62 119 def sort_variables(exprs): 63 120 """! … … 67 124 @throws AssertionError circular dependencies 68 125 """ 69 vars = exprs.keys() 70 #get dependencies for each expression 71 vars_deps = dict([(var, get_variable_dependencies(expr, vars)) for var, expr in exprs.iteritems()]) 126 var_graph = get_graph(exprs) 72 127 sorted_vars = list() 73 128 #determine dependency order 74 while var s_deps:75 #get a list of vars with no dependencies76 indep_vars = set(filter(lambda v: not vars_deps[v], vars_deps.keys()))129 while var_graph.get_nodes(): 130 #get a list of nodes with no edges 131 indep_vars = filter(lambda var: not var_graph.get_edges(var), var_graph.get_nodes()) 77 132 assert indep_vars 78 #remove inpep vars from dict79 for var in indep_vars: vars_deps.pop(var)80 133 #add the indep vars to the end of the list 81 134 sorted_vars.extend(sorted(indep_vars)) 82 #remove deps from other vars involving indep_vars83 for var in vars_deps.keys(): vars_deps[var] -= indep_vars84 return sorted_vars135 #remove each edge-less node from the graph 136 for var in indep_vars: var_graph.remove_node(var) 137 return reversed(sorted_vars) 85 138 139 if __name__ == '__main__': 140 for i in sort_variables({'x':'1', 'y':'x+1', 'a':'x+y', 'b':'y+1', 'c':'a+b+x+y'}): print i
