************************************************************

* Merged Source Code from Development Trunk: Revision 4063 *
************************************************************
- Source Code is merged from: https://81.169.133.124/source/ja2/branches/Wanne/JA2%201.13%20MP
- This will be the Source for the Beta 2011 Test

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@4064 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Wanne
2011-01-18 09:11:09 +00:00
parent 44e1646410
commit 91087ca8c0
469 changed files with 118108 additions and 24678 deletions
+247
View File
@@ -0,0 +1,247 @@
#include "lua_class_interface.h"
#include <Debug.h>
#define ARRAY_INDEX " idx" // The space is intentional to make this an out-of-band field
luaL_Reg LuaInterface::s_ClassList[] = {
{ "__index", LuaInterface::luaGetObject, },
{ "__newindex", LuaInterface::luaSetObject, },
{ NULL, },
};
const char* LuaInterface::luaClassName = "ja2_LuaInterface";
LuaInterface::LuaInterface()
: luaObject(NULL)
{
}
LuaInterface::~LuaInterface()
{
}
LuaInterface::SInterfaceData* LuaInterface::luaGetInterface()
{
return NULL;
}
void* LuaInterface::luaIsOfType(LuaState state, int index, const char* sClassName)
{
lua_State* L = state();
void *p = lua_touserdata(L, index);
LuaInterface::SInterfaceData* iface = NULL;
if( lua_getmetatable(L, index) ) /* does it have a metatable? */
{
lua_getfield(L, -1, "__ClassInterface");
iface = (LuaInterface::SInterfaceData*) lua_touserdata(L, -1);
if( !iface )
{
return NULL;
}
lua_pop(L,2);
}
else
{
return NULL;
}
LuaInterface::SInterfaceData::tClassInterface::iterator it = iface->ClassHierarchy.begin();
for(; it != iface->ClassHierarchy.end(); ++it)
{
if( *it == sClassName )
{
return p;
}
}
return NULL;
}
LuaInterface::SInterfaceData* LuaInterface::luaGetExportedInterface( SInterfaceData* iface )
{
//iface.Attribs.push_back(s_attrClassList);
//iface.ClassHierarchy.push_back(LuaInterface::luaClassName);
return iface;
}
void LuaInterface::luaExportInterface(LuaState state, LuaInterface::SInterfaceData& iface )
{
luaL_Reg *i;
LuaAttrib *idx;
lua_State* L = state();
LuaInterface::SInterfaceData::tClassInterface::iterator it_class = iface.ClassHierarchy.begin();
luaL_newmetatable( L, (*it_class).c_str() );
for (i = s_ClassList; i->name; i++)
{
lua_pushstring(L, i->name);
lua_pushlightuserdata(L, &iface);
lua_pushcclosure(L, i->func, 1);
lua_rawset(L, -3);
}
lua_pushlightuserdata(L, &iface);
lua_setfield(L, -2, "__ClassInterface");
LuaInterface::SInterfaceData::tAttribs::iterator it_attrib = iface.Attribs.begin();
for(;it_attrib != iface.Attribs.end(); ++it_attrib)
{
for (idx=*it_attrib; idx->name; idx++)
{
if (idx->staticcall)
{
lua_pushstring(L, idx->name);
lua_pushcfunction(L, idx->staticcall);
lua_rawset(L, -3 );
}
}
}
}
LuaAttrib* LuaInterface::luaCommonGetSet(LuaState state)
{
const char *AttrToFind;
typedef std::list<LuaAttrib*> tAttributes;
lua_State* L = state();
LuaInterface::SInterfaceData* iface = (LuaInterface::SInterfaceData*) lua_touserdata(L, lua_upvalueindex( 1));
if(!iface)
{
return NULL;
}
tAttributes* Attributes = &iface->Attribs;
if (lua_isnumber(L, 2) )
{
AttrToFind = ARRAY_INDEX;
}
else if (lua_isstring(L, 2) )
{
AttrToFind = lua_tostring(L, 2);
}
else
{
luaL_argcheck(L, 0, 2, "Invalid index to the table" );
// The last function doesn't return, but gotta keep the compiler happy
return NULL;
}
tAttributes::iterator it = Attributes->begin();
for(;it != Attributes->end(); ++it)
{
LuaAttrib* attrib = (*it);
for ( ; attrib->name; attrib++ )
{
if ( strcmp( attrib->name, AttrToFind) == 0 )
{
return attrib;
}
}
}
std::string err = "No such field : " + std::string(AttrToFind);
luaL_error(L, err.c_str());
return NULL;
}
//int LuaInterface::luaGetObject(lua_State* L)
DEFINE_LUA_CFUNCTION(LuaInterface, luaGetObject)
{
LuaAttrib *Attributes;
Attributes = LuaInterface::luaCommonGetSet(L);
if (!Attributes)
{
lua_pushnil( L );
return 1;
}
if (!Attributes->get)
{
if (!Attributes->call)
{
lua_pushnil( L );
}
else
{
lua_pushcfunction(L, Attributes->call);
}
return 1;
}
return Attributes->get( L );
}
//int LuaInterface::luaSetObject(lua_State* L)
DEFINE_LUA_CFUNCTION(LuaInterface, luaSetObject)
{
LuaAttrib *Attributes;
Attributes = LuaInterface::luaCommonGetSet(L);
if (!Attributes)
{
lua_rawset( L, 1 );
return 0;
}
if (!Attributes->set)
{
luaL_error( L, "The attribute is not writable" );
}
return Attributes->set(L);
}
void LuaInterface::luaCreateObject( LuaState state, void *Ptr )
{
lua_State* L = state();
// Create the object and initialize its pointer
void **ud;
ud = (void**)lua_newuserdata( L, sizeof( void*) );
*ud = Ptr;
// save user data
state.registry().GetUserDataTable();
lua_pushlightuserdata(L, this);
lua_pushvalue(L, -3);
lua_rawset(L, -3);
lua_pop(L, 1);
// Swap the table and metatable for stack arg purposes
lua_insert( L, -2 );
lua_setmetatable( L, -2 );
}
void LuaInterface::luaPushObject( LuaState state, const char* sClassName, void *Ptr )
{
lua_State* L = state();
state.registry().GetUserDataTable();
lua_pushlightuserdata(L, Ptr);
lua_rawget(L,-2);
if(lua_isnil(L,-1))
{
lua_pop(L, 1);
luaL_getmetatable( L, sClassName );
if (lua_istable( L, -1 ) )
{
this->luaCreateObject( state, Ptr );
}
}
if(!lua_isuserdata(L,-1))
{
SGP_THROW(L"Could not create User Data");
}
lua_insert(L, -2);
lua_pop(L, 1);
}
void LuaInterface::luaPushObject( LuaState state, const char* luaName )
{
LuaInterface::SInterfaceData* iface = this->luaGetInterface();
this->luaPushObject(state, iface->ClassHierarchy.front().c_str(), this);
if(luaName != NULL)
{
lua_setglobal( state(), luaName );
}
}