mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-10 01:29:05 -04:00
whiteout: kill worm_thread, eliminate race #504
This commit is contained in:
parent
9fa52fcdef
commit
80a1185529
@ -7,12 +7,6 @@
|
||||
#include <pthread.h>
|
||||
#include "demo.h"
|
||||
|
||||
// some random value to differentiate a demo abort, as indicated via
|
||||
// demo_render() in worm_thread(). we can't use PTHREAD_CANCELED, since we
|
||||
// do actually make use of cancellation.
|
||||
static int demo_aborted = 0;
|
||||
static void* DEMO_ABORTED = &demo_aborted;
|
||||
|
||||
// Fill up the screen with as much crazy Unicode as we can, and then set a
|
||||
// gremlin loose, looking to brighten up the world.
|
||||
|
||||
@ -131,38 +125,42 @@ wormy(worm* s, int dimy, int dimx){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// each worm wanders around aimlessly. it lights up the cells around it; to do
|
||||
// this, we keep an array of 13 cells with the original colors, which we tune up.
|
||||
static void *
|
||||
worm_thread(void* vnc){
|
||||
struct notcurses* nc = vnc;
|
||||
int dimy, dimx;
|
||||
notcurses_term_dim_yx(nc, &dimy, &dimx);
|
||||
int wormcount = (dimy * dimx) / 800;
|
||||
worm worms[wormcount];
|
||||
for(int s = 0 ; s < wormcount ; ++s){
|
||||
init_worm(&worms[s], dimy, dimx);
|
||||
struct worm_ctx {
|
||||
int wormcount;
|
||||
worm* worms;
|
||||
};
|
||||
|
||||
int init_worms(struct worm_ctx* wctx, int dimy, int dimx){
|
||||
if((wctx->wormcount = (dimy * dimx) / 800) == 0){
|
||||
wctx->wormcount = 1;
|
||||
}
|
||||
while(true){
|
||||
pthread_testcancel();
|
||||
for(int s = 0 ; s < wormcount ; ++s){
|
||||
if(wormy_top(nc, &worms[s])){
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
int err;
|
||||
if( (err = demo_render(nc)) ){
|
||||
if(err > 0){
|
||||
return DEMO_ABORTED;
|
||||
}
|
||||
}
|
||||
for(int s = 0 ; s < wormcount ; ++s){
|
||||
if(wormy(&worms[s], dimy, dimx)){
|
||||
return NULL;
|
||||
}
|
||||
if((wctx->worms = malloc(sizeof(*wctx->worms) * wctx->wormcount)) == NULL){
|
||||
return -1;
|
||||
}
|
||||
for(int s = 0 ; s < wctx->wormcount ; ++s){
|
||||
init_worm(&wctx->worms[s], dimy, dimx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// the whiteworms wander around aimlessly, lighting up cells around themselves
|
||||
static int
|
||||
worm_move(struct notcurses* nc, struct worm_ctx* wctx, int dimy, int dimx){
|
||||
for(int s = 0 ; s < wctx->wormcount ; ++s){
|
||||
if(wormy_top(nc, &wctx->worms[s])){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
int err;
|
||||
if( (err = demo_render(nc)) ){
|
||||
return err;
|
||||
}
|
||||
for(int s = 0 ; s < wctx->wormcount ; ++s){
|
||||
if(wormy(&wctx->worms[s], dimy, dimx)){
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -555,27 +553,27 @@ int witherworm_demo(struct notcurses* nc){
|
||||
}
|
||||
ncplane_fadein(n, &tv, demo_fader, NULL);
|
||||
}
|
||||
pthread_t tid;
|
||||
// FIXME this could just be brought inline, no need for a thread
|
||||
pthread_create(&tid, NULL, worm_thread, nc);
|
||||
|
||||
struct worm_ctx wctx;
|
||||
if( (err = init_worms(&wctx, maxy, maxx)) ){
|
||||
return err;
|
||||
}
|
||||
struct timespec cur;
|
||||
do{
|
||||
struct timespec left, cur;
|
||||
clock_gettime(CLOCK_MONOTONIC, &cur);
|
||||
timespec_subtract(&left, &screenend, &cur);
|
||||
key = demo_getc(nc, &left, NULL);
|
||||
clock_gettime(CLOCK_MONOTONIC, &cur);
|
||||
int64_t ns = timespec_subtract_ns(&cur, &screenend);
|
||||
if(ns > 0){
|
||||
if( (err = worm_move(nc, &wctx, maxy, maxx)) ){
|
||||
break;
|
||||
}
|
||||
}while(key < 0);
|
||||
pthread_cancel(tid);
|
||||
void* result = NULL;
|
||||
pthread_join(tid, &result);
|
||||
key = demo_getc_nblock(nc, NULL);
|
||||
clock_gettime(CLOCK_MONOTONIC, &cur);
|
||||
if(timespec_to_ns(&screenend) < timespec_to_ns(&cur)){
|
||||
break;
|
||||
}
|
||||
}while(key == 0);
|
||||
|
||||
ncplane_destroy(mess);
|
||||
ncplane_destroy(math);
|
||||
if(result == DEMO_ABORTED){
|
||||
return 1;
|
||||
if(err){
|
||||
return err;
|
||||
}
|
||||
if(key == NCKEY_RESIZE){
|
||||
DEMO_RENDER(nc);
|
||||
|
Loading…
x
Reference in New Issue
Block a user