Curry a void* to fader callbacks #284

This commit is contained in:
nick black 2020-01-17 09:30:53 -05:00
parent d95069fb1e
commit b02acd8631
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC
13 changed files with 95 additions and 51 deletions

View File

@ -1056,27 +1056,26 @@ My 14 year-old self would never forgive me if we didn't have sweet palette fades
// Called for each delta performed in a fade on ncp. If anything but 0 is returned,
// the fading operation ceases immediately, and that value is propagated out. If provided
// and not NULL, the faders will not themselves call notcurses_render().
typedef int (*fadecb)(struct notcurses* nc, struct ncplane* ncp);
typedef int (*fadecb)(struct notcurses* nc, struct ncplane* ncp, void* curry);
// Fade the ncplane out over the provided time, calling the specified function
// when done. Requires a terminal which supports direct color, or at least
// palette modification (if the terminal uses a palette, our ability to fade
// planes is limited, and affected by the complexity of the rest of the screen).
// It is not safe to resize or destroy the plane during the fadeout.
int ncplane_fadeout(struct ncplane* n, const struct timespec* ts, fadecb fader);
// It is not safe to resize or destroy the plane during the fadeout FIXME.
int ncplane_fadeout(struct ncplane* n, const struct timespec* ts, fadecb fader, void* curry);
// Fade the ncplane in over the specified time. Load the ncplane with the
// target cells without rendering, then call this function. When it's done, the
// ncplane will have reached the target levels, starting from zeroes.
// It is not safe to resize or destroy the plane during the fadein.
int ncplane_fadein(struct ncplane* n, const struct timespec* ts, fadecb fader);
int ncplane_fadein(struct ncplane* n, const struct timespec* ts, fadecb fader, void* curry);
// Pulse the plane in and out until the callback returns non-zero, relying on
// the callback 'fader' to initiate rendering. 'ts' defines the half-period
// (i.e. the transition from black to full brightness, or back again). Proper
// use involves preparing (but not rendering) an ncplane, then calling
// ncplane_pulse(), which will fade in from black to the specified colors.
int ncplane_pulse(struct ncplane* n, const struct timespec* ts, fadecb fader);
int ncplane_pulse(struct ncplane* n, const struct timespec* ts, fadecb fader, void* curry);
```
#### Plane channels API

View File

@ -11,14 +11,20 @@ notcurses_fade - fade ncplanes in and out
**#include <notcurses.h>**
```c
// Called for each delta performed in a fade on ncp. If anything but 0 is
// returned, the fading operation ceases immediately, and that value is
// propagated out. If provided and not NULL, the faders will not themselves
// call notcurses_render().
typedef int (*fadecb)(struct notcurses* nc, struct ncplane* ncp);
```
**int ncplane_fadeout(struct ncplane* n, const struct timespec* ts);**
**bool notcurses_canfade(const struct notcurses* nc);**
**int ncplane_fadein(struct ncplane* n, const struct timespec* ts);**
**int ncplane_fadeout(struct ncplane* n, const struct timespec* ts, fadecb fader, void* curry);**
**int ncplane_pulse(struct ncplane* n, const struct timespec* ts, fadecb fader);**
**int ncplane_fadein(struct ncplane* n, const struct timespec* ts, fadecb fader, void* curry);**
**int ncplane_pulse(struct ncplane* n, const struct timespec* ts, fadecb fader, void* curry);**
# DESCRIPTION

View File

@ -9,9 +9,6 @@ notcurses_ncvisual - notcurses multimedia
**#include <notcurses.h>**
**struct ncvisual* ncplane_visual_open(struct ncplane* nc, const char* file,
int* averr);**
```c
typedef enum {
NCSCALE_NONE,
@ -22,6 +19,11 @@ typedef enum {
typedef int (*streamcb)(struct notcurses*, struct ncvisual*, void*);
```
**bool notcurses_canopen(const struct notcurses* nc);**
**struct ncvisual* ncplane_visual_open(struct ncplane* nc, const char* file,
int* averr);**
**struct ncvisual* ncvisual_open_plane(struct notcurses* nc, const char* file,
int* averr, int y, int x,
ncscale_e style);**

View File

@ -1435,26 +1435,26 @@ API unsigned ncplane_styles(struct ncplane* n);
// Called for each delta performed in a fade on ncp. If anything but 0 is returned,
// the fading operation ceases immediately, and that value is propagated out. If provided
// and not NULL, the faders will not themselves call notcurses_render().
typedef int (*fadecb)(struct notcurses* nc, struct ncplane* ncp);
typedef int (*fadecb)(struct notcurses* nc, struct ncplane* ncp, void* curry);
// Fade the ncplane out over the provided time, calling the specified function
// when done. Requires a terminal which supports direct color, or at least
// palette modification (if the terminal uses a palette, our ability to fade
// planes is limited, and affected by the complexity of the rest of the screen).
// It is not safe to resize or destroy the plane during the fadeout FIXME.
API int ncplane_fadeout(struct ncplane* n, const struct timespec* ts, fadecb fader);
API int ncplane_fadeout(struct ncplane* n, const struct timespec* ts, fadecb fader, void* curry);
// Fade the ncplane in over the specified time. Load the ncplane with the
// target cells without rendering, then call this function. When it's done, the
// ncplane will have reached the target levels, starting from zeroes.
API int ncplane_fadein(struct ncplane* n, const struct timespec* ts, fadecb fader);
API int ncplane_fadein(struct ncplane* n, const struct timespec* ts, fadecb fader, void* curry);
// Pulse the plane in and out until the callback returns non-zero, relying on
// the callback 'fader' to initiate rendering. 'ts' defines the half-period
// (i.e. the transition from black to full brightness, or back again). Proper
// use involves preparing (but not rendering) an ncplane, then calling
// ncplane_pulse(), which will fade in from black to the specified colors.
API int ncplane_pulse(struct ncplane* n, const struct timespec* ts, fadecb fader);
API int ncplane_pulse(struct ncplane* n, const struct timespec* ts, fadecb fader, void* curry);
// Working with cells

View File

@ -123,7 +123,7 @@ int hud_schedule(const char* demoname);
// demo_render(), which will ensure the HUD stays on the top of the z-stack.
int demo_render(struct notcurses* nc);
int demo_fader(struct notcurses* nc, struct ncplane* ncp);
int demo_fader(struct notcurses* nc, struct ncplane* ncp, void* curry);
// grab the hud with the mouse
int hud_grab(int y, int x);
@ -146,16 +146,12 @@ const demoresult* demoresult_lookup(int idx);
/*----------------------------------HUD----------------------------------*/
static inline int
pulser(struct notcurses* nc, struct ncplane* ncp __attribute__ ((unused))){
static struct timespec first = { .tv_sec = 0, .tv_nsec = 0, };
pulser(struct notcurses* nc, struct ncplane* ncp __attribute__ ((unused)), void* curry){
struct timespec* start = curry;
struct timespec now;
if(timespec_to_ns(&first) == 0){
clock_gettime(CLOCK_MONOTONIC, &first);
}else{
clock_gettime(CLOCK_MONOTONIC, &now);
if(timespec_to_ns(&now) - timespec_to_ns(&first) >= timespec_to_ns(&demodelay) * 4 / 3){
return 1;
}
clock_gettime(CLOCK_MONOTONIC, &now);
if(timespec_to_ns(&now) - timespec_to_ns(start) >= timespec_to_ns(&demodelay) * 4 / 3){
return 1;
}
return demo_render(nc);
}

View File

@ -1,4 +1,32 @@
#include "demo.h"
#include <pthread.h>
static bool done = false;
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
static int
patentpulser(struct notcurses* nc, struct ncplane* ncp, void* curry){
(void)ncp;
(void)curry;
if(notcurses_render(nc)){
return -1;
}
bool donecheck;
pthread_mutex_lock(&lock);
donecheck = done;
pthread_mutex_unlock(&lock);
if(donecheck){
return 1;
}
return 0;
}
static void*
patentpulsar(void* n){
struct notcurses* nc = n;
ncplane_pulse(notcurses_stdplane(nc), &demodelay, patentpulser, NULL);
return NULL;
}
static int
drop_bricks(struct notcurses* nc, struct ncplane** arr, int arrcount){
@ -184,11 +212,20 @@ int fallin_demo(struct notcurses* nc){
ncvisual_destroy(ncv);
return -1;
}
notcurses_render(nc);
pthread_t tid;
if(pthread_create(&tid, NULL, patentpulsar, nc)){
return -1;
}
int ret = drop_bricks(nc, arr, arrcount);
sleep(1);
pthread_mutex_lock(&lock);
done = true;
pthread_mutex_unlock(&lock);
if(pthread_join(tid, NULL)){
return -1;
}
assert(ncvisual_decode(ncv, &averr) == NULL);
assert(averr == AVERROR_EOF);
ncvisual_destroy(ncv);
ncplane_pulse(notcurses_stdplane(nc), &demodelay, pulser);
return ret;
}

View File

@ -32,8 +32,9 @@ static struct elem* running;
// it, and throw away the oldest entry each time.
static int writeline = HUD_ROWS - 1;
int demo_fader(struct notcurses* nc, struct ncplane* ncp){
int demo_fader(struct notcurses* nc, struct ncplane* ncp, void* curry){
(void)ncp;
(void)curry;
return demo_render(nc);
}

View File

@ -96,6 +96,6 @@ int intro(struct notcurses* nc){
}
nanosleep(&demodelay, NULL);
struct timespec fade = demodelay;
ncplane_fadeout(ncp, &fade, demo_fader);
ncplane_fadeout(ncp, &fade, demo_fader, NULL);
return 0;
}

View File

@ -27,7 +27,7 @@ fadethread(void* vnc){
struct notcurses* nc = vnc;
struct ncplane* ncp = notcurses_stdplane(nc);
struct timespec fade = { .tv_sec = 2, .tv_nsec = 0, };
ncplane_fadeout(ncp, &fade, demo_fader);
ncplane_fadeout(ncp, &fade, demo_fader, NULL);
ncvisual_destroy(chncv);
int averr;
char* path = find_data("samoa.avi");
@ -158,7 +158,7 @@ int outro(struct notcurses* nc){
targy = 3;
pthread_create(&tid, NULL, fadethread, nc);
pthread_join(tid, &ret);
ncplane_fadeout(on, &demodelay, demo_fader);
ncplane_fadeout(on, &demodelay, demo_fader, NULL);
ncplane_destroy(on);
}
if(ret == NULL){

View File

@ -264,7 +264,9 @@ int trans_demo(struct notcurses* nc){
if(demo_render(nc)){
return -1;
}
ncplane_pulse(l, &demodelay, pulser);
struct timespec now;
clock_gettime(CLOCK_MONOTONIC_RAW, &now);
ncplane_pulse(l, &demodelay, pulser, &now);
ncplane_destroy(l);
return slidepanel(nc);
}

View File

@ -538,7 +538,7 @@ int witherworm_demo(struct notcurses* nc){
}else{
ns_to_timespec(delay, &tv);
}
ncplane_fadein(n, &tv, demo_fader);
ncplane_fadein(n, &tv, demo_fader, NULL);
}
pthread_t tid;
pthread_create(&tid, NULL, worm_thread, nc);

View File

@ -81,7 +81,7 @@ alloc_ncplane_palette(ncplane* n, planepalette* pp){
static int
ncplane_fadein_internal(ncplane* n, const struct timespec* ts,
fadecb fader, planepalette* pp){
fadecb fader, planepalette* pp, void* curry){
int maxfsteps = pp->maxg > pp->maxr ? (pp->maxb > pp->maxg ? pp->maxb : pp->maxg) :
(pp->maxb > pp->maxr ? pp->maxb : pp->maxr);
int maxbsteps = pp->maxbg > pp->maxbr ? (pp->maxbb > pp->maxbg ? pp->maxbb : pp->maxbg) :
@ -133,7 +133,7 @@ ncplane_fadein_internal(ncplane* n, const struct timespec* ts,
}
}
if(fader){
ret |= fader(n->nc, n);
ret |= fader(n->nc, n, curry);
}else{
ret |= notcurses_render(n->nc);
}
@ -155,7 +155,7 @@ ncplane_fadein_internal(ncplane* n, const struct timespec* ts,
return ret;
}
int ncplane_fadeout(ncplane* n, const struct timespec* ts, fadecb fader){
int ncplane_fadeout(ncplane* n, const struct timespec* ts, fadecb fader, void* curry){
planepalette pp;
if(!n->nc->RGBflag && !n->nc->CCCflag){ // terminal can't fade
return -1;
@ -227,7 +227,7 @@ int ncplane_fadeout(ncplane* n, const struct timespec* ts, fadecb fader){
cell_set_bg_rgb(&n->basecell, br, bg, bb);
}
if(fader){
ret = fader(n->nc, n);
ret = fader(n->nc, n, curry);
}else{
ret = notcurses_render(n->nc);
}
@ -250,11 +250,11 @@ int ncplane_fadeout(ncplane* n, const struct timespec* ts, fadecb fader){
return ret;
}
int ncplane_fadein(ncplane* n, const struct timespec* ts, fadecb fader){
int ncplane_fadein(ncplane* n, const struct timespec* ts, fadecb fader, void* curry){
planepalette pp;
if(!n->nc->RGBflag && !n->nc->CCCflag){ // terminal can't fade
if(fader){
fader(n->nc, n);
fader(n->nc, n, curry);
}else{
notcurses_render(n->nc);
}
@ -263,12 +263,12 @@ int ncplane_fadein(ncplane* n, const struct timespec* ts, fadecb fader){
if(alloc_ncplane_palette(n, &pp)){
return -1;
}
int ret = ncplane_fadein_internal(n, ts, fader, &pp);
int ret = ncplane_fadein_internal(n, ts, fader, &pp, curry);
free(pp.channels);
return ret;
}
int ncplane_pulse(ncplane* n, const struct timespec* ts, fadecb fader){
int ncplane_pulse(ncplane* n, const struct timespec* ts, fadecb fader, void* curry){
planepalette pp;
int ret;
if(!n->nc->RGBflag && !n->nc->CCCflag){ // terminal can't fade
@ -278,11 +278,11 @@ int ncplane_pulse(ncplane* n, const struct timespec* ts, fadecb fader){
return -1;
}
for(;;){
ret = ncplane_fadein_internal(n, ts, fader, &pp);
ret = ncplane_fadein_internal(n, ts, fader, &pp, curry);
if(ret){
break;
}
ret = ncplane_fadeout(n, ts, fader);
ret = ncplane_fadeout(n, ts, fader, curry);
if(ret){
break;
}

View File

@ -3,15 +3,14 @@
#include <iostream>
#include "internal.h"
struct timespec pulsestart;
int pulser(struct notcurses* nc, struct ncplane* ncp __attribute__ ((unused))){
int pulser(struct notcurses* nc, struct ncplane* ncp __attribute__ ((unused)), void* curry){
struct timespec* pulsestart = static_cast<struct timespec*>(curry);
if(notcurses_render(nc)){
return -1;
}
struct timespec now;
clock_gettime(CLOCK_MONOTONIC_RAW, &now);
auto delta = timespec_to_ns(&now) - timespec_to_ns(&pulsestart);
auto delta = timespec_to_ns(&now) - timespec_to_ns(pulsestart);
if(delta > 1000000000){
return 1;
}
@ -53,19 +52,20 @@ TEST_CASE("Fade") {
}
}
SUBCASE("FadeOut") {
CHECK(0 == notcurses_render(nc_));
struct timespec ts;
ts.tv_sec = 1;
ts.tv_nsec = 0;
CHECK(0 == ncplane_fadeout(n_, &ts, nullptr));
CHECK(0 == ncplane_fadeout(n_, &ts, nullptr, nullptr));
}
SUBCASE("FadeIn") {
struct timespec ts;
ts.tv_sec = 1;
ts.tv_nsec = 0;
CHECK(0 == ncplane_fadein(n_, &ts, nullptr));
CHECK(0 == ncplane_fadein(n_, &ts, nullptr, nullptr));
}
SUBCASE("Pulse") {
@ -75,8 +75,9 @@ TEST_CASE("Fade") {
ncplane_erase(n_);
ncplane_set_fg(n_, 0xffd700);
CHECK(0 < ncplane_printf_aligned(n_, dimy - 1, NCALIGN_CENTER, "pulllllllse"));
struct timespec pulsestart;
clock_gettime(CLOCK_MONOTONIC_RAW, &pulsestart);
CHECK(0 < ncplane_pulse(n_, &ts, pulser));
CHECK(0 < ncplane_pulse(n_, &ts, pulser, &pulsestart));
}
CHECK(0 == notcurses_stop(nc_));