mirror of https://github.com/bjornbytes/lovr.git
Lua userdata store their destructor in their metatable;
This commit is contained in:
parent
5ec6f1d1d1
commit
d11e9be175
|
@ -295,7 +295,7 @@ int luaopen_lovr_math(lua_State* L) {
|
|||
luax_registertype(L, RandomGenerator);
|
||||
|
||||
for (int i = 0; i < MAX_MATH_TYPES; i++) {
|
||||
_luax_registertype(L, lovrMathTypeNames[i], lovrMathTypes[i]);
|
||||
_luax_registertype(L, lovrMathTypeNames[i], lovrMathTypes[i], NULL);
|
||||
luaL_getmetatable(L, lovrMathTypeNames[i]);
|
||||
|
||||
// Remove usual __gc handler
|
||||
|
|
|
@ -13,7 +13,14 @@ static int luax_meta__tostring(lua_State* L) {
|
|||
|
||||
static int luax_meta__gc(lua_State* L) {
|
||||
Proxy* p = lua_touserdata(L, 1);
|
||||
lovrGenericRelease(p->object);
|
||||
if (p) {
|
||||
lua_getmetatable(L, 1);
|
||||
lua_getfield(L, -1, "__destructor");
|
||||
lovrDestructor* destructor = (lovrDestructor*) lua_tocfunction(L, -1);
|
||||
if (destructor) {
|
||||
_lovrRelease(destructor, p->object);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -101,7 +108,7 @@ void luax_registerloader(lua_State* L, lua_CFunction loader, int index) {
|
|||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
void _luax_registertype(lua_State* L, const char* name, const luaL_Reg* functions) {
|
||||
void _luax_registertype(lua_State* L, const char* name, const luaL_Reg* functions, lovrDestructor* destructor) {
|
||||
|
||||
// Push metatable
|
||||
luaL_newmetatable(L, name);
|
||||
|
@ -115,6 +122,10 @@ void _luax_registertype(lua_State* L, const char* name, const luaL_Reg* function
|
|||
lua_pushcfunction(L, luax_meta__gc);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
|
||||
// m.__destructor = destructor (used to release reference)
|
||||
lua_pushcfunction(L, (lua_CFunction) destructor);
|
||||
lua_setfield(L, -2, "__destructor");
|
||||
|
||||
// m.name = name
|
||||
lua_pushstring(L, name);
|
||||
lua_setfield(L, -2, "name");
|
||||
|
@ -132,8 +143,8 @@ void _luax_registertype(lua_State* L, const char* name, const luaL_Reg* function
|
|||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
void _luax_extendtype(lua_State* L, const char* name, const luaL_Reg* baseFunctions, const luaL_Reg* functions) {
|
||||
_luax_registertype(L, name, functions);
|
||||
void _luax_extendtype(lua_State* L, const char* name, const luaL_Reg* baseFunctions, const luaL_Reg* functions, lovrDestructor* destructor) {
|
||||
_luax_registertype(L, name, functions, destructor);
|
||||
luaL_getmetatable(L, name);
|
||||
luaL_register(L, NULL, baseFunctions);
|
||||
lua_pop(L, 1);
|
||||
|
|
|
@ -17,8 +17,8 @@ typedef struct {
|
|||
#endif
|
||||
|
||||
#define luax_len(L, i) (int) lua_objlen(L, i)
|
||||
#define luax_registertype(L, T) _luax_registertype(L, #T, lovr ## T)
|
||||
#define luax_extendtype(L, S, T) _luax_extendtype(L, #T, lovr ## S, lovr ## T)
|
||||
#define luax_registertype(L, T) _luax_registertype(L, #T, lovr ## T, lovr ## T ## Destroy)
|
||||
#define luax_extendtype(L, S, T) _luax_extendtype(L, #T, lovr ## S, lovr ## T, lovr ## T ## Destroy)
|
||||
#define luax_totype(L, i, T) ((T*) _luax_totype(L, i, T_ ## T))
|
||||
#define luax_checktype(L, i, T) ((T*) _luax_checktype(L, i, T_ ## T, #T))
|
||||
#define luax_checkfloat(L, i) (float) luaL_checknumber(L, i)
|
||||
|
@ -32,8 +32,8 @@ int luax_print(lua_State* L);
|
|||
void luax_setmainthread(lua_State* L);
|
||||
void luax_atexit(lua_State* L, luax_destructor destructor);
|
||||
void luax_registerloader(lua_State* L, lua_CFunction loader, int index);
|
||||
void _luax_registertype(lua_State* L, const char* name, const luaL_Reg* functions);
|
||||
void _luax_extendtype(lua_State* L, const char* name, const luaL_Reg* baseFunctions, const luaL_Reg* functions);
|
||||
void _luax_registertype(lua_State* L, const char* name, const luaL_Reg* functions, lovrDestructor* destructor);
|
||||
void _luax_extendtype(lua_State* L, const char* name, const luaL_Reg* baseFunctions, const luaL_Reg* functions, lovrDestructor* destructor);
|
||||
void* _luax_totype(lua_State* L, int index, Type type);
|
||||
void* _luax_checktype(lua_State* L, int index, Type type, const char* debug);
|
||||
void luax_pushobject(lua_State* L, void* object);
|
||||
|
|
|
@ -86,3 +86,4 @@ void* _lovrAlloc(size_t size, Type type);
|
|||
#define lovrRetain(o) if (o && refcount_increment(_ref(o)->count) >= 0xff) lovrThrow("Ref count overflow")
|
||||
#define lovrRelease(T, o) if (o && refcount_decrement(_ref(o)->count) == 0) lovr ## T ## Destroy(o), free(_ref(o))
|
||||
#define lovrGenericRelease(o) if (o && refcount_decrement(_ref(o)->count) == 0) lovrTypeInfo[_ref(o)->type].destructor(o), free(_ref(o))
|
||||
#define _lovrRelease(f, o) if (o && refcount_decrement(_ref(o)->count) == 0) f(o), free(_ref(o))
|
||||
|
|
Loading…
Reference in New Issue