shithub: asif

Download patch

ref: a9376bfb28fbd354131420aafa67fedd1e9a3ca0
parent: 24fe53736af84d40f9f513e08876a4e05278b9a4
author: qwx <qwx@sciops.net>
date: Thu Nov 3 18:48:12 EDT 2022

fix panning performance, drawing, reseting

- avoid redrawing everything at every mouse event
- pan boundaries, should be correct now
- partial fix to spurious malformed path error

--- a/app/path/client.c
+++ b/app/path/client.c
@@ -29,6 +29,7 @@
 void
 evloop(void)
 {
+	int n;
 	Rune r;
 	Mouse mold;
 
@@ -46,6 +47,15 @@
 	};
 	for(;;){
 		switch(alt(a)){
+		Redraw:
+			switch(n){
+			case 0: updatedrw(0, 0); break;
+			case 1: updatedrw(0, 1); break;
+			case 2: updatedrw(1, 0); break;
+			case 3: updatedrw(1, 1); break;
+			case 4: resetdrw(); break;
+			}
+			break;
 		case Aresize:
 			if(getwindow(display, Refnone) < 0)
 				sysfatal("resize failed: %r");
@@ -53,13 +63,12 @@
 			mold = mc->Mouse;
 			break;
 		case Amouse:
-			if(mousefn(mc->Mouse, subpt(mc->Mouse.xy, mold.xy)))
-				updatedrw(0);
+			n = mousefn(mc->Mouse, subpt(mc->Mouse.xy, mold.xy));
 			mold = mc->Mouse;
-			break;
+			goto Redraw;
 		case Akbd:
-			keyfn(r);
-			break;
+			n = keyfn(r);
+			goto Redraw;
 		}
 	}
 }
--- a/app/path/drw.c
+++ b/app/path/drw.c
@@ -7,7 +7,6 @@
 #include "dat.h"
 #include "fns.h"
 
-QLock drawlock;
 Node *selected;
 int showgrid;
 int nodesz = 1;
@@ -30,9 +29,9 @@
 	Cend,
 };
 static Image *col[Cend];
-static Point viewΔ;
+static Point viewΔ, panmax;
 static Rectangle viewr, hudr;
-static Image *view;
+static Image *view, *board;
 
 static Image *
 eallocimage(Rectangle r, int repl, ulong col)
@@ -44,11 +43,24 @@
 	return i;
 }
 
-void
+int
 dopan(Point p)
 {
-	pan.x -= p.x;
-	pan.y -= p.y;
+	p.x = pan.x - p.x;
+	p.y = pan.y - p.y;
+	if(p.x < -panmax.x/2)
+		p.x = -panmax.x/2;
+	else if(p.x > panmax.x/2)
+		p.x = panmax.x/2;
+	if(p.y < 0)
+		p.y = 0;
+	else if(p.y > panmax.y)
+		p.y = panmax.y;
+	if(!eqpt(p, pan)){
+		pan = p;
+		return 0;
+	}
+	return -1;
 }
 
 void
@@ -94,6 +106,7 @@
 	char s[128], *sp;
 	Node *n;
 	Point p;
+	Sim *sim;
 
 	draw(screen, hudr, col[Cbg], nil, ZP);
 	sp = seprint(s, s+sizeof s, "grid size: %dx%d (x%d)", gridwidth, gridheight, nodesz);
@@ -129,8 +142,18 @@
 		p.y += font->height;
 		string(screen, p, col[Cfree], ZP, font, s);
 	}
+	if(sims != nil && curscen < sims->n){
+		sim = (Sim *)sims->p + curscen;
+		seprint(s, s+sizeof s,
+			"ref len=%d Δ=%.2f $=%.2f opened=%d expanded=%d updated=%d closed=%d",
+			sim->steps, sim->dist, sim->cost, sim->opened, sim->expanded,
+			sim->updated, sim->closed);
+		p.y += font->height;
+		string(screen, p, col[Cfree], ZP, font, s);
+	}
 }
 
+/* FIXME: multiple, spurious calls when repathing */
 static void
 drawscenpath(void)
 {
@@ -140,7 +163,7 @@
 	Node *n;
 	Rectangle r;
 
-	if(sims == nil || curscen >= sims->n)
+	if(sims == nil || curscen >= sims->n || goal == nil || start == nil)
 		return;
 	sp = (Sim *)sims->p + curscen;
 	if(sp->path == nil || sp->path->n == 0)
@@ -152,7 +175,7 @@
 			return;
 		r.min = n2s(n);
 		r.max = addpt(r.min, Pt(sz, sz));
-		draw(view, r, col[Cref], nil, ZP);
+		draw(board, r, col[Cref], nil, ZP);
 	}
 	dprint(Lognone, "path::drawscenpath: malformed or wrong path\n");
 }
@@ -165,6 +188,7 @@
 	Rectangle r;
 	Image *c;
 
+	draw(board, board->r, col[Cfree], nil, ZP);
 	sz = MAX(nodesz - showgrid, 1);
 	for(n=grid; n<grid+gridwidth*gridheight; n++){
 		if(isblocked(n))
@@ -183,7 +207,7 @@
 			continue;
 		r.min = n2s(n);
 		r.max = addpt(r.min, Pt(sz, sz));
-		draw(view, r, c, nil, ZP);
+		draw(board, r, c, nil, ZP);
 	}
 }
 
@@ -222,25 +246,27 @@
 }
 
 static void
-redraw(int clear)
+redraw(int clear, int turboclear)
 {
 	if(clear)
 		draw(screen, screen->r, col[Cbg], nil, ZP);
-	draw(view, view->r, col[Cfree], nil, ZP);
+	if(turboclear){
+		drawnodes();
+		drawscenpath();
+	}
+	draw(view, view->r, board, nil, ZP);
 	if(showgrid && nodesz > 1)
 		drawgrid();
-	drawnodes();
-	drawscenpath();
 	if(nodesz > 8)
 		drawfrom();
 }
 
 void
-updatedrw(int clear)
+updatedrw(int clear, int turboclear)
 {
-	qlock(&drawlock);
-	redraw(clear);
-	qunlock(&drawlock);
+	lockdisplay(display);
+	redraw(clear, turboclear);
+	unlockdisplay(display);
 	drawhud();
 	flushdrw();
 }
@@ -252,11 +278,16 @@
 	viewΔ = divpt(addpt(subpt(ZP, subpt(screen->r.max, screen->r.min)), viewr.max), 2);
 	if(-viewΔ.y < font->height * 2)
 		viewΔ.y = 0;
+	panmax.x = MAX(nodesz * gridwidth - Dx(screen->r), 0);
+	panmax.y = MAX(nodesz * gridheight - Dy(screen->r), 0);
+	dopan(ZP);
 	hudr.min = addpt(screen->r.min, subpt(Pt(2, viewr.max.y+2), viewΔ));
 	hudr.max = addpt(hudr.min, Pt(screen->r.max.x, font->height*3));
 	freeimage(view);
 	view = eallocimage(viewr, 0, DNofill);
-	updatedrw(1);
+	freeimage(board);
+	board = eallocimage(viewr, 0, DNofill);
+	updatedrw(1, 1);
 }
 
 void
@@ -266,6 +297,8 @@
 
 	if(initdraw(nil, nil, "path") < 0)
 		sysfatal("initdraw: %r");
+	display->locking = 1;
+	unlockdisplay(display);
 	col[Cbg] = display->black;
 	col[Cgrid] = eallocimage(Rect(0,0,1,1), 1, 0x222222ff);
 	col[Cblocked] = display->black;
--- a/app/path/fns.h
+++ b/app/path/fns.h
@@ -2,7 +2,7 @@
 void	init(char*, Vertex, int, int, int);
 Node*	scrselect(Point);
 void	errmsg(char*, ...);
-void	updatedrw(int);
+void	updatedrw(int, int);
 int	menter(char*, char*, int);
 void	evloop(void);
 void	writeresults(void);
--- a/app/path/path.c
+++ b/app/path/path.c
@@ -11,7 +11,7 @@
 #include "dat.h"
 #include "fns.h"
 
-extern void	dopan(Point);
+extern int	dopan(Point);
 extern Point pan;
 
 mainstacksize = 128*1024;
@@ -23,34 +23,38 @@
 grmouse(Mouse m, Point Δ)
 {
 	static Node *old;
+	int r;
 	Node *n;
 
 	if(m.buttons == 0){
 		old = nil;
-		return 0;
-	}else if((m.buttons & 7) == 2){
-		dopan(Δ);
-		updatedrw(1);
-		return 1;
-	}
+		return -1;
+	}else if((m.buttons & 7) == 2)
+		return dopan(Δ) >= 0 ? 0 : -1;
 	if((n = scrselect(m.xy)) == nil || old == n)
 		return 0;
+	r = 0;
 	switch(m.buttons & 7){
 	case 1: break; /* just selecting the node */
 	case 4:
 		switch(mousemode){
-		case Mmodegoal: if(n != start && !isblocked(n)) goal = n; break;
-		case Mmodestart: if(n != goal && !isblocked(n)) start = n; break;
+		case Mmodegoal: if(n != start && !isblocked(n)){ goal = n; r=1; } break;
+		case Mmodestart: if(n != goal && !isblocked(n)){ start = n; r=1; } break;
 		case Mmodeblock:
 			if(n != start && n != goal
-			&& (old == nil || isblocked(n) ^ isblocked(old)))
+			&& (old == nil || isblocked(n) ^ isblocked(old))){
 				toggleblocked(n);
+				r = 1;
+			}
 			break;
 		}
 	}
 	old = n;
-	trypath(start, goal);
-	return 1;
+	if(r){
+		trypath(start, goal);
+		return 1;
+	}
+	return 0;
 }
 
 static int
@@ -77,43 +81,19 @@
 {
 	switch(r){
 	case Kdel:
-	case 'q':
-		threadexitsall(nil);
-	case 'r':
-		reloadscen();
-		updatedrw(0);
-		break;
+	case 'q': threadexitsall(nil);
+	case 'r': reloadscen(); return 1;
 	case ' ':
-	case '\n':
-		mousemode = (mousemode + 1) % Mmodes;
-		updatedrw(0);
-		break;
-	case 'g':
-		showgrid ^= 1;
-		updatedrw(0);
-		break;
+	case '\n': mousemode = (mousemode + 1) % Mmodes; return 0;
+	case 'g': showgrid ^= 1; return 0;
 	case '0': case '1': case '2': case '3': case '4':
 	case '5': case '6': case '7': case '8': case '9':
-		if(setscen() >= 0)
-			updatedrw(0);
-		break;
+		return setscen() >= 0 ? 0 : -1;
 	case '+':
-	case '=':
-		if(nodesz < 1<<16){
-			nodesz <<= 1;
-			resetdrw();
-		}
-		break;
-	case '-':
-		if(nodesz > 1){
-			nodesz >>= 1;
-			resetdrw();
-		}
-		break;
-	case 'z':
-		pan = ZP;
-		updatedrw(1);
-		break;
+	/* FIXME: no hud when screen too small */
+	case '=': return nodesz < 1<<16 ? (nodesz <<= 1, 4) : -1;
+	case '-': return nodesz > 1     ? (nodesz >>= 1, 4) : -1;
+	case 'z': pan = ZP; return 2;
 	}
 	return 0;
 }
@@ -217,7 +197,7 @@
 	initgraphics(grkey, grmouse);
 	if(scen != nil){
 		showscen(0);
-		updatedrw(0);
+		updatedrw(0, 1);
 	}
 	evloop();
 	threadexitsall(nil);