mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-25 03:00:46 +00:00
Lunatic: event chaining.
git-svn-id: https://svn.eduke32.com/eduke32@3320 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
41bfa1b841
commit
fa2ac57674
7 changed files with 106 additions and 15 deletions
|
@ -17,6 +17,7 @@ MAXLEVELS = 64
|
|||
|
||||
MAXSKILLS = 7
|
||||
|
||||
MAXEVENTS = 95 -- KEEPINSYNC with EVENT_* list
|
||||
MAXSOUNDS = 4096
|
||||
|
||||
|
||||
|
|
|
@ -24,8 +24,6 @@ local tostring = tostring
|
|||
local type = type
|
||||
|
||||
|
||||
--== First, load the definitions common to the game's and editor's Lua interface.
|
||||
|
||||
-- The "gv" global will provide access to C global *scalars* and safe functions.
|
||||
-- XXX: still exposes C library functions etc. contained in ffi.C, problem?
|
||||
local gv_ = {
|
||||
|
@ -53,7 +51,7 @@ function decl(str)
|
|||
ffi.cdef(str)
|
||||
end
|
||||
|
||||
-- load the common definitions!
|
||||
-- Load the definitions common to the game's and editor's Lua interface.
|
||||
local defs_c = require("defs_common")
|
||||
local cansee = defs_c.cansee
|
||||
local strip_const = defs_c.strip_const
|
||||
|
@ -449,6 +447,7 @@ typedef struct {
|
|||
decl[[
|
||||
const char *g_sizes_of_what[];
|
||||
int32_t g_sizes_of[];
|
||||
int32_t g_elCallDepth;
|
||||
actor_t actor[MAXSPRITES];
|
||||
user_defs ud;
|
||||
playerdata_t g_player[MAXPLAYERS];
|
||||
|
@ -990,6 +989,10 @@ G_._G = G_
|
|||
local gameactor_internal = gameactor_internal -- included in lunatic.c
|
||||
-- gameactor(tilenum [, strength [, act [, mov [, movflags]]]], actor_func)
|
||||
local function our_gameactor(tilenum, ...)
|
||||
if (ffiC.g_elCallDepth > 0) then
|
||||
error("Invalid use of gameactor: must be called from top level", 2)
|
||||
end
|
||||
|
||||
local args = {...}
|
||||
if (type(tilenum) ~= "number") then
|
||||
error("invalid argument #1 to gameactor: must be a number", 2)
|
||||
|
@ -1000,6 +1003,9 @@ local function our_gameactor(tilenum, ...)
|
|||
if (#args == 0) then
|
||||
error("invalid call to gameactor: must have at least two arguments (tilenum, func)", 2)
|
||||
end
|
||||
if (#args > 6) then
|
||||
error("invalid call to gameactor: must have at most six arguments", 2)
|
||||
end
|
||||
if (type(args[#args]) ~= "function") then
|
||||
error("invalid last argument to gameactor: must be a function", 2)
|
||||
end
|
||||
|
@ -1035,8 +1041,52 @@ local function our_gameactor(tilenum, ...)
|
|||
gameactor_internal(tilenum, strength, act, mov, movflags, args[#args])
|
||||
end
|
||||
|
||||
-- Event functions, saved for event chaining
|
||||
local event_funcs = {}
|
||||
|
||||
local gameevent_internal = gameevent_internal -- included in lunatic.c
|
||||
-- gameevent(<event idx or string>, <event function>)
|
||||
local function our_gameevent(event, func)
|
||||
if (ffiC.g_elCallDepth > 0) then
|
||||
error("Invalid use of gameevent: must be called from top level", 2)
|
||||
end
|
||||
if (type(event) == "string") then
|
||||
if (event:sub(1,6) ~= "EVENT_") then
|
||||
event = "EVENT_"..event
|
||||
end
|
||||
local eventidx = con_lang.labels[3][event] -- 3: event list
|
||||
if (eventidx == nil) then
|
||||
errorf(2, "gameevent: invalid event label %q", event)
|
||||
end
|
||||
event = eventidx
|
||||
end
|
||||
if (type(event) ~= "number") then
|
||||
error("invalid argument #1 to gameevent: must be a number", 2)
|
||||
end
|
||||
if (event >= con_lang.MAXEVENTS+0ULL) then
|
||||
error("invalid argument #1 to gameevent: must be an event number (0 .. MAXEVENTS-1)", 2)
|
||||
end
|
||||
|
||||
if (type(func) ~= "function") then
|
||||
error("invalid argument #2 to gameevent: must be a function", 2)
|
||||
end
|
||||
|
||||
local newfunc = func
|
||||
local oldfunc = event_funcs[event]
|
||||
-- event chaining: events defined later come first
|
||||
if (oldfunc ~= nil) then
|
||||
newfunc = function(aci, pli, dist)
|
||||
func(aci, pli, dist)
|
||||
oldfunc(aci, pli, dist)
|
||||
end
|
||||
end
|
||||
|
||||
gameevent_internal(event, newfunc)
|
||||
event_funcs[event] = newfunc
|
||||
end
|
||||
|
||||
--- non-default data and functions
|
||||
G_.gameevent = gameevent -- included in lunatic.c
|
||||
G_.gameevent = our_gameevent
|
||||
G_.gameactor = our_gameactor
|
||||
G_.player = player -- from above
|
||||
|
||||
|
@ -1052,8 +1102,6 @@ local lunacon = require("lunacon")
|
|||
setfenv(1, G_)
|
||||
|
||||
-- Print keys and values of a table.
|
||||
-- REMEMBER special position of 'tostring' (it's looked up and used as a global
|
||||
-- from 'print')
|
||||
local function printkv(label, table)
|
||||
print("========== Keys and values of "..label.." ("..tostring(table)..")")
|
||||
for k,v in pairs(table) do
|
||||
|
|
|
@ -12,12 +12,14 @@ local string = require("string")
|
|||
local error = error
|
||||
local pairs = pairs
|
||||
local setmetatable = setmetatable
|
||||
local tostring = tostring
|
||||
|
||||
local decl = decl
|
||||
local getfenv = getfenv
|
||||
|
||||
decl "void OSD_Printf(const char *fmt, ...);"
|
||||
print = function(str)
|
||||
-- our "print" doesn't use the global "tostring", but the initial one
|
||||
str = tostring(str)
|
||||
if (type(str) ~= "string") then
|
||||
error("invalid argument to print: must be convertible to a string")
|
||||
|
|
|
@ -50,6 +50,7 @@ OSD_Printf;
|
|||
|
||||
g_sizes_of_what;
|
||||
g_sizes_of;
|
||||
g_elCallDepth;
|
||||
|
||||
kopen4loadfrommod;
|
||||
kfilelength;
|
||||
|
|
|
@ -23,6 +23,8 @@ uint8_t g_elEvents[MAXEVENTS];
|
|||
// same thing for actors:
|
||||
el_actor_t g_elActors[MAXTILES];
|
||||
|
||||
int32_t g_elCallDepth = 0;
|
||||
|
||||
// for timing events and actors
|
||||
uint32_t g_eventCalls[MAXEVENTS], g_actorCalls[MAXTILES];
|
||||
double g_eventTotalMs[MAXEVENTS], g_actorTotalMs[MAXTILES];
|
||||
|
@ -104,7 +106,7 @@ void El_PrintTimes(void)
|
|||
}
|
||||
|
||||
////////// ERROR REPORTING //////////
|
||||
#define EL_MAXERRORS 2
|
||||
#define EL_MAXERRORS 20
|
||||
static int32_t el_numErrors=0, el_tooMuchErrors;
|
||||
static char *el_errorMsgs[EL_MAXERRORS];
|
||||
|
||||
|
@ -202,7 +204,7 @@ static void El_StateSetup(lua_State *L)
|
|||
|
||||
// create misc. global functions in the Lua state
|
||||
lua_pushcfunction(L, SetEvent_luacf);
|
||||
lua_setglobal(L, "gameevent");
|
||||
lua_setglobal(L, "gameevent_internal");
|
||||
lua_pushcfunction(L, SetActor_luacf);
|
||||
lua_setglobal(L, "gameactor_internal");
|
||||
|
||||
|
@ -230,12 +232,10 @@ static int32_t SetEvent_luacf(lua_State *L)
|
|||
{
|
||||
int32_t eventidx;
|
||||
|
||||
if (lua_gettop(L) != 2)
|
||||
luaL_error(L, "gameevent: must pass exactly two arguments");
|
||||
|
||||
Bassert(lua_gettop(L) == 2);
|
||||
eventidx = luaL_checkint(L, 1);
|
||||
Bassert((unsigned)eventidx < MAXEVENTS);
|
||||
|
||||
luaL_argcheck(L, (unsigned)eventidx < MAXEVENTS, 1, "must be an event number (0 .. MAXEVENTS-1)");
|
||||
L_CheckAndRegisterFunction(L, &g_elEvents[eventidx]);
|
||||
g_elEvents[eventidx] = 1;
|
||||
|
||||
|
@ -308,8 +308,11 @@ int32_t El_CallEvent(L_State *estate, int32_t eventidx, int32_t iActor, int32_t
|
|||
// make a global?
|
||||
|
||||
lua_State *const L = estate->L;
|
||||
int32_t i;
|
||||
|
||||
int32_t i = call_regd_function3(L, &g_elEvents[eventidx], iActor, iPlayer, lDist);
|
||||
g_elCallDepth++;
|
||||
i = call_regd_function3(L, &g_elEvents[eventidx], iActor, iPlayer, lDist);
|
||||
g_elCallDepth--;
|
||||
|
||||
if (i == LUA_ERRRUN)
|
||||
{
|
||||
|
@ -337,8 +340,11 @@ int32_t El_CallEvent(L_State *estate, int32_t eventidx, int32_t iActor, int32_t
|
|||
int32_t El_CallActor(L_State *estate, int32_t actortile, int32_t iActor, int32_t iPlayer, int32_t lDist)
|
||||
{
|
||||
lua_State *const L = estate->L;
|
||||
int32_t i;
|
||||
|
||||
int32_t i = call_regd_function3(L, &g_elActors[actortile], iActor, iPlayer, lDist);
|
||||
g_elCallDepth++;
|
||||
i = call_regd_function3(L, &g_elActors[actortile], iActor, iPlayer, lDist);
|
||||
g_elCallDepth--;
|
||||
|
||||
if (i == LUA_ERRRUN)
|
||||
{
|
||||
|
|
|
@ -7,6 +7,9 @@ local string = require("string")
|
|||
local bit = require("bit")
|
||||
local math = require("math")
|
||||
|
||||
local pcall = pcall
|
||||
local DBG_ = DBG_
|
||||
|
||||
print('---=== ELua Test script ===---')
|
||||
|
||||
local function printf(fmt, ...)
|
||||
|
@ -183,7 +186,7 @@ checkfail("do local bt=require'bittest'; bt.QWE=1; end", "modifying module table
|
|||
-- the cdata returned by player[] can't be made into a pointer!
|
||||
checkfail("do local pl=player[0]; i=pl[1]; end")
|
||||
checkfail("do local ud=gv.ud.camera; end", "dummy variable: read access forbidden") -- test for proper decl()
|
||||
checkfail("sprite[0]:set_picnum(-10)", "attempt to set invalid picnums")
|
||||
checkfail("sprite[0]:set_picnum(-10)", "attempt to set invalid picnum")
|
||||
|
||||
printf('ceilingbunch of sector 0: %d', getbunch(0, gv.CEILING))
|
||||
|
||||
|
@ -194,6 +197,13 @@ gameevent(gv.EVENT_JUMP,
|
|||
end
|
||||
)
|
||||
|
||||
-- test event chaining
|
||||
gameevent("JUMP",
|
||||
function(actori, playeri, dist)
|
||||
print("I'm first!")
|
||||
end
|
||||
)
|
||||
|
||||
gameevent(gv.EVENT_ENTERLEVEL,
|
||||
function()
|
||||
-- NOTE: times are for helixhorned (Core2Duo 3GHz)
|
||||
|
@ -230,6 +240,9 @@ gameevent(gv.EVENT_ENTERLEVEL,
|
|||
|
||||
printf("sqrt(0xffffffff) = %f(ksqrt) %f(math.sqrt)",
|
||||
gv.ksqrt(0xffffffff), math.sqrt(0xffffffff))
|
||||
|
||||
checkfail("gameevent('GAME', function() print('qwe') end)",
|
||||
"must be called from top level")
|
||||
end
|
||||
)
|
||||
|
||||
|
|
20
polymer/eduke32/source/lunatic/test/event_chaining.con
Normal file
20
polymer/eduke32/source/lunatic/test/event_chaining.con
Normal file
|
@ -0,0 +1,20 @@
|
|||
definequote 125 FIRST
|
||||
definequote 126 SECOND
|
||||
definequote 127 THIRD
|
||||
|
||||
onevent EVENT_INIT
|
||||
echo 125
|
||||
endevent
|
||||
|
||||
onevent EVENT_INIT
|
||||
echo 126
|
||||
endevent
|
||||
|
||||
onevent EVENT_INIT
|
||||
echo 127
|
||||
endevent
|
||||
|
||||
// output:
|
||||
// THIRD
|
||||
// SECOND
|
||||
// FIRST
|
Loading…
Reference in a new issue