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);