mirror of
https://github.com/dankamongmen/notcurses.git
synced 2024-11-16 00:13:00 +00:00
zoo: delay based off mult, add reader thread #835
This commit is contained in:
parent
86e6b2d89b
commit
bea35fb91f
126
src/demo/zoo.c
126
src/demo/zoo.c
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user