759 lines
17 KiB
C++
759 lines
17 KiB
C++
// lua_tinker.cpp
|
|
//
|
|
// LuaTinker - Simple and light C++ wrapper for Lua.
|
|
//
|
|
// Copyright (c) 2005-2007 Kwon-il Lee (zupet@hitel.net)
|
|
//
|
|
// please check Licence.txt file for licence and legal issues.
|
|
|
|
#include "stdafx.h"
|
|
#include "lua_tinker.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
|
|
#endif
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* init */
|
|
/*---------------------------------------------------------------------------*/
|
|
void lua_tinker::init(lua_State *L)
|
|
{
|
|
init_s64(L);
|
|
init_u64(L);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* __s64 */
|
|
/*---------------------------------------------------------------------------*/
|
|
static int tostring_s64(lua_State *L)
|
|
{
|
|
char temp[64];
|
|
sprintf_s(temp, "%I64d", *(__int64*)lua_topointer(L, 1));
|
|
lua_pushstring(L, temp);
|
|
return 1;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
static int eq_s64(lua_State *L)
|
|
{
|
|
lua_pushboolean(L, memcmp(lua_topointer(L, 1), lua_topointer(L, 2), sizeof(__int64)) == 0);
|
|
return 1;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
static int lt_s64(lua_State *L)
|
|
{
|
|
lua_pushboolean(L, memcmp(lua_topointer(L, 1), lua_topointer(L, 2), sizeof(__int64)) < 0);
|
|
return 1;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
static int le_s64(lua_State *L)
|
|
{
|
|
lua_pushboolean(L, memcmp(lua_topointer(L, 1), lua_topointer(L, 2), sizeof(__int64)) <= 0);
|
|
return 1;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
void lua_tinker::init_s64(lua_State *L)
|
|
{
|
|
const char* name = "__s64";
|
|
lua_pushstring(L, name);
|
|
lua_newtable(L);
|
|
|
|
lua_pushstring(L, "__name");
|
|
lua_pushstring(L, name);
|
|
lua_rawset(L, -3);
|
|
|
|
lua_pushstring(L, "__tostring");
|
|
lua_pushcclosure(L, tostring_s64, 0);
|
|
lua_rawset(L, -3);
|
|
|
|
lua_pushstring(L, "__eq");
|
|
lua_pushcclosure(L, eq_s64, 0);
|
|
lua_rawset(L, -3);
|
|
|
|
lua_pushstring(L, "__lt");
|
|
lua_pushcclosure(L, lt_s64, 0);
|
|
lua_rawset(L, -3);
|
|
|
|
lua_pushstring(L, "__le");
|
|
lua_pushcclosure(L, le_s64, 0);
|
|
lua_rawset(L, -3);
|
|
|
|
lua_settable(L, LUA_GLOBALSINDEX);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* __u64 */
|
|
/*---------------------------------------------------------------------------*/
|
|
static int tostring_u64(lua_State *L)
|
|
{
|
|
char temp[64];
|
|
sprintf_s(temp, "%I64u", *(unsigned __int64*)lua_topointer(L, 1));
|
|
lua_pushstring(L, temp);
|
|
return 1;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
static int eq_u64(lua_State *L)
|
|
{
|
|
lua_pushboolean(L, memcmp(lua_topointer(L, 1), lua_topointer(L, 2), sizeof(unsigned __int64)) == 0);
|
|
return 1;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
static int lt_u64(lua_State *L)
|
|
{
|
|
lua_pushboolean(L, memcmp(lua_topointer(L, 1), lua_topointer(L, 2), sizeof(unsigned __int64)) < 0);
|
|
return 1;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
static int le_u64(lua_State *L)
|
|
{
|
|
lua_pushboolean(L, memcmp(lua_topointer(L, 1), lua_topointer(L, 2), sizeof(unsigned __int64)) <= 0);
|
|
return 1;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
void lua_tinker::init_u64(lua_State *L)
|
|
{
|
|
const char* name = "__u64";
|
|
lua_pushstring(L, name);
|
|
lua_newtable(L);
|
|
|
|
lua_pushstring(L, "__name");
|
|
lua_pushstring(L, name);
|
|
lua_rawset(L, -3);
|
|
|
|
lua_pushstring(L, "__tostring");
|
|
lua_pushcclosure(L, tostring_u64, 0);
|
|
lua_rawset(L, -3);
|
|
|
|
lua_pushstring(L, "__eq");
|
|
lua_pushcclosure(L, eq_u64, 0);
|
|
lua_rawset(L, -3);
|
|
|
|
lua_pushstring(L, "__lt");
|
|
lua_pushcclosure(L, lt_u64, 0);
|
|
lua_rawset(L, -3);
|
|
|
|
lua_pushstring(L, "__le");
|
|
lua_pushcclosure(L, le_u64, 0);
|
|
lua_rawset(L, -3);
|
|
|
|
lua_settable(L, LUA_GLOBALSINDEX);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* excution */
|
|
/*---------------------------------------------------------------------------*/
|
|
int lua_tinker::dofile(lua_State *L, const char *filename, std::string* errmsg)
|
|
{
|
|
lua_pushcclosure(L, on_error, 0);
|
|
int errfunc = lua_gettop(L);
|
|
|
|
if(luaL_loadfile(L, filename) == 0)
|
|
{
|
|
if(lua_pcall(L, 0, 0, errfunc) != 0)
|
|
{
|
|
lua_pop(L, 1);
|
|
return -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
print_error(L, "%s", lua_tostring(L, -1));
|
|
if (errmsg) {
|
|
(*errmsg) = lua_tostring(L, -1);
|
|
}
|
|
lua_pop(L, 1);
|
|
return -1;
|
|
}
|
|
|
|
lua_pop(L, 1);
|
|
return 0;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
int lua_tinker::dostring(lua_State *L, const char* buff, std::string* errmsg)
|
|
{
|
|
return lua_tinker::dobuffer(L, buff, strlen(buff), errmsg);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
int lua_tinker::dobuffer(lua_State *L, const char* buff, size_t len, std::string* errmsg)
|
|
{
|
|
lua_pushcclosure(L, on_error, 0);
|
|
int errfunc = lua_gettop(L);
|
|
|
|
if(luaL_loadbuffer(L, buff, len, "lua_tinker::dobuffer()") == 0)
|
|
{
|
|
if(lua_pcall(L, 0, 0, errfunc) != 0)
|
|
{
|
|
lua_pop(L, 1);
|
|
return -1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
print_error(L, "%s", lua_tostring(L, -1));
|
|
if (errmsg) {
|
|
(*errmsg) = lua_tostring(L, -1);
|
|
}
|
|
lua_pop(L, 1);
|
|
return -1;
|
|
}
|
|
|
|
lua_pop(L, 1);
|
|
return 0;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* debug helpers */
|
|
/*---------------------------------------------------------------------------*/
|
|
static void call_stack(lua_State* L, int n)
|
|
{
|
|
lua_Debug ar;
|
|
if(lua_getstack(L, n, &ar) == 1)
|
|
{
|
|
lua_getinfo(L, "nSlu", &ar);
|
|
|
|
const char* indent;
|
|
if(n == 0)
|
|
{
|
|
indent = "->\t";
|
|
lua_tinker::print_error(L, "\t<call stack>");
|
|
}
|
|
else
|
|
{
|
|
indent = "\t";
|
|
}
|
|
|
|
if(ar.name)
|
|
lua_tinker::print_error(L, "%s%s() : line %d [%s : line %d]", indent, ar.name, ar.currentline, ar.source, ar.linedefined);
|
|
else
|
|
lua_tinker::print_error(L, "%sunknown : line %d [%s : line %d]", indent, ar.currentline, ar.source, ar.linedefined);
|
|
|
|
call_stack(L, n+1);
|
|
}
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
int lua_tinker::on_error(lua_State *L)
|
|
{
|
|
#if !defined(_FINAL_BUILD)
|
|
print_error(L, "%s", lua_tostring(L, -1));
|
|
|
|
call_stack(L, 0);
|
|
#endif // #if !defined(_FINAL_BUILD)
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
void lua_tinker::print_error(lua_State *L, const char* fmt, ...)
|
|
{
|
|
#if defined( _DEBUG ) || defined( _RDEBUG )
|
|
|
|
char text[4096];
|
|
|
|
va_list args;
|
|
va_start(args, fmt);
|
|
vsprintf_s(text, fmt, args);
|
|
va_end(args);
|
|
|
|
lua_pushstring(L, "_ALERT");
|
|
lua_gettable(L, LUA_GLOBALSINDEX);
|
|
if(lua_isfunction(L, -1))
|
|
{
|
|
lua_pushstring(L, text);
|
|
lua_call(L, 1, 0);
|
|
}
|
|
else
|
|
{
|
|
printf("%s\n", text);
|
|
lua_pop(L, 1);
|
|
}
|
|
|
|
#endif // #if defined( _DEBUG ) || defined( _RDEBUG )
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
void lua_tinker::enum_stack(lua_State *L)
|
|
{
|
|
int top = lua_gettop(L);
|
|
print_error(L, "Type:%d", top);
|
|
for(int i=1; i<=lua_gettop(L); ++i)
|
|
{
|
|
switch(lua_type(L, i))
|
|
{
|
|
case LUA_TNIL:
|
|
print_error(L, "\t%s", lua_typename(L, lua_type(L, i)));
|
|
break;
|
|
case LUA_TBOOLEAN:
|
|
print_error(L, "\t%s %s", lua_typename(L, lua_type(L, i)), lua_toboolean(L, i)?"true":"false");
|
|
break;
|
|
case LUA_TLIGHTUSERDATA:
|
|
print_error(L, "\t%s 0x%08p", lua_typename(L, lua_type(L, i)), lua_topointer(L, i));
|
|
break;
|
|
case LUA_TNUMBER:
|
|
print_error(L, "\t%s %f", lua_typename(L, lua_type(L, i)), lua_tonumber(L, i));
|
|
break;
|
|
case LUA_TSTRING:
|
|
print_error(L, "\t%s %s", lua_typename(L, lua_type(L, i)), lua_tostring(L, i));
|
|
break;
|
|
case LUA_TTABLE:
|
|
print_error(L, "\t%s 0x%08p", lua_typename(L, lua_type(L, i)), lua_topointer(L, i));
|
|
break;
|
|
case LUA_TFUNCTION:
|
|
print_error(L, "\t%s() 0x%08p", lua_typename(L, lua_type(L, i)), lua_topointer(L, i));
|
|
break;
|
|
case LUA_TUSERDATA:
|
|
print_error(L, "\t%s 0x%08p", lua_typename(L, lua_type(L, i)), lua_topointer(L, i));
|
|
break;
|
|
case LUA_TTHREAD:
|
|
print_error(L, "\t%s", lua_typename(L, lua_type(L, i)));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* read */
|
|
/*---------------------------------------------------------------------------*/
|
|
template<>
|
|
char* lua_tinker::read(lua_State *L, int index)
|
|
{
|
|
return (char*)lua_tostring(L, index);
|
|
}
|
|
|
|
template<>
|
|
const char* lua_tinker::read(lua_State *L, int index)
|
|
{
|
|
return (const char*)lua_tostring(L, index);
|
|
}
|
|
|
|
template<>
|
|
char lua_tinker::read(lua_State *L, int index)
|
|
{
|
|
return (char)lua_tonumber(L, index);
|
|
}
|
|
|
|
template<>
|
|
unsigned char lua_tinker::read(lua_State *L, int index)
|
|
{
|
|
return (unsigned char)lua_tonumber(L, index);
|
|
}
|
|
|
|
template<>
|
|
short lua_tinker::read(lua_State *L, int index)
|
|
{
|
|
return (short)lua_tonumber(L, index);
|
|
}
|
|
|
|
template<>
|
|
unsigned short lua_tinker::read(lua_State *L, int index)
|
|
{
|
|
return (unsigned short)lua_tonumber(L, index);
|
|
}
|
|
|
|
template<>
|
|
long lua_tinker::read(lua_State *L, int index)
|
|
{
|
|
return (long)lua_tonumber(L, index);
|
|
}
|
|
|
|
template<>
|
|
unsigned long lua_tinker::read(lua_State *L, int index)
|
|
{
|
|
return (unsigned long)lua_tonumber(L, index);
|
|
}
|
|
|
|
template<>
|
|
int lua_tinker::read(lua_State *L, int index)
|
|
{
|
|
return (int)lua_tonumber(L, index);
|
|
}
|
|
|
|
template<>
|
|
unsigned int lua_tinker::read(lua_State *L, int index)
|
|
{
|
|
return (unsigned int)lua_tonumber(L, index);
|
|
}
|
|
|
|
template<>
|
|
float lua_tinker::read(lua_State *L, int index)
|
|
{
|
|
return (float)lua_tonumber(L, index);
|
|
}
|
|
|
|
template<>
|
|
double lua_tinker::read(lua_State *L, int index)
|
|
{
|
|
return (double)lua_tonumber(L, index);
|
|
}
|
|
|
|
template<>
|
|
bool lua_tinker::read(lua_State *L, int index)
|
|
{
|
|
if(lua_isboolean(L, index))
|
|
return lua_toboolean(L, index) != 0;
|
|
else
|
|
return lua_tonumber(L, index) != 0;
|
|
}
|
|
|
|
template<>
|
|
void lua_tinker::read(lua_State *L, int index)
|
|
{
|
|
return;
|
|
}
|
|
|
|
template<>
|
|
__int64 lua_tinker::read(lua_State *L, int index)
|
|
{
|
|
if(lua_isnumber(L,index))
|
|
return (__int64)lua_tonumber(L, index);
|
|
else
|
|
return *(__int64*)lua_touserdata(L, index);
|
|
}
|
|
template<>
|
|
unsigned __int64 lua_tinker::read(lua_State *L, int index)
|
|
{
|
|
if(lua_isnumber(L,index))
|
|
return (unsigned __int64)lua_tonumber(L, index);
|
|
else
|
|
return *(unsigned __int64*)lua_touserdata(L, index);
|
|
}
|
|
|
|
template<>
|
|
lua_tinker::table lua_tinker::read(lua_State *L, int index)
|
|
{
|
|
return table(L, index);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* push */
|
|
/*---------------------------------------------------------------------------*/
|
|
template<>
|
|
void lua_tinker::push(lua_State *L, char ret)
|
|
{
|
|
lua_pushnumber(L, ret);
|
|
}
|
|
|
|
template<>
|
|
void lua_tinker::push(lua_State *L, unsigned char ret)
|
|
{
|
|
lua_pushnumber(L, ret);
|
|
}
|
|
|
|
template<>
|
|
void lua_tinker::push(lua_State *L, short ret)
|
|
{
|
|
lua_pushnumber(L, ret);
|
|
}
|
|
|
|
template<>
|
|
void lua_tinker::push(lua_State *L, unsigned short ret)
|
|
{
|
|
lua_pushnumber(L, ret);
|
|
}
|
|
|
|
template<>
|
|
void lua_tinker::push(lua_State *L, long ret)
|
|
{
|
|
lua_pushnumber(L, ret);
|
|
}
|
|
|
|
template<>
|
|
void lua_tinker::push(lua_State *L, unsigned long ret)
|
|
{
|
|
lua_pushnumber(L, ret);
|
|
}
|
|
|
|
template<>
|
|
void lua_tinker::push(lua_State *L, int ret)
|
|
{
|
|
lua_pushnumber(L, ret);
|
|
}
|
|
|
|
template<>
|
|
void lua_tinker::push(lua_State *L, unsigned int ret)
|
|
{
|
|
lua_pushnumber(L, ret);
|
|
}
|
|
|
|
template<>
|
|
void lua_tinker::push(lua_State *L, float ret)
|
|
{
|
|
lua_pushnumber(L, ret);
|
|
}
|
|
|
|
template<>
|
|
void lua_tinker::push(lua_State *L, double ret)
|
|
{
|
|
lua_pushnumber(L, ret);
|
|
}
|
|
|
|
template<>
|
|
void lua_tinker::push(lua_State *L, char* ret)
|
|
{
|
|
lua_pushstring(L, ret);
|
|
}
|
|
|
|
template<>
|
|
void lua_tinker::push(lua_State *L, const char* ret)
|
|
{
|
|
lua_pushstring(L, ret);
|
|
}
|
|
|
|
template<>
|
|
void lua_tinker::push(lua_State *L, bool ret)
|
|
{
|
|
lua_pushboolean(L, ret);
|
|
}
|
|
|
|
template<>
|
|
void lua_tinker::push(lua_State *L, lua_value* ret)
|
|
{
|
|
if(ret) ret->to_lua(L); else lua_pushnil(L);
|
|
}
|
|
|
|
template<>
|
|
void lua_tinker::push(lua_State *L, __int64 ret)
|
|
{
|
|
*(__int64*)lua_newuserdata(L, sizeof(__int64)) = ret;
|
|
lua_pushstring(L, "__s64");
|
|
lua_gettable(L, LUA_GLOBALSINDEX);
|
|
lua_setmetatable(L, -2);
|
|
}
|
|
template<>
|
|
void lua_tinker::push(lua_State *L, unsigned __int64 ret)
|
|
{
|
|
*(unsigned __int64*)lua_newuserdata(L, sizeof(unsigned __int64)) = ret;
|
|
lua_pushstring(L, "__u64");
|
|
lua_gettable(L, LUA_GLOBALSINDEX);
|
|
lua_setmetatable(L, -2);
|
|
}
|
|
|
|
template<>
|
|
void lua_tinker::push(lua_State *L, lua_tinker::table ret)
|
|
{
|
|
lua_pushvalue(L, ret.m_obj->m_index);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* pop */
|
|
/*---------------------------------------------------------------------------*/
|
|
template<>
|
|
void lua_tinker::pop(lua_State *L)
|
|
{
|
|
lua_pop(L, 1);
|
|
}
|
|
|
|
template<>
|
|
lua_tinker::table lua_tinker::pop(lua_State *L)
|
|
{
|
|
return table(L, lua_gettop(L));
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Tinker Class Helper */
|
|
/*---------------------------------------------------------------------------*/
|
|
static void invoke_parent(lua_State *L)
|
|
{
|
|
lua_pushstring(L, "__parent");
|
|
lua_rawget(L, -2);
|
|
if(lua_istable(L,-1))
|
|
{
|
|
lua_pushvalue(L,2);
|
|
lua_rawget(L, -2);
|
|
if(!lua_isnil(L,-1))
|
|
{
|
|
lua_remove(L,-2);
|
|
}
|
|
else
|
|
{
|
|
lua_remove(L, -1);
|
|
invoke_parent(L);
|
|
lua_remove(L,-2);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
int lua_tinker::meta_get(lua_State *L)
|
|
{
|
|
lua_getmetatable(L,1);
|
|
lua_pushvalue(L,2);
|
|
lua_rawget(L,-2);
|
|
|
|
if(lua_isuserdata(L,-1))
|
|
{
|
|
user2type<var_base*>::invoke(L,-1)->get(L);
|
|
lua_remove(L, -2);
|
|
}
|
|
else if(lua_isnil(L,-1))
|
|
{
|
|
lua_remove(L,-1);
|
|
invoke_parent(L);
|
|
if(lua_isnil(L,-1))
|
|
{
|
|
lua_pushfstring(L, "can't find '%s' class variable. (forgot registering class variable ?)", lua_tostring(L, 2));
|
|
lua_error(L);
|
|
}
|
|
}
|
|
|
|
lua_remove(L,-2);
|
|
|
|
return 1;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
int lua_tinker::meta_set(lua_State *L)
|
|
{
|
|
lua_getmetatable(L,1);
|
|
lua_pushvalue(L,2);
|
|
lua_rawget(L,-2);
|
|
|
|
if(lua_isuserdata(L,-1))
|
|
{
|
|
user2type<var_base*>::invoke(L,-1)->set(L);
|
|
}
|
|
else if(lua_isnil(L, -1))
|
|
{
|
|
lua_pushvalue(L,2);
|
|
lua_pushvalue(L,3);
|
|
lua_rawset(L, -4);
|
|
}
|
|
lua_settop(L, 3);
|
|
return 0;
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
void lua_tinker::meta_push(lua_State *L, const char* name)
|
|
{
|
|
lua_pushstring(L, name);
|
|
lua_gettable(L, LUA_GLOBALSINDEX);
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* table object on stack */
|
|
/*---------------------------------------------------------------------------*/
|
|
lua_tinker::table_obj::table_obj(lua_State* L, int index)
|
|
:m_L(L)
|
|
,m_index(index)
|
|
,m_ref(0)
|
|
{
|
|
m_pointer = lua_topointer(m_L, m_index);
|
|
}
|
|
|
|
lua_tinker::table_obj::~table_obj()
|
|
{
|
|
if(validate())
|
|
{
|
|
lua_remove(m_L, m_index);
|
|
}
|
|
}
|
|
|
|
void lua_tinker::table_obj::inc_ref()
|
|
{
|
|
++m_ref;
|
|
}
|
|
|
|
void lua_tinker::table_obj::dec_ref()
|
|
{
|
|
if(--m_ref == 0)
|
|
delete this;
|
|
}
|
|
|
|
bool lua_tinker::table_obj::validate()
|
|
{
|
|
if(m_pointer != NULL)
|
|
{
|
|
if(m_pointer == lua_topointer(m_L, m_index))
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
int top = lua_gettop(m_L);
|
|
|
|
for(int i=1; i<=top; ++i)
|
|
{
|
|
if(m_pointer == lua_topointer(m_L, i))
|
|
{
|
|
m_index = i;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
m_pointer = NULL;
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|
|
/* Table Object Holder */
|
|
/*---------------------------------------------------------------------------*/
|
|
lua_tinker::table::table(lua_State* L)
|
|
{
|
|
lua_newtable(L);
|
|
|
|
m_obj = new table_obj(L, lua_gettop(L));
|
|
|
|
m_obj->inc_ref();
|
|
}
|
|
|
|
lua_tinker::table::table(lua_State* L, const char* name)
|
|
{
|
|
enum_stack(L);
|
|
|
|
lua_pushstring(L, name);
|
|
lua_gettable(L, LUA_GLOBALSINDEX);
|
|
|
|
if(lua_istable(L, -1) == 0)
|
|
{
|
|
lua_pop(L, 1);
|
|
|
|
lua_newtable(L);
|
|
lua_pushstring(L, name);
|
|
lua_pushvalue(L, -2);
|
|
lua_settable(L, LUA_GLOBALSINDEX);
|
|
}
|
|
|
|
m_obj = new table_obj(L, lua_gettop(L));
|
|
m_obj->inc_ref();
|
|
}
|
|
|
|
lua_tinker::table::table(lua_State* L, int index)
|
|
{
|
|
if(index < 0)
|
|
{
|
|
index = lua_gettop(L) + index + 1;
|
|
}
|
|
|
|
m_obj = new table_obj(L, index);
|
|
|
|
m_obj->inc_ref();
|
|
}
|
|
|
|
lua_tinker::table::table(const table& input)
|
|
{
|
|
m_obj = input.m_obj;
|
|
|
|
m_obj->inc_ref();
|
|
}
|
|
|
|
lua_tinker::table::~table()
|
|
{
|
|
m_obj->dec_ref();
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*/
|