mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 17:19:03 -04:00
Curry a void* to fader callbacks #284
This commit is contained in:
parent
d95069fb1e
commit
b02acd8631
11
README.md
11
README.md
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);**
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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){
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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_));
|
||||
|
Loading…
x
Reference in New Issue
Block a user