Files
FC1/CryScriptSystem/ScriptObject.cpp
romkazvo 34d6c5d489 123
2023-08-07 19:29:24 +08:00

1480 lines
27 KiB
C++

// ScriptObject.cpp: implementation of the CScriptObject class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ScriptObject.h"
#include "ScriptSystem.h"
#include "StackGuard.h"
#include <ISystem.h>
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#if defined(_DEBUG) && !defined(LINUX)
#include <crtdbg.h>
#define DEBUG_CLIENTBLOCK new( _NORMAL_BLOCK, __FILE__, __LINE__)
#define new DEBUG_CLIENTBLOCK
#endif
#ifdef _DEBUG
#define BEGIN_CHECK_STACK \
int __nStack = lua_stackspace(m_pLS);
#define END_CHECK_STACK \
{ \
if (__nStack != lua_stackspace(m_pLS)) \
CryError( "<CryScript> END_CHECK_STATE Failed." ); \
}
#else
#define BEGIN_CHECK_STACK
#define END_CHECK_STACK
#endif
#define GET_FUNCTION lua_rawget
#define SET_FUNCTION lua_rawset
inline int CScriptObject::GetThisRef()
{
if (m_bDeleted)
{
CryError( "Access to deleted script object" );
}
return lua_xgetref(m_pLS, m_nRef);
}
#define _GET_THIS() GetThisRef()
CScriptObject::CScriptObject(int nCreationNumber)
{
m_nRef=nCreationNumber;
m_pLS = NULL;
m_hDelegationTag= 0;
m_pSink = NULL;
m_nIterationCounter=-1;
m_pSetGetParams=NULL;
m_bAttached = false;
m_bDeleted = false;
}
CScriptObject::~CScriptObject()
{
if(m_pSetGetParams)
delete m_pSetGetParams;
}
int CScriptObject::GetRef()
{
return m_nRef;
}
void CScriptObject::Attach()
{
m_bAttached = true;
Detach();
lua_xref(m_pLS,m_nRef);
}
void CScriptObject::Recreate()
{
m_hDelegationTag= 0;
m_pSink = NULL;
m_nIterationCounter=-1;
m_pSetGetParams=NULL;
m_bAttached = false;
m_bDeleted = false;
}
bool CScriptObject::CreateEmpty(CScriptSystem *pScriptSystem)
{
;
m_pLS=(lua_State *)pScriptSystem->GetScriptHandle();
Detach();
return true;
}
bool CScriptObject::Create(CScriptSystem *pScriptSystem)
{
m_pLS=(lua_State *)pScriptSystem->GetScriptHandle();
_GUARD_STACK(m_pLS);
Detach();
lua_newtable(m_pLS);
Attach();
return true;
//return false;
}
bool CScriptObject::CreateGlobal(CScriptSystem *pScriptSystem, const char *sName)
{
m_pLS=(lua_State *)pScriptSystem->GetScriptHandle();
_GUARD_STACK(m_pLS);
Detach();
lua_newtable(m_pLS);
Attach();
_GET_THIS();
lua_setglobal(m_pLS, sName);
return true;
}
void CScriptObject::PushBack(int nVal)
{
_GUARD_STACK(m_pLS);
if (!_GET_THIS())
return;
int nLastPos=lua_getn(m_pLS,-1);
SetAt(nLastPos+1,nVal);
}
void CScriptObject::PushBack(float fVal)
{
_GUARD_STACK(m_pLS);
if (!_GET_THIS())
return;
int nLastPos=lua_getn(m_pLS,-1);
SetAt(nLastPos+1,fVal);
}
void CScriptObject::PushBack(const char *sVal)
{
_GUARD_STACK(m_pLS);
if (!_GET_THIS())
return;
int nLastPos=lua_getn(m_pLS,-1);
SetAt(nLastPos+1,sVal);
}
void CScriptObject::PushBack(bool bVal)
{
_GUARD_STACK(m_pLS);
if (!_GET_THIS())
return;
int nLastPos=lua_getn(m_pLS,-1);
SetAt(nLastPos+1,bVal);
}
void CScriptObject::PushBack(IScriptObject *pObj)
{
_GUARD_STACK(m_pLS);
if (!_GET_THIS())
return;
int nLastPos=lua_getn(m_pLS,-1);
SetAt(nLastPos+1,pObj);
}
bool CScriptObject::BeginSetGetChain()
{
if (!_GET_THIS())
return false;
return true;
}
void CScriptObject::EndSetGetChain()
{
if(lua_istable(m_pLS,-1))
lua_pop(m_pLS,1);
else{
DebugBreak();
}
}
void CScriptObject::SetValueChain(const char *sKey, int nVal)
{
lua_pushstring(m_pLS, sKey);
lua_pushnumber(m_pLS, (lua_Number)nVal);
SET_FUNCTION(m_pLS, - 3);
}
void CScriptObject::SetValue(const char *sKey, int nVal)
{
_GUARD_STACK(m_pLS);
if (!_GET_THIS())
return;
SetValueChain(sKey,nVal);
}
void CScriptObject::SetValueChain(const char *sKey, float fVal)
{
lua_pushstring(m_pLS, sKey);
lua_pushnumber(m_pLS, fVal);
SET_FUNCTION(m_pLS, - 3);
}
void CScriptObject::SetValue(const char *sKey, float fVal)
{
_GUARD_STACK(m_pLS);
if (!_GET_THIS())
return;
SetValueChain(sKey,fVal);
}
void CScriptObject::SetValueChain(const char *sKey, bool bVal)
{
lua_pushstring(m_pLS, sKey);
if (bVal)
lua_pushnumber(m_pLS, 1);
else
lua_pushnil(m_pLS);
SET_FUNCTION(m_pLS, - 3);
}
void CScriptObject::SetValue(const char *sKey, bool bVal)
{
_GUARD_STACK(m_pLS);
// int nVal=bVal?1:0;
if (!_GET_THIS())
return;
SetValueChain(sKey,bVal);
}
void CScriptObject::SetValueChain(const char *sKey, const char *sVal)
{
lua_pushstring(m_pLS, sKey);
lua_pushstring(m_pLS, sVal);
SET_FUNCTION(m_pLS, - 3);
}
void CScriptObject::SetValue(const char *sKey, const char *sVal)
{
_GUARD_STACK(m_pLS);
if (!_GET_THIS())
return;
SetValueChain(sKey,sVal);
}
void CScriptObject::SetValueChain(const char *sKey, IScriptObject *pObj)
{
lua_pushstring(m_pLS, sKey);
if (!pObj)
{
CryWarning( VALIDATOR_MODULE_GAME,VALIDATOR_WARNING,"\001 ERROR! Passing NULL IScriptObject to SETVALUE CHAIN!");
#if defined(_DEBUG) && !defined(WIN64)
DEBUG_BREAK;
#endif
lua_pushnil(m_pLS);
}
else
lua_xgetref(m_pLS, pObj->GetRef());
SET_FUNCTION(m_pLS, - 3);
}
void CScriptObject::SetValue(const char *sKey, IScriptObject *pObj)
{
_GUARD_STACK(m_pLS);
if (!_GET_THIS())
return;
SetValueChain(sKey,pObj);
}
void CScriptObject::SetValueChain(const char *sKey, USER_DATA ud)
{
_GUARD_STACK(m_pLS);
lua_pushstring(m_pLS, sKey);
if(ud && lua_getref(m_pLS, ud))
{
if(lua_isuserdata(m_pLS,-1))
{
SET_FUNCTION(m_pLS, - 3);
}
}
}
void CScriptObject::SetValue(const char *sKey, USER_DATA ud)
{
_GUARD_STACK(m_pLS);
if (!_GET_THIS())
return;
SetValueChain(sKey,ud);
}
void CScriptObject::SetToNullChain(const char *sKey)
{
lua_pushstring(m_pLS, sKey);
lua_pushnil(m_pLS);
SET_FUNCTION(m_pLS, - 3);
}
void CScriptObject::SetToNull(const char *sKey)
{
_GUARD_STACK(m_pLS);
if (!_GET_THIS())
return;
SetToNullChain(sKey);
}
bool CScriptObject::GetValueChain(const char *sKey, int &nVal)
{
_GUARD_STACK(m_pLS);
bool res=false;
lua_pushstring(m_pLS, sKey);
GET_FUNCTION(m_pLS, - 2);
if (lua_isnumber(m_pLS, - 1))
{
res = true;
nVal =(int)lua_tonumber(m_pLS, - 1);
}
return res;
}
bool CScriptObject::GetValue(const char *sKey, int &nVal)
{
BEGIN_CHECK_STACK
bool res = false;
if (!_GET_THIS())
return false;
res=GetValueChain(sKey,nVal);
lua_pop(m_pLS, 1);
END_CHECK_STACK
return res;
}
bool CScriptObject::GetValueChain(const char *sKey, HSCRIPTFUNCTION &funcVal)
{
_GUARD_STACK(m_pLS);
bool res = false;
lua_pushstring(m_pLS, sKey);
GET_FUNCTION(m_pLS, - 2);
if (lua_isfunction(m_pLS, - 1))
{
res = true;
funcVal =(HSCRIPTFUNCTION)lua_ref(m_pLS,0);
}
return res;
}
bool CScriptObject::GetValue(const char *sKey, HSCRIPTFUNCTION &funcVal)
{
_GUARD_STACK(m_pLS);
bool res = false;
if (!_GET_THIS())
return false;
res=GetValueChain(sKey,funcVal);
return res;
}
bool CScriptObject::GetValueChain(const char *sKey, bool &bVal)
{
_GUARD_STACK(m_pLS);
int nVal;
bool res;
lua_pushstring(m_pLS, sKey);
GET_FUNCTION(m_pLS, - 2);
if (lua_isnil(m_pLS, - 1))
{
res = true;
bVal = false;
}
else if (lua_isnumber(m_pLS, - 1))
{
res = true;
nVal =(int)lua_tonumber(m_pLS, - 1);
if (nVal)
bVal = true;
else
bVal = false;
}
return res;
}
bool CScriptObject::GetValue(const char *sKey, bool &bVal)
{
_GUARD_STACK(m_pLS);
bool res = false;
if (!_GET_THIS())
return false;
res=GetValueChain(sKey,bVal);
return res;
}
bool CScriptObject::GetValueChain(const char *sKey, float &fVal)
{
_GUARD_STACK(m_pLS);
bool res=false;
lua_pushstring(m_pLS, sKey);
GET_FUNCTION(m_pLS, - 2);
if (lua_isnumber(m_pLS, - 1))
{
res = true;
fVal =(float)lua_tonumber(m_pLS, - 1);
}
return res;
}
bool CScriptObject::GetValue(const char *sKey, float &fVal)
{
_GUARD_STACK(m_pLS);
bool res = false;
if (!_GET_THIS())
return false;
res=GetValueChain(sKey,fVal);
return res;
}
bool CScriptObject::GetValueChain(const char *sKey, const char* &sVal)
{
_GUARD_STACK(m_pLS);
bool res=false;
lua_pushstring(m_pLS, sKey);
GET_FUNCTION(m_pLS, - 2);
if (lua_isstring(m_pLS, - 1))
{
res = true;
sVal =(char *)lua_tostring(m_pLS, - 1);
}
return res;
}
bool CScriptObject::GetValue(const char *sKey, const char* &sVal)
{
_GUARD_STACK(m_pLS);
bool res = false;
if (!_GET_THIS())
return false;
res=GetValueChain(sKey,sVal);
return res;
}
bool CScriptObject::GetValueChain(const char *sKey, IScriptObject *pObj)
{
_GUARD_STACK(m_pLS);
bool res=false;
lua_pushstring(m_pLS, sKey);
GET_FUNCTION(m_pLS, - 2);
if (lua_istable(m_pLS, - 1))
{
res = true;
lua_pushvalue(m_pLS, - 1);
pObj->Attach();
}
return res;
}
bool CScriptObject::GetValue(const char *sKey, IScriptObject *pObj)
{
_GUARD_STACK(m_pLS);
bool res = false;
if (!_GET_THIS())
return false;
res=GetValueChain(sKey,pObj);
return res;
}
bool CScriptObject::GetValueRecursive( const char *szPath, IScriptObject *pObj )
{
assert(pObj);
_GUARD_STACK(m_pLS);
const char *pSrc=szPath;
IScriptObject *pCurrent=this;
pObj->Clone(this);
while(*pSrc)
{
char szInterm[256],*pDst=szInterm;
while(*pSrc)
*pDst++=*pSrc++;
*pDst=0; // zero termination
if(!pCurrent->GetValue(szInterm,pObj))
return false;
pCurrent=pObj;
}
return true;
}
bool CScriptObject::GetUDValueChain(const char *sKey, USER_DATA &nValue, int &nCookie) //AMD Port
{
_GUARD_STACK(m_pLS);
lua_pushstring(m_pLS, sKey);
GET_FUNCTION(m_pLS, - 2);
if(lua_isuserdata(m_pLS,-1))
{
USER_DATA_CHUNK *udc=(USER_DATA_CHUNK *)lua_touserdata(m_pLS,-1);
if(!udc)
return false;
nValue=udc->nVal;
nCookie=udc->nCookie;
return true;
}
return false;
}
bool CScriptObject::GetUDValue(const char *sKey, USER_DATA &nValue, int &nCookie) //AMD Port
{
_GUARD_STACK(m_pLS);
bool res = false;
if (!_GET_THIS())
return false;
return GetUDValueChain(sKey,nValue,nCookie);
}
void CScriptObject::SetAt(int nIdx, int nVal)
{
assert(nIdx>=0); // nIdx=1 -> first element
_GUARD_STACK(m_pLS);
if (!_GET_THIS())
return;
lua_pushnumber(m_pLS, (lua_Number)nVal);
lua_rawseti(m_pLS, - 2, nIdx);
}
void CScriptObject::SetAt(int nIdx, float fVal)
{
assert(nIdx>=0); // nIdx=1 -> first element
_GUARD_STACK(m_pLS);
if (!_GET_THIS())
return;
lua_pushnumber(m_pLS, fVal);
lua_rawseti(m_pLS, - 2, nIdx);
}
void CScriptObject::SetAt(int nIdx, bool bVal)
{
assert(nIdx>=0); // nIdx=1 -> first element
_GUARD_STACK(m_pLS);
if (!_GET_THIS())
return;
if (bVal)
lua_pushnumber(m_pLS, 1);
else
lua_pushnil(m_pLS);
lua_rawseti(m_pLS, - 2, nIdx);
}
void CScriptObject::SetAt(int nIdx, const char* sVal)
{
assert(nIdx>=0); // nIdx=1 -> first element
_GUARD_STACK(m_pLS);
if (!_GET_THIS())
return;
lua_pushstring(m_pLS, sVal);
lua_rawseti(m_pLS, - 2, nIdx);
}
void CScriptObject::SetAt(int nIdx, IScriptObject *pObj)
{
_GUARD_STACK(m_pLS);
if (!_GET_THIS())
return;
lua_xgetref(m_pLS, pObj->GetRef());
lua_rawseti(m_pLS, - 2, nIdx);
}
void CScriptObject::SetAtUD(int nIdx, USER_DATA nVal)
{
_GUARD_STACK(m_pLS);
if (!_GET_THIS())
return;
if(nVal && lua_getref(m_pLS, nVal))
{
if(lua_isuserdata(m_pLS, -1))
{
lua_rawseti(m_pLS, -2, nIdx);
}
}
}
void CScriptObject::SetNullAt(int nIdx)
{
_GUARD_STACK(m_pLS);
if (!_GET_THIS())
return;
lua_pushnil(m_pLS);
lua_rawseti(m_pLS, - 2, nIdx);
}
int CScriptObject::Count()
{
_GUARD_STACK(m_pLS);
int top = lua_gettop(m_pLS);
int nCount=0;
if (!_GET_THIS())
return -1;
int trgTable = top + 1;
lua_pushnil(m_pLS); // first key
while (lua_next(m_pLS, trgTable) != 0)
{
// `key' is at index -2 and `value' at index -1
nCount++;
lua_pop(m_pLS, 1); // pop value, leave index.
}
//lua_settop(m_pLS, top); // Restore stack.
return nCount;
}
bool CScriptObject::GetAt(int nIdx, int &nVal)
{
_GUARD_STACK(m_pLS);
bool res = false;
if (!_GET_THIS())
return false;
if (lua_getn(m_pLS, - 1) < nIdx)
{
return false;
}
lua_rawgeti(m_pLS, - 1, nIdx);
if (lua_isnumber(m_pLS, - 1))
{
res = true;
nVal =(int)lua_tonumber(m_pLS, - 1);
}
return res;
}
bool CScriptObject::GetAt(int nIdx, float &fVal)
{
_GUARD_STACK(m_pLS);
bool res = false;
if (!_GET_THIS())
return false;
if (lua_getn(m_pLS, - 1) < nIdx)
{
return false;
}
lua_rawgeti(m_pLS, - 1, nIdx);
if (lua_isnumber(m_pLS, - 1))
{
res = true;
fVal = lua_tonumber(m_pLS, - 1);
}
return res;
}
bool CScriptObject::GetAt(int nIdx, bool &bVal)
{
_GUARD_STACK(m_pLS);
bool res = false;
int nVal;
if (!_GET_THIS())
return false;
if (lua_getn(m_pLS, - 1) < nIdx)
{
return false;
}
lua_rawgeti(m_pLS, - 1, nIdx);
if (lua_isnumber(m_pLS, - 1))
{
res = true;
nVal =(int)lua_tonumber(m_pLS, - 1);
if (nVal)
bVal = true;
else
bVal = false;
}
return res;
}
bool CScriptObject::GetAt(int nIdx, const char* &sVal)
{
_GUARD_STACK(m_pLS);
bool res = false;
if (!_GET_THIS())
return false;
if (lua_getn(m_pLS, - 1) < nIdx)
{
return false;
}
lua_rawgeti(m_pLS, - 1, nIdx);
if (lua_isstring(m_pLS, - 1))
{
res = true;
sVal =(char *)lua_tostring(m_pLS, - 1);
}
return res;
}
bool CScriptObject::GetAt(int nIdx, IScriptObject *pObj)
{
_GUARD_STACK(m_pLS);
bool res = false;
if (!_GET_THIS())
return false;
if (lua_getn(m_pLS, - 1) < nIdx)
{
return false;
}
lua_rawgeti(m_pLS, - 1, nIdx);
if (lua_istable(m_pLS, - 1))
{
res = true;
lua_pushvalue(m_pLS, - 1);
pObj->Attach();
}
return res;
}
bool CScriptObject::GetAtUD(int nIdx, USER_DATA &nVal, int &nCookie)
{
_GUARD_STACK(m_pLS);
bool res = false;
if (!_GET_THIS())
return false;
if (lua_getn(m_pLS, -1) < nIdx)
{
return false;
}
lua_rawgeti(m_pLS, -1, nIdx);
if (lua_isuserdata(m_pLS, - 1))
{
USER_DATA_CHUNK *udc=(USER_DATA_CHUNK *)lua_touserdata(m_pLS,-1);
if(!udc)
return false;
nVal=udc->nVal;
nCookie=udc->nCookie;
return true;
}
return res;
}
/*void CScriptObject::SetThis(THIS_PTR pThis)
{
//m_pThis = pThis;
}
THIS_PTR CScriptObject::GetThis()
{
THIS_PTR res = NULL;
return m_pThis;
}*/
bool CScriptObject::AddFunction(const char *sName, SCRIPT_FUNCTION pThunk, int nFuncID)
{
_GUARD_STACK(m_pLS);
if (!_GET_THIS())
return false;
lua_pushstring(m_pLS, sName);
lua_pushnumber(m_pLS, (lua_Number)nFuncID);
//lua_newuserdatabox(m_pLS, m_pThis);
lua_pushcclosure(m_pLS, (lua_CFunction)pThunk, 1);
SET_FUNCTION(m_pLS, -3);
return true;
}
bool CScriptObject::AddSetGetHandlers(SCRIPT_FUNCTION pSetThunk,SCRIPT_FUNCTION pGetThunk)
{
if((!m_pSetGetParams) && pSetThunk && pGetThunk && m_hDelegationTag)
{
m_pSetGetParams=new CScriptObject::SetGetParams;
//int nTag = lua_newtag(m_pLS);
lua_newuserdatabox(m_pLS, this);
//lua_newuserdatabox(m_pLS, m_pThis);
lua_pushcclosure(m_pLS, CScriptObject::SetTableTagHandler, 1);
lua_settagmethod(m_pLS, m_hDelegationTag, "settable");
/* lua_newuserdatabox(m_pLS, this);
//lua_newuserdatabox(m_pLS, m_pThis);
lua_pushcclosure(m_pLS, CScriptObject::GetTableTagHandler, 1);
lua_settagmethod(m_pLS, nTag, "gettable");*/
if (!_GET_THIS())
{
lua_pushnil(m_pLS);
lua_settagmethod(m_pLS, m_hDelegationTag, "settable");
/*lua_pushnil(m_pLS);
lua_settagmethod(m_pLS, nTag, "gettable");;*/
return false;
}
lua_settag(m_pLS, m_hDelegationTag);
lua_pop(m_pLS,1);
m_pSetGetParams->m_pSetThunk=pSetThunk;
m_pSetGetParams->m_pGetThunk=pGetThunk;
m_pSetGetParams->m_hSetGetTag=m_hDelegationTag;
}
else
{
if(m_pSetGetParams)
{
if(m_pSetGetParams->m_hSetGetTag)
{
lua_pushnil(m_pLS);
lua_settagmethod(m_pLS, m_pSetGetParams->m_hSetGetTag, "settable");
/*lua_pushnil(m_pLS);
lua_settagmethod(m_pLS, m_pSetGetParams->m_hSetGetTag, "gettable");;*/
m_pSetGetParams->m_hSetGetTag=NULL;
}
delete m_pSetGetParams;
m_pSetGetParams=NULL;
}
}
return true;
}
#ifdef PS2
#define FIXME_ASSERT(cond) { if(!(cond)) { FORCE_EXIT() } }
#else
#ifdef _DEBUG
#if defined(WIN64) || defined(LINUX64)
#define FIXME_ASSERT(cond) assert (cond)
#else
#define FIXME_ASSERT(cond) { if(!(cond)) { DEBUG_BREAK; } }
#endif
#else
//Timur[2/20/2003]
//@FIXME Should be removed in gold Release.
// Debugging mod
#define FIXME_ASSERT(cond) { if(!(cond)) { CryError( "<ScriptSystem> ASSERT %s",#cond ); }}
#endif
#endif
int CScriptObject::GetTableTagHandler(lua_State *L)
{
CScriptObject *pThis = (CScriptObject *)lua_touserdata(L, - 1);
int nRet;
FIXME_ASSERT(pThis->m_pSetGetParams->m_pGetThunk!=NULL);
/*{
//lua_pop(L,2);
FIXME_ASSERT(lua_istable(L,1));
lua_pop(L,1);
lua_rawget(L,1);
return 1;
}*/
if(((nRet=pThis->m_pSetGetParams->m_pGetThunk((HSCRIPT)L))==-1))
{
//lua_pop(L,2);
FIXME_ASSERT(lua_istable(L,1));
lua_pop(L,1);
lua_rawget(L,1);
return 1;
}
else return nRet;
}
int CScriptObject::SetTableTagHandler(lua_State *L)
{
CScriptObject *pThis = (CScriptObject *)lua_touserdata(L, - 1);
int nRet;
FIXME_ASSERT(pThis->m_pSetGetParams->m_pGetThunk!=NULL);
/*if(!pThis->m_pSetThunk)
{
FIXME_ASSERT(lua_istable(L,1));
lua_pop(L,1);
lua_rawset(L,1);
return 0;
}*/
if( /*!lua_isfunction(L,-2) && !lua_iscfunction(L,-2) && !lua_isuserdata(L,-2) &&*/ (!((nRet=pThis->m_pSetGetParams->m_pSetThunk((HSCRIPT)L))==-1)))
{
FIXME_ASSERT(lua_istable(L,1));
lua_pop(L,1);
}
else{
FIXME_ASSERT(lua_istable(L,1));
lua_pop(L,1);
lua_rawset(L,1);
return 0;
}
return 0;
}
void CScriptObject::RegisterParent(IScriptObjectSink *pSink)
{
m_pSink = pSink;
}
bool CScriptObject::Clone(IScriptObject *pObj)
{
//BEGIN_CHECK_STACK
_GUARD_STACK(m_pLS);
int top = lua_gettop(m_pLS);
if (!lua_xgetref(m_pLS, pObj->GetRef()))
return false;
if (!_GET_THIS())
return false;
int srcTable = top + 1;
int trgTable = top + 2;
lua_pushnil(m_pLS); // first key
while (lua_next(m_pLS, srcTable) != 0)
{
// `key' is at index -2 and `value' at index -1
lua_pushvalue(m_pLS, - 2); // Push again index.
lua_pushvalue(m_pLS, - 2); // Push value.
SET_FUNCTION(m_pLS, trgTable);
lua_pop(m_pLS, 1); // pop value, leave index.
}
//lua_settop(m_pLS, top); // Restore stack.
//END_CHECK_STACK
return true;
}
void CScriptObject::Dump(IScriptObjectDumpSink *p)
{
if(!p)return;
_GUARD_STACK(m_pLS);
int top = lua_gettop(m_pLS);
if (!_GET_THIS())
return;
int trgTable = top + 1;
lua_pushnil(m_pLS); // first key
int reftop=lua_gettop(m_pLS);
while (lua_next(m_pLS, trgTable) != 0)
{
// `key' is at index -2 and `value' at index -1
if(lua_isnumber(m_pLS, - 2))
{
int nIdx = (int)lua_tonumber(m_pLS, - 2); // again index
if (lua_isnil(m_pLS, - 1))
{
p->OnElementFound(nIdx, svtNull);
}
else if (lua_isfunction(m_pLS, - 1))
{
p->OnElementFound(nIdx, svtFunction);
}
else if (lua_isnumber(m_pLS, - 1))
{
p->OnElementFound(nIdx, svtNumber);
}
else if (lua_isstring(m_pLS, - 1))
{
p->OnElementFound(nIdx, svtString);
}
else if (lua_istable(m_pLS, - 1))
{
p->OnElementFound(nIdx, svtObject);
}
else if (lua_isuserdata(m_pLS, - 1))
{
p->OnElementFound(nIdx, svtUserData);
}
}
else
{
const char *sName = lua_tostring(m_pLS, - 2); // again index
if (lua_isnil(m_pLS, - 1))
{
p->OnElementFound(sName, svtNull);
}
else if (lua_isfunction(m_pLS, - 1))
{
p->OnElementFound(sName, svtFunction);
}
else if (lua_isnumber(m_pLS, - 1))
{
p->OnElementFound(sName, svtNumber);
}
else if (lua_isstring(m_pLS, - 1))
{
p->OnElementFound(sName, svtString);
}
else if (lua_istable(m_pLS, - 1))
{
p->OnElementFound(sName, svtObject);
}
else if (lua_isuserdata(m_pLS, - 1))
{
p->OnElementFound(sName, svtUserData);
}
}
lua_settop(m_pLS, reftop); // pop value, leave index.
}
//lua_settop(m_pLS, top); // Restore stack.
//END_CHECK_STACK
}
ScriptVarType CScriptObject::GetValueType(const char *sKey)
{
_GUARD_STACK(m_pLS);
ScriptVarType svtRetVal=svtNull;
if (!_GET_THIS())
return svtNull;
lua_pushstring(m_pLS, sKey);
GET_FUNCTION(m_pLS, - 2);
if (lua_isnil(m_pLS, - 1))
{
svtRetVal=svtNull;
}
else if (lua_isfunction(m_pLS, - 1))
{
svtRetVal=svtFunction;
}
else if (lua_isnumber(m_pLS, - 1))
{
svtRetVal=svtNumber;
}
else if (lua_isstring(m_pLS, - 1))
{
svtRetVal=svtString;
}
else if (lua_istable(m_pLS, - 1))
{
svtRetVal=svtObject;
}
else if (lua_isuserdata(m_pLS, - 1))
{
svtRetVal=svtUserData;
}
//lua_pop(m_pLS, 2);
//END_CHECK_STACK
return svtRetVal;
}
ScriptVarType CScriptObject::GetAtType(int nIdx)
{
_GUARD_STACK(m_pLS);
ScriptVarType svtRetVal=svtNull;
if (!_GET_THIS())
return svtNull;
if (lua_getn(m_pLS, - 1) < nIdx)
{
//lua_pop(m_pLS, 1);
return svtNull;
}
lua_rawgeti(m_pLS, - 1, nIdx);
if (lua_isnil(m_pLS, - 1))
{
svtRetVal=svtNull;
}
else if (lua_isfunction(m_pLS, - 1))
{
svtRetVal=svtFunction;
}
else if (lua_isnumber(m_pLS, - 1))
{
svtRetVal=svtNumber;
}
else if (lua_isstring(m_pLS, - 1))
{
svtRetVal=svtString;
}
else if (lua_istable(m_pLS, - 1))
{
svtRetVal=svtObject;
}
//lua_pop(m_pLS, 2);
//END_CHECK_STACK
return svtRetVal;
}
void CScriptObject::Detach()
{
if (m_bAttached)
{
lua_xunref(m_pLS, m_nRef);
m_bAttached = false;
}
}
void CScriptObject::Release()
{
AddSetGetHandlers(NULL,NULL);
if (m_pSink)
{
m_pSink->OnRelease();
if(m_nRef)
{
if (_GET_THIS())
{
lua_setnativedata(m_pLS,-1,NULL);
lua_pop(m_pLS,1);
}
}
}
m_pSink = NULL;
Detach();
//m_hSetGetTag=NULL;
CScriptSystem *pScriptSystem=(CScriptSystem *)lua_getuserptr(m_pLS);
pScriptSystem->ReleaseScriptObject(this);
m_bDeleted = true;
//delete this;
}
bool CScriptObject::BeginIteration()
{
if(m_nIterationCounter!=-1)
return false;
m_nIterationCounter=lua_gettop(m_pLS);
if (!_GET_THIS())
return false;
lua_pushnil(m_pLS);
return true;
}
bool CScriptObject::MoveNext()
{
if(m_nIterationCounter==-1)
return false;
//leave only the index into the stack
while((lua_gettop(m_pLS)-(m_nIterationCounter+1))>1)
{
lua_pop(m_pLS,1);
}
return (lua_next(m_pLS, m_nIterationCounter+1) != 0);
}
bool CScriptObject::GetCurrent(int &nVal)
{
if(m_nIterationCounter==-1)
return false;
if (lua_isnumber(m_pLS, -1))
{
nVal =(int)lua_tonumber(m_pLS, -1);
return true;
}
return false;
}
bool CScriptObject::GetCurrent(float &fVal)
{
if(m_nIterationCounter==-1)
return false;
if (lua_isnumber(m_pLS, -1))
{
fVal =lua_tonumber(m_pLS, -1);
return true;
}
return false;
}
bool CScriptObject::GetCurrent(bool &bVal)
{
if(m_nIterationCounter==-1)
return false;
bool res=false;
if (lua_isnil(m_pLS, - 1))
{
res = true;
bVal = false;
}
else if (lua_isnumber(m_pLS, - 1))
{
res = true;
int nVal =(int)lua_tonumber(m_pLS, - 1);
if (nVal)
bVal = true;
else
bVal = false;
}
return res;
}
bool CScriptObject::GetCurrent(const char* &sVal)
{
if(m_nIterationCounter==-1)
return false;
if (lua_isstring(m_pLS, - 1))
{
sVal =(char *)lua_tostring(m_pLS, - 1);
return true;
}
return false;
}
bool CScriptObject::GetCurrentPtr(const void * &pObj)
{
if(m_nIterationCounter==-1)
return false;
pObj=lua_topointer(m_pLS, - 1);
return pObj!=0;
}
bool CScriptObject::GetCurrent(IScriptObject *pObj)
{
if(m_nIterationCounter==-1)
return false;
bool res=false;
if (lua_istable(m_pLS, -1))
{
res = true;
lua_pushvalue(m_pLS, -1);
pObj->Attach();
}
return res;
}
// MartinM, used to create a hash value out of a lua function (for cheat protection)
bool CScriptObject::GetCurrentFuncData(unsigned int * &pCode, int &iSize)
{
if(m_nIterationCounter==-1)
return false;
if (lua_isfunction(m_pLS, -1))
{
lua_getluafuncdata(m_pLS,-1,&pCode,&iSize);
return true;
}
return false;
}
// MartinM, used to create a hash value out of a lua function (for cheat protection)
bool CScriptObject::GetFuncData(const char *sKey, unsigned int * &pCode, int &iSize)
{
_GUARD_STACK(m_pLS);
bool res = false;
lua_pushstring(m_pLS, sKey);
GET_FUNCTION(m_pLS, - 2);
if (lua_isfunction(m_pLS, -1))
{
lua_getluafuncdata(m_pLS,-1,&pCode,&iSize);
return true;
}
return false;
}
bool CScriptObject::GetCurrentKey(const char* &sKey)
{
if(m_nIterationCounter==-1)
return false;
// if (lua_isstring(m_pLS, - 2))
if(lua_rawtag(m_pLS, -2)==LUA_TSTRING) // get the internal type without converting it
{
sKey=(char *)lua_tostring(m_pLS, - 2);
return true;
}
return false;
}
bool CScriptObject::GetCurrentKey(int &nKey)
{
if(m_nIterationCounter==-1)
return false;
// if(lua_isnumber(m_pLS,-2))
if(lua_rawtag(m_pLS, -2)==LUA_TNUMBER) // get the internal type without converting it
{
nKey =(int)lua_tonumber(m_pLS, -2);
return true;
}
return false;
}
void CScriptObject::Attach(IScriptObject *so)
{
if(!lua_xgetref(m_pLS,so->GetRef()))
{
return;
}
Attach();
}
void CScriptObject::EndIteration()
{
if(m_nIterationCounter==-1)
{
//Timur[2/20/2003]
// This is invalid call, fire warning.
FIXME_ASSERT(0);
return;
}
lua_settop(m_pLS,m_nIterationCounter);
m_nIterationCounter=-1;
}
ScriptVarType CScriptObject::GetCurrentType()
{
ScriptVarType svtRetVal=svtNull;
if (lua_isnil(m_pLS, - 1))
{
svtRetVal=svtNull;
}
else if (lua_isfunction(m_pLS, - 1))
{
svtRetVal=svtFunction;
}
else if (lua_isnumber(m_pLS, - 1))
{
svtRetVal=svtNumber;
}
else if (lua_isstring(m_pLS, - 1))
{
svtRetVal=svtString;
}
else if (lua_isuserdata(m_pLS, - 1))
{
svtRetVal=svtUserData;
}
else if (lua_istable(m_pLS, - 1))
{
svtRetVal=svtObject;
}
return svtRetVal;
}
void CScriptObject::Clear()
{
_GUARD_STACK(m_pLS);
int top = lua_gettop(m_pLS);
if (!_GET_THIS())
return;
int trgTable = top + 1;
lua_pushnil(m_pLS); // first key
while (lua_next(m_pLS, trgTable) != 0)
{
lua_pop(m_pLS, 1); // pop value, leave index.
lua_pushvalue(m_pLS, -1); // Push again index.
lua_pushnil(m_pLS);
lua_rawset(m_pLS,trgTable);
}
// lua_settop(m_pLS, top); // Restore stack.
// END_CHECK_STACK
}
void CScriptObject::SetNativeData(void *nd)
{
_GUARD_STACK(m_pLS);
if (!_GET_THIS())
return;
lua_setnativedata(m_pLS,-1,nd);
}
void *CScriptObject::GetNativeData()
{
_GUARD_STACK(m_pLS);
if (!_GET_THIS())
return NULL;
return lua_getnativedata(m_pLS,-1);
}
int CScriptObject::IndexTagHandler(lua_State *L)
{
CScriptObject *p=(CScriptObject *)lua_touserdata(L,-2);
int nRet=0;
if(p && p->m_pSetGetParams)
{
if (p->m_bDeleted)
{
CryError( "<CScriptObject::IndexTagHandler> Access to deleted script object" );
}
if((nRet=p->m_pSetGetParams->m_pGetThunk((HSCRIPT)L))!=-1)
{
return nRet;
}
//lua_pop(L,1);
}
if(lua_istable(L,4))
{
if(!lua_getnativedata(L,1))return 0;
lua_pushvalue(L,2);
lua_rawget(L,-2);
lua_remove(L,-2);
return 1;
}
return 0;
}
void CScriptObject::Delegate(IScriptObject *pObj)
{
if(!pObj)return;
m_hDelegationTag = lua_newtag(m_pLS);
lua_newuserdatabox(m_pLS, this);
if(!lua_xgetref(m_pLS,pObj->GetRef()))return;
lua_pushcclosure(m_pLS, CScriptObject::IndexTagHandler, 2);
lua_settagmethod(m_pLS, m_hDelegationTag, "index");
if (!_GET_THIS())
{
lua_pushnil(m_pLS);
lua_settagmethod(m_pLS, m_hDelegationTag, "index");
return ;
}
lua_settag(m_pLS, m_hDelegationTag);
lua_pop(m_pLS,1);
}