mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-04-20 09:11:01 +00:00
Use only one state for LUA_EvalMath and open enum lib once
This commit is contained in:
parent
e94bccc503
commit
da1ef9376c
3 changed files with 72 additions and 58 deletions
|
@ -29,6 +29,8 @@
|
|||
#include "deh_soc.h" // for get_mus
|
||||
#endif
|
||||
|
||||
boolean lua_mathlib;
|
||||
|
||||
// freeslot takes a name (string only!)
|
||||
// and allocates it to the appropriate free slot.
|
||||
// Returns the slot number allocated for it or nil if failed.
|
||||
|
@ -224,7 +226,6 @@ static inline int lib_getenum(lua_State *L)
|
|||
{
|
||||
const char *word, *p;
|
||||
fixed_t i;
|
||||
boolean mathlib = lua_toboolean(L, lua_upvalueindex(1));
|
||||
if (lua_type(L,2) != LUA_TSTRING)
|
||||
return 0;
|
||||
word = lua_tostring(L,2);
|
||||
|
@ -234,7 +235,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
lua_pushinteger(L, *word-'A');
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "constant '%s' could not be parsed.\n", word);
|
||||
if (lua_mathlib) return luaL_error(L, "constant '%s' could not be parsed.\n", word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("MF_", word, 3)) {
|
||||
|
@ -244,7 +245,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
lua_pushinteger(L, ((lua_Integer)1<<i));
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "mobjflag '%s' could not be found.\n", word);
|
||||
if (lua_mathlib) return luaL_error(L, "mobjflag '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("MF2_", word, 4)) {
|
||||
|
@ -254,7 +255,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
lua_pushinteger(L, ((lua_Integer)1<<i));
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "mobjflag2 '%s' could not be found.\n", word);
|
||||
if (lua_mathlib) return luaL_error(L, "mobjflag2 '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("MFE_", word, 4)) {
|
||||
|
@ -264,7 +265,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
lua_pushinteger(L, ((lua_Integer)1<<i));
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "mobjeflag '%s' could not be found.\n", word);
|
||||
if (lua_mathlib) return luaL_error(L, "mobjeflag '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("MTF_", word, 4)) {
|
||||
|
@ -274,7 +275,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
lua_pushinteger(L, ((lua_Integer)1<<i));
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "mapthingflag '%s' could not be found.\n", word);
|
||||
if (lua_mathlib) return luaL_error(L, "mapthingflag '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("PF_", word, 3)) {
|
||||
|
@ -294,7 +295,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
lua_pushinteger(L, (lua_Integer)PF_SPINDOWN);
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "playerflag '%s' could not be found.\n", word);
|
||||
if (lua_mathlib) return luaL_error(L, "playerflag '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("GT_", word, 3)) {
|
||||
|
@ -304,7 +305,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
lua_pushinteger(L, i);
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "gametype '%s' could not be found.\n", word);
|
||||
if (lua_mathlib) return luaL_error(L, "gametype '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("GTR_", word, 4)) {
|
||||
|
@ -314,7 +315,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
lua_pushinteger(L, ((lua_Integer)1<<i));
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "game type rule '%s' could not be found.\n", word);
|
||||
if (lua_mathlib) return luaL_error(L, "game type rule '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("TOL_", word, 4)) {
|
||||
|
@ -324,7 +325,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
lua_pushinteger(L, TYPEOFLEVEL[i].flag);
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "typeoflevel '%s' could not be found.\n", word);
|
||||
if (lua_mathlib) return luaL_error(L, "typeoflevel '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("ML_", word, 3)) {
|
||||
|
@ -334,7 +335,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
lua_pushinteger(L, ((lua_Integer)1<<i));
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "linedef flag '%s' could not be found.\n", word);
|
||||
if (lua_mathlib) return luaL_error(L, "linedef flag '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("S_",word,2)) {
|
||||
|
@ -378,7 +379,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
lua_pushinteger(L, i);
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "sprite '%s' could not be found.\n", word);
|
||||
if (lua_mathlib) return luaL_error(L, "sprite '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("SPR2_",word,5)) {
|
||||
|
@ -399,10 +400,10 @@ static inline int lib_getenum(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "player sprite '%s' could not be found.\n", word);
|
||||
if (lua_mathlib) return luaL_error(L, "player sprite '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
else if (!mathlib && fastncmp("sfx_",word,4)) {
|
||||
else if (!lua_mathlib && fastncmp("sfx_",word,4)) {
|
||||
p = word+4;
|
||||
for (i = 0; i < NUMSFX; i++)
|
||||
if (S_sfx[i].name && fastcmp(p, S_sfx[i].name)) {
|
||||
|
@ -411,7 +412,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
else if (mathlib && fastncmp("SFX_",word,4)) { // SOCs are ALL CAPS!
|
||||
else if (lua_mathlib && fastncmp("SFX_",word,4)) { // SOCs are ALL CAPS!
|
||||
p = word+4;
|
||||
for (i = 0; i < NUMSFX; i++)
|
||||
if (S_sfx[i].name && fasticmp(p, S_sfx[i].name)) {
|
||||
|
@ -420,32 +421,32 @@ static inline int lib_getenum(lua_State *L)
|
|||
}
|
||||
return luaL_error(L, "sfx '%s' could not be found.\n", word);
|
||||
}
|
||||
else if (mathlib && fastncmp("DS",word,2)) {
|
||||
else if (lua_mathlib && fastncmp("DS",word,2)) {
|
||||
p = word+2;
|
||||
for (i = 0; i < NUMSFX; i++)
|
||||
if (S_sfx[i].name && fasticmp(p, S_sfx[i].name)) {
|
||||
lua_pushinteger(L, i);
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "sfx '%s' could not be found.\n", word);
|
||||
if (lua_mathlib) return luaL_error(L, "sfx '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
#ifdef MUSICSLOT_COMPATIBILITY
|
||||
else if (!mathlib && fastncmp("mus_",word,4)) {
|
||||
else if (!lua_mathlib && fastncmp("mus_",word,4)) {
|
||||
p = word+4;
|
||||
if ((i = get_mus(p, false)) == 0)
|
||||
return 0;
|
||||
lua_pushinteger(L, i);
|
||||
return 1;
|
||||
}
|
||||
else if (mathlib && fastncmp("MUS_",word,4)) { // SOCs are ALL CAPS!
|
||||
else if (lua_mathlib && fastncmp("MUS_",word,4)) { // SOCs are ALL CAPS!
|
||||
p = word+4;
|
||||
if ((i = get_mus(p, false)) == 0)
|
||||
return luaL_error(L, "music '%s' could not be found.\n", word);
|
||||
lua_pushinteger(L, i);
|
||||
return 1;
|
||||
}
|
||||
else if (mathlib && (fastncmp("O_",word,2) || fastncmp("D_",word,2))) {
|
||||
else if (lua_mathlib && (fastncmp("O_",word,2) || fastncmp("D_",word,2))) {
|
||||
p = word+2;
|
||||
if ((i = get_mus(p, false)) == 0)
|
||||
return luaL_error(L, "music '%s' could not be found.\n", word);
|
||||
|
@ -453,7 +454,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
#endif
|
||||
else if (!mathlib && fastncmp("pw_",word,3)) {
|
||||
else if (!lua_mathlib && fastncmp("pw_",word,3)) {
|
||||
p = word+3;
|
||||
for (i = 0; i < NUMPOWERS; i++)
|
||||
if (fasticmp(p, POWERS_LIST[i])) {
|
||||
|
@ -462,7 +463,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
else if (mathlib && fastncmp("PW_",word,3)) { // SOCs are ALL CAPS!
|
||||
else if (lua_mathlib && fastncmp("PW_",word,3)) { // SOCs are ALL CAPS!
|
||||
p = word+3;
|
||||
for (i = 0; i < NUMPOWERS; i++)
|
||||
if (fastcmp(p, POWERS_LIST[i])) {
|
||||
|
@ -478,7 +479,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
lua_pushinteger(L, i);
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "huditem '%s' could not be found.\n", word);
|
||||
if (lua_mathlib) return luaL_error(L, "huditem '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("SKINCOLOR_",word,10)) {
|
||||
|
@ -507,7 +508,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
lua_pushinteger(L, i);
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "NiGHTS grade '%s' could not be found.\n", word);
|
||||
if (lua_mathlib) return luaL_error(L, "NiGHTS grade '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
else if (fastncmp("MN_",word,3)) {
|
||||
|
@ -517,10 +518,10 @@ static inline int lib_getenum(lua_State *L)
|
|||
lua_pushinteger(L, i);
|
||||
return 1;
|
||||
}
|
||||
if (mathlib) return luaL_error(L, "menutype '%s' could not be found.\n", word);
|
||||
if (lua_mathlib) return luaL_error(L, "menutype '%s' could not be found.\n", word);
|
||||
return 0;
|
||||
}
|
||||
else if (!mathlib && fastncmp("A_",word,2)) {
|
||||
else if (!lua_mathlib && fastncmp("A_",word,2)) {
|
||||
char *caps;
|
||||
// Try to get a Lua action first.
|
||||
/// \todo Push a closure that sets superactions[] and superstack.
|
||||
|
@ -545,7 +546,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
else if (!mathlib && fastcmp("super",word))
|
||||
else if (!lua_mathlib && fastcmp("super",word))
|
||||
{
|
||||
if (!superstack)
|
||||
{
|
||||
|
@ -572,7 +573,7 @@ static inline int lib_getenum(lua_State *L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (mathlib) return luaL_error(L, "constant '%s' could not be parsed.\n", word);
|
||||
if (lua_mathlib) return luaL_error(L, "constant '%s' could not be parsed.\n", word);
|
||||
|
||||
// DYNAMIC variables too!!
|
||||
// Try not to add anything that would break netgames or timeattack replays here.
|
||||
|
@ -582,13 +583,9 @@ static inline int lib_getenum(lua_State *L)
|
|||
|
||||
int LUA_EnumLib(lua_State *L)
|
||||
{
|
||||
if (lua_gettop(L) == 0)
|
||||
lua_pushboolean(L, 0);
|
||||
|
||||
// Set the global metatable
|
||||
lua_createtable(L, 0, 1);
|
||||
lua_pushvalue(L, 1); // boolean passed to LUA_EnumLib as first argument.
|
||||
lua_pushcclosure(L, lib_getenum, 1);
|
||||
lua_pushcfunction(L, lib_getenum);
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_setmetatable(L, LUA_GLOBALSINDEX);
|
||||
return 0;
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#ifndef __DEH_LUA_H__
|
||||
#define __DEH_LUA_H__
|
||||
|
||||
extern boolean lua_mathlib;
|
||||
|
||||
boolean LUA_SetLuaAction(void *state, const char *actiontocompare);
|
||||
const char *LUA_GetActionName(void *action);
|
||||
void LUA_SetActionByName(void *state, const char *actiontocompare);
|
||||
|
|
|
@ -39,9 +39,10 @@
|
|||
|
||||
lua_State *gL = NULL;
|
||||
|
||||
static lua_State *soc_lua_state;
|
||||
|
||||
// List of internal libraries to load from SRB2
|
||||
static lua_CFunction liblist[] = {
|
||||
LUA_EnumLib, // global metatable for enums
|
||||
LUA_SOCLib, // A_Action functions, freeslot
|
||||
LUA_BaseLib, // string concatination by +, CONS_Printf, p_local.h stuff (P_InstaThrust, P_Move), etc.
|
||||
LUA_MathLib, // fixed_t and angle_t math functions
|
||||
|
@ -474,24 +475,28 @@ static int setglobals(lua_State *L)
|
|||
return luaL_error(L, "Implicit global " LUA_QS " prevented. Create a local variable instead.", csname);
|
||||
}
|
||||
|
||||
static lua_State * LUA_EnumState (void)
|
||||
{
|
||||
lua_State *L = soc_lua_state;
|
||||
if (!L)
|
||||
{
|
||||
L = lua_newstate(LUA_Alloc, NULL);
|
||||
lua_atpanic(L, LUA_Panic);
|
||||
LUA_EnumLib(L); // global metatable for enums
|
||||
soc_lua_state = L;
|
||||
}
|
||||
return L;
|
||||
}
|
||||
|
||||
// Clear and create a new Lua state, laddo!
|
||||
// There's SCRIPTIN to be had!
|
||||
static void LUA_ClearState(void)
|
||||
{
|
||||
lua_State *L;
|
||||
lua_State *L = LUA_EnumState();
|
||||
int i;
|
||||
|
||||
// close previous state
|
||||
if (gL)
|
||||
lua_close(gL);
|
||||
gL = NULL;
|
||||
|
||||
CONS_Printf(M_GetText("Pardon me while I initialize the Lua scripting interface...\n"));
|
||||
|
||||
// allocate state
|
||||
L = lua_newstate(LUA_Alloc, NULL);
|
||||
lua_atpanic(L, LUA_Panic);
|
||||
|
||||
// open base libraries
|
||||
luaL_openlibs(L);
|
||||
lua_settop(L, 0);
|
||||
|
@ -670,21 +675,13 @@ void LUA_DumpFile(const char *filename)
|
|||
|
||||
fixed_t LUA_EvalMath(const char *word)
|
||||
{
|
||||
lua_State *L = NULL;
|
||||
static int fenv_ref = LUA_NOREF;
|
||||
|
||||
lua_State *L = LUA_EnumState();
|
||||
char buf[1024], *b;
|
||||
const char *p;
|
||||
fixed_t res = 0;
|
||||
|
||||
// make a new state so SOC can't interefere with scripts
|
||||
// allocate state
|
||||
L = lua_newstate(LUA_Alloc, NULL);
|
||||
lua_atpanic(L, LUA_Panic);
|
||||
|
||||
// open only enum lib
|
||||
lua_pushcfunction(L, LUA_EnumLib);
|
||||
lua_pushboolean(L, true);
|
||||
lua_call(L, 1, 0);
|
||||
|
||||
// change ^ into ^^ for Lua.
|
||||
strcpy(buf, "return ");
|
||||
b = buf+strlen(buf);
|
||||
|
@ -696,8 +693,23 @@ fixed_t LUA_EvalMath(const char *word)
|
|||
}
|
||||
*b = '\0';
|
||||
|
||||
// eval string.
|
||||
if (fenv_ref == LUA_NOREF)
|
||||
{
|
||||
lua_createtable(L, 0, 1);
|
||||
lua_getmetatable(L, LUA_GLOBALSINDEX);
|
||||
lua_setmetatable(L, -2);
|
||||
fenv_ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
|
||||
lua_settop(L, 0);
|
||||
lua_pushthread(L);
|
||||
|
||||
lua_getref(L, fenv_ref);
|
||||
lua_setfenv(L, 1);
|
||||
|
||||
lua_mathlib = true;
|
||||
|
||||
// eval string.
|
||||
if (luaL_dostring(L, buf))
|
||||
{
|
||||
p = lua_tostring(L, -1);
|
||||
|
@ -708,8 +720,11 @@ fixed_t LUA_EvalMath(const char *word)
|
|||
else
|
||||
res = lua_tointeger(L, -1);
|
||||
|
||||
// clean up and return.
|
||||
lua_close(L);
|
||||
lua_mathlib = false;
|
||||
|
||||
lua_pushvalue(L, LUA_GLOBALSINDEX);
|
||||
lua_setfenv(L, 1);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue