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"
|
#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.
|
/** Increment a object reference in its store table.
|
||||||
* \param L The Lua VM state.
|
* \param L The Lua VM state.
|
||||||
* \param tud The table index on the stack.
|
* \param tud The table index on the stack.
|
||||||
|
|
|
@ -33,6 +33,9 @@ luaA_settype(lua_State *L, const char *type)
|
||||||
return 1;
|
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_incref(lua_State *, int, int);
|
||||||
void luaA_object_decref(lua_State *, int, void *);
|
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;
|
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 \
|
/** Reference an object and return a pointer to it.
|
||||||
int_array_t refs;
|
* 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.
|
/** Generic type for all objects.
|
||||||
* All Lua objects can be casted to this type.
|
* All Lua objects can be casted to this type.
|
||||||
|
@ -119,37 +169,19 @@ typedef struct
|
||||||
static inline int \
|
static inline int \
|
||||||
prefix##_push(lua_State *L, type *item) \
|
prefix##_push(lua_State *L, type *item) \
|
||||||
{ \
|
{ \
|
||||||
if(item) \
|
return luaA_object_push(L, item); \
|
||||||
{ \
|
|
||||||
assert(item->refs.len); \
|
|
||||||
lua_rawgeti(L, LUA_REGISTRYINDEX, item->refs.tab[0]); \
|
|
||||||
} \
|
|
||||||
else \
|
|
||||||
lua_pushnil(L); \
|
|
||||||
return 1; \
|
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static inline type * \
|
static inline type * \
|
||||||
prefix##_ref(lua_State *L, int ud) \
|
prefix##_ref(lua_State *L, int ud) \
|
||||||
{ \
|
{ \
|
||||||
if(lua_isnil(L, ud)) \
|
return luaA_object_ref(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; \
|
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static inline void \
|
static inline void \
|
||||||
prefix##_unref(lua_State *L, type *item) \
|
prefix##_unref(lua_State *L, type *item) \
|
||||||
{ \
|
{ \
|
||||||
if(item) \
|
luaA_object_unref(L, item); \
|
||||||
{ \
|
|
||||||
assert(item->refs.len); \
|
|
||||||
luaL_unref(L, LUA_REGISTRYINDEX, item->refs.tab[0]); \
|
|
||||||
int_array_take(&item->refs, 0); \
|
|
||||||
} \
|
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
static inline int \
|
static inline int \
|
||||||
|
@ -169,8 +201,6 @@ typedef struct
|
||||||
static inline int
|
static inline int
|
||||||
luaA_object_gc(lua_State *L)
|
luaA_object_gc(lua_State *L)
|
||||||
{
|
{
|
||||||
lua_object_t *item = lua_touserdata(L, 1);
|
|
||||||
int_array_wipe(&item->refs);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue