ncreel_destroy: return void

This commit is contained in:
nick black 2020-09-27 15:57:03 -04:00
parent 943e23535f
commit ec85dd1c3b
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC
8 changed files with 116 additions and 121 deletions

View File

@ -1,6 +1,9 @@
This document attempts to list user-visible changes and any major internal
rearrangements of Notcurses.
* 1.7.5 (not yet released)
* `ncreel_destroy()` now returns `void` rather than `int`.
* 1.7.4 (2020-09-20)
* All `_rgb_clipped()` functions have been renamed `_rgb8_clipped()`, to
match the changes made in 1.7.2. Sorry, I ought have done this before.

View File

@ -1949,24 +1949,25 @@ configured instead.
```c
// An ncreel is a notcurses region devoted to displaying zero or more
// line-oriented, contained planes ("tablets") between which the user may
// navigate. If at least one tablet exists, there is an active tablet. As much
// of the active tablet as is possible is always displayed. If there is space
// left over, other tablets are included in the display. Tablets can come and go
// at any time, and can grow or shrink at any time.
// line-oriented, contained tablets between which the user may navigate. If at
// least one tablets exists, there is a "focused tablet". As much of the focused
// tablet as is possible is always displayed. If there is space left over, other
// tablets are included in the display. Tablets can come and go at any time, and
// can grow or shrink at any time.
//
// This structure is amenable to line- and page-based navigation via keystrokes,
// scrolling gestures, trackballs, scrollwheels, touchpads, and verbal commands.
typedef struct ncreel_options {
// is scrolling infinite (can one move down or up forever, or is an end
// reached?). if true, 'circular' specifies how to handle the special case of
// an incompletely-filled reel.
bool infinitescroll;
#define NCREEL_OPTION_INFINITESCROLL 0x0001ull
// is navigation circular (does moving down from the last tablet move to the
// first, and vice versa)? only meaningful when infinitescroll is true. if
// infinitescroll is false, this must be false.
bool circular;
#define NCREEL_OPTION_CIRCULAR 0x0002ull
typedef struct ncreel_options {
// notcurses can draw a border around the ncreel, and also around the
// component tablets. inhibit borders by setting all valid bits in the masks.
// partially inhibit borders by setting individual bits in the masks. the
@ -1978,16 +1979,16 @@ typedef struct ncreel_options {
unsigned tabletmask; // bitfield; same as bordermask but for tablet borders
uint64_t tabletchan; // tablet border styling channel
uint64_t focusedchan;// focused tablet border styling channel
uint64_t bgchannel; // background colors
unsigned flags; // bitfield over NCREEL_OPTION_*
uint64_t flags; // bitfield over NCREEL_OPTION_*
} ncreel_options;
struct nctablet;
struct ncreel;
// Create an ncreel according to the provided specifications. Returns NULL on
// failure. 'nc' must be a valid plane.
struct ncreel* ncreel_create(struct ncplane* nc, const ncreel_options* popts);
// Take over the ncplane 'nc' and use it to draw a reel according to 'popts'.
// The plane will be destroyed by ncreel_destroy(); this transfers ownership.
struct ncreel* ncreel_create(struct ncplane* n, const ncreel_options* popts)
__attribute__ ((nonnull (1)));
// Returns the ncplane on which this ncreel lives.
struct ncplane* ncreel_plane(struct ncreel* pr);
@ -1996,58 +1997,55 @@ struct ncplane* ncreel_plane(struct ncreel* pr);
// may be extracted), and a bool indicating whether output ought be drawn from
// the top (true) or bottom (false). Returns non-negative count of output lines,
// which must be less than or equal to ncplane_dim_y(nctablet_plane(t)).
typedef int (*tabletcb)(struct nctablet* t, bool cliptop);
typedef int (*tabletcb)(struct nctablet* t, bool drawfromtop);
// Add a new nctablet to the provided ncreel, having the callback object
// opaque. Neither, either, or both of after and before may be specified. If
// neither is specified, the new tablet can be added anywhere on the reel. If
// one or the other is specified, the tablet will be added before or after the
// specified tablet. If both are specified, the tablet will be added to the
// Add a new nctablet to the provided ncreel 'nr', having the callback object
// 'opaque'. Neither, either, or both of 'after' and 'before' may be specified.
// If neither is specified, the new tablet can be added anywhere on the reel.
// If one or the other is specified, the tablet will be added before or after
// the specified tablet. If both are specified, the tablet will be added to the
// resulting location, assuming it is valid (after->next == before->prev); if
// it is not valid, or there is any other error, NULL will be returned.
// Calls ncreel_redraw() upon success.
struct nctablet* ncreel_add(struct ncreel* pr, struct nctablet* after,
struct nctablet* before, tabletcb cb,
void* opaque);
struct nctablet* ncreel_add(struct ncreel* nr, struct nctablet* after,
struct nctablet* before, tabletcb cb, void* opaque);
// Return the number of nctablets in the ncreel.
int ncreel_tabletcount(const struct ncreel* pr);
// Return the number of nctablets in the ncreel 'nr'.
int ncreel_tabletcount(const struct ncreel* nr);
// Delete the tablet specified by t from the ncreel specified by pr. Returns
// -1 if the tablet cannot be found. Calls ncreel_redraw() on success.
int ncreel_del(struct ncreel* pr, struct nctablet* t);
// Delete the tablet specified by t from the ncreel 'nr'. Returns -1 if the
// tablet cannot be found.
int ncreel_del(struct ncreel* nr, struct nctablet* t);
// Redraw the ncreel in its entirety. The reel will be cleared, and tablets
// will be lain out, using the focused tablet as a fulcrum. Tablet drawing
// callbacks will be invoked for each visible tablet.
int ncreel_redraw(struct ncreel* pr);
// Redraw the ncreel 'nr' in its entirety. The reel will be cleared, and
// tablets will be lain out, using the focused tablet as a fulcrum. Tablet
// drawing callbacks will be invoked for each visible tablet.
int ncreel_redraw(struct ncreel* nr);
// Offer the input to the ncreel. If it's relevant, this function returns
// Offer input 'ni' to the ncreel 'nr'. If it's relevant, this function returns
// true, and the input ought not be processed further. If it's irrelevant to
// the reel, false is returned. Relevant inputs include:
// * a mouse click on a tablet (focuses tablet)
// * a mouse scrollwheel event (rolls reel)
// * up, down, pgup, or pgdown (navigates among items)
bool ncreel_offer_input(struct ncreel* n, const struct ncinput* nc);
bool ncreel_offer_input(struct ncreel* nr, const struct ncinput* ni);
// Return the focused tablet, if any tablets are present. This is not a copy;
// be careful to use it only for the duration of a critical section.
struct nctablet* ncreel_focused(struct ncreel* pr);
struct nctablet* ncreel_focused(struct ncreel* nr);
// Change focus to the next tablet, if one exists. Calls ncreel_redraw().
struct nctablet* ncreel_next(struct ncreel* pr);
// Change focus to the next tablet, if one exists
struct nctablet* ncreel_next(struct ncreel* nr);
// Change focus to the previous tablet, if one exists. Calls ncreel_redraw().
struct nctablet* ncreel_prev(struct ncreel* pr);
// Change focus to the previous tablet, if one exists
struct nctablet* ncreel_prev(struct ncreel* nr);
// Destroy an ncreel allocated with ncreel_create(). Does not destroy the
// underlying plane. Returns non-zero on failure.
int ncreel_destroy(struct ncreel* pr);
// Destroy an ncreel allocated with ncreel_create().
void ncreel_destroy(struct ncreel* nr);
// Returns a pointer to a user pointer associated with this nctablet.
void* nctablet_userptr(struct nctablet* t);
// Access the ncplane associated with this tablet, if one exists.
// Access the ncplane associated with this nctablet, if one exists.
struct ncplane* nctablet_ncplane(struct nctablet* t);
```

View File

@ -30,7 +30,6 @@ typedef struct ncreel_options {
unsigned tabletmask; // bitfield for tablet borders
uint64_t tabletchan; // tablet border styling channel
uint64_t focusedchan;// focused tablet border styling channel
uint64_t bgchannel; // background colors
unsigned flags; // bitfield over NCREEL_OPTION_*
} ncreel_options;
```
@ -55,7 +54,7 @@ typedef struct ncreel_options {
**struct nctablet* ncreel_prev(struct ncreel* nr);**
**int ncreel_destroy(struct ncreel* nr);**
**void ncreel_destroy(struct ncreel* nr);**
**void* nctablet_userptr(struct nctablet* t);**

View File

@ -2493,49 +2493,49 @@ API struct ncplane* ncreel_plane(struct ncreel* pr);
// which must be less than or equal to ncplane_dim_y(nctablet_plane(t)).
typedef int (*tabletcb)(struct nctablet* t, bool drawfromtop);
// Add a new nctablet to the provided ncreel, having the callback object
// opaque. Neither, either, or both of after and before may be specified. If
// neither is specified, the new tablet can be added anywhere on the reel. If
// one or the other is specified, the tablet will be added before or after the
// specified tablet. If both are specified, the tablet will be added to the
// Add a new nctablet to the provided ncreel 'nr', having the callback object
// 'opaque'. Neither, either, or both of 'after' and 'before' may be specified.
// If neither is specified, the new tablet can be added anywhere on the reel.
// If one or the other is specified, the tablet will be added before or after
// the specified tablet. If both are specified, the tablet will be added to the
// resulting location, assuming it is valid (after->next == before->prev); if
// it is not valid, or there is any other error, NULL will be returned.
API struct nctablet* ncreel_add(struct ncreel* pr, struct nctablet* after,
API struct nctablet* ncreel_add(struct ncreel* nr, struct nctablet* after,
struct nctablet* before, tabletcb cb,
void* opaque);
// Return the number of nctablets in the ncreel.
API int ncreel_tabletcount(const struct ncreel* pr);
// Return the number of nctablets in the ncreel 'nr'.
API int ncreel_tabletcount(const struct ncreel* nr);
// Delete the tablet specified by t from the ncreel specified by pr. Returns
// -1 if the tablet cannot be found.
API int ncreel_del(struct ncreel* pr, struct nctablet* t);
// Delete the tablet specified by t from the ncreel 'nr'. Returns -1 if the
// tablet cannot be found.
API int ncreel_del(struct ncreel* nr, struct nctablet* t);
// Redraw the ncreel in its entirety. The reel will be cleared, and tablets
// will be lain out, using the focused tablet as a fulcrum. Tablet drawing
// callbacks will be invoked for each visible tablet.
API int ncreel_redraw(struct ncreel* pr);
// Redraw the ncreel 'nr' in its entirety. The reel will be cleared, and
// tablets will be lain out, using the focused tablet as a fulcrum. Tablet
// drawing callbacks will be invoked for each visible tablet.
API int ncreel_redraw(struct ncreel* nr);
// Offer the input to the ncreel. If it's relevant, this function returns
// Offer input 'ni' to the ncreel 'nr'. If it's relevant, this function returns
// true, and the input ought not be processed further. If it's irrelevant to
// the reel, false is returned. Relevant inputs include:
// * a mouse click on a tablet (focuses tablet)
// * a mouse scrollwheel event (rolls reel)
// * up, down, pgup, or pgdown (navigates among items)
API bool ncreel_offer_input(struct ncreel* n, const struct ncinput* nc);
API bool ncreel_offer_input(struct ncreel* nr, const struct ncinput* ni);
// Return the focused tablet, if any tablets are present. This is not a copy;
// be careful to use it only for the duration of a critical section.
API struct nctablet* ncreel_focused(struct ncreel* pr);
API struct nctablet* ncreel_focused(struct ncreel* nr);
// Change focus to the next tablet, if one exists
API struct nctablet* ncreel_next(struct ncreel* pr);
API struct nctablet* ncreel_next(struct ncreel* nr);
// Change focus to the previous tablet, if one exists
API struct nctablet* ncreel_prev(struct ncreel* pr);
API struct nctablet* ncreel_prev(struct ncreel* nr);
// Destroy an ncreel allocated with ncreel_create(). Returns non-zero on failure.
API int ncreel_destroy(struct ncreel* pr);
// Destroy an ncreel allocated with ncreel_create().
API void ncreel_destroy(struct ncreel* nr);
// Returns a pointer to a user pointer associated with this nctablet.
API void* nctablet_userptr(struct nctablet* t);

View File

@ -337,7 +337,7 @@ int ncreel_redraw(struct ncreel* pr);
struct nctablet* ncreel_focused(struct ncreel* pr);
struct nctablet* ncreel_next(struct ncreel* pr);
struct nctablet* ncreel_prev(struct ncreel* pr);
int ncreel_destroy(struct ncreel* pr);
void ncreel_destroy(struct ncreel* pr);
void* nctablet_userptr(struct nctablet* t);
struct ncplane* nctablet_ncplane(struct nctablet* t);
int ncplane_polyfill_yx(struct ncplane* n, int y, int x, const cell* c);

View File

@ -195,8 +195,8 @@ ncreel_demo_core(struct notcurses* nc){
int x = 8, y = 4;
int dimy, dimx;
struct ncplane* std = notcurses_stddim_yx(nc, &dimy, &dimx);
struct ncplane* w = ncplane_new(std, dimy - 12, dimx - 16, y, x, NULL, NULL);
if(w == NULL){
struct ncplane* n = ncplane_new(std, dimy - 12, dimx - 16, y, x, NULL, NULL);
if(n == NULL){
return -1;
}
ncreel_options popts = {
@ -214,17 +214,17 @@ ncreel_demo_core(struct notcurses* nc){
channels_set_bg_rgb8(&popts.borderchan, 0, 0, 0);
uint64_t bgchannels = 0;
if(channels_set_fg_alpha(&bgchannels, CELL_ALPHA_TRANSPARENT)){
ncplane_destroy(w);
ncplane_destroy(n);
return -1;
}
if(channels_set_bg_alpha(&bgchannels, CELL_ALPHA_TRANSPARENT)){
ncplane_destroy(w);
ncplane_destroy(n);
return -1;
}
ncplane_set_base(w, "", 0, bgchannels);
struct ncreel* pr = ncreel_create(w, &popts);
if(pr == NULL){
ncplane_destroy(w);
ncplane_set_base(n, "", 0, bgchannels);
struct ncreel* nr = ncreel_create(n, &popts);
if(nr == NULL){
ncplane_destroy(n);
return -1;
}
// Press a for a new nc above the current, c for a new one below the
@ -243,9 +243,9 @@ ncreel_demo_core(struct notcurses* nc){
struct tabletctx* newtablet;
// Make an initial number of tablets suitable for the screen's height
while(id < dimy / 8u){
newtablet = new_tabletctx(pr, &id);
newtablet = new_tabletctx(nr, &id);
if(newtablet == NULL){
ncreel_destroy(pr);
ncreel_destroy(nr);
return -1;
}
newtablet->next = tctxs;
@ -254,7 +254,7 @@ ncreel_demo_core(struct notcurses* nc){
do{
ncplane_styles_set(std, NCSTYLE_NONE);
ncplane_set_fg_rgb8(std, 197, 15, 31);
int count = ncreel_tabletcount(pr);
int count = ncreel_tabletcount(nr);
ncplane_styles_on(std, NCSTYLE_BOLD);
ncplane_printf_yx(std, 2, 2, "%d tablet%s", count, count == 1 ? "" : "s");
ncplane_styles_off(std, NCSTYLE_BOLD);
@ -263,12 +263,12 @@ ncreel_demo_core(struct notcurses* nc){
wchar_t rw;
ncinput ni;
pthread_mutex_lock(&renderlock);
ncreel_redraw(pr);
ncreel_redraw(nr);
int renderret;
renderret = demo_render(nc);
pthread_mutex_unlock(&renderlock);
if(renderret){
ncreel_destroy(pr);
ncreel_destroy(nr);
return renderret;
}
if((rw = handle_input(nc, &deadline, &ni)) == (wchar_t)-1){
@ -277,23 +277,23 @@ ncreel_demo_core(struct notcurses* nc){
// FIXME clrtoeol();
newtablet = NULL;
switch(rw){
case 'a': newtablet = new_tabletctx(pr, &id); break;
case 'b': newtablet = new_tabletctx(pr, &id); break;
case 'c': newtablet = new_tabletctx(pr, &id); break;
case 'k': ncreel_prev(pr); break;
case 'j': ncreel_next(pr); break;
case 'a': newtablet = new_tabletctx(nr, &id); break;
case 'b': newtablet = new_tabletctx(nr, &id); break;
case 'c': newtablet = new_tabletctx(nr, &id); break;
case 'k': ncreel_prev(nr); break;
case 'j': ncreel_next(nr); break;
case 'q': aborted = true; break;
case NCKEY_UP: ncreel_prev(pr); break;
case NCKEY_DOWN: ncreel_next(pr); break;
case NCKEY_UP: ncreel_prev(nr); break;
case NCKEY_DOWN: ncreel_next(nr); break;
case NCKEY_LEFT:
ncplane_yx(ncreel_plane(pr), &y, &x);
ncplane_move_yx(ncreel_plane(pr), y, x - 1);
ncplane_yx(ncreel_plane(nr), &y, &x);
ncplane_move_yx(ncreel_plane(nr), y, x - 1);
break;
case NCKEY_RIGHT:
ncplane_yx(ncreel_plane(pr), &y, &x);
ncplane_move_yx(ncreel_plane(pr), y, x + 1);
ncplane_yx(ncreel_plane(nr), &y, &x);
ncplane_move_yx(ncreel_plane(nr), y, x + 1);
break;
case NCKEY_DEL: kill_active_tablet(pr, &tctxs); break;
case NCKEY_DEL: kill_active_tablet(nr, &tctxs); break;
case NCKEY_RESIZE: notcurses_render(nc); break;
default: ncplane_printf_yx(std, 3, 2, "Unknown keycode (0x%lx)\n", (unsigned long)rw); break;
}
@ -306,15 +306,12 @@ ncreel_demo_core(struct notcurses* nc){
if(timespec_subtract_ns(&cur, &deadline) >= 0){
break;
}
dimy = ncplane_dim_y(w);
dimy = ncplane_dim_y(n);
}while(!aborted);
while(tctxs){
kill_tablet(&tctxs);
}
if(ncreel_destroy(pr)){
fprintf(stderr, "Error destroying ncreel\n");
return -1;
}
ncreel_destroy(nr);
return aborted ? 1 : 0;
}

View File

@ -811,8 +811,7 @@ int ncreel_del(ncreel* nr, struct nctablet* t){
return 0;
}
int ncreel_destroy(ncreel* nreel){
int ret = 0;
void ncreel_destroy(ncreel* nreel){
if(nreel){
nctablet* t;
while( (t = nreel->tablets) ){
@ -821,7 +820,6 @@ int ncreel_destroy(ncreel* nreel){
ncplane_destroy(nreel->p);
free(nreel);
}
return ret;
}
void* nctablet_userptr(nctablet* t){

View File

@ -79,7 +79,7 @@ TEST_CASE("Reels") {
struct ncreel* nr = ncreel_create(n_, &r);
REQUIRE(nr);
CHECK(0 == notcurses_render(nc_));
CHECK(0 == ncreel_destroy(nr));
ncreel_destroy(nr);
}
SUBCASE("InitLinearInfinite") {
@ -88,7 +88,7 @@ TEST_CASE("Reels") {
struct ncreel* nr = ncreel_create(n_, &r);
REQUIRE(nr);
CHECK(0 == notcurses_render(nc_));
CHECK(0 == ncreel_destroy(nr));
ncreel_destroy(nr);
}
SUBCASE("InitCircular") {
@ -98,7 +98,7 @@ TEST_CASE("Reels") {
REQUIRE(nr);
CHECK(ncreel_validate(nr));
CHECK(0 == notcurses_render(nc_));
REQUIRE(0 == ncreel_destroy(nr));
ncreel_destroy(nr);
}
// circular is not allowed to be true when infinitescroll is false
@ -108,7 +108,7 @@ TEST_CASE("Reels") {
struct ncreel* nr = ncreel_create(n_, &r);
REQUIRE(!nr);
CHECK(0 == notcurses_render(nc_));
REQUIRE(0 == ncreel_destroy(nr));
ncreel_destroy(nr);
}
// We ought be able to invoke ncreel_next() and ncreel_prev() safely,
@ -123,7 +123,7 @@ TEST_CASE("Reels") {
CHECK(!ncreel_prev(nr));
CHECK_EQ(0, notcurses_render(nc_));
CHECK(ncreel_validate(nr));
REQUIRE(0 == ncreel_destroy(nr));
ncreel_destroy(nr);
}
SUBCASE("OneTablet") {
@ -137,7 +137,7 @@ TEST_CASE("Reels") {
CHECK(0 == ncreel_del(nr, t));
CHECK_EQ(0, notcurses_render(nc_));
CHECK(ncreel_validate(nr));
REQUIRE(0 == ncreel_destroy(nr));
ncreel_destroy(nr);
}
SUBCASE("MovementWithOneTablet") {
@ -157,7 +157,7 @@ TEST_CASE("Reels") {
CHECK(0 == ncreel_del(nr, t));
CHECK_EQ(0, notcurses_render(nc_));
CHECK(ncreel_validate(nr));
REQUIRE(0 == ncreel_destroy(nr));
ncreel_destroy(nr);
}
SUBCASE("DeleteActiveTablet") {
@ -169,7 +169,7 @@ TEST_CASE("Reels") {
CHECK(0 == ncreel_del(nr, ncreel_focused(nr)));
CHECK_EQ(0, notcurses_render(nc_));
CHECK(ncreel_validate(nr));
REQUIRE(0 == ncreel_destroy(nr));
ncreel_destroy(nr);
}
SUBCASE("NoBorder") {
@ -181,7 +181,7 @@ TEST_CASE("Reels") {
CHECK_EQ(0, ncreel_redraw(nr));
CHECK_EQ(0, notcurses_render(nc_));
CHECK(ncreel_validate(nr));
CHECK(0 == ncreel_destroy(nr));
ncreel_destroy(nr);
}
SUBCASE("BadBorderBitsRejected") {
@ -200,7 +200,7 @@ TEST_CASE("Reels") {
CHECK_EQ(0, ncreel_redraw(nr));
CHECK_EQ(0, notcurses_render(nc_));
CHECK(ncreel_validate(nr));
CHECK(0 == ncreel_destroy(nr));
ncreel_destroy(nr);
}
SUBCASE("NoTopBottomBorder") {
@ -211,7 +211,7 @@ TEST_CASE("Reels") {
CHECK_EQ(0, ncreel_redraw(nr));
CHECK_EQ(0, notcurses_render(nc_));
CHECK(ncreel_validate(nr));
CHECK(0 == ncreel_destroy(nr));
ncreel_destroy(nr);
}
SUBCASE("NoSideBorders") {
@ -222,7 +222,7 @@ TEST_CASE("Reels") {
CHECK_EQ(0, ncreel_redraw(nr));
CHECK_EQ(0, notcurses_render(nc_));
CHECK(ncreel_validate(nr));
CHECK(0 == ncreel_destroy(nr));
ncreel_destroy(nr);
}
SUBCASE("BadTabletBorderBitsRejected") {
@ -246,7 +246,7 @@ TEST_CASE("Reels") {
CHECK_EQ(0, ncreel_redraw(nr));
CHECK_EQ(0, notcurses_render(nc_));
CHECK(ncreel_validate(nr));
CHECK(0 == ncreel_destroy(nr));
ncreel_destroy(nr);
}
// Layout tests. Add some tablets, move around, and verify that they all
@ -324,7 +324,7 @@ TEST_CASE("Reels") {
CHECK(y == expectedy);
expectedy += 7;
}
CHECK(0 == ncreel_destroy(nr));
ncreel_destroy(nr);
}
// Layout tests. Add some tablets, move around, and verify that they all
@ -402,7 +402,7 @@ TEST_CASE("Reels") {
CHECK(y == expectedy);
expectedy += 5;
}
CHECK(0 == ncreel_destroy(nr));
ncreel_destroy(nr);
}
CHECK(0 == notcurses_stop(nc_));
}