From: Tero K. <te...@us...> - 2005-08-15 23:36:25
|
Update of /cvsroot/openexvis/openexvis In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv13582 Modified Files: ChangeLog oevt_python.py openexvis.py visualizer.py Log Message: Further visualization improvements. Visualization area now cleared when a file is loaded. Output area likewise and also when starting a new visualization. Index: oevt_python.py =================================================================== RCS file: /cvsroot/openexvis/openexvis/oevt_python.py,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- oevt_python.py 15 Aug 2005 20:36:04 -0000 1.7 +++ oevt_python.py 15 Aug 2005 23:36:15 -0000 1.8 @@ -49,67 +49,86 @@ # We return strings, since what the translator gives to the visualizer # should be language-independent. #print "DEBUG: data == ", data - # Remove the line number from the data. - viscommands = str(data.pop(0)) + ';' # The visualization commands - lastconst = None # Track the last loaded constant - olderconst = None # Track the constant loaded before lastconst + # Remove the line number from the data and store it at the beginning of + # the visualization commands. + viscommands = str(data.pop(0)) + ';' + # In the following, the first list item tells the variable name. If the + # first item is None, it means the value is a constant. The second item + # is the actual value. + lastval = [None, None] # Last loaded value + olderval = [None, None] # Value loaded before lastval for op in data: #print "DEBUG: op == ", op + if op['opcode'] == 'LOAD_CONST': # Loading a constant. viscommands += 'GET_CONSTANT:' + op['oparg2'] + ';' - # Load the given constant to lastconst. - olderconst = lastconst - lastconst = op['oparg2'] + # Load the given constant to lastval. + olderval = lastval + lastval = [None, op['oparg2']] + elif op['opcode'] == 'STORE_NAME' or op['opcode'] == 'STORE_ATTR': # Storing the last constant in the given variable. if self.variables.has_key(op['oparg2']): tmp = self.variables[op['oparg2']] - v = [lastconst, tmp[0]] + v = [lastval[1], tmp[0]] else: - v = [lastconst, ''] + v = [lastval[1], ''] self.variables[op['oparg2']] = v #print "DEBUG: variables == ", self.variables viscommands += 'STORE_VARIABLE:' + op['oparg2'] + ':' + \ str(v[0]) + ':' + str(v[1]) + ';' + elif op['opcode'] == 'SETUP_LOOP': viscommands += 'BEGIN_LOOP;' + elif op['opcode'] == 'LOAD_NAME' or op['opcode'] == 'LOAD_ATTR': # Loading the given variable. try: + # op['oparg2'] is the variable name. v = self.variables[op['oparg2']] viscommands += 'LOAD:' + op['oparg2'] + ':' + str(v[0]) + \ ':' + str(v[1]) + ';' - olderconst = lastconst - lastconst = v[0] + olderval = lastval + lastval = [op['oparg2'], v[0]] except KeyError, msg: print "oevt_python.py: No such key: ", msg # It can still be a valid operation, so do it like this. # TODO: Think this over. viscommands += 'LOAD:' + op['oparg2'] + ':' + '' +':' + \ '' + ';' + elif op['opcode'] == 'COMPARE_OP': viscommands += 'COMPARE:' + op['oparg2'] + ':' + \ - str(olderconst) + ':' + str(lastconst) + ';' + str(olderval[0]) + ':' + str(olderval[1]) + ':' + \ + str(lastval[0]) + ':' + str(lastval[1]) + ';' + elif op['opcode'] == 'INPLACE_ADD': - #print "DEBUG: older, last == ", olderconst, " ", lastconst - viscommands += 'SHOW_INT_OPERATION:+:' + str(lastconst) + \ - ':' + str(olderconst) + ';' - tmp = lastconst - lastconst = int(lastconst) + int(olderconst) - olderconst = tmp + #print "DEBUG: older, last == ", olderval, " ", lastval + viscommands += 'SHOW_INT_OPERATION:+:' + \ + str(olderval[0]) + ':' + str(olderval[1]) + ':' + \ + str(lastval[0]) + ':' + str(lastval[1]) + ';' + tmp = lastval + lastval[0] = None + lastval[1] = int(lastval[1]) + int(olderval[1]) + olderval = tmp + elif op['opcode'] == 'PRINT_ITEM': - viscommands += 'OUTPUT:' + str(lastconst) + ';' + viscommands += 'OUTPUT:' + str(lastval[1]) + ';' + elif op['opcode'] == 'PRINT_NEWLINE': viscommands += 'OUTPUT:\n;' + elif op['opcode'] == 'RETURN_VALUE': viscommands += 'RETURN;' + #elif opcode['opcode'] == : # pass #elif opcode['opcode'] == : # pass #elif opcode['opcode'] == : # pass + elif op['opcode'] == 'JUMP_IF_FALSE': # Not visualized in visualization area. pass @@ -123,7 +142,7 @@ # XXX Needed? pass else: - pass + print "Not supported in translator yet: ", op #print "DEBUG: vc == ", viscommands return viscommands Index: openexvis.py =================================================================== RCS file: /cvsroot/openexvis/openexvis/openexvis.py,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- openexvis.py 15 Aug 2005 20:36:04 -0000 1.13 +++ openexvis.py 15 Aug 2005 23:36:15 -0000 1.14 @@ -96,7 +96,7 @@ self.const_split = self.gridh * 9 self.eval_split = self.gridh * 12 # Some important locations for drawing the visualization. - self.const_start = (self.vis_split_x - self.gridw * 3, \ + self.const_start = (self.vis_split_x - self.gridw * 4, \ self.const_split + self.gridh * 1) self.var_name_pos = (self.vis_split_x + self.gridw * 1, \ self.eval_split - self.gridh * 3) @@ -160,7 +160,8 @@ def draw_step(self, lineno, viscommands): """Draw one visualization step.""" - self.vis_pixmaps = [] + self.vis_steps = [] + self.vis_pixmaps = {} # Mark the line we're visualizing on the code area. vis_code = self.mark_line(lineno) # If the line is marked, we should skip it. Note that the buffer counts @@ -173,7 +174,7 @@ return True # Create the animation pixmaps. self.update_pixmaps(vis_code, viscommands) - for elem in self.vis_pixmaps: + for elem in self.vis_steps: # Update the visualization area. self.animate_element(elem) if self.do_steps: @@ -210,62 +211,89 @@ self.draw_show_storing(cmd[1], cmd[2]) elif cmd[0] == 'SHOW_COMPARISON': # cmd[1] is the comparison sign (==,<,>) - # cmd[2] is the left side of the comparison. - # cmd[3] is the right side of the comparison. + # cmd[2] is the variable on the left side of the comparison or + # None if the value is a constant. + # cmd[3] is the value of the left side of the comparison. + # cmd[4] is the variable on the right side of the comparison or + # None if the value is a constant. + # cmd[5] is the value of the right side of the comparison. + # Could there be an easier way to do the following? if cmd[1] == '==': - if cmd[2] == cmd[3]: + if cmd[3] == cmd[5]: result = 'TRUE' else: result = 'FALSE' elif cmd[1] == '<': - if cmd[2] < cmd[3]: + if cmd[3] < cmd[5]: result = 'TRUE' else: result = 'FALSE' elif cmd[1] == '>': - if cmd[2] > cmd[3]: + if cmd[3] > cmd[5]: result = 'TRUE' else: result = 'FALSE' else: - print "Unsupported comparison: ", cmd[1] + print "Unsupported comparison operation: ", cmd[1] continue - self.draw_show_eval(cmd[2], cmd[1], cmd[3], result) + if cmd[2] != 'None': + left = str(cmd[2]) + '_value' + else: + left = 'const_' + str(cmd[3]) + if cmd[4] != 'None': + right = str(cmd[4]) + '_value' + else: + right = 'const_' + str(cmd[5]) + self.draw_show_eval(left, cmd[1], right, result) elif cmd[0] == 'SHOW_OPERATION': # cmd[1] is the operation sign (+,-,*,/) - # cmd[2] is the left side of the operation. - # cmd[3] is the right side of the operation. + # cmd[2] is the variable on the left side of the operation or + # None if the value is a constant. + # cmd[3] is the value of the left side of the operation. + # cmd[4] is the variable on the right side of the operation or + # None if the value is a constant. + # cmd[5] is the value of the right side of the operation. + # Could there be an easier way to do the following? if cmd[1] == '+': - result = cmd[2] + cmd[3] + result = cmd[3] + cmd[5] elif cmd[1] == '-': - result = cmd[2] - cmd[3] + result = cmd[3] - cmd[5] elif cmd[1] == '*': - result = cmd[2] * cmd[3] + result = cmd[3] * cmd[5] elif cmd[1] == '/': - result = cmd[2] / cmd[3] + result = cmd[3] / cmd[5] else: - print "Unsupported comparison: ", cmd[1] + print "Unsupported operation: ", cmd[1] continue - self.draw_show_eval(str(cmd[2]), cmd[1], str(cmd[3]), \ - str(result)) + if cmd[2] != 'None': + left = str(cmd[2]) + '_value' + else: + left = 'const_' + str(cmd[3]) + if cmd[4] != 'None': + right = str(cmd[4]) + '_value' + else: + right = 'const_' + str(cmd[5]) + self.draw_show_eval(left, cmd[1], right, str(result)) else: - print "Visualizing ", cmd[0], " not supported." + if cmd[0]: + print "Visualizing ", cmd[0], " not supported." return True def animate_element(self, elem): """Draw one animation frame. - Parameter elem is self.vispixmaps[i], where: - i[0] is current x, i[1] is x to move to - i[2] is current y, i[3] is y to move to - i[4] is the pixmap to draw on main pixmap + Parameter elem is self.vis_steps[i], where: + i[0] is the pixmap name + i[1] is the x coordinate to move to + i[2] is the y coordinate to move to """ # This is now so that horizontal movement always comes before vertical. # It might not be desireable in all cases. Figure that out when such a # situation arises. + pm = self.vis_pixmaps[elem[0]] more_for_element = True while more_for_element: while gtk.events_pending(): @@ -275,55 +303,49 @@ gtk.main_iteration() more_for_element = False # Move the element if needed. - prevx = elem[0] - prevy = elem[2] - if elem[0] < elem[1]: - elem[0] += self.gridw + prevx = pm[1] + prevy = pm[2] + if pm[1] < elem[1]: + pm[1] += self.gridw more_for_element = True - elif elem[0] > elem[1]: - elem[0] -= self.gridw + elif pm[1] > elem[1]: + pm[1] -= self.gridw more_for_element = True - elif elem[2] < elem[3]: - elem[2] += self.gridh + elif pm[2] < elem[2]: + pm[2] += self.gridh more_for_element = True - elif elem[2] > elem[3]: - elem[2] -= self.gridh + elif pm[2] > elem[2]: + pm[2] -= self.gridh more_for_element = True - # Clear the last position of the element. - pmw, pmh = elem[4].get_size() - self.pixmap.draw_rectangle(self.vArea.get_style().white_gc, True, \ - prevx, prevy, pmw, pmh) + # This makes things a bit slower but makes sure we don't erase + # other elements on our way. + pmw, pmh = pm[0].get_size() + self.clear_visualization_area() + for name, data in self.vis_pixmaps.iteritems(): + self.pixmap.draw_drawable(self.gc, data[0], 0, 0, \ + data[1], data[2], -1, -1) # Draw the element. - self.pixmap.draw_drawable(self.gc, elem[4], 0, 0, elem[0], elem[2], -1, -1) - self.refresh_screen() + self.pixmap.draw_drawable(self.gc, pm[0], 0, 0, pm[1], pm[2], \ + -1, -1) + self.refresh() # Higher speed setting gives higher speed like this. time.sleep((11-self.speed) * 0.05) # NOTE: To grok the following draw_show_* methods, see do_frame_pixmap. def draw_show_eval(self, left, sign, right, result): - """Store an evaluation in the visualization pixmap.""" - # The left side of the evaluation. - lx = self.eval_left_pos[0] - ly = self.eval_left_pos[1] - lw = self.gridw * 3 - ltxt = self.vArea.create_pango_layout(left) + # Create a pixmap for the result and the sign. + # The result. + res_x = self.eval_result_pos[0] + res_ex = self.eval_result_pos[0] + self.gridw * 2 # Hack to delay a bit + res_y = self.eval_result_pos[1] + res_w = self.gridw * 3 # The sign. sx = self.eval_sign_pos[0] sy = self.eval_sign_pos[1] sw = self.gridw * 2 stxt = self.vArea.create_pango_layout(sign) - # The right side of the evaluation. - rx = self.eval_right_pos[0] - ry = self.eval_right_pos[1] - rw = self.gridw * 3 - rtxt = self.vArea.create_pango_layout(right) - # The result of the evaluation. - # The res_ex is a hack to make sure the evaluation stays on screen for - # a while. - res_x = self.eval_result_pos[0] - res_ex = self.eval_result_pos[0] + self.gridw * 2 - res_y = self.eval_result_pos[1] - res_w = self.gridw * 3 + # Height is same for both + h = self.gridh if result == 'TRUE': res_fg = self.bool_true_color elif result == 'FALSE': @@ -331,17 +353,21 @@ else: res_fg = self.const_color res_txt = self.vArea.create_pango_layout(result) - # Height is same for all. - h = self.gridh - # Create the pixmaps to display the evaluation. - pm1 = self.create_element_pixmap(self.var_color, lw, h, ltxt) - pm2 = self.create_element_pixmap(self.const_color, sw, h, stxt) - pm3 = self.create_element_pixmap(self.var_color, rw, h, rtxt) - pm4 = self.create_element_pixmap(res_fg, res_w, h, res_txt) - self.vis_pixmaps.append([lx, lx, ly, ly, pm1]) - self.vis_pixmaps.append([sx, sx, sy, sy, pm2]) - self.vis_pixmaps.append([rx, rx, ry, ry, pm3]) - self.vis_pixmaps.append([res_x, res_x, res_y, res_y, pm4]) + self.create_element_pixmap('result_' + result, res_x, res_y, \ + res_fg, res_w, h, res_txt) + self.create_element_pixmap(sign, sx, sy, \ + self.const_color, sw, h, stxt) + # Names to use the correct pixmaps. + result = 'result_' + result + # Create the animation. + self.vis_steps.append([left, \ + self.eval_left_pos[0], self.eval_left_pos[1]]) + self.vis_steps.append([sign, \ + self.eval_sign_pos[0], self.eval_sign_pos[1]]) + self.vis_steps.append([right, \ + self.eval_right_pos[0], self.eval_right_pos[1]]) + self.vis_steps.append([result, \ + self.eval_result_pos[0], self.eval_result_pos[1]]) def draw_show_variables(self, cur_vars): """Store displaying the variables in the visualization pixmap.""" @@ -359,43 +385,48 @@ vtxt = self.vArea.create_pango_layout(v[2]) # Height is same for both h = self.gridh - pm1 = self.create_element_pixmap(self.var_color, nw, h, ntxt) - pm2 = self.create_element_pixmap(self.var_color, vw, h, vtxt) - self.vis_pixmaps.append([nx, nx, ny, ny, pm1]) - self.vis_pixmaps.append([vx, vx, vy, vy, pm2]) + pm1 = v[0] + pm2 = v[0] + '_value' + self.create_element_pixmap(pm1, nx, ny, \ + self.var_color, nw, h, ntxt) + self.create_element_pixmap(pm2, vx, vy, \ + self.var_color, vw, h, vtxt) + self.vis_steps.append([pm1, nx, ny]) + self.vis_steps.append([pm2, vx, vy]) pos += 1 def draw_show_constants(self, cur_consts): """Store displaying the constants in the visualization pixmap.""" pos = 0 - for c in cur_consts: - print "DEBUG: c == ", c - if c == 'None': + for const in cur_consts: + if const == 'None': continue - # We draw the static constants one column left from where moving - # ones start. - x = self.const_start[0] - self.gridw + x = self.const_start[0] y = self.const_start[1] + (self.gridh * pos) w = self.gridw * 2 h = self.gridh - txt = self.vArea.create_pango_layout(c[:8]) - pm = self.create_element_pixmap(self.static_const_color, w, h, txt) - self.vis_pixmaps.append([x, x, y, y, pm]) + txt = self.vArea.create_pango_layout(const) + pmname = 'const_' + const + self.create_element_pixmap(pmname, x, y, \ + self.static_const_color, w, h, txt) + self.vis_steps.append([pmname, x, y]) pos += 1 def draw_show_storing(self, const, var): """Store a constant moved to a variable in the visualization pixmap.""" startx = self.const_start[0] starty = self.const_start[1] - endx = self.var_value_pos[0] - endy = self.var_value_pos[1] + endx = self.vis_pixmaps[var + '_value'][1] + endy = self.vis_pixmaps[var + '_value'][2] w = self.gridw * 2 h = self.gridh - txt = self.vArea.create_pango_layout(const[:8]) - pm = self.create_element_pixmap(self.const_color, w, h, txt) - self.vis_pixmaps.append([startx, endx, starty, endy, pm]) + txt = self.vArea.create_pango_layout(const) + pmname = 'move_const_' + const + self.create_element_pixmap(pmname, startx, starty,\ + self.const_color, w, h, txt) + self.vis_steps.append([pmname, endx, endy]) - def create_element_pixmap(self, fgc, w, h, txt): + def create_element_pixmap(self, name, x, y, fgc, w, h, txt): """Build a pixmap for an element of a visualization.""" gc = self.vDraw.new_gc() pm = gtk.gdk.Pixmap(self.vDraw, w, h) @@ -404,9 +435,10 @@ gc.set_foreground(fgc) pm.draw_rectangle(gc, True, 1, 1, w - 2, h - 2) pm.draw_layout(self.gc, 2, 2, txt) + self.vis_pixmaps[name] = [pm, x, y] return pm - def refresh_screen(self): + def refresh(self): """Refresh the OpenExVis window.""" w = self.oevWindow.window w.invalidate_rect(self.oevWindow.allocation, True) @@ -464,11 +496,14 @@ except: print "Failed to load file ", filename return False + self.clear_visualization_area() + self.oArea.get_buffer().set_text('') self.cBuf.set_text(code) self.cBuf.set_data('filename', path) self.cBuf.end_not_undoable_action() self.cBuf.set_modified(False) self.cBuf.place_cursor(self.cBuf.get_start_iter()) + self.refresh() print "Loaded ", filename def save_file(self, filename): @@ -484,6 +519,7 @@ return self.cBuf.get_text(si, ei) def do_visualization(self): + self.oArea.get_buffer().set_text('') # Make sure the UI only calls visualize() once for one # visualization. self.cArea.set_sensitive(False) Index: visualizer.py =================================================================== RCS file: /cvsroot/openexvis/openexvis/visualizer.py,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- visualizer.py 15 Aug 2005 20:36:04 -0000 1.9 +++ visualizer.py 15 Aug 2005 23:36:15 -0000 1.10 @@ -79,14 +79,23 @@ cmd.append(['SHOW_LOOP']) elif c[0] == 'COMPARE': # c[1] is the sign of the comparison. - # c[2] is the left side of the comparison. - # c[3] is the right side of the comparison. - cmd.append(['SHOW_COMPARISON', c[1], c[2], c[3]]) + # cmd[2] is the variable on the left side of the comparison or + # None if the value is a constant. + # cmd[3] is the value of the left side of the comparison. + # cmd[4] is the variable on the right side of the comparison or + # None if the value is a constant. + # cmd[5] is the value of the right side of the comparison. + cmd.append(['SHOW_COMPARISON', c[1], c[2], c[3], c[4], c[5]]) elif c[0] == 'SHOW_INT_OPERATION': # c[1] is the sign of the operation. - # c[2] is the left side of the operation. - # c[3] is the right side of the operation. - cmd.append(['SHOW_OPERATION', c[1], int(c[2]), int(c[3])]) + # cmd[2] is the variable on the left side of the operation or + # None if the value is a constant. + # cmd[3] is the value of the left side of the operation. + # cmd[4] is the variable on the right side of the operation or + # None if the value is a constant. + # cmd[5] is the value of the right side of the operation. + cmd.append(['SHOW_OPERATION', c[1], c[2], int(c[3]), \ + c[4], int(c[5])]) elif c[0] == 'OUTPUT': # c[1] is the string to output. cmd.append(['OUTPUT', c[1]]) Index: ChangeLog =================================================================== RCS file: /cvsroot/openexvis/openexvis/ChangeLog,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- ChangeLog 15 Aug 2005 20:36:04 -0000 1.10 +++ ChangeLog 15 Aug 2005 23:36:15 -0000 1.11 @@ -4,7 +4,9 @@ CVS * Internal restructuring - * Improve the animation + * Improve the animation a lot + * The screen is now cleaned up when a new file is loaded + * The output area is cleared when beginning a new visualization * Fix showing integer calculation result * When storing to a variable, the old value is now shown and new value moved on top of it |