Skip to content

Commit

Permalink
Make the custom widget be able to do more complex clean up.
Browse files Browse the repository at this point in the history
  • Loading branch information
bobbens committed Apr 19, 2024
1 parent 9ea3588 commit 6ce8299
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 40 deletions.
19 changes: 9 additions & 10 deletions src/dialogue.c
Expand Up @@ -884,15 +884,14 @@ static int dialogue_custom_event( unsigned int wid, SDL_Event *event )
* @param event Custom event callback.
* @param data Custom data.
* @param dynamic Whether or not the custom is dynamic.
* @param autofree Should \p data be freed when the window is destroyed?
* @param freefunc Function to be run when cleaning the custom data.
*/
void dialogue_custom( const char *caption, int width, int height,
int ( *update )( double dt, void *data ),
void ( *render )( double x, double y, double w, double h,
void *data ),
int ( *event )( unsigned int wid, SDL_Event *event,
void *data ),
void *data, int autofree, int dynamic )
void dialogue_custom(
const char *caption, int width, int height,
int ( *update )( double dt, void *data ),
void ( *render )( double x, double y, double w, double h, void *data ),
int ( *event )( unsigned int wid, SDL_Event *event, void *data ), void *data,
int dynamic, void ( *freefunc )( void *data ) )
{
struct dialogue_custom_data_s cd;
dialogue_update_t du;
Expand Down Expand Up @@ -923,8 +922,8 @@ void dialogue_custom( const char *caption, int width, int height,
NULL, NULL, data );
if ( dynamic )
window_custSetDynamic( wid, "cstCustom", 1 );
if ( autofree )
window_custAutoFreeData( wid, "cstCustom" );
if ( freefunc != NULL )
window_custFreeDataFunc( wid, "cstCustom", freefunc );
window_custSetClipping( wid, "cstCustom", 1 );

/* set up event stuff. */
Expand Down
17 changes: 8 additions & 9 deletions src/dialogue.h
Expand Up @@ -68,15 +68,14 @@ int dialogue_listPanelRaw(
/*
* Custom.
*/
void dialogue_custom( const char *caption, int width, int height,
int ( *update )( double dt, void *data ),
void ( *render )( double x, double y, double w, double h,
void *data ),
int ( *event )( unsigned int wid, SDL_Event *event,
void *data ),
void *data, int autofree, int dynamic );
int dialogue_customFullscreen( int enable );
int dialogue_customResize( int width, int height );
void dialogue_custom(
const char *caption, int width, int height,
int ( *update )( double dt, void *data ),
void ( *render )( double x, double y, double w, double h, void *data ),
int ( *event )( unsigned int wid, SDL_Event *event, void *data ), void *data,
int dynamic, void ( *freefunc )( void *data ) );
int dialogue_customFullscreen( int enable );
int dialogue_customResize( int width, int height );

/*
* misc
Expand Down
2 changes: 1 addition & 1 deletion src/land_shipyard.c
Expand Up @@ -134,7 +134,7 @@ void shipyard_open( unsigned int wid )
window_custSetOverlay( wid, "cstSlots", shipyard_renderSlotsOver );
window_custSetClipping( wid, "cstSlots", 0 );
window_canFocusWidget( wid, "cstSlots", 0 );
window_custAutoFreeData( wid, "cstSlots" );
window_custFreeDataFunc( wid, "cstSlots", free );

/* stat text */
window_addText( wid, -4, -sw - 50 - 70 - 20, sw, -sh - 60 - 70 - 20 + h - bh,
Expand Down
2 changes: 1 addition & 1 deletion src/map.c
Expand Up @@ -3243,7 +3243,7 @@ void map_show( int wid, int x, int y, int w, int h, double zoom, double xoff,
window_addCust( wid, x, y, w, h, "cstMap", 1, map_render, map_mouse, NULL,
map_focusLose, cst );
window_custSetDynamic( wid, "cstMap", 1 );
window_custAutoFreeData( wid, "cstMap" );
window_custFreeDataFunc( wid, "cstMap", free );

/* Set up stuff. */
map_setup();
Expand Down
2 changes: 1 addition & 1 deletion src/news.c
Expand Up @@ -303,7 +303,7 @@ void news_widget( unsigned int wid, int x, int y, int w, int h )
news_focusLose, widptr );
window_custSetDynamic( wid, "cstNews", 1 );
window_canFocusWidget( wid, "cstNews", 0 );
window_custAutoFreeData( wid, "cstNews" );
window_custFreeDataFunc( wid, "cstNews", free );
}

/* clears newslines for bar text, for when taking off */
Expand Down
29 changes: 19 additions & 10 deletions src/nlua_tk.c
Expand Up @@ -38,6 +38,7 @@ typedef struct custom_functions_s {
int resize;
int textinput;
} custom_functions_t;
static void cust_cleanup( void *data );
static int cust_update( double dt, void *data );
static void cust_render( double x, double y, double w, double h, void *data );
static int cust_event( unsigned int wid, SDL_Event *event, void *data );
Expand Down Expand Up @@ -407,6 +408,22 @@ static int tkL_merchantOutfit( lua_State *L )
return 0;
}

/**
* @brief Cleans up after the window.
*/
static void cust_cleanup( void *data )
{
custom_functions_t *cf = data;
lua_State *L = cf->L;
luaL_unref( L, LUA_REGISTRYINDEX, cf->update );
luaL_unref( L, LUA_REGISTRYINDEX, cf->draw );
luaL_unref( L, LUA_REGISTRYINDEX, cf->keyboard );
luaL_unref( L, LUA_REGISTRYINDEX, cf->mouse );
luaL_unref( L, LUA_REGISTRYINDEX, cf->resize );
luaL_unref( L, LUA_REGISTRYINDEX, cf->textinput );
free( cf );
}

/**
* @brief Creates a custom widget window.
*
Expand Down Expand Up @@ -458,17 +475,9 @@ static int tkL_custom( lua_State *L )
lua_setglobal( L, TK_CUSTOMDONE );

/* Create the dialogue. */
dialogue_custom( caption, w, h, cust_update, cust_render, cust_event, cf, 1,
!nodynamic );

/* Clean up. */
dialogue_custom( caption, w, h, cust_update, cust_render, cust_event, cf,
!nodynamic, cust_cleanup );
cf->done = 1;
luaL_unref( L, LUA_REGISTRYINDEX, cf->update );
luaL_unref( L, LUA_REGISTRYINDEX, cf->draw );
luaL_unref( L, LUA_REGISTRYINDEX, cf->keyboard );
luaL_unref( L, LUA_REGISTRYINDEX, cf->mouse );
luaL_unref( L, LUA_REGISTRYINDEX, cf->resize );
luaL_unref( L, LUA_REGISTRYINDEX, cf->textinput );

return 0;
}
Expand Down
12 changes: 7 additions & 5 deletions src/tk/widget/cust.c
Expand Up @@ -71,7 +71,7 @@ void window_addCust(
wgt->dat.cst.focusGain = focusGain;
wgt->dat.cst.focusLose = focusLose;
wgt->dat.cst.userdata = data;
wgt->dat.cst.autofree = 0;
wgt->dat.cst.free = NULL;

/* position/size */
wgt->w = (double)w;
Expand Down Expand Up @@ -154,8 +154,8 @@ static void cst_renderOverlay( Widget *cst, double bx, double by )
*/
static void cst_cleanup( Widget *cst )
{
if ( cst->dat.cst.autofree )
free( cst->dat.cst.userdata );
if ( cst->dat.cst.free != NULL )
cst->dat.cst.free( cst->dat.cst.userdata );
}

/**
Expand Down Expand Up @@ -237,12 +237,14 @@ void *window_custGetData( unsigned int wid, const char *name )
*
* @param wid Window to which widget belongs.
* @param name Name of the widget.
* @param func Function to use when freeing the data.
*/
void window_custAutoFreeData( unsigned int wid, const char *name )
void window_custFreeDataFunc( unsigned int wid, const char *name,
void ( *func )( void *ptr ) )
{
Widget *wgt = cst_getWidget( wid, name );
if ( wgt != NULL )
wgt->dat.cst.autofree = 1;
wgt->dat.cst.free = func;
}

/**
Expand Down
6 changes: 3 additions & 3 deletions src/tk/widget/cust.h
Expand Up @@ -27,8 +27,7 @@ typedef struct WidgetCustData_ {
const char *wgtname ); /**< Lose focus. */
int clip; /**< 1 if should clip with glScissors or the like, 0 otherwise. */
void *userdata;
int autofree; /**< 1 if widget should free userdata upon cleanup, 0 if it
shouldn't. */
void ( *free )( void *data );
} WidgetCustData;

/* Required functions. */
Expand All @@ -48,5 +47,6 @@ void window_custSetOverlay( unsigned int wid, const char *name,
double bw, double bh,
void *data ) );
void *window_custGetData( unsigned int wid, const char *name );
void window_custAutoFreeData( unsigned int wid, const char *name );
void window_custFreeDataFunc( unsigned int wid, const char *name,
void ( *func )( void *ptr ) );
void window_custSetDynamic( unsigned int wid, const char *name, int dynamic );

0 comments on commit 6ce8299

Please sign in to comment.