Skip to content

Commit dde334a

Browse files
committed
🐛 allow cell fill for different initialization types
This forces a render of all cells on the very first frame, which is perfectly acceptable.
1 parent 37594f1 commit dde334a

3 files changed

Lines changed: 27 additions & 12 deletions

File tree

src/cell.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22

33
#include "cell.h"
44

5-
void cells_clear(Cell *buf, int w, int h) {
5+
void cells_fill(Cell *buf, int w, int h, uint32_t ch, uint32_t fg,
6+
uint32_t bg) {
67
for (int i = 0; i < w * h; i++) {
7-
buf[i].ch = ' ';
8-
buf[i].fg = ATTR_DEFAULT;
9-
buf[i].bg = ATTR_DEFAULT;
8+
buf[i].ch = ch;
9+
buf[i].fg = fg;
10+
buf[i].bg = bg;
1011
}
1112
}
1213

src/cell.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ typedef struct {
2424
#define ATTR_MASK 0xFF000000
2525
#define COLOR_MASK 0x00FFFFFF
2626

27-
void cells_clear(Cell *buf, int w, int h);
27+
void cells_fill(Cell *buf, int w, int h, uint32_t ch, uint32_t fg, uint32_t bg);
2828
int cell_cmp(Cell *a, Cell *b);
2929

3030
#endif

src/clayterm.c

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,13 @@ static void emit_ch(struct Clayterm *ct, int x, int y, uint32_t ch) {
149149
buf_char(&ct->out, ch);
150150
}
151151

152-
/* ── Double-buffer diff (from termbox2 tb_present) ────────────────── */
153-
154-
static void present(struct Clayterm *ct) {
152+
/**
153+
* Diff back buffer against front buffer and emit only changed cells
154+
* using absolute CUP positioning (\x1b[row;colH). Unchanged cells are
155+
* skipped, making this efficient for subsequent frames where most of
156+
* the screen is static. Derived from termbox2 tb_present.
157+
*/
158+
static void present_cups(struct Clayterm *ct) {
155159
ct->lastx = -1;
156160
ct->lasty = -1;
157161

@@ -191,6 +195,13 @@ static void present(struct Clayterm *ct) {
191195
}
192196
}
193197

198+
/**
199+
* Emit back buffer as newline-separated rows without CUP positioning.
200+
* Every cell is written (no diffing), and the front buffer is primed
201+
* so that a subsequent present() call can diff efficiently. This is
202+
* used for inline "region" rendering where the caller manages cursor
203+
* positioning externally and the output must work in pipes.
204+
*/
194205
static void present_lines(struct Clayterm *ct) {
195206
for (int y = 0; y < ct->h; y++) {
196207
if (y > 0)
@@ -416,8 +427,11 @@ struct Clayterm *init(void *mem, int w, int h, int row) {
416427
.lasty = -1,
417428
};
418429

419-
cells_clear(ct->front, w, h);
420-
cells_clear(ct->back, w, h);
430+
// initialize back buffer with spaces and default fg/bg
431+
cells_fill(ct->back, w, h, ' ', ATTR_DEFAULT, ATTR_DEFAULT);
432+
433+
// initialize front buffer with zeros. Every cell will be
434+
cells_fill(ct->front, w, h, 0, 0, 0);
421435
return ct;
422436
}
423437

@@ -551,7 +565,7 @@ void reduce(struct Clayterm *ct, uint32_t *buf, int len, int mode) {
551565
ct->lastfg = ct->lastbg = 0xffffffff;
552566
ct->lastx = ct->lasty = -1;
553567

554-
cells_clear(ct->back, ct->w, ct->h);
568+
cells_fill(ct->back, ct->w, ct->h, ' ', ATTR_DEFAULT, ATTR_DEFAULT);
555569

556570
/* walk Clay render commands into back buffer */
557571
for (int32_t j = 0; j < cmds.length; j++) {
@@ -590,7 +604,7 @@ void reduce(struct Clayterm *ct, uint32_t *buf, int len, int mode) {
590604
if (mode == 1) {
591605
present_lines(ct);
592606
} else {
593-
present(ct);
607+
present_cups(ct);
594608
}
595609
}
596610

0 commit comments

Comments
 (0)