zoo: delay based off mult, add reader thread #835

This commit is contained in:
nick black 2020-07-30 02:47:10 -04:00 committed by Nick Black
parent 86e6b2d89b
commit bea35fb91f
2 changed files with 115 additions and 12 deletions

View File

@ -1,4 +1,19 @@
#include "demo.h"
#include <pthread.h>
static int
locked_demo_render(struct notcurses* nc, pthread_mutex_t* lock){
int ret;
if(pthread_mutex_lock(lock)){
return -1;
}
ret = demo_render(nc);
if(pthread_mutex_unlock(lock)){
return -1;
}
return ret;
}
// we list all distributions on which notcurses is known to exist
static struct ncselector_item select_items[] = {
@ -38,7 +53,8 @@ static struct ncmselector_item mselect_items[] = {
};
static struct ncmultiselector*
multiselector_demo(struct notcurses* nc, struct ncplane* n, int dimx, int y){
multiselector_demo(struct ncplane* n, int dimx, int y, pthread_mutex_t* lock){
struct notcurses* nc = ncplane_notcurses(n);
ncmultiselector_options mopts = {
.maxdisplay = 8,
.title = "multi-item selector",
@ -63,7 +79,7 @@ multiselector_demo(struct notcurses* nc, struct ncplane* n, int dimx, int y){
ncplane_move_yx(mplane, y, -length);
ncinput ni;
for(int i = -length + 1 ; i < dimx - (length + 1) ; ++i){
if(demo_render(nc)){
if(locked_demo_render(nc, lock)){
ncmultiselector_destroy(mselector);
return NULL;
}
@ -76,14 +92,14 @@ multiselector_demo(struct notcurses* nc, struct ncplane* n, int dimx, int y){
ncmultiselector_offer_input(mselector, &ni);
}
}
if(demo_render(nc)){
if(locked_demo_render(nc, lock)){
ncmultiselector_destroy(mselector);
return NULL;
}
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
uint64_t cur = timespec_to_ns(&ts);
uint64_t targ = cur + GIG;
uint64_t targ = cur + timespec_to_ns(&demodelay);
do{
struct timespec rel;
ns_to_timespec(targ - cur, &rel);
@ -122,7 +138,8 @@ draw_background(struct notcurses* nc){
}
static struct ncselector*
selector_demo(struct notcurses* nc, struct ncplane* n, int dimx, int y){
selector_demo(struct ncplane* n, int dimx, int y, pthread_mutex_t* lock){
struct notcurses* nc = ncplane_notcurses(n);
ncselector_options sopts = {
.title = "single-item selector",
.items = select_items,
@ -146,7 +163,7 @@ selector_demo(struct notcurses* nc, struct ncplane* n, int dimx, int y){
timespec_div(&demodelay, dimx / 3, &swoopdelay);
ncinput ni;
for(int i = dimx - 1 ; i > 1 ; --i){
if(demo_render(nc)){
if(locked_demo_render(nc, lock)){
ncselector_destroy(selector, NULL);
return NULL;
}
@ -159,14 +176,14 @@ selector_demo(struct notcurses* nc, struct ncplane* n, int dimx, int y){
ncselector_offer_input(selector, &ni);
}
}
if(demo_render(nc)){
if(locked_demo_render(nc, lock)){
ncselector_destroy(selector, NULL);
return NULL;
}
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
uint64_t cur = timespec_to_ns(&ts);
uint64_t targ = cur + GIG;
uint64_t targ = cur + timespec_to_ns(&demodelay);
do{
struct timespec rel;
ns_to_timespec(targ - cur, &rel);
@ -183,24 +200,109 @@ selector_demo(struct notcurses* nc, struct ncplane* n, int dimx, int y){
return selector;
}
typedef struct read_marshal {
struct notcurses* nc;
struct ncreader* reader;
pthread_mutex_t* lock;
} read_marshal;
static void*
reader_thread(void* vmarsh){
read_marshal* marsh = vmarsh;
struct notcurses* nc = marsh->nc;
struct ncreader* reader = marsh->reader;
pthread_mutex_t* lock = marsh->lock;
free(marsh);
int x, y;
struct ncplane* rplane = ncreader_plane(reader);
ncplane_yx(rplane, &y, &x);
// FIXME move it up, add text
if(locked_demo_render(nc, lock)){
// FIXME
}
return NULL;
}
// creates an ncreader, and spawns a thread which will fill it with text
// describing the rest of the demo
static struct ncreader*
reader_demo(struct notcurses* nc, pthread_t* tid, pthread_mutex_t* lock){
read_marshal* marsh = malloc(sizeof(*marsh));
if(marsh == NULL){
return NULL;
}
marsh->nc = nc;
marsh->lock = lock;
int dimy;
struct ncplane* std = notcurses_stddim_yx(nc, &dimy, NULL);
const int READER_COLS = 40;
const int READER_ROWS = 8;
ncreader_options nopts = {
.physcols = READER_COLS,
.physrows = READER_ROWS,
};
const int x = ncplane_align(std, NCALIGN_CENTER, nopts.physcols);
fprintf(stderr, "PUT READER AT %d/%d\n", dimy, x);
if((marsh->reader = ncreader_create(std, dimy, x, &nopts)) == NULL){
free(marsh);
return NULL;
}
struct ncreader* reader = marsh->reader;
fprintf(stderr, "PUT READER AT %p\n", reader);
if(pthread_create(tid, NULL, reader_thread, marsh)){
ncreader_destroy(marsh->reader, NULL);
free(marsh);
return NULL;
}
return reader;
}
static int
zap_reader(pthread_t tid, struct ncreader* reader){
pthread_cancel(tid);
int ret = pthread_join(tid, NULL);
ncreader_destroy(reader, NULL);
return ret;
}
int zoo_demo(struct notcurses* nc){
int dimx;
if(draw_background(nc)){
return -1;
}
pthread_mutex_t lock;
if(pthread_mutex_init(&lock, NULL)){
return -1;
}
struct ncplane* n = notcurses_stddim_yx(nc, NULL, &dimx);
struct ncselector* selector = selector_demo(nc, n, dimx, 2);
struct ncmultiselector* mselector = multiselector_demo(nc, n, dimx, 8); // FIXME calculate from splane
pthread_t readertid;
struct ncreader* reader = reader_demo(nc, &readertid, &lock);
// if we didn't get a reader, need to hand-roll the exit, since we have no
// thread at which we might go off blasting
if(reader == NULL){
pthread_mutex_destroy(&lock);
return -1;
}
struct ncselector* selector = selector_demo(n, dimx, 2, &lock);
struct ncmultiselector* mselector = multiselector_demo(n, dimx, 8, &lock); // FIXME calculate from splane
if(selector == NULL || mselector == NULL){
goto err;
}
ncselector_destroy(selector, NULL);
ncmultiselector_destroy(mselector);
DEMO_RENDER(nc);
return 0;
locked_demo_render(nc, &lock);
int ret = 0;
fprintf(stderr, "RET: %d\n", ret);
ret |= zap_reader(readertid, reader);
fprintf(stderr, "RET: %d\n", ret);
ret |= pthread_mutex_destroy(&lock);
fprintf(stderr, "RET: %d\n", ret);
return ret;
err:
ncselector_destroy(selector, NULL);
ncmultiselector_destroy(mselector);
zap_reader(readertid, reader);
pthread_mutex_destroy(&lock);
return -1;
}

View File

@ -2329,6 +2329,7 @@ uint32_t* ncplane_rgba(const ncplane* nc, ncblitter_e blit,
return ret;
}
// return a heap-allocated copy of the contents
char* ncplane_contents(const ncplane* nc, int begy, int begx, int leny, int lenx){
if(begy < 0 || begx < 0){
logerror(nc->nc, "Beginning coordinates (%d/%d) below 0\n", begy, begx);