mirror of
https://github.com/dankamongmen/notcurses.git
synced 2024-11-02 09:40:15 +00: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 <pthread.h>
|
||||||
#include "demo.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
|
// Fill up the screen with as much crazy Unicode as we can, and then set a
|
||||||
// gremlin loose, looking to brighten up the world.
|
// gremlin loose, looking to brighten up the world.
|
||||||
|
|
||||||
@ -131,38 +125,42 @@ wormy(worm* s, int dimy, int dimx){
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// each worm wanders around aimlessly. it lights up the cells around it; to do
|
struct worm_ctx {
|
||||||
// this, we keep an array of 13 cells with the original colors, which we tune up.
|
int wormcount;
|
||||||
static void *
|
worm* worms;
|
||||||
worm_thread(void* vnc){
|
};
|
||||||
struct notcurses* nc = vnc;
|
|
||||||
int dimy, dimx;
|
int init_worms(struct worm_ctx* wctx, int dimy, int dimx){
|
||||||
notcurses_term_dim_yx(nc, &dimy, &dimx);
|
if((wctx->wormcount = (dimy * dimx) / 800) == 0){
|
||||||
int wormcount = (dimy * dimx) / 800;
|
wctx->wormcount = 1;
|
||||||
worm worms[wormcount];
|
|
||||||
for(int s = 0 ; s < wormcount ; ++s){
|
|
||||||
init_worm(&worms[s], dimy, dimx);
|
|
||||||
}
|
}
|
||||||
while(true){
|
if((wctx->worms = malloc(sizeof(*wctx->worms) * wctx->wormcount)) == NULL){
|
||||||
pthread_testcancel();
|
return -1;
|
||||||
for(int s = 0 ; s < wormcount ; ++s){
|
}
|
||||||
if(wormy_top(nc, &worms[s])){
|
for(int s = 0 ; s < wctx->wormcount ; ++s){
|
||||||
return NULL;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int err;
|
int err;
|
||||||
if( (err = demo_render(nc)) ){
|
if( (err = demo_render(nc)) ){
|
||||||
if(err > 0){
|
return err;
|
||||||
return DEMO_ABORTED;
|
}
|
||||||
|
for(int s = 0 ; s < wctx->wormcount ; ++s){
|
||||||
|
if(wormy(&wctx->worms[s], dimy, dimx)){
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(int s = 0 ; s < wormcount ; ++s){
|
return 0;
|
||||||
if(wormy(&worms[s], dimy, dimx)){
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -555,27 +553,27 @@ int witherworm_demo(struct notcurses* nc){
|
|||||||
}
|
}
|
||||||
ncplane_fadein(n, &tv, demo_fader, NULL);
|
ncplane_fadein(n, &tv, demo_fader, NULL);
|
||||||
}
|
}
|
||||||
pthread_t tid;
|
|
||||||
// FIXME this could just be brought inline, no need for a thread
|
struct worm_ctx wctx;
|
||||||
pthread_create(&tid, NULL, worm_thread, nc);
|
if( (err = init_worms(&wctx, maxy, maxx)) ){
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
struct timespec cur;
|
||||||
do{
|
do{
|
||||||
struct timespec left, cur;
|
if( (err = worm_move(nc, &wctx, maxy, maxx)) ){
|
||||||
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){
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}while(key < 0);
|
key = demo_getc_nblock(nc, NULL);
|
||||||
pthread_cancel(tid);
|
clock_gettime(CLOCK_MONOTONIC, &cur);
|
||||||
void* result = NULL;
|
if(timespec_to_ns(&screenend) < timespec_to_ns(&cur)){
|
||||||
pthread_join(tid, &result);
|
break;
|
||||||
|
}
|
||||||
|
}while(key == 0);
|
||||||
|
|
||||||
ncplane_destroy(mess);
|
ncplane_destroy(mess);
|
||||||
ncplane_destroy(math);
|
ncplane_destroy(math);
|
||||||
if(result == DEMO_ABORTED){
|
if(err){
|
||||||
return 1;
|
return err;
|
||||||
}
|
}
|
||||||
if(key == NCKEY_RESIZE){
|
if(key == NCKEY_RESIZE){
|
||||||
DEMO_RENDER(nc);
|
DEMO_RENDER(nc);
|
||||||
|
Loading…
Reference in New Issue
Block a user