From 3a255e86c4cd8145b7f11b7d17848844e4dc21ec Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 23 Aug 2022 17:34:13 +0300 Subject: [PATCH] Some lua selection userdata code cleanup --- include/extern.h | 2 +- src/nhlsel.c | 67 +++++++++++++++++++++++++++++------------------- src/sp_lev.c | 13 +++++++--- 3 files changed, 50 insertions(+), 32 deletions(-) diff --git a/include/extern.h b/include/extern.h index 18a65328d..9898f9d51 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2585,7 +2585,7 @@ extern boolean pm_good_location(coordxy, coordxy, struct permonst *); extern void get_location_coord(coordxy *, coordxy *, int, struct mkroom *, long); extern void selection_setpoint(coordxy, coordxy, struct selectionvar *, int); extern struct selectionvar * selection_not(struct selectionvar *); -extern void selection_filter_percent(struct selectionvar *, int); +extern struct selectionvar *selection_filter_percent(struct selectionvar *, int); extern int selection_rndcoord(struct selectionvar *, coordxy *, coordxy *, boolean); extern void selection_do_grow(struct selectionvar *, int); diff --git a/src/nhlsel.c b/src/nhlsel.c index a0478f640..2885ad1a3 100644 --- a/src/nhlsel.c +++ b/src/nhlsel.c @@ -5,6 +5,11 @@ #include "hack.h" #include "sp_lev.h" + +struct selectionvar *l_selection_check(lua_State *, int); +static struct selectionvar *l_selection_push_new(lua_State *); +static void l_selection_push_copy(lua_State *, struct selectionvar *); + /* lua_CFunction prototypes */ static int l_selection_new(lua_State *); static int l_selection_clone(lua_State *); @@ -80,8 +85,9 @@ l_selection_to(lua_State *L, int index) } #endif +/* push a new selection into lua stack, return the selectionvar */ static struct selectionvar * -l_selection_push(lua_State *L) +l_selection_push_new(lua_State *L) { struct selectionvar *tmp = selection_new(); struct selectionvar @@ -97,11 +103,26 @@ l_selection_push(lua_State *L) return sel; } +/* push a copy of selectionvar tmp to lua stack */ +static void +l_selection_push_copy(lua_State *L, struct selectionvar *tmp) +{ + struct selectionvar + *sel = (struct selectionvar *) lua_newuserdata(L, sizeof(struct selectionvar)); + + luaL_getmetatable(L, "selection"); + lua_setmetatable(L, -2); + + *sel = *tmp; + sel->map = dupstr(tmp->map); +} + + /* local sel = selection.new(); */ static int l_selection_new(lua_State *L) { - (void) l_selection_push(L); + (void) l_selection_push_new(L); return 1; } @@ -230,7 +251,7 @@ l_selection_and(lua_State *L) int x,y; struct selectionvar *sela = l_selection_check(L, 1); struct selectionvar *selb = l_selection_check(L, 2); - struct selectionvar *selr = l_selection_push(L); + struct selectionvar *selr = l_selection_push_new(L); for (x = 0; x < selr->wid; x++) for (y = 0; y < selr->hei; y++) { @@ -250,7 +271,7 @@ l_selection_or(lua_State *L) int x,y; struct selectionvar *sela = l_selection_check(L, 1); struct selectionvar *selb = l_selection_check(L, 2); - struct selectionvar *selr = l_selection_push(L); + struct selectionvar *selr = l_selection_push_new(L); for (x = 0; x < selr->wid; x++) for (y = 0; y < selr->hei; y++) { @@ -270,7 +291,7 @@ l_selection_xor(lua_State *L) int x,y; struct selectionvar *sela = l_selection_check(L, 1); struct selectionvar *selb = l_selection_check(L, 2); - struct selectionvar *selr = l_selection_push(L); + struct selectionvar *selr = l_selection_push_new(L); for (x = 0; x < selr->wid; x++) for (y = 0; y < selr->hei; y++) { @@ -291,7 +312,7 @@ l_selection_sub(lua_State *L) int x,y; struct selectionvar *sela = l_selection_check(L, 1); struct selectionvar *selb = l_selection_check(L, 2); - struct selectionvar *selr = l_selection_push(L); + struct selectionvar *selr = l_selection_push_new(L); for (x = 0; x < selr->wid; x++) { for (y = 0; y < selr->hei; y++) { @@ -311,15 +332,15 @@ l_selection_sub(lua_State *L) static int l_selection_filter_percent(lua_State *L) { - struct selectionvar *ret; - int p; + int argc = lua_gettop(L); + struct selectionvar *sel = l_selection_check(L, 1); + int p = (int) luaL_checkinteger(L, 2); + struct selectionvar *tmp; - (void) l_selection_check(L, 1); - p = (int) luaL_checkinteger(L, 2); - lua_pop(L, 1); - (void) l_selection_clone(L); - ret = l_selection_check(L, 2); - selection_filter_percent(ret, p); + tmp = selection_filter_percent(sel, p); + lua_pop(L, argc); + l_selection_push_copy(L, tmp); + selection_free(tmp, TRUE); return 1; } @@ -538,23 +559,15 @@ l_selection_filter_mapchar(lua_State *L) char *mapchr = dupstr(luaL_checkstring(L, 2)); coordxy typ = check_mapchr(mapchr); int lit = (int) luaL_optinteger(L, 3, -2); /* TODO: special lit values */ - struct selectionvar *tmp, *tmp2; + struct selectionvar *tmp; if (typ == INVALID_TYPE) nhl_error(L, "Erroneous map char"); - if (argc > 1) - lua_pop(L, argc - 1); - - tmp = l_selection_push(L); - tmp2 = selection_filter_mapchar(sel, typ, lit); - - free(tmp->map); - tmp->map = tmp2->map; - tmp2->map = NULL; - selection_free(tmp2, TRUE); - - lua_remove(L, 1); + tmp = selection_filter_mapchar(sel, typ, lit); + lua_pop(L, argc); + l_selection_push_copy(L, tmp); + selection_free(tmp, TRUE); if (mapchr) free(mapchr); diff --git a/src/sp_lev.c b/src/sp_lev.c index 9f3e3aa67..f06a80aa6 100644 --- a/src/sp_lev.c +++ b/src/sp_lev.c @@ -4464,17 +4464,22 @@ selection_filter_mapchar(struct selectionvar* ov, xint16 typ, int lit) return ret; } -void +struct selectionvar * selection_filter_percent(struct selectionvar* ov, int percent) { int x, y; + struct selectionvar *ret; if (!ov) - return; + return NULL; + + ret = selection_new(); + for (x = 0; x < ov->wid; x++) for (y = 0; y < ov->hei; y++) - if (selection_getpoint(x, y, ov) && (rn2(100) >= percent)) - selection_setpoint(x, y, ov, 0); + if (selection_getpoint(x, y, ov) && (rn2(100) < percent)) + selection_setpoint(x, y, ret, 1); + return ret; } int