172 lines
4.8 KiB
C
172 lines
4.8 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>
|
||
|
|
||
|
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)
|
||
|
{
|
||
|
if (value == NULL)
|
||
|
lua_pushnil(L);
|
||
|
else
|
||
|
{
|
||
|
luaL_getmetatable(L, type);
|
||
|
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);
|
||
|
lua_rawget(L,-2); /* stack: mt ubox ubox[u] */
|
||
|
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 u newud */
|
||
|
lua_pushvalue(L,-1); /* stack: mt ubox u newud newud */
|
||
|
lua_insert(L,-4); /* stack: mt newud ubox u newud */
|
||
|
lua_rawset(L,-3); /* 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); /* stack: mt newud */
|
||
|
|
||
|
#ifdef LUA_VERSION_NUM
|
||
|
lua_pushvalue(L, TOLUA_NOPEER);
|
||
|
lua_setfenv(L, -2);
|
||
|
#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]*/
|
||
|
}
|
||
|
}
|
||
|
|
||
|
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_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);
|
||
|
}
|
||
|
|