Optimized away intermediate Lua proxy classes.

This commit is contained in:
Guillaume Melquiond 2009-08-16 22:29:09 +00:00
parent de92d5ae28
commit 85bd943dfb

View File

@ -741,6 +741,19 @@ static int lua_wml_action_collect(lua_State *L)
return 0;
}
/**
* Calls the first upvalue and passes the first argument and the second upvalue.
* - Arg 1: optional WML config.
*/
static int lua_wml_action_proxy(lua_State *L)
{
lua_pushvalue(L, lua_upvalueindex(1));
lua_pushvalue(L, 1);
lua_pushvalue(L, lua_upvalueindex(2));
lua_call(L, 2, 0);
return 0;
}
/**
* Proxy class for calling WML action handlers defined in Lua.
*/
@ -814,6 +827,18 @@ static int lua_register_wml_action(lua_State *L)
game_events::register_action_handler(m, new lua_action_handler(L, length + 1), &previous);
if (!previous) return 0;
// Detect if the previous handler was already from Lua and optimize it away.
lua_action_handler *lua_prev = dynamic_cast<lua_action_handler *>(previous);
if (lua_prev)
{
lua_rawgeti(L, -1, lua_prev->num);
lua_rawgeti(L, -2, lua_prev->num + 1);
lua_pushcclosure(L, lua_wml_action_proxy, 2);
lua_rawseti(L, -2, length + 2);
delete lua_prev;
return 0;
}
// Push the previous handler in the user action table too.
void *p = lua_newuserdata(L, sizeof(game_events::action_handler *));
*static_cast<game_events::action_handler **>(p) = previous;