shithub: da

Download patch

ref: 02c13a3ce3bcf6e19dcf794c4efa57d4056b2d4c
parent: 31ef221de8dcd5baca4e48520af6c84d97a8ec8b
author: glenda <glenda@krsna>
date: Wed Aug 20 16:42:20 EDT 2025

soa-refactor

--- a/da.c
+++ b/da.c
@@ -5,9 +5,9 @@
 #include <keyboard.h>
 #include <bio.h>
 
-#define CONFIG_FILE 						"/tmp/da.conf"
-#define DEFAULT_CTL_FILE 					"/tmp/da.ctl"
-#define DEFAULT_SAVE_PATH 					"/tmp/canvas.da"
+#define CONFIG_FILE 						"/usr/glenda/da/da.conf"
+#define DEFAULT_CTL_FILE 					"/usr/glenda/da/da.ctl"
+#define DEFAULT_SAVE_PATH 					"/usr/glenda/da/canvas.da"
 #define DEFAULT_CTL_CHECK_INTERVAL 			200
 #define DEFAULT_REDRAW_INTERVAL 			30
 #define DEFAULT_BANNER_HEIGHT 				25
@@ -23,7 +23,7 @@
 #define DEFAULT_GRIDSNAP					1
 #define DEFAULT_EMOJI						1
 /* const */
-#define MAXBOXES 							2000
+#define MAXBOXES 							9000
 
 
 enum {
@@ -74,23 +74,24 @@
 
 typedef struct Box Box;
 struct Box {
-	Point		pos;
-	Rectangle	r;
-	int			type;
-	int			selected;
-	int 		color_idx;
+	Rectangle	r[MAXBOXES];
+	int 		color_idx[MAXBOXES];
+	Point		pos[MAXBOXES];
+	int			type[MAXBOXES];
+	int			selected[MAXBOXES];
+
 };
 
 typedef struct BoxType BoxType;
 struct BoxType {
 	char	*name;
-	void	(*draw)(Box*, Image*);
+	void	(*draw)(int idx, Image*);
 	int		default_color;
 };
 
 typedef struct Canvas Canvas;
 struct Canvas {
-	Box		boxes[MAXBOXES];
+	Box		boxes;
 	int		nboxes;
 	int		selected;
 	int		fnkey;
@@ -163,8 +164,7 @@
 void handlekey(int key);
 void handlemouse(Mouse m);
 void cleanup(void);
-void draw_box(Box*, Image*);
-void draw_bigbox(Box*, Image*);
+void draw_box(int idx, Image *dst);
 void draw_nol(void);
 void draw_fnol(void);
 void draw_bg(void);
@@ -193,6 +193,9 @@
 void initcolors(void);
 void validate_config(void);
 void apply_config(void);
+int addbox(Point p);
+void delbox(int i);
+int boxat(Point p);
 
 static ulong palette[] = {
 	0x2ECC71FF, 0x34495EFF, 0x95A5A6FF, 0xE67E22FF,
@@ -243,7 +246,7 @@
 			file_key,
 			fn_mouse,
 			draw_fnol,
-			"Tab:/tmp/  Enter:confirm  Esc:cancel"
+			"Tab:/usr/glenda/da/  Enter:confirm  Esc:cancel"
 		},
 };
 
@@ -656,107 +659,142 @@
     "~v~v~"
 };
 
-void
+void 
 save_da(char *file)
 {
-	int fd;
-	Biobuf *b;
-	int i;
-	Box *box;
-
-	fd = create(file, OWRITE, 0644);
-	if(fd < 0){
-		fprint(2, "cannot create %s: %r\n", file);
-		return;
-	}
-
-	b = Bfdopen(fd, OWRITE);
-
-	for(i = 0; i < canvas.nboxes; i++){
-		box = &canvas.boxes[i];
-		Bprint(b, "box %d\n", i);
-		Bprint(b, "  pos %d %d\n", box->pos.x, box->pos.y);
-		Bprint(b, "  type %d\n", box->type);
-		Bprint(b, "  color %08lux\n", palette[box->color_idx]);
-	}
-
-	Bterm(b);
-	close(fd);
+    int fd, i;
+    Biobuf *b;
+    
+    fd = create(file, OWRITE, 0644);
+    if(fd < 0){
+        fprint(2, "cannot create %s: %r\n", file);
+        return;
+    }
+    
+    b = Bfdopen(fd, OWRITE);
+    
+    // New format - write arrays in bulk
+    Bprint(b, "count %d\n", canvas.nboxes);
+    
+    // Write all data in array chunks - much more efficient!
+    
+    // Positions array
+    Bprint(b, "positions\n");
+    for(i = 0; i < canvas.nboxes; i++){
+        Bprint(b, "%d %d\n", 
+            canvas.boxes.pos[i].x, 
+            canvas.boxes.pos[i].y);
+    }
+    
+    // Types array
+    Bprint(b, "types\n");
+    for(i = 0; i < canvas.nboxes; i++){
+        Bprint(b, "%d\n", canvas.boxes.type[i]);
+    }
+    
+    // Colors array  
+    Bprint(b, "colors\n");
+    for(i = 0; i < canvas.nboxes; i++){
+        Bprint(b, "%d\n", canvas.boxes.color_idx[i]);
+    }
+    
+    Bterm(b);
+    close(fd);
 }
 
-void
+void 
 load_da(char *file)
 {
-	Biobuf *b;
-	char *line;
-	char *fields[10];
-	int nf;
-
-	b = Bopen(file, OREAD);
-	if(b == nil){
-		fprint(2, "cannot open %s: %r\n", file);
-		return;
-	}
-
-	memset(&canvas, 0, sizeof(canvas));
-	canvas.selected = -1;
-	canvas.fnkey = 0;
-	canvas.current_mode = 0;
-	canvas.current_color = 8;
-	canvas.gridsize = config.gridsize;
-	canvas.gridsnap = config.gridsnap;
-	init_emoji();
-
-	while((line = Brdline(b, '\n')) != nil){
-		line[Blinelen(b)-1] = '\0';
-
-		if(line[0] == '#' || line[0] == '\0')
-			continue;
-
-		nf = tokenize(line, fields, nelem(fields));
-
-		if(nf >= 2 && strcmp(fields[0], "box") == 0){
-			if(canvas.nboxes < MAXBOXES){
-				Box *box = &canvas.boxes[canvas.nboxes];
-				memset(box, 0, sizeof(Box));
-				box->r = Rect(0, 0, config.box_width, config.box_height);
-				canvas.nboxes++;
-			}
-		} else if(nf >= 3 && strcmp(fields[0], "pos") == 0){
-			Box *box = &canvas.boxes[canvas.nboxes-1];
-			box->pos.x = atoi(fields[1]);
-			box->pos.y = atoi(fields[2]);
-			box->r = Rect(box->pos.x, box->pos.y,
-					 box->pos.x + config.box_width, box->pos.y + config.box_height);
-
-		} else if(nf >= 2 && strcmp(fields[0], "type") == 0){
-			int type = atoi(fields[1]);
-			if (type >= 0 && type < MAXBOXTYPES) {
-				Box *box = &canvas.boxes[canvas.nboxes-1];
-				box->type = type;
-				
-				if(type == T_BIGBOX){
-					box->r = Rect(box->pos.x, box->pos.y, 
-						box->pos.x + config.bigbox_width, 
-						box->pos.y + config.bigbox_height);
-				}
-			}
-		} else if(nf >= 2 && strcmp(fields[0], "color") == 0){
-				ulong loaded_color = strtoul(fields[1], nil, 16);
-				int color_idx = 0; 
-					for(int i = 0; i < 16; i++) {
-						if (palette[i] == loaded_color) {
-							color_idx = i;
-							break;
-						}
-					}
-				canvas.boxes[canvas.nboxes-1].color_idx = color_idx;
-		}
-	}
-
-	Bterm(b);
-	redraw();
-}
+    Biobuf *b;
+    char *line;
+    char *fields[10];
+    int nf, i;
+    enum { NONE, POSITIONS, TYPES, COLORS } section = NONE;
+    int idx = 0;
+    int count = 0;
+    
+    b = Bopen(file, OREAD);
+    if(b == nil){
+        fprint(2, "cannot open %s: %r\n", file);
+        return;
+    }
+    
+    // Clear canvas
+    memset(&canvas.boxes, 0, sizeof(canvas.boxes));
+    canvas.nboxes = 0;
+    canvas.selected = -1;
+    canvas.current_color = 8;
+    init_emoji();
+    
+    while((line = Brdline(b, '\n')) != nil){
+        line[Blinelen(b)-1] = '\0';
+        
+        if(line[0] == '#' || line[0] == '\0')
+            continue;
+        
+        nf = tokenize(line, fields, nelem(fields));
+        if(nf == 0) continue;
+        
+        // Check for section headers 
+		if(strcmp(fields[0], "count") == 0 && nf >= 2){
+            count = atoi(fields[1]);
+            if(count > MAXBOXES) count = MAXBOXES;
+        } else if(strcmp(fields[0], "positions") == 0){
+            section = POSITIONS;
+            idx = 0;
+        } else if(strcmp(fields[0], "types") == 0){
+            section = TYPES;
+            idx = 0;
+        } else if(strcmp(fields[0], "colors") == 0){
+            section = COLORS;
+            idx = 0;
+        } else {
+            // Parse data based on current section
+            switch(section){
+            case POSITIONS:
+                if(nf >= 2 && idx < count){
+                    canvas.boxes.pos[idx] = Pt(atoi(fields[0]), atoi(fields[1]));
+                    idx++;
+                }
+                break;
+                
+            case TYPES:
+                if(nf >= 1 && idx < count){
+                    canvas.boxes.type[idx] = atoi(fields[0]);
+                    idx++;
+                }
+                break;
+                
+            case COLORS:
+                if(nf >= 1 && idx < count){
+                    canvas.boxes.color_idx[idx] = atoi(fields[0]);
+                    idx++;
+                }
+                break;
+            }
+        }
+    }
+    
+    canvas.nboxes = count;
+    
+    // Reconstruct rectangles from positions and types
+    for(i = 0; i < canvas.nboxes; i++){
+        Point p = canvas.boxes.pos[i];
+        if(canvas.boxes.type[i] == T_BIGBOX){
+            canvas.boxes.r[i] = Rect(p.x, p.y,
+                p.x + config.bigbox_width,
+                p.y + config.bigbox_height);
+        } else {
+            canvas.boxes.r[i] = Rect(p.x, p.y,
+                p.x + config.box_width,
+                p.y + config.box_height);
+        }
+        canvas.boxes.selected[i] = 0;  // Clear selection on load
+    }
+    
+    Bterm(b);
+    redraw();
+}
 
 void
 save_config(char *path)
@@ -996,15 +1034,14 @@
 void
 cmd_set_color(int idx)
 {
-	if(idx >= 0 && idx < 16) {
-		canvas.current_color = idx;
-		if(canvas.selected >= 0 && canvas.selected < canvas.nboxes) {
-			canvas.boxes[canvas.selected].color_idx = idx;
-		}
-		canvas.needredraw = 1;
-	}
+    if(idx >= 0 && idx < 16) {
+        canvas.current_color = idx;
+        if(canvas.selected >= 0 && canvas.selected < canvas.nboxes) {
+            canvas.boxes.color_idx[canvas.selected] = idx;
+        }
+        canvas.needredraw = 1;
+    }
 }
-
 void 
 cmd_toggle_boxtype(void)
 {
@@ -1012,73 +1049,78 @@
     canvas.needredraw = 1;
 }
 
-int
+int 
 boxat(Point p)
 {
-	int i;
-	Box *b;
-
-	for(i = canvas.nboxes - 1; i >= 0; i--){
-		b = &canvas.boxes[i];
-		if(ptinrect(p, b->r))
-			return i;
-	}
-	return -1;
+    int i;
+    for(i = canvas.nboxes - 1; i >= 0; i--){
+        if(ptinrect(p, canvas.boxes.r[i]))
+            return i;
+    }
+    return -1;
 }
 
-int
+int 
 addbox(Point p)
 {
-    Box *b;
+    int idx;
     if(canvas.nboxes >= MAXBOXES)
         return -1;
-
-    b = &canvas.boxes[canvas.nboxes];
-    memset(b, 0, sizeof(Box));
-
-    if(canvas.gridsnap){
+    
+    idx = canvas.nboxes;
+    
+    if(canvas.gridsnap) {
         p.x = (p.x / canvas.gridsize) * canvas.gridsize;
         p.y = (p.y / canvas.gridsize) * canvas.gridsize;
     }
-
-    b->pos = p;
-    b->type = canvas.next_box_type; 
-    b->color_idx = canvas.current_color;
-
-    if(b->type == T_BIGBOX) {
-        b->r = Rect(p.x, p.y, 
-            p.x + config.bigbox_width,   
-            p.y + config.bigbox_height);  
+    
+    canvas.boxes.pos[idx] = p;
+    canvas.boxes.type[idx] = canvas.next_box_type;
+    canvas.boxes.color_idx[idx] = canvas.current_color;
+    canvas.boxes.selected[idx] = 0;
+    
+    if(canvas.boxes.type[idx] == T_BIGBOX) {
+        canvas.boxes.r[idx] = Rect(p.x, p.y, 
+            p.x + config.bigbox_width,
+            p.y + config.bigbox_height);
     } else {
-        b->r = Rect(p.x, p.y, 
-            p.x + config.box_width,       
-            p.y + config.box_height);      
+        canvas.boxes.r[idx] = Rect(p.x, p.y,
+            p.x + config.box_width,
+            p.y + config.box_height);
     }
     
     return canvas.nboxes++;
 }
 
-void
+void 
 delbox(int i)
 {
-	if(i < 0 || i >= canvas.nboxes)
-		return;
-
-	memmove(&canvas.boxes[i], &canvas.boxes[i+1],
-		(canvas.nboxes - i - 1) * sizeof(Box));
-	canvas.nboxes--;
-	
+    int last;
+    if(i < 0 || i >= canvas.nboxes)
+        return;
+    
+    last = canvas.nboxes - 1;
+    
+    if(i != last) {
+        canvas.boxes.pos[i] = canvas.boxes.pos[last];
+        canvas.boxes.r[i] = canvas.boxes.r[last];
+        canvas.boxes.type[i] = canvas.boxes.type[last];
+        canvas.boxes.selected[i] = canvas.boxes.selected[last];
+        canvas.boxes.color_idx[i] = canvas.boxes.color_idx[last];
+    }
+    
+    canvas.nboxes--;
 }
 
 void
-draw_box(Box *b, Image *dst)
+draw_box(int idx, Image *dst)
 {
-    Image *bg = colors[b->color_idx];
+    Image *bg = colors[canvas.boxes.color_idx[idx]];
     
-    if(b->selected)
+    if(canvas.boxes.selected[idx])
         bg = boxselected;
     
-    draw(dst, b->r, bg, nil, ZP);
+    draw(dst, canvas.boxes.r[idx], bg, nil, ZP);
 }
 
 void
@@ -1143,21 +1185,33 @@
 	drawgrid(screen);
 }
 
-void
+void 
 draw_all(void)
 {
-	int i;
-	for(i = 0; i < canvas.nboxes; i++) {
-		Box *b = &canvas.boxes[i];
-		if (b->type >= 0 && b->type < MAXBOXTYPES) {
-			BoxType *bt = &boxtypes[b->type];
-			if (bt->draw) {
-				bt->draw(b, screen);
-			}
-		}
-	}
+    int i;
+    // First pass: Draw all regular boxes
+    for(i = 0; i < canvas.nboxes; i++) {
+        if(canvas.boxes.type[i] == T_BOX) {
+            Image *color = colors[canvas.boxes.color_idx[i]];
+            draw(screen, canvas.boxes.r[i], color, nil, ZP);
+        }
+    }
+    
+    // Second pass: Draw all big boxes  
+    for(i = 0; i < canvas.nboxes; i++) {
+        if(canvas.boxes.type[i] == T_BIGBOX) {
+            Image *color = colors[canvas.boxes.color_idx[i]];
+            draw(screen, canvas.boxes.r[i], color, nil, ZP);
+        }
+    }
+    
+    // Third pass: Draw selection highlights
+    for(i = 0; i < canvas.nboxes; i++) {
+        if(canvas.boxes.selected[i]) {
+            border(screen, canvas.boxes.r[i], 2, boxselected, ZP);
+        }
+    }
 }
-
 void
 draw_status(void)
 {
@@ -1538,24 +1592,23 @@
 void
 norm_key(int key)
 {
-	Command *cmd;
-
+	Command *cmd;	
 	if(key >= '0' && key <= '9') {
-		cmd_set_color(key - '0');
-		return;
-	}
-	
-	if(key >= 'a' && key <= 'f') {
-		cmd_set_color(10 + (key - 'a'));
-		return;
-	}
+        cmd_set_color(key - '0');  // Pass the index
+        return;
+    }
+    
+    if(key >= 'a' && key <= 'f') {
+        cmd_set_color(10 + (key - 'a'));  // Pass the index
+        return;
+    }
 
-	for(cmd = commands; cmd->action; cmd++) {
-		if(cmd->key == key) {
-			cmd->action();
-			return;
-		}
-	}
+    for(cmd = commands; cmd->action; cmd++) {
+        if(cmd->key == key) {
+            cmd->action();
+            return;
+        }
+    }
 }
 
 void
@@ -1580,8 +1633,8 @@
 		canvas.current_mode = 0;
 		canvas.needredraw = 1;
 	} else if(key == '\t') {
-		if(!strstr(canvas.fnbuf, "/tmp/")) {
-			strcat(canvas.fnbuf, "/tmp/");
+		if(!strstr(canvas.fnbuf, "/usr/glenda/da/")) {
+			strcat(canvas.fnbuf, "/usr/glenda/da/");
 			canvas.fnpos = strlen(canvas.fnbuf);
 			canvas.needredraw = 1;
 		}
@@ -1615,26 +1668,29 @@
         }
     }
     
-    if(m.buttons & 2){ 
+	if(m.buttons & 2){ 
         i = boxat(m.xy);
         if(i >= 0){
             canvas.selected = i;
-            Box *box = &canvas.boxes[i];
-            int width = (box->type == T_BIGBOX) ? config.bigbox_width : config.box_width;
-            int height = (box->type == T_BIGBOX) ? config.bigbox_height : config.box_height;
-            box->selected = 1;
+            // Access arrays directly, not through pointer
+            int type = canvas.boxes.type[i];
+            int width = (type == T_BIGBOX) ? config.bigbox_width : config.box_width;
+            int height = (type == T_BIGBOX) ? config.bigbox_height : config.box_height;
+            canvas.boxes.selected[i] = 1;
+            
             while(m.buttons & 2){
-                box->pos = subpt(m.xy, Pt(width/2, height/2));
+                Point new_pos = subpt(m.xy, Pt(width/2, height/2));
                 if(canvas.gridsnap){
-                    box->pos.x = (box->pos.x / canvas.gridsize) * canvas.gridsize;
-                    box->pos.y = (box->pos.y / canvas.gridsize) * canvas.gridsize;
+                    new_pos.x = (new_pos.x / canvas.gridsize) * canvas.gridsize;
+                    new_pos.y = (new_pos.y / canvas.gridsize) * canvas.gridsize;
                 }
-                box->r = Rect(box->pos.x, box->pos.y,
-                    box->pos.x + width, box->pos.y + height);
+                canvas.boxes.pos[i] = new_pos;
+                canvas.boxes.r[i] = Rect(new_pos.x, new_pos.y,
+                    new_pos.x + width, new_pos.y + height);
                 redraw();
                 m = emouse();
             }
-			box->selected = 0;
+            canvas.boxes.selected[i] = 0;
             canvas.needredraw = 1;
         }
     }
@@ -1655,14 +1711,13 @@
 {
 	USED(m);
 }
-
 void
 ctl_addbox(char **args, int nargs)
 {
-	Point p = Pt(atoi(args[0]), atoi(args[1]));
-	int idx = addbox(p);
-
-	canvas.needredraw = 1;
+    USED(nargs);  // Add this
+    Point p = Pt(atoi(args[0]), atoi(args[1]));
+    addbox(p);     // Don't need to capture idx if not using it
+    canvas.needredraw = 1;
 }
 
 void
--