mirror of
https://github.com/love2d/love-android.git
synced 2026-08-19 12:14:49 +02:00
actual update to latest mobile-common
This commit is contained in:
@@ -58,6 +58,8 @@ namespace
|
||||
namespace love
|
||||
{
|
||||
|
||||
Module *Module::instances[] = {};
|
||||
|
||||
Module::~Module()
|
||||
{
|
||||
ModuleRegistry ®istry = registryInstance();
|
||||
@@ -72,6 +74,13 @@ Module::~Module()
|
||||
}
|
||||
}
|
||||
|
||||
// Same deal with Module::getModuleType().
|
||||
for (int i = 0; i < (int) M_MAX_ENUM; i++)
|
||||
{
|
||||
if (instances[i] == this)
|
||||
instances[i] = nullptr;
|
||||
}
|
||||
|
||||
freeEmptyRegistry();
|
||||
}
|
||||
|
||||
@@ -94,6 +103,16 @@ void Module::registerInstance(Module *instance)
|
||||
}
|
||||
|
||||
registry.insert(make_pair(name, instance));
|
||||
|
||||
ModuleType moduletype = instance->getModuleType();
|
||||
|
||||
if (instances[moduletype] != nullptr)
|
||||
{
|
||||
printf("Warning: overwriting module instance %s with new instance %s\n",
|
||||
instances[moduletype]->getName(), instance->getName());
|
||||
}
|
||||
|
||||
instances[moduletype] = instance;
|
||||
}
|
||||
|
||||
Module *Module::getInstance(const std::string &name)
|
||||
@@ -108,17 +127,4 @@ Module *Module::getInstance(const std::string &name)
|
||||
return it->second;
|
||||
}
|
||||
|
||||
Module *Module::findInstance(const std::string &name)
|
||||
{
|
||||
ModuleRegistry ®istry = registryInstance();
|
||||
|
||||
for (auto it = registry.begin(); it != registry.end(); ++it)
|
||||
{
|
||||
if (it->first.find(name) == 0)
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // love
|
||||
|
||||
@@ -34,11 +34,35 @@ class Module : public Object
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Destructor.
|
||||
**/
|
||||
enum ModuleType
|
||||
{
|
||||
M_AUDIO,
|
||||
M_EVENT,
|
||||
M_FILESYSTEM,
|
||||
M_FONT,
|
||||
M_GRAPHICS,
|
||||
M_IMAGE,
|
||||
M_JOYSTICK,
|
||||
M_KEYBOARD,
|
||||
M_MATH,
|
||||
M_MOUSE,
|
||||
M_PHYSICS,
|
||||
M_SOUND,
|
||||
M_SYSTEM,
|
||||
M_THREAD,
|
||||
M_TIMER,
|
||||
M_TOUCH,
|
||||
M_WINDOW,
|
||||
M_MAX_ENUM
|
||||
};
|
||||
|
||||
virtual ~Module();
|
||||
|
||||
/**
|
||||
* Gets the base type of the module.
|
||||
**/
|
||||
virtual ModuleType getModuleType() const = 0;
|
||||
|
||||
/**
|
||||
* Gets the name of the module. This is used in case of errors
|
||||
* and other messages.
|
||||
@@ -63,13 +87,19 @@ public:
|
||||
static Module *getInstance(const std::string &name);
|
||||
|
||||
/**
|
||||
* Find the first module instance from the internal registry whose name
|
||||
* starts with the supplied name. May return NULL if module is not
|
||||
* registered or the supplied name is not part of any module name.
|
||||
* @param name The partial name of the module.
|
||||
* @return Module instance or NULL if the module is not registered.
|
||||
* Retrieve module instance from the internal registry using the base
|
||||
* module type. May return null if the module is not registered.
|
||||
* @param type The base type of the module.
|
||||
**/
|
||||
static Module *findInstance(const std::string &name);
|
||||
template <typename T>
|
||||
static T *getInstance(ModuleType type)
|
||||
{
|
||||
return (T *) instances[type];
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
static Module *instances[M_MAX_ENUM];
|
||||
|
||||
}; // Module
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
// LOVE
|
||||
#include "Object.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
namespace love
|
||||
{
|
||||
|
||||
|
||||
@@ -92,11 +92,73 @@ public:
|
||||
|
||||
}; // AutoRelease
|
||||
|
||||
/**
|
||||
* Partial re-implementation + specialization of std::shared_ptr. We can't
|
||||
* use C++11's stdlib yet...
|
||||
**/
|
||||
template <typename T>
|
||||
class StrongRef
|
||||
{
|
||||
public:
|
||||
|
||||
StrongRef()
|
||||
: object(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
StrongRef(T *obj)
|
||||
: object(obj)
|
||||
{
|
||||
if (object) object->retain();
|
||||
}
|
||||
|
||||
StrongRef(const StrongRef &other)
|
||||
: object(other.get())
|
||||
{
|
||||
if (object) object->retain();
|
||||
}
|
||||
|
||||
~StrongRef()
|
||||
{
|
||||
if (object) object->release();
|
||||
}
|
||||
|
||||
StrongRef &operator = (const StrongRef &other)
|
||||
{
|
||||
set(other.get());
|
||||
return *this;
|
||||
}
|
||||
|
||||
T *operator->() const
|
||||
{
|
||||
return object;
|
||||
}
|
||||
|
||||
void set(T *obj)
|
||||
{
|
||||
if (obj) obj->retain();
|
||||
if (object) object->release();
|
||||
object = obj;
|
||||
}
|
||||
|
||||
T *get() const
|
||||
{
|
||||
return object;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
T *object;
|
||||
|
||||
}; // StrongRef
|
||||
|
||||
private:
|
||||
|
||||
// The reference count.
|
||||
int count;
|
||||
|
||||
}; // Object
|
||||
|
||||
} // love
|
||||
|
||||
#endif // LOVE_OBJECT_H
|
||||
|
||||
@@ -226,7 +226,6 @@ void Variant::toLua(lua_State *L)
|
||||
{
|
||||
const char *name = NULL;
|
||||
love::types.find(udatatype, name);
|
||||
((love::Object *) data.userdata)->retain();
|
||||
luax_pushtype(L, name, flags, (love::Object *) data.userdata);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -78,6 +78,10 @@
|
||||
# define LOVE_LEGENDARY_APP_ARGV_HACK
|
||||
#endif
|
||||
|
||||
#if defined(LOVE_ANDROID) || defined(LOVE_IOS)
|
||||
# define LOVE_LEGENDARY_ACCELEROMETER_AS_JOYSTICK_HACK
|
||||
#endif
|
||||
|
||||
// Autotools config.h
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <../config.h>
|
||||
|
||||
@@ -36,8 +36,7 @@
|
||||
namespace love
|
||||
{
|
||||
|
||||
static thread::Mutex *gcmutex = 0;
|
||||
void *_gcmutex = 0;
|
||||
static thread::Mutex *gcmutex = nullptr;
|
||||
|
||||
/**
|
||||
* Called when an object is collected. The object is released
|
||||
@@ -46,25 +45,15 @@ void *_gcmutex = 0;
|
||||
static int w__gc(lua_State *L)
|
||||
{
|
||||
if (!gcmutex)
|
||||
{
|
||||
gcmutex = thread::newMutex();
|
||||
_gcmutex = (void *) gcmutex;
|
||||
}
|
||||
|
||||
Proxy *p = (Proxy *)lua_touserdata(L, 1);
|
||||
Object *t = (Object *)p->data;
|
||||
Proxy *p = (Proxy *) lua_touserdata(L, 1);
|
||||
Object *object = (Object *) p->data;
|
||||
|
||||
thread::Lock lock(gcmutex);
|
||||
|
||||
int numretains = p->retains;
|
||||
if (numretains >= 0)
|
||||
numretains = std::min(numretains, t->getReferenceCount());
|
||||
object->release();
|
||||
|
||||
for (int i = numretains; i > 0; i--)
|
||||
t->release();
|
||||
|
||||
// Signal that this Proxy is dead.
|
||||
p->retains = -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -228,7 +217,6 @@ int luax_register_module(lua_State *L, const WrappedModule &m)
|
||||
luax_insistregistry(L, REGISTRY_MODULES);
|
||||
|
||||
Proxy *p = (Proxy *)lua_newuserdata(L, sizeof(Proxy));
|
||||
p->retains = 1;
|
||||
p->data = m.module;
|
||||
p->flags = m.flags;
|
||||
|
||||
@@ -394,20 +382,24 @@ int luax_register_searcher(lua_State *L, lua_CFunction f, int pos)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void luax_rawnewtype(lua_State *L, const char *name, bits flags, love::Object *data, bool own)
|
||||
void luax_rawnewtype(lua_State *L, const char *name, bits flags, love::Object *object)
|
||||
{
|
||||
Proxy *u = (Proxy *)lua_newuserdata(L, sizeof(Proxy));
|
||||
|
||||
u->data = (void *) data;
|
||||
object->retain();
|
||||
|
||||
u->data = (void *) object;
|
||||
u->flags = flags;
|
||||
u->retains = own ? 1 : 0;
|
||||
|
||||
luaL_newmetatable(L, name);
|
||||
lua_setmetatable(L, -2);
|
||||
}
|
||||
|
||||
void luax_pushtype(lua_State *L, const char *name, bits flags, love::Object *data, bool own)
|
||||
void luax_pushtype(lua_State *L, const char *name, bits flags, love::Object *object)
|
||||
{
|
||||
if (object == nullptr)
|
||||
lua_pushnil(L);
|
||||
|
||||
// Fetch the registry table of instantiated types.
|
||||
luax_getregistry(L, REGISTRY_TYPES);
|
||||
|
||||
@@ -415,11 +407,11 @@ void luax_pushtype(lua_State *L, const char *name, bits flags, love::Object *dat
|
||||
if (!lua_istable(L, -1))
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
return luax_rawnewtype(L, name, flags, data, own);
|
||||
return luax_rawnewtype(L, name, flags, object);
|
||||
}
|
||||
|
||||
// Get the value of lovetypes[data] on the stack.
|
||||
lua_pushlightuserdata(L, (void *) data);
|
||||
// Get the value of lovetypes[object] on the stack.
|
||||
lua_pushlightuserdata(L, (void *) object);
|
||||
lua_gettable(L, -2);
|
||||
|
||||
// If the Proxy userdata isn't in the instantiated types table yet, add it.
|
||||
@@ -427,38 +419,18 @@ void luax_pushtype(lua_State *L, const char *name, bits flags, love::Object *dat
|
||||
{
|
||||
lua_pop(L, 1);
|
||||
|
||||
luax_rawnewtype(L, name, flags, data, own);
|
||||
luax_rawnewtype(L, name, flags, object);
|
||||
|
||||
lua_pushlightuserdata(L, (void *) data);
|
||||
lua_pushlightuserdata(L, (void *) object);
|
||||
lua_pushvalue(L, -2);
|
||||
|
||||
// lovetypes[data] = Proxy.
|
||||
// lovetypes[object] = Proxy.
|
||||
lua_settable(L, -4);
|
||||
|
||||
// Remove the lovetypes table from the stack.
|
||||
lua_remove(L, -2);
|
||||
|
||||
// The Proxy userdata remains at the top of the stack.
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the lovetypes table from the stack.
|
||||
lua_remove(L, -2);
|
||||
|
||||
// If the object should be released on GC and we already have a stored
|
||||
// Proxy, we should tell the Proxy that the object was retained again.
|
||||
if (own)
|
||||
{
|
||||
Proxy *p = (Proxy *) lua_touserdata(L, -1);
|
||||
|
||||
thread::EmptyLock lock;
|
||||
if (gcmutex)
|
||||
lock.setLock(gcmutex);
|
||||
|
||||
if (p->retains >= 0)
|
||||
++(p->retains);
|
||||
}
|
||||
|
||||
// Keep the Proxy userdata on the stack.
|
||||
}
|
||||
|
||||
@@ -486,6 +458,10 @@ int luax_getfunction(lua_State *L, const char *mod, const char *fn)
|
||||
|
||||
int luax_convobj(lua_State *L, int idx, const char *mod, const char *fn)
|
||||
{
|
||||
// Convert to absolute index if necessary.
|
||||
if (idx < 0 && idx > LUA_REGISTRYINDEX)
|
||||
idx += lua_gettop(L) + 1;
|
||||
|
||||
// Convert string to a file.
|
||||
luax_getfunction(L, mod, fn);
|
||||
lua_pushvalue(L, idx); // The initial argument.
|
||||
|
||||
@@ -33,6 +33,9 @@ extern "C" {
|
||||
#include <lauxlib.h>
|
||||
}
|
||||
|
||||
// C++
|
||||
#include <exception>
|
||||
|
||||
namespace love
|
||||
{
|
||||
|
||||
@@ -40,16 +43,13 @@ namespace love
|
||||
class Module;
|
||||
class Reference;
|
||||
|
||||
// Exposed mutex of the GC
|
||||
extern void *_gcmutex;
|
||||
|
||||
/**
|
||||
* Registries represent special tables which can be accessed with
|
||||
* luax_insistregistry and luax_getregistry.
|
||||
**/
|
||||
enum Registry
|
||||
{
|
||||
REGISTRY_GC = 1,
|
||||
REGISTRY_GC,
|
||||
REGISTRY_MODULES,
|
||||
REGISTRY_TYPES
|
||||
};
|
||||
@@ -67,9 +67,6 @@ struct Proxy
|
||||
|
||||
// The light userdata (pointer to the love::Object).
|
||||
void *data;
|
||||
|
||||
// The number of times release() should be called on GC.
|
||||
int retains;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -228,6 +225,9 @@ void luax_setfuncs(lua_State *L, const luaL_Reg *l);
|
||||
|
||||
/**
|
||||
* Register a module in the love table. The love table will be created if it does not exist.
|
||||
* NOTE: The module-object is expected to have a +1 reference count before calling
|
||||
* this function, as it doesn't retain the object itself but Lua will release it
|
||||
* upon garbage collection.
|
||||
* @param L The Lua state.
|
||||
**/
|
||||
int luax_register_module(lua_State *L, const WrappedModule &m);
|
||||
@@ -268,27 +268,27 @@ int luax_register_searcher(lua_State *L, lua_CFunction f, int pos = -1);
|
||||
/**
|
||||
* Pushes a Lua representation of the given object onto the stack, creating and
|
||||
* storing the Lua representation in a weak table if it doesn't exist yet.
|
||||
* NOTE: The object will be retained by Lua and released upon garbage collection.
|
||||
* @param L The Lua state.
|
||||
* @param name The name of the type. This must match the name used with luax_register_type.
|
||||
* @param flags The type information of the object.
|
||||
* @param data The pointer to the actual object.
|
||||
* @param own Set this to true (default) if the object should be released upon garbage collection.
|
||||
* @param object The pointer to the actual object.
|
||||
**/
|
||||
void luax_pushtype(lua_State *L, const char *name, bits flags, love::Object *data, bool own = true);
|
||||
void luax_pushtype(lua_State *L, const char *name, bits flags, love::Object *object);
|
||||
|
||||
/**
|
||||
* Creates a new Lua representation of the given object *without* checking if it
|
||||
* exists yet, and *without* storing it in a weak table.
|
||||
* This should only be used when performance is an extreme concern and the
|
||||
* object is not ever expected to be pushed to Lua again, as it prevents the
|
||||
* Lua-side objects from working in all cases when used as keys in tables.
|
||||
* Lua-side objects from working in some cases when used as keys in tables.
|
||||
* NOTE: The object will be retained by Lua and released upon garbage collection.
|
||||
* @param L The Lua state.
|
||||
* @param name The name of the type. This must match the name used with luax_register_type.
|
||||
* @param flags The type information of the object.
|
||||
* @param data The pointer to the actual object.
|
||||
* @param own Set this to true (default) if the object should be released upon garbage collection.
|
||||
* @param object The pointer to the actual object.
|
||||
**/
|
||||
void luax_rawnewtype(lua_State *L, const char *name, bits flags, love::Object *data, bool own = true);
|
||||
void luax_rawnewtype(lua_State *L, const char *name, bits flags, love::Object *object);
|
||||
|
||||
/**
|
||||
* Checks whether the value at idx is a certain type.
|
||||
@@ -471,22 +471,55 @@ T *luax_totype(lua_State *L, int idx, const char * /* name */, love::bits /* typ
|
||||
Type luax_type(lua_State *L, int idx);
|
||||
|
||||
/**
|
||||
* Macro for converting a LOVE exception into a Lua error.
|
||||
* Converts any exceptions thrown by the passed lambda function into a Lua error.
|
||||
* lua_error (and luaL_error) cannot be called from inside the exception handler
|
||||
* because they use longjmp, which causes undefined behaviour when the
|
||||
* destructor of the exception would have been called.
|
||||
**/
|
||||
#define EXCEPT_GUARD(A) \
|
||||
{ \
|
||||
bool should_error = false; \
|
||||
try { A } \
|
||||
catch (love::Exception &e) \
|
||||
{ \
|
||||
should_error = true; \
|
||||
lua_pushstring(L, e.what()); \
|
||||
} \
|
||||
if (should_error) \
|
||||
return luaL_error(L, "%s", lua_tostring(L, -1)); \
|
||||
template <typename T>
|
||||
int luax_catchexcept(lua_State *L, const T& func)
|
||||
{
|
||||
bool should_error = false;
|
||||
|
||||
try
|
||||
{
|
||||
func();
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
should_error = true;
|
||||
lua_pushstring(L, e.what());
|
||||
}
|
||||
|
||||
if (should_error)
|
||||
return luaL_error(L, "%s", lua_tostring(L, -1));
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
template <typename T, typename F>
|
||||
int luax_catchexcept(lua_State *L, const T& func, const F& finallyfunc)
|
||||
{
|
||||
bool should_error = false;
|
||||
|
||||
try
|
||||
{
|
||||
func();
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
should_error = true;
|
||||
lua_pushstring(L, e.what());
|
||||
}
|
||||
|
||||
finallyfunc();
|
||||
|
||||
if (should_error)
|
||||
return luaL_error(L, "%s", lua_tostring(L, -1));
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
} // love
|
||||
|
||||
@@ -27,9 +27,9 @@ namespace love
|
||||
// Version stuff.
|
||||
const int VERSION_MAJOR = 0;
|
||||
const int VERSION_MINOR = 9;
|
||||
const int VERSION_REV = 1;
|
||||
const char *VERSION = "0.9.1";
|
||||
const char *VERSION_COMPATIBILITY[] = { VERSION, "0.9.0", 0 };
|
||||
const int VERSION_REV = 2;
|
||||
const char *VERSION = "0.9.2";
|
||||
const char *VERSION_COMPATIBILITY[] = { VERSION, "0.9.1", "0.9.0", 0 };
|
||||
const char *VERSION_CODENAME = "Baby Inspector";
|
||||
|
||||
} // love
|
||||
|
||||
Reference in New Issue
Block a user