actual update to latest mobile-common

This commit is contained in:
fysx
2014-08-27 23:23:26 +02:00
parent abb819335b
commit c6ac06c366
992 changed files with 169762 additions and 177 deletions
+19 -13
View File
@@ -58,6 +58,8 @@ namespace
namespace love
{
Module *Module::instances[] = {};
Module::~Module()
{
ModuleRegistry &registry = 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 &registry = registryInstance();
for (auto it = registry.begin(); it != registry.end(); ++it)
{
if (it->first.find(name) == 0)
return it->second;
}
return nullptr;
}
} // love
+39 -9
View File
@@ -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
+2
View File
@@ -21,6 +21,8 @@
// LOVE
#include "Object.h"
#include <stdio.h>
namespace love
{
+62
View File
@@ -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
-1
View File
@@ -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
+4
View File
@@ -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>
+22 -46
View File
@@ -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.
+59 -26
View File
@@ -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
+3 -3
View File
@@ -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