mirror of
https://github.com/AquariaOSE/Aquaria.git
synced 2024-12-25 22:25:46 +00:00
Really fix variadic calls (including self). Also fix avatar_setPullTarget() failing because entities are userdata now.
This does now allow constructs like this, in an entity script: function msg(me, a) if a > 1 then a = a * entity_msg(me, a - 1) end return a end So that entity_msg(thing, 5) == 120 is true.
This commit is contained in:
parent
0cdbc66c02
commit
e94de627eb
5 changed files with 31 additions and 42 deletions
|
@ -234,7 +234,7 @@ public:
|
||||||
bool canSetState(int state);
|
bool canSetState(int state);
|
||||||
|
|
||||||
virtual void message(const std::string &msg, int v) {}
|
virtual void message(const std::string &msg, int v) {}
|
||||||
virtual void messageVariadic(lua_State *L, int nparams) {}
|
virtual int messageVariadic(lua_State *L, int nparams) { return 0; }
|
||||||
|
|
||||||
bool isUnderWater(const Vector &o=Vector());
|
bool isUnderWater(const Vector &o=Vector());
|
||||||
|
|
||||||
|
|
|
@ -2889,8 +2889,8 @@ luaFunc(entity_isBeingPulled)
|
||||||
luaFunc(avatar_setPullTarget)
|
luaFunc(avatar_setPullTarget)
|
||||||
{
|
{
|
||||||
Entity *e = 0;
|
Entity *e = 0;
|
||||||
if (lua_tonumber(L, 1) != 0)
|
if (lua_isuserdata(L, 1))
|
||||||
e = entity(L);
|
e = entity(L, 1);
|
||||||
|
|
||||||
if (dsq->game->avatar->pullTarget != 0)
|
if (dsq->game->avatar->pullTarget != 0)
|
||||||
dsq->game->avatar->pullTarget->stopPull();
|
dsq->game->avatar->pullTarget->stopPull();
|
||||||
|
@ -4202,10 +4202,10 @@ luaFunc(entity_msg)
|
||||||
Entity *e = entity(L);
|
Entity *e = entity(L);
|
||||||
if (e)
|
if (e)
|
||||||
{
|
{
|
||||||
int top = lua_gettop(L);
|
|
||||||
// pass everything on the stack except the entity pointer
|
// pass everything on the stack except the entity pointer
|
||||||
e->messageVariadic(L, top - 1);
|
int res = e->messageVariadic(L, lua_gettop(L) - 1);
|
||||||
return lua_gettop(L) - top; // return everything that was pushed on our stack
|
if (res >= 0)
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
luaReturnNil();
|
luaReturnNil();
|
||||||
}
|
}
|
||||||
|
@ -9177,42 +9177,27 @@ bool Script::call(const char *name, void *param1, void *param2, void *param3, fl
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Script::callVariadic(const char *name, lua_State *fromL, int nparams, void *param)
|
int Script::callVariadic(const char *name, lua_State *fromL, int nparams, void *param)
|
||||||
{
|
{
|
||||||
lookupFunc(name); // [f]
|
int oldtop = lua_gettop(L);
|
||||||
luaPushPointer(L, param); // [f, p]
|
|
||||||
|
|
||||||
if (L != fromL)
|
lookupFunc(name);
|
||||||
{
|
luaPushPointer(L, param);
|
||||||
// clone topmost nparams elements, they will be popped by xmove
|
|
||||||
|
// If both stacks are the same, we already pushed 2 more entries to the stack.
|
||||||
|
int pos = (L == fromL) ? -(nparams+2) : -nparams;
|
||||||
for (int i = 0; i < nparams; ++i)
|
for (int i = 0; i < nparams; ++i)
|
||||||
lua_pushvalue(fromL, -nparams);
|
lua_pushvalue(fromL, pos);
|
||||||
|
|
||||||
// Move them to the other stack
|
// Move them to the other stack. Ignored if L == fromL.
|
||||||
lua_xmove(fromL, L, nparams); // [f, p, ...]
|
lua_xmove(fromL, L, nparams);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Same stack, insert pointer param below the parameters which are already there
|
|
||||||
lua_insert(L, -(nparams + 2));
|
|
||||||
// and the function, now below the pointer param
|
|
||||||
lua_insert(L, -(nparams + 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do the call
|
// Do the call
|
||||||
bool success = doCall(nparams + 1, LUA_MULTRET);
|
if (!doCall(nparams + 1, LUA_MULTRET))
|
||||||
|
return -1;
|
||||||
|
|
||||||
// after returning from the call, push everything that is left on the stack
|
nparams = lua_gettop(L) - oldtop;
|
||||||
// (= what the function returned) back onto the caller's stack, if not already there.
|
lua_xmove(L, fromL, nparams);
|
||||||
if (success && L != fromL)
|
|
||||||
{
|
|
||||||
// clone elements again
|
|
||||||
int count = lua_gettop(L);
|
|
||||||
for (int i = 0; i < count; ++i)
|
|
||||||
lua_pushvalue(L, -count);
|
|
||||||
|
|
||||||
lua_xmove(L, fromL, count);
|
return nparams;
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,8 @@ public:
|
||||||
// boolean = function(pointer, pointer, pointer, number, number, number, number, pointer)
|
// boolean = function(pointer, pointer, pointer, number, number, number, number, pointer)
|
||||||
bool call(const char *name, void *param1, void *param2, void *param3, float param4, float param5, float param6, float param7, void *param8, bool *ret1);
|
bool call(const char *name, void *param1, void *param2, void *param3, float param4, float param5, float param6, float param7, void *param8, bool *ret1);
|
||||||
// function(pointer, ...) - anything that is already on the stack is forwarded. Results are left on the stack.
|
// function(pointer, ...) - anything that is already on the stack is forwarded. Results are left on the stack.
|
||||||
bool callVariadic(const char *name, lua_State *L, int nparams, void *param);
|
// Returns how many values the called function returned, or -1 in case of error.
|
||||||
|
int callVariadic(const char *name, lua_State *L, int nparams, void *param);
|
||||||
|
|
||||||
lua_State *getLuaState() {return L;}
|
lua_State *getLuaState() {return L;}
|
||||||
const std::string &getFile() {return file;}
|
const std::string &getFile() {return file;}
|
||||||
|
|
|
@ -96,14 +96,17 @@ void ScriptedEntity::message(const std::string &msg, int v)
|
||||||
Entity::message(msg, v);
|
Entity::message(msg, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptedEntity::messageVariadic(lua_State *L, int nparams)
|
int ScriptedEntity::messageVariadic(lua_State *L, int nparams)
|
||||||
{
|
{
|
||||||
if (script)
|
if (script)
|
||||||
{
|
{
|
||||||
if (!script->callVariadic("msg", L, nparams, this))
|
int res = script->callVariadic("msg", L, nparams, this);
|
||||||
|
if (res < 0)
|
||||||
luaDebugMsg("msg", script->getLastError());
|
luaDebugMsg("msg", script->getLastError());
|
||||||
|
else
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
Entity::messageVariadic(L, nparams);
|
return Entity::messageVariadic(L, nparams);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScriptedEntity::warpSegments()
|
void ScriptedEntity::warpSegments()
|
||||||
|
|
|
@ -47,7 +47,7 @@ public:
|
||||||
void lightFlare();
|
void lightFlare();
|
||||||
void entityDied(Entity *e);
|
void entityDied(Entity *e);
|
||||||
void message(const std::string &msg, int v);
|
void message(const std::string &msg, int v);
|
||||||
void messageVariadic(lua_State *L, int nparams);
|
int messageVariadic(lua_State *L, int nparams);
|
||||||
|
|
||||||
static bool runningActivation;
|
static bool runningActivation;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue