Add love.event.restart(optionalvalue) as a shorthand for love.event.quit("restart", optionalvalue). If a Lua value is provided as an argument, a new love.restart field will contain the value after restarting.

--HG--
branch : minor
This commit is contained in:
Alex Szpakowski
2019-12-28 22:43:39 -05:00
parent 443250ffd5
commit b001b2e1d5
6 changed files with 65 additions and 20 deletions
+9 -3
View File
@@ -152,7 +152,7 @@ Variant &Variant::operator = (const Variant &v)
return *this;
}
Variant Variant::fromLua(lua_State *L, int n, std::set<const void*> *tableSet)
Variant Variant::fromLua(lua_State *L, int n, bool allowuserdata, std::set<const void*> *tableSet)
{
size_t len;
const char *str;
@@ -173,6 +173,11 @@ Variant Variant::fromLua(lua_State *L, int n, std::set<const void*> *tableSet)
case LUA_TLIGHTUSERDATA:
return Variant(lua_touserdata(L, n));
case LUA_TUSERDATA:
if (!allowuserdata)
{
luax_typerror(L, n, "copyable Lua value");
return Variant();
}
p = tryextractproxy(L, n);
if (p != nullptr)
return Variant(p->type, p->object);
@@ -187,7 +192,6 @@ Variant Variant::fromLua(lua_State *L, int n, std::set<const void*> *tableSet)
{
bool success = true;
std::set<const void *> topTableSet;
SharedTable *table = new SharedTable();
// We can use a pointer to a stack-allocated variable because it's
// never used after the stack-allocated variable is destroyed.
@@ -202,6 +206,8 @@ Variant Variant::fromLua(lua_State *L, int n, std::set<const void*> *tableSet)
throw love::Exception("Cycle detected in table");
}
SharedTable *table = new SharedTable();
size_t len = luax_objlen(L, -1);
if (len > 0)
table->pairs.reserve(len);
@@ -210,7 +216,7 @@ Variant Variant::fromLua(lua_State *L, int n, std::set<const void*> *tableSet)
while (lua_next(L, n))
{
table->pairs.emplace_back(fromLua(L, -2, tableSet), fromLua(L, -1, tableSet));
table->pairs.emplace_back(fromLua(L, -2, allowuserdata, tableSet), fromLua(L, -1, allowuserdata, tableSet));
lua_pop(L, 1);
const auto &p = table->pairs.back();
+1 -1
View File
@@ -111,7 +111,7 @@ public:
Type getType() const { return type; }
const Data &getData() const { return data; }
static Variant fromLua(lua_State *L, int n, std::set<const void*> *tableSet = nullptr);
static Variant fromLua(lua_State *L, int n, bool allowuserdata = true, std::set<const void*> *tableSet = nullptr);
void toLua(lua_State *L) const;
private:
+22 -6
View File
@@ -20,6 +20,7 @@
#include "common/version.h"
#include "common/runtime.h"
#include "common/Variant.h"
#include "modules/love/love.h"
#include <SDL.h>
@@ -139,7 +140,7 @@ enum DoneAction
DONE_RESTART,
};
static DoneAction runlove(int argc, char **argv, int &retval)
static DoneAction runlove(int argc, char **argv, int &retval, love::Variant &restartvalue)
{
#ifdef LOVE_LEGENDARY_APP_ARGV_HACK
int hack_argc = 0;
@@ -203,6 +204,11 @@ static DoneAction runlove(int argc, char **argv, int &retval)
lua_setfield(L, -2, "_exe");
}
// Set love.restart = restartvalue, and clear restartvalue.
restartvalue.toLua(L);
lua_setfield(L, -2, "restart");
restartvalue = love::Variant();
// Pop the love table returned by require "love".
lua_pop(L, 1);
@@ -223,10 +229,19 @@ static DoneAction runlove(int argc, char **argv, int &retval)
// if love.boot() returns "restart", we'll start up again after closing this
// Lua state.
if (lua_type(L, -1) == LUA_TSTRING && strcmp(lua_tostring(L, -1), "restart") == 0)
done = DONE_RESTART;
if (lua_isnumber(L, -1))
retval = (int) lua_tonumber(L, -1);
int retidx = stackpos;
if (!lua_isnoneornil(L, retidx))
{
if (lua_type(L, retidx) == LUA_TSTRING && strcmp(lua_tostring(L, retidx), "restart") == 0)
done = DONE_RESTART;
if (lua_isnumber(L, retidx))
retval = (int) lua_tonumber(L, retidx);
// Disallow userdata (love objects) from being referenced by the restart
// value.
if (retidx < lua_gettop(L))
restartvalue = love::Variant::fromLua(L, retidx + 1, false);
}
lua_close(L);
@@ -253,10 +268,11 @@ int main(int argc, char **argv)
int retval = 0;
DoneAction done = DONE_QUIT;
love::Variant restartvalue;
do
{
done = runlove(argc, argv, retval);
done = runlove(argc, argv, retval, restartvalue);
#ifdef LOVE_IOS
// on iOS we should never programmatically exit the app, so we'll just
+23 -2
View File
@@ -22,9 +22,10 @@
// LOVE
#include "common/runtime.h"
#include "sdl/Event.h"
#include <algorithm>
// Shove the wrap_Event.lua code directly into a raw string literal.
static const char event_lua[] =
#include "wrap_Event.lua"
@@ -95,7 +96,26 @@ int w_clear(lua_State *L)
int w_quit(lua_State *L)
{
luax_catchexcept(L, [&]() {
std::vector<Variant> args = {Variant::fromLua(L, 1)};
std::vector<Variant> args;
for (int i = 1; i <= std::max(1, lua_gettop(L)); i++)
args.push_back(Variant::fromLua(L, i));
StrongRef<Message> m(new Message("quit", args), Acquire::NORETAIN);
instance()->push(m);
});
luax_pushboolean(L, true);
return 1;
}
int w_restart(lua_State *L)
{
luax_catchexcept(L, [&]() {
std::vector<Variant> args;
args.emplace_back("restart", strlen("restart"));
for (int i = 1; i <= lua_gettop(L); i++)
args.push_back(Variant::fromLua(L, i));
StrongRef<Message> m(new Message("quit", args), Acquire::NORETAIN);
instance()->push(m);
@@ -114,6 +134,7 @@ static const luaL_Reg functions[] =
{ "push", w_push },
{ "clear", w_clear },
{ "quit", w_quit },
{ "restart", w_restart },
{ 0, 0 }
};
+3 -3
View File
@@ -598,7 +598,7 @@ function love.run()
for name, a,b,c,d,e,f in love.event.poll() do
if name == "quit" then
if not love.quit or not love.quit() then
return a or 0
return a or 0, b
end
end
love.handlers[name](a,b,c,d,e,f)
@@ -799,8 +799,8 @@ return function()
func = earlyinit
while func do
local _, retval = xpcall(func, deferErrhand)
if retval then return retval end
local _, retval, restartvalue = xpcall(func, deferErrhand)
if retval then return retval, restartvalue end
coroutine.yield()
end
+7 -5
View File
@@ -1208,7 +1208,7 @@ const unsigned char boot_lua[] =
0x75, 0x69, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x71, 0x75,
0x69, 0x74, 0x28, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x20, 0x6f, 0x72, 0x20,
0x30, 0x0a,
0x30, 0x2c, 0x20, 0x62, 0x0a,
0x09, 0x09, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x5b,
@@ -1581,11 +1581,13 @@ const unsigned char boot_lua[] =
0x09, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x65, 0x61, 0x72, 0x6c, 0x79, 0x69, 0x6e, 0x69, 0x74, 0x0a,
0x0a,
0x09, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x20, 0x64, 0x6f, 0x0a,
0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x2c, 0x20, 0x72, 0x65, 0x74, 0x76, 0x61, 0x6c, 0x20,
0x3d, 0x20, 0x78, 0x70, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x2c, 0x20, 0x64, 0x65, 0x66,
0x65, 0x72, 0x45, 0x72, 0x72, 0x68, 0x61, 0x6e, 0x64, 0x29, 0x0a,
0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x5f, 0x2c, 0x20, 0x72, 0x65, 0x74, 0x76, 0x61, 0x6c, 0x2c,
0x20, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x3d, 0x20, 0x78, 0x70,
0x63, 0x61, 0x6c, 0x6c, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x2c, 0x20, 0x64, 0x65, 0x66, 0x65, 0x72, 0x45, 0x72,
0x72, 0x68, 0x61, 0x6e, 0x64, 0x29, 0x0a,
0x09, 0x09, 0x69, 0x66, 0x20, 0x72, 0x65, 0x74, 0x76, 0x61, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72,
0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x76, 0x61, 0x6c, 0x20, 0x65, 0x6e, 0x64, 0x0a,
0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x76, 0x61, 0x6c, 0x2c, 0x20, 0x72, 0x65, 0x73, 0x74,
0x61, 0x72, 0x74, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x63, 0x6f, 0x72, 0x6f, 0x75, 0x74, 0x69, 0x6e, 0x65, 0x2e, 0x79, 0x69, 0x65, 0x6c, 0x64, 0x28,
0x29, 0x0a,
0x09, 0x65, 0x6e, 0x64, 0x0a,