From e9032003f7397b19e3e58ac11da021db9a6a9061 Mon Sep 17 00:00:00 2001 From: Anna Wiggins Date: Wed, 18 Apr 2012 01:04:36 -0400 Subject: [PATCH] Implemented performance updates in GoGame --- pygo.py | 1 + widgets/gogame.py | 63 ++++++++++++++++++++++++++++++++++------------- 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/pygo.py b/pygo.py index e493903..6f3dc27 100755 --- a/pygo.py +++ b/pygo.py @@ -51,6 +51,7 @@ class Pygo(): self.gogame = gogame.GoGame(goban.Goban()) self.contents.pack_start(self.gogame) self.gogame.show_all() + self.gogame.update() def on_net_direct(self, widget): diff --git a/widgets/gogame.py b/widgets/gogame.py index d6edc1f..f1c59ce 100644 --- a/widgets/gogame.py +++ b/widgets/gogame.py @@ -65,11 +65,12 @@ class GoGame(gtk.HBox): gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK) - self.board_area.connect('expose-event', self.draw_board) + self.board_area.connect('expose-event', self.do_board_expose) + self.board_area.connect('configure-event', self.do_board_configure) self.board_area.connect('motion-notify-event', self.do_hover) self.board_area.connect('button-press-event', self.do_play) - self.pack_start(self.board_area) + self.pack_start(self.board_area, expand=False) self.pack_end(info_box, expand=False) self.update_info() @@ -86,13 +87,14 @@ class GoGame(gtk.HBox): row = int(y / inc) col = int(x / inc) + old_hover = self.goban.hover if max(row,col) < board_size: if self.goban._real_pos((row,col)) != self.goban.hover: self.goban.set_hover((row,col)) - self.board_area.queue_draw() + self.update_board((old_hover, self.goban.hover)) else: self.goban.clear_hover() - self.board_area.queue_draw() + self.update_board([old_hover]) def do_play(self, widget, event): @@ -107,29 +109,51 @@ class GoGame(gtk.HBox): col = int(x / inc) self.goban.play_move((row,col)) - self.update_info() + self.update() - # fixme: create a backbuffer pixmap and draw to *that* when we need to update - # the board, then just use *this* to print that to the DrawingArea... - def draw_board(self, widget, event): + def do_board_configure(self, widget, event): gc = widget.get_style().fg_gc[gtk.STATE_NORMAL] - drawable = widget.window - # pixmap = gtk.gdk.Pixmap(window, width, height, depth=-1) + x,y,width,height = widget.get_allocation() + self.board_backbuf = gtk.gdk.Pixmap(widget.window, width, height, depth=-1) + self.board_backbuf.draw_rectangle(widget.get_style().white_gc, True, 0, 0, width, height) + return True + + + def do_board_expose(self, widget, event): + x , y, width, height = event.area + widget.window.draw_drawable(widget.get_style().fg_gc[gtk.STATE_NORMAL], + self.board_backbuf, x, y, x, y, width, height) + return False + + + # fixme: rendering/updating the whole board is pretty slow. Eliminate the need to + # render the whole board when a stone is played (we need a list of modified + # locations from somewhere) + def update_board(self, to_update=None): + if to_update == None: + to_update = range(len(self.goban.board)) + + gc = self.board_area.get_style().fg_gc[gtk.STATE_NORMAL] + + # this is a bit of a hack... + width, height = self.board_area.get_size_request() - width, height = widget.size_request() size = min(width, height) board_size = self.goban.board_size inc = size / board_size - for i in range(len(self.goban.board)): + for i in to_update: + if i is None: + continue + # Get the right image and scale it base_img = GoGame.img_res[self.goban.draw_code(i)] img = base_img.scale_simple(inc, inc, gtk.gdk.INTERP_BILINEAR) row = i / board_size col = i % board_size - drawable.draw_pixbuf(gc, img, 0, 0, inc * col, inc * row, inc, inc) + self.board_backbuf.draw_pixbuf(gc, img, 0, 0, inc * col, inc * row, inc, inc) if i == self.goban.hover: if self.goban.to_move == goban.Goban.BLACK: @@ -139,19 +163,19 @@ class GoGame(gtk.HBox): base_img = GoGame.img_res[code] img = base_img.scale_simple(inc, inc, gtk.gdk.INTERP_BILINEAR) - drawable.draw_pixbuf(gc, img, 0, 0, inc * col, inc * row, inc, inc) - + self.board_backbuf.draw_pixbuf(gc, img, 0, 0, inc * col, inc * row, inc, inc) + self.board_area.queue_draw() def on_pass(self, widget): self.goban.pass_move() - self.update_info() + self.update() def on_resign(self, widget): self.goban.resign() - self.update_info() + self.update() # fixme: Add a widget to show the outcome @@ -167,6 +191,11 @@ class GoGame(gtk.HBox): self.white_cap_value.set_text(str(self.goban.white_captures)) + def update(self): + self.update_info() + self.update_board() + + def _magnitude(vector):