O(1) plane bondage #670

Make ncplane_reparent() O(1).
Make ncplane_delete() O(1)
O(1) link severance for planes bound to deleted plane.
Allglyph demo requires UTF8.
pull/677/head
nick black 4 years ago
parent e99abeae01
commit b65437a53f
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC

@ -41,6 +41,9 @@ allglyphs(struct notcurses* nc, struct ncplane* column){
// render all the glyphs worth rendering
int allglyphs_demo(struct notcurses* nc){
if(!notcurses_canutf8(nc)){
return 0;
}
int dimy, dimx;
struct ncplane* n = notcurses_stddim_yx(nc, &dimy, &dimx);
ncplane_erase(n);

@ -9,13 +9,16 @@ void notcurses_debug(notcurses* nc, FILE* debugfp){
fprintf(debugfp, "%04d off y: %3d x: %3d geom y: %3d x: %3d curs y: %3d x: %3d %s %p\n",
planeidx, n->absy, n->absx, n->leny, n->lenx, n->y, n->x,
n == notcurses_stdplane_const(nc) ? "std" : " ", n);
if(n->bound || n->bnext || n->blist){
if(n->bound || n->bnext || *n->bprev){
fprintf(debugfp, " bound to %p, next bound %p, bind %p\n",
n->bound, n->bnext, n->blist);
n->bound, n->bnext, *n->bprev);
}
if(n->bound == n || n->bnext == n || n->blist == n){
if(n->bnext == n || n->bound == n){
fprintf(debugfp, "WARNING: bound pointers target self\n");
}
if(*n->bprev != n){
fprintf(stderr, " WARNING: expected *->bprev %p, got %p\n", n, *n->bprev);
}
if(n->above != prev){
fprintf(stderr, " WARNING: expected ->above %p, got %p\n", prev, n->above);
}

@ -126,6 +126,9 @@ calc_highgradient(cell* c, uint64_t ul, uint64_t ur, uint64_t ll,
int ncplane_highgradient(ncplane* n, uint32_t ul, uint32_t ur,
uint32_t ll, uint32_t lr, int ystop, int xstop){
if(!notcurses_canutf8(n->nc)){
return -1;
}
if(check_gradient_channel_args(ul, ur, ll, lr)){
return -1;
}

@ -64,23 +64,23 @@ struct esctrie;
// circular buffer of rows. 'logrow' is the index of the row at the logical top
// of the plane.
typedef struct ncplane {
cell* fb; // "framebuffer" of character cells
int logrow; // logical top row, starts at 0, add one for each scroll
int x, y; // current cursor location within this plane
int absx, absy; // origin of the plane relative to the screen
int lenx, leny; // size of the plane, [0..len{x,y}) is addressable
struct ncplane* above;// plane above us, NULL if we're on top
struct ncplane* below;// plane below us, NULL if we're on bottom
struct ncplane* bnext;// next in the bound list of plane to which we are bound
struct ncplane* blist;// head of our own bound list, if any
struct ncplane* bound;// plane to which we are bound, if any
egcpool pool; // attached storage pool for UTF-8 EGCs
uint64_t channels; // works the same way as cells
uint32_t attrword; // same deal as in a cell
void* userptr; // slot for the user to stick some opaque pointer
cell basecell; // cell written anywhere that fb[i].gcluster == 0
struct notcurses* nc; // notcurses object of which we are a part
bool scrolling; // is scrolling enabled? always disabled by default
cell* fb; // "framebuffer" of character cells
int logrow; // logical top row, starts at 0, add one for each scroll
int x, y; // current cursor location within this plane
int absx, absy; // origin of the plane relative to the screen
int lenx, leny; // size of the plane, [0..len{x,y}) is addressable
struct ncplane* above; // plane above us, NULL if we're on top
struct ncplane* below; // plane below us, NULL if we're on bottom
struct ncplane* bnext; // next in the bound list of plane to which we are bound
struct ncplane** bprev;// link to us if we're bound
struct ncplane* bound; // plane to which we are bound, if any
egcpool pool; // attached storage pool for UTF-8 EGCs
uint64_t channels; // works the same way as cells
uint32_t attrword; // same deal as in a cell
void* userptr; // slot for the user to stick some opaque pointer
cell basecell; // cell written anywhere that fb[i].gcluster == 0
struct notcurses* nc; // notcurses object of which we are a part
bool scrolling; // is scrolling enabled? always disabled by default
} ncplane;
#include "blitset.h"

@ -277,21 +277,25 @@ ncplane_create(notcurses* nc, ncplane* n, int rows, int cols,
p->lenx = cols;
p->x = p->y = 0;
p->logrow = 0;
if( (p->bound = n) ){
p->bound = NULL;
if(n){
p->absx = xoff + n->absx;
p->absy = yoff + n->absy;
p->bnext = n->blist;
n->blist = p;
if( (p->bnext = n->bound) ){
n->bound->bprev = &p->bnext;
}
n->bound = p;
p->bprev = &n->bound;
}else{
p->absx = xoff + nc->margin_l;
p->absy = yoff + nc->margin_t;
p->bnext = NULL;
p->bprev = NULL;
}
p->attrword = 0;
p->channels = 0;
egcpool_init(&p->pool);
cell_init(&p->basecell);
p->blist = NULL;
p->userptr = opaque;
p->above = NULL;
if( (p->below = nc->top) ){ // always happens save initial plane
@ -504,12 +508,11 @@ int ncplane_destroy(ncplane* ncp){
}else{
ncp->nc->bottom = ncp->above;
}
if(ncp->bprev){
*ncp->bprev = ncp->bnext;
}
if(ncp->bound){
ncplane** prev = &ncp->bound->blist;
while(*prev != ncp){
prev = &(*prev)->bnext;
}
*prev = (*prev)->bnext;
ncp->bound->bprev = NULL;
}
free_plane(ncp);
return 0;
@ -1653,7 +1656,7 @@ move_bound_planes(ncplane* n, int dy, int dx){
while(n){
n->absy += dy;
n->absx += dx;
move_bound_planes(n->blist, dy, dx);
move_bound_planes(n->bound, dy, dx);
n = n->bnext;
}
}
@ -1672,7 +1675,7 @@ int ncplane_move_yx(ncplane* n, int y, int x){
}
n->absx += dx;
n->absy += dy;
move_bound_planes(n->blist, dy, dx);
move_bound_planes(n->bound, dy, dx);
return 0;
}
@ -1831,19 +1834,14 @@ ncplane* ncplane_reparent(ncplane* n, ncplane* newparent){
if(n == n->nc->stdscr){
return NULL; // can't reparent standard plane
}
if(n->bound){ // detach it, and extract it from list
for(ncplane** prev = &n->bound->blist ; *prev ; prev = &(*prev)->bnext){
if(*prev == n){
*prev = n->bnext;
break;
}
}
n->bnext = NULL;
if( (*n->bprev = n->bnext) ){
n->bnext->bprev = n->bprev;
}
if( (n->bound = newparent) ){
n->bnext = newparent->blist;
newparent->blist = n;
if( (n->bnext = newparent->bound) ){
n->bnext->bprev = &n->bnext;
}
n->bprev = &newparent->bound;
newparent->bound = n;
return n;
}

Loading…
Cancel
Save