luaobject: change global refering method
We now store elements in registry: registry.pointer = userdata And count references. Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
fb3c5d90c7
commit
a1b113901c
|
@ -21,6 +21,25 @@
|
|||
|
||||
#include "common/luaobject.h"
|
||||
|
||||
/** Setup the object system at startup.
|
||||
* \param L The Lua VM state.
|
||||
*/
|
||||
void
|
||||
luaA_object_setup(lua_State *L)
|
||||
{
|
||||
/* Push identification string */
|
||||
lua_pushliteral(L, LUAA_OBJECT_REGISTRY_KEY);
|
||||
/* Create an empty table */
|
||||
lua_newtable(L);
|
||||
/* Create an empty metatable */
|
||||
lua_newtable(L);
|
||||
/* Set this empty table as the registry metatable.
|
||||
* It's used to store the number of reference on stored objects. */
|
||||
lua_setmetatable(L, -2);
|
||||
/* Register table inside registry */
|
||||
lua_rawset(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
|
||||
/** Increment a object reference in its store table.
|
||||
* \param L The Lua VM state.
|
||||
* \param tud The table index on the stack.
|
||||
|
|
|
@ -33,6 +33,9 @@ luaA_settype(lua_State *L, const char *type)
|
|||
return 1;
|
||||
}
|
||||
|
||||
#define LUAA_OBJECT_REGISTRY_KEY "awesome.object.registry"
|
||||
|
||||
void luaA_object_setup(lua_State *);
|
||||
void * luaA_object_incref(lua_State *, int, int);
|
||||
void luaA_object_decref(lua_State *, int, void *);
|
||||
|
||||
|
@ -89,10 +92,57 @@ luaA_object_push_item(lua_State *L, int ud, void *pointer)
|
|||
return 1;
|
||||
}
|
||||
|
||||
DO_ARRAY(int, int, DO_NOTHING)
|
||||
static inline void
|
||||
luaA_object_registry_push(lua_State *L)
|
||||
{
|
||||
lua_pushliteral(L, LUAA_OBJECT_REGISTRY_KEY);
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
}
|
||||
|
||||
#define LUA_OBJECT_HEADER \
|
||||
int_array_t refs;
|
||||
/** Reference an object and return a pointer to it.
|
||||
* That only works with userdata, table, thread or function.
|
||||
* \param L The Lua VM state.
|
||||
* \param oud The object index on the stack.
|
||||
* \return The object reference, or NULL if not referencable.
|
||||
*/
|
||||
static inline void *
|
||||
luaA_object_ref(lua_State *L, int oud)
|
||||
{
|
||||
luaA_object_registry_push(L);
|
||||
void *p = luaA_object_incref(L, -1, oud < 0 ? oud - 1 : oud);
|
||||
lua_pop(L, 1);
|
||||
return p;
|
||||
}
|
||||
|
||||
/** Unreference an object and return a pointer to it.
|
||||
* That only works with userdata, table, thread or function.
|
||||
* \param L The Lua VM state.
|
||||
* \param oud The object index on the stack.
|
||||
*/
|
||||
static inline void
|
||||
luaA_object_unref(lua_State *L, void *pointer)
|
||||
{
|
||||
luaA_object_registry_push(L);
|
||||
luaA_object_decref(L, -1, pointer);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
/** Push a referenced object onto the stack.
|
||||
* \param L The Lua VM state.
|
||||
* \param pointer The object to push.
|
||||
* \return The number of element pushed on stack.
|
||||
*/
|
||||
static inline int
|
||||
luaA_object_push(lua_State *L, void *pointer)
|
||||
{
|
||||
luaA_object_registry_push(L);
|
||||
lua_pushlightuserdata(L, pointer);
|
||||
lua_rawget(L, -2);
|
||||
lua_remove(L, -2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define LUA_OBJECT_HEADER
|
||||
|
||||
/** Generic type for all objects.
|
||||
* All Lua objects can be casted to this type.
|
||||
|
@ -119,37 +169,19 @@ typedef struct
|
|||
static inline int \
|
||||
prefix##_push(lua_State *L, type *item) \
|
||||
{ \
|
||||
if(item) \
|
||||
{ \
|
||||
assert(item->refs.len); \
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, item->refs.tab[0]); \
|
||||
} \
|
||||
else \
|
||||
lua_pushnil(L); \
|
||||
return 1; \
|
||||
return luaA_object_push(L, item); \
|
||||
} \
|
||||
\
|
||||
static inline type * \
|
||||
prefix##_ref(lua_State *L, int ud) \
|
||||
{ \
|
||||
if(lua_isnil(L, ud)) \
|
||||
return NULL; \
|
||||
type *item = luaL_checkudata(L, ud, lua_type); \
|
||||
lua_pushvalue(L, ud); \
|
||||
int_array_append(&item->refs, luaL_ref(L, LUA_REGISTRYINDEX)); \
|
||||
lua_remove(L, ud); \
|
||||
return item; \
|
||||
return luaA_object_ref(L, ud); \
|
||||
} \
|
||||
\
|
||||
static inline void \
|
||||
prefix##_unref(lua_State *L, type *item) \
|
||||
{ \
|
||||
if(item) \
|
||||
{ \
|
||||
assert(item->refs.len); \
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, item->refs.tab[0]); \
|
||||
int_array_take(&item->refs, 0); \
|
||||
} \
|
||||
luaA_object_unref(L, item); \
|
||||
} \
|
||||
\
|
||||
static inline int \
|
||||
|
@ -169,8 +201,6 @@ typedef struct
|
|||
static inline int
|
||||
luaA_object_gc(lua_State *L)
|
||||
{
|
||||
lua_object_t *item = lua_touserdata(L, 1);
|
||||
int_array_wipe(&item->refs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue