Using latest love-android branch (9a508a54700d)

This commit is contained in:
fysx
2015-08-13 11:12:17 +02:00
parent c91dbb6957
commit f3dd769e98
63 changed files with 738 additions and 556 deletions
+14 -26
View File
@@ -26,13 +26,13 @@ namespace love
const char REFERENCE_TABLE_NAME[] = "love-references";
Reference::Reference()
: L(nullptr)
: pinnedL(nullptr)
, idx(LUA_REFNIL)
{
}
Reference::Reference(lua_State *L)
: L(L)
: pinnedL(nullptr)
, idx(LUA_REFNIL)
{
ref(L);
@@ -46,7 +46,7 @@ Reference::~Reference()
void Reference::ref(lua_State *L)
{
unref(); // Just to be safe.
this->L = L;
pinnedL = luax_getpinnedthread(L);
luax_insist(L, LUA_REGISTRYINDEX, REFERENCE_TABLE_NAME);
lua_insert(L, -2); // Move reference table behind value.
idx = luaL_ref(L, -2);
@@ -57,38 +57,26 @@ void Reference::unref()
{
if (idx != LUA_REFNIL)
{
luax_insist(L, LUA_REGISTRYINDEX, REFERENCE_TABLE_NAME);
luaL_unref(L, -1, idx);
lua_pop(L, 1);
// We use a pinned thread/coroutine for the Lua state because we know it
// hasn't been garbage collected and is valid, as long as the whole lua
// state is still open.
luax_insist(pinnedL, LUA_REGISTRYINDEX, REFERENCE_TABLE_NAME);
luaL_unref(pinnedL, -1, idx);
lua_pop(pinnedL, 1);
idx = LUA_REFNIL;
}
}
void Reference::push(lua_State *newL)
void Reference::push(lua_State *L)
{
if (idx != LUA_REFNIL)
{
luax_insist(newL, LUA_REGISTRYINDEX, REFERENCE_TABLE_NAME);
lua_rawgeti(newL, -1, idx);
lua_remove(newL, -2);
luax_insist(L, LUA_REGISTRYINDEX, REFERENCE_TABLE_NAME);
lua_rawgeti(L, -1, idx);
lua_remove(L, -2);
}
else
lua_pushnil(newL);
}
void Reference::push()
{
push(L);
}
lua_State *Reference::getL() const
{
return L;
}
void Reference::setL(lua_State *newL)
{
L = newL;
lua_pushnil(L);
}
} // love
+7 -26
View File
@@ -64,36 +64,17 @@ public:
void unref();
/**
* Pushes the referred value onto the stack of a different coroutine
* in the same main Lua state.
* THIS SHOULD NOT BE USED FOR DIFFERENT LUA STATES (created with
* luaL_newstate)! Only with different coroutines!
* Pushes the referred value onto the stack of the specified Lua coroutine.
* NOTE: The coroutine *must* belong to the same Lua state that was used for
* Reference::ref.
**/
void push(lua_State *newL);
/**
* Pushes the referred value onto the stack.
**/
void push();
/**
* Gets the Lua state associated with this
* reference.
**/
lua_State *getL() const;
/**
* Associates a new Lua state with this reference.
* THIS IS DANGEROUS! It is only designed to be
* used with different coroutines from the same
* main Lua state!
**/
void setL(lua_State *newL);
void push(lua_State *L);
private:
// The Lua state in which the reference resides.
lua_State *L;
// A pinned coroutine (probably the main thread) belonging to the Lua state
// in which the reference resides.
lua_State *pinnedL;
// Index to the Lua reference.
int idx;
+1 -1
View File
@@ -31,7 +31,7 @@ static love::Type extractudatatype(lua_State *L, int idx)
Type t = INVALID_ID;
if (!lua_isuserdata(L, idx))
return t;
if (luaL_getmetafield(L, idx, "__tostring") == 0)
if (luaL_getmetafield(L, idx, "type") == 0)
return t;
lua_pushvalue(L, idx);
int result = lua_pcall(L, 1, 1, 0);
+47 -10
View File
@@ -47,6 +47,14 @@ static int w__gc(lua_State *L)
}
static int w__tostring(lua_State *L)
{
Proxy *p = (Proxy *) lua_touserdata(L, 1);
const char *typname = lua_tostring(L, lua_upvalueindex(1));
lua_pushfstring(L, "%s: %p", typname, p->object);
return 1;
}
static int w__type(lua_State *L)
{
lua_pushvalue(L, lua_upvalueindex(1));
return 1;
@@ -83,7 +91,7 @@ Reference *luax_refif(lua_State *L, int type)
void luax_printstack(lua_State *L)
{
for (int i = 1; i<=lua_gettop(L); i++)
for (int i = 1; i <= lua_gettop(L); i++)
std::cout << i << " - " << luaL_typename(L, i) << std::endl;
}
@@ -313,9 +321,9 @@ int luax_register_type(lua_State *L, love::Type type, const luaL_Reg *f, bool pu
lua_pushcclosure(L, w__tostring, 1);
lua_setfield(L, -2, "__tostring");
// Add tostring to as type() as well.
// Add type
lua_pushstring(L, tname);
lua_pushcclosure(L, w__tostring, 1);
lua_pushcclosure(L, w__type, 1);
lua_setfield(L, -2, "type");
// Add typeOf
@@ -590,8 +598,6 @@ int luax_insistregistry(lua_State *L, Registry r)
{
switch (r)
{
case REGISTRY_GC:
return luax_insistlove(L, "_gc");
case REGISTRY_MODULES:
return luax_insistlove(L, "_modules");
case REGISTRY_OBJECTS:
@@ -605,8 +611,6 @@ int luax_getregistry(lua_State *L, Registry r)
{
switch (r)
{
case REGISTRY_GC:
return luax_getlove(L, "_gc");
case REGISTRY_MODULES:
return luax_getlove(L, "_modules");
case REGISTRY_OBJECTS:
@@ -617,21 +621,54 @@ int luax_getregistry(lua_State *L, Registry r)
}
}
static const char *MAIN_THREAD_KEY = "_love_mainthread";
lua_State *luax_insistpinnedthread(lua_State *L)
{
lua_getfield(L, LUA_REGISTRYINDEX, MAIN_THREAD_KEY);
if (lua_isnoneornil(L, -1))
{
lua_pop(L, 1);
// lua_pushthread returns 1 if it's actually the main thread, but we
// can't actually get the real main thread if lua_pushthread doesn't
// return it (in Lua 5.1 at least), so we ignore that for now...
// We do store a strong reference to the current thread/coroutine in
// the registry, however.
lua_pushthread(L);
lua_pushvalue(L, -1);
lua_setfield(L, LUA_REGISTRYINDEX, MAIN_THREAD_KEY);
}
lua_State *thread = lua_tothread(L, -1);
lua_pop(L, 1);
return thread;
}
lua_State *luax_getpinnedthread(lua_State *L)
{
lua_getfield(L, LUA_REGISTRYINDEX, MAIN_THREAD_KEY);
lua_State *thread = lua_tothread(L, -1);
lua_pop(L, 1);
return thread;
}
extern "C" int luax_typerror(lua_State *L, int narg, const char *tname)
{
int argtype = lua_type(L, narg);
const char *argtname = 0;
// We want to use the love type name for userdata, if possible.
if (argtype == LUA_TUSERDATA && luaL_getmetafield(L, narg, "__tostring") != 0)
if (argtype == LUA_TUSERDATA && luaL_getmetafield(L, narg, "type") != 0)
{
lua_pushvalue(L, narg);
if (lua_pcall(L, 1, 1, 0) == 0 && lua_type(L, -1) == LUA_TSTRING)
{
argtname = lua_tostring(L, -1);
// Non-love userdata might have a tostring metamethod which doesn't
// describe its type, so we only use __tostring for love types.
// Non-love userdata might have a type metamethod which doesn't
// describe its type properly, so we only use it for love types.
love::Type t;
if (!love::getType(argtname, t))
argtname = 0;
+18 -1
View File
@@ -49,7 +49,6 @@ class Reference;
**/
enum Registry
{
REGISTRY_GC,
REGISTRY_MODULES,
REGISTRY_OBJECTS
};
@@ -390,6 +389,24 @@ int luax_insistregistry(lua_State *L, Registry r);
**/
int luax_getregistry(lua_State *L, Registry r);
/**
* Gets (and pins if needed) a "pinned" Lua thread (coroutine) in the specified
* Lua state. This will usually be the main Lua thread, unless the first call
* to this function for a specific Lua state is made from within a coroutine.
* NOTE: This does not push anything to the stack.
**/
lua_State *luax_insistpinnedthread(lua_State *L);
/**
* Gets a "pinned" Lua thread (coroutine) in the specified Lua state. This will
* usually be the main Lua thread. This can be used to access global variables
* in a specific Lua state without needing another alive lua_State value.
* PRECONDITION: luax_insistpinnedthread must have been called on a lua_State
* value corresponding to the Lua state which will be used with this function.
* NOTE: This does not push anything to the stack.
**/
lua_State *luax_getpinnedthread(lua_State *L);
extern "C" { // Also called from luasocket
int luax_typerror(lua_State *L, int narg, const char *tname);
}