Changed how return values work for the iteration function supplied to searchBlockmap

This commit is contained in:
Monster Iestyn 2016-12-18 16:53:11 +00:00
parent 7bcb595eaf
commit 752eca5253
1 changed files with 39 additions and 21 deletions

View File

@ -24,17 +24,21 @@ static const char *const search_opt[] = {
NULL}; NULL};
// a quickly-made function pointer typedef used by lib_searchBlockmap... // a quickly-made function pointer typedef used by lib_searchBlockmap...
typedef boolean (*blockmap_func)(lua_State *, INT32, INT32, mobj_t *); // return values:
// 0 - normal, no interruptions
// 1 - stop search through current block
// 2 - stop search completely
typedef UINT8 (*blockmap_func)(lua_State *, INT32, INT32, mobj_t *);
static boolean blockfuncerror = false; // errors should only print once per search blockmap call static boolean blockfuncerror = false; // errors should only print once per search blockmap call
// Helper function for "objects" search // Helper function for "objects" search
static boolean lib_searchBlockmap_Objects(lua_State *L, INT32 x, INT32 y, mobj_t *thing) static UINT8 lib_searchBlockmap_Objects(lua_State *L, INT32 x, INT32 y, mobj_t *thing)
{ {
mobj_t *mobj, *bnext = NULL; mobj_t *mobj, *bnext = NULL;
if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight) if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
return true; return 0;
// Check interaction with the objects in the blockmap. // Check interaction with the objects in the blockmap.
for (mobj = blocklinks[y*bmapwidth + x]; mobj; mobj = bnext) for (mobj = blocklinks[y*bmapwidth + x]; mobj; mobj = bnext)
@ -50,26 +54,28 @@ static boolean lib_searchBlockmap_Objects(lua_State *L, INT32 x, INT32 y, mobj_t
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1); lua_pop(gL, 1);
blockfuncerror = true; blockfuncerror = true;
return true; return 0; // *shrugs*
} }
if (!lua_isnil(gL, -1)) if (!lua_isnil(gL, -1))
{ // if nil, continue { // if nil, continue
if (lua_toboolean(gL, -1)) if (lua_toboolean(gL, -1))
return false; return 2; // stop whole search
else
return 1; // stop block search
} }
lua_pop(gL, 1); lua_pop(gL, 1);
if (P_MobjWasRemoved(thing) // func just popped our thing, cannot continue. if (P_MobjWasRemoved(thing) // func just popped our thing, cannot continue.
|| (bnext && P_MobjWasRemoved(bnext))) // func just broke blockmap chain, cannot continue. || (bnext && P_MobjWasRemoved(bnext))) // func just broke blockmap chain, cannot continue.
{ {
P_SetTarget(&bnext, NULL); P_SetTarget(&bnext, NULL);
return true; return (P_MobjWasRemoved(thing)) ? 2 : 1;
} }
} }
return true; return 0;
} }
// Helper function for "lines" search // Helper function for "lines" search
static boolean lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *thing) static UINT8 lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *thing)
{ {
INT32 offset; INT32 offset;
const INT32 *list; // Big blockmap const INT32 *list; // Big blockmap
@ -79,7 +85,7 @@ static boolean lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *
line_t *ld; line_t *ld;
if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight) if (x < 0 || y < 0 || x >= bmapwidth || y >= bmapheight)
return true; return 0;
offset = y*bmapwidth + x; offset = y*bmapwidth + x;
@ -110,16 +116,18 @@ static boolean lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1); lua_pop(gL, 1);
blockfuncerror = true; blockfuncerror = true;
return true; return 0; // *shrugs*
} }
if (!lua_isnil(gL, -1)) if (!lua_isnil(gL, -1))
{ // if nil, continue { // if nil, continue
if (lua_toboolean(gL, -1)) if (lua_toboolean(gL, -1))
return false; return 2; // stop whole search
else
return 1; // stop block search
} }
lua_pop(gL, 1); lua_pop(gL, 1);
if (P_MobjWasRemoved(thing)) if (P_MobjWasRemoved(thing))
return true; return 2;
} }
} }
plink = (polymaplink_t *)(plink->link.next); plink = (polymaplink_t *)(plink->link.next);
@ -146,25 +154,27 @@ static boolean lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1); lua_pop(gL, 1);
blockfuncerror = true; blockfuncerror = true;
return true; return 0; // *shrugs*
} }
if (!lua_isnil(gL, -1)) if (!lua_isnil(gL, -1))
{ // if nil, continue { // if nil, continue
if (lua_toboolean(gL, -1)) if (lua_toboolean(gL, -1))
return false; return 2; // stop whole search
else
return 1; // stop block search
} }
lua_pop(gL, 1); lua_pop(gL, 1);
if (P_MobjWasRemoved(thing)) if (P_MobjWasRemoved(thing))
return true; return 2;
} }
return true; // Everything was checked. return 0; // Everything was checked.
} }
// The searchBlockmap function // The searchBlockmap function
// arguments: searchBlockmap(searchtype, function, mobj, [x1, x2, y1, y2]) // arguments: searchBlockmap(searchtype, function, mobj, [x1, x2, y1, y2])
// return value: // return value:
// true = search completely uninteruppted, // true = search completely uninteruppted,
// false = searching of at least one block stopped mid-way (doesn't stop the whole search though) // false = searching of at least one block stopped mid-way (including if the whole search was stopped)
static int lib_searchBlockmap(lua_State *L) static int lib_searchBlockmap(lua_State *L)
{ {
int searchtype = luaL_checkoption(L, 1, "objects", search_opt); int searchtype = luaL_checkoption(L, 1, "objects", search_opt);
@ -173,6 +183,7 @@ static int lib_searchBlockmap(lua_State *L)
INT32 xl, xh, yl, yh, bx, by; INT32 xl, xh, yl, yh, bx, by;
fixed_t x1, x2, y1, y2; fixed_t x1, x2, y1, y2;
boolean retval = true; boolean retval = true;
UINT8 funcret = 0;
blockmap_func searchFunc; blockmap_func searchFunc;
lua_remove(L, 1); // remove searchtype, stack is now function, mobj, [x1, x2, y1, y2] lua_remove(L, 1); // remove searchtype, stack is now function, mobj, [x1, x2, y1, y2]
@ -228,10 +239,17 @@ static int lib_searchBlockmap(lua_State *L)
for (bx = xl; bx <= xh; bx++) for (bx = xl; bx <= xh; bx++)
for (by = yl; by <= yh; by++) for (by = yl; by <= yh; by++)
{ {
if (!searchFunc(L, bx, by, mobj)) funcret = searchFunc(L, bx, by, mobj);
retval = false; // return value of searchFunc determines searchFunc's return value and/or when to stop
if (P_MobjWasRemoved(mobj)){ if (funcret == 2){ // stop whole search
lua_pushboolean(L, false); lua_pushboolean(L, false); // return false
return 1;
}
else if (funcret == 1) // search was interrupted for this block
retval = false; // this changes the return value, but doesn't stop the whole search
// else don't do anything, continue as normal
if (P_MobjWasRemoved(mobj)){ // ...unless the original object was removed
lua_pushboolean(L, false); // in which case we have to stop now regardless
return 1; return 1;
} }
} }