mirror of
https://github.com/love2d/love.git
synced 2026-08-18 03:34:23 +02:00
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:
@@ -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();
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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 }
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user