mirror of https://github.com/axmolengine/axmol.git
218 lines
7.6 KiB
C
218 lines
7.6 KiB
C
/* tolua: functions to push C values.
|
|
** Support code for Lua bindings.
|
|
** Written by Waldemar Celes
|
|
** TeCGraf/PUC-Rio
|
|
** Apr 2003
|
|
** $Id: $
|
|
*/
|
|
|
|
/* This code is free software; you can redistribute it and/or modify it.
|
|
** The software provided hereunder is on an "as is" basis, and
|
|
** the author has no obligation to provide maintenance, support, updates,
|
|
** enhancements, or modifications.
|
|
*/
|
|
|
|
#include "tolua++.h"
|
|
#include "lauxlib.h"
|
|
|
|
#include <stdlib.h>
|
|
|
|
void tolua_pushusertype_internal (lua_State* L, void* value, const char* type, int addToRoot)
|
|
{
|
|
if (value == NULL)
|
|
lua_pushnil(L);
|
|
else
|
|
{
|
|
luaL_getmetatable(L, type); /* stack: mt */
|
|
if (lua_isnil(L, -1)) { /* NOT FOUND metatable */
|
|
lua_pop(L, 1);
|
|
return;
|
|
}
|
|
lua_pushstring(L,"tolua_ubox");
|
|
lua_rawget(L,-2); /* stack: mt ubox */
|
|
if (lua_isnil(L, -1)) {
|
|
lua_pop(L, 1);
|
|
lua_pushstring(L, "tolua_ubox");
|
|
lua_rawget(L, LUA_REGISTRYINDEX);
|
|
};
|
|
|
|
lua_pushlightuserdata(L,value); /* stack: mt ubox key<value> */
|
|
lua_rawget(L,-2); /* stack: mt ubox ubox[value] */
|
|
|
|
if (lua_isnil(L,-1))
|
|
{
|
|
lua_pop(L,1); /* stack: mt ubox */
|
|
lua_pushlightuserdata(L,value);
|
|
*(void**)lua_newuserdata(L,sizeof(void *)) = value; /* stack: mt ubox value newud */
|
|
lua_pushvalue(L,-1); /* stack: mt ubox value newud newud */
|
|
lua_insert(L,-4); /* stack: mt newud ubox value newud */
|
|
lua_rawset(L,-3); /* ubox[value] = newud, stack: mt newud ubox */
|
|
lua_pop(L,1); /* stack: mt newud */
|
|
/*luaL_getmetatable(L,type);*/
|
|
lua_pushvalue(L, -2); /* stack: mt newud mt */
|
|
lua_setmetatable(L,-2); /* update mt, stack: mt newud */
|
|
|
|
#ifdef LUA_VERSION_NUM
|
|
lua_pushvalue(L, TOLUA_NOPEER); /* stack: mt newud peer */
|
|
lua_setfenv(L, -2); /* stack: mt newud */
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
/* check the need of updating the metatable to a more specialized class */
|
|
lua_insert(L,-2); /* stack: mt ubox[u] ubox */
|
|
lua_pop(L,1); /* stack: mt ubox[u] */
|
|
lua_pushstring(L,"tolua_super");
|
|
lua_rawget(L,LUA_REGISTRYINDEX); /* stack: mt ubox[u] super */
|
|
lua_getmetatable(L,-2); /* stack: mt ubox[u] super mt */
|
|
lua_rawget(L,-2); /* stack: mt ubox[u] super super[mt] */
|
|
if (lua_istable(L,-1))
|
|
{
|
|
lua_pushstring(L,type); /* stack: mt ubox[u] super super[mt] type */
|
|
lua_rawget(L,-2); /* stack: mt ubox[u] super super[mt] flag */
|
|
if (lua_toboolean(L,-1) == 1) /* if true */
|
|
{
|
|
lua_pop(L,3); /* mt ubox[u]*/
|
|
lua_remove(L, -2);
|
|
return;
|
|
}
|
|
}
|
|
/* type represents a more specilized type */
|
|
/*luaL_getmetatable(L,type); // stack: mt ubox[u] super super[mt] flag mt */
|
|
lua_pushvalue(L, -5); /* stack: mt ubox[u] super super[mt] flag mt */
|
|
lua_setmetatable(L,-5); /* stack: mt ubox[u] super super[mt] flag */
|
|
lua_pop(L,3); /* stack: mt ubox[u] */
|
|
}
|
|
lua_remove(L, -2); /* stack: ubox[u]*/
|
|
|
|
if (0 != addToRoot)
|
|
{
|
|
lua_pushvalue(L, -1);
|
|
tolua_add_value_to_root(L, value);
|
|
}
|
|
}
|
|
}
|
|
|
|
TOLUA_API void tolua_pushvalue (lua_State* L, int lo)
|
|
{
|
|
lua_pushvalue(L,lo);
|
|
}
|
|
|
|
TOLUA_API void tolua_pushboolean (lua_State* L, int value)
|
|
{
|
|
lua_pushboolean(L,value);
|
|
}
|
|
|
|
TOLUA_API void tolua_pushnumber (lua_State* L, lua_Number value)
|
|
{
|
|
lua_pushnumber(L,value);
|
|
}
|
|
|
|
TOLUA_API void tolua_pushstring (lua_State* L, const char* value)
|
|
{
|
|
if (value == NULL)
|
|
lua_pushnil(L);
|
|
else
|
|
lua_pushstring(L,value);
|
|
}
|
|
|
|
TOLUA_API void tolua_pushuserdata (lua_State* L, void* value)
|
|
{
|
|
if (value == NULL)
|
|
lua_pushnil(L);
|
|
else
|
|
lua_pushlightuserdata(L,value);
|
|
}
|
|
|
|
TOLUA_API void tolua_pushusertype (lua_State* L, void* value, const char* type)
|
|
{
|
|
tolua_pushusertype_internal(L, value, type, 0);
|
|
}
|
|
|
|
TOLUA_API void tolua_pushusertype_and_addtoroot (lua_State* L, void* value, const char* type)
|
|
{
|
|
tolua_pushusertype_internal(L, value, type, 1);
|
|
}
|
|
|
|
TOLUA_API void tolua_pushusertype_and_takeownership (lua_State* L, void* value, const char* type)
|
|
{
|
|
tolua_pushusertype(L,value,type);
|
|
tolua_register_gc(L,lua_gettop(L));
|
|
}
|
|
|
|
TOLUA_API void tolua_add_value_to_root(lua_State* L, void* ptr)
|
|
{
|
|
|
|
lua_pushstring(L, TOLUA_VALUE_ROOT);
|
|
lua_rawget(L, LUA_REGISTRYINDEX); /* stack: value root */
|
|
lua_insert(L, -2); /* stack: root value */
|
|
lua_pushlightuserdata(L, ptr); /* stack: root value ptr */
|
|
lua_insert(L, -2); /* stack: root ptr value */
|
|
lua_rawset(L, -3); /* root[ptr] = value, stack: root */
|
|
lua_pop(L, 1); /* stack: - */
|
|
}
|
|
|
|
|
|
TOLUA_API void tolua_remove_value_from_root (lua_State* L, void* ptr)
|
|
{
|
|
lua_pushstring(L, TOLUA_VALUE_ROOT);
|
|
lua_rawget(L, LUA_REGISTRYINDEX); /* stack: root */
|
|
lua_pushlightuserdata(L, ptr); /* stack: root ptr */
|
|
|
|
lua_pushnil(L); /* stack: root ptr nil */
|
|
lua_rawset(L, -3); /* root[ptr] = nil, stack: root */
|
|
lua_pop(L, 1);
|
|
}
|
|
|
|
TOLUA_API void tolua_pushfieldvalue (lua_State* L, int lo, int index, int v)
|
|
{
|
|
lua_pushnumber(L,index);
|
|
lua_pushvalue(L,v);
|
|
lua_settable(L,lo);
|
|
}
|
|
|
|
TOLUA_API void tolua_pushfieldboolean (lua_State* L, int lo, int index, int v)
|
|
{
|
|
lua_pushnumber(L,index);
|
|
lua_pushboolean(L,v);
|
|
lua_settable(L,lo);
|
|
}
|
|
|
|
|
|
TOLUA_API void tolua_pushfieldnumber (lua_State* L, int lo, int index, lua_Number v)
|
|
{
|
|
lua_pushnumber(L,index);
|
|
tolua_pushnumber(L,v);
|
|
lua_settable(L,lo);
|
|
}
|
|
|
|
TOLUA_API void tolua_pushfieldstring (lua_State* L, int lo, int index, const char* v)
|
|
{
|
|
lua_pushnumber(L,index);
|
|
tolua_pushstring(L,v);
|
|
lua_settable(L,lo);
|
|
}
|
|
|
|
TOLUA_API void tolua_pushfielduserdata (lua_State* L, int lo, int index, void* v)
|
|
{
|
|
lua_pushnumber(L,index);
|
|
tolua_pushuserdata(L,v);
|
|
lua_settable(L,lo);
|
|
}
|
|
|
|
TOLUA_API void tolua_pushfieldusertype (lua_State* L, int lo, int index, void* v, const char* type)
|
|
{
|
|
lua_pushnumber(L,index);
|
|
tolua_pushusertype(L,v,type);
|
|
lua_settable(L,lo);
|
|
}
|
|
|
|
TOLUA_API void tolua_pushfieldusertype_and_takeownership (lua_State* L, int lo, int index, void* v, const char* type)
|
|
{
|
|
lua_pushnumber(L,index);
|
|
tolua_pushusertype(L,v,type);
|
|
tolua_register_gc(L,lua_gettop(L));
|
|
lua_settable(L,lo);
|
|
}
|
|
|