302 lines
4.9 KiB
C++
302 lines
4.9 KiB
C++
|
|
|
|
#include "LuaVM.h"
|
|
#include <toolkit/XConsole.h>
|
|
#include <stdarg.h>
|
|
#include <algorithm>
|
|
#include <toolkit/XSTLUtil.h>
|
|
|
|
#ifndef _STOOL
|
|
#ifndef _RAC
|
|
#include "FileLog.h"
|
|
#endif
|
|
#endif
|
|
|
|
|
|
#include <lua/lua.hpp>
|
|
|
|
struct LUA_INFO
|
|
{
|
|
#if (_WIN32_WINNT >= 0x0403)
|
|
LUA_INFO() : pState( NULL ), cs( 4000 )
|
|
{
|
|
}
|
|
#else
|
|
LUA_INFO() : pState( NULL )
|
|
{
|
|
}
|
|
#endif
|
|
|
|
lua_State* pState;
|
|
XCriticalSection cs;
|
|
};
|
|
|
|
#if (_WIN32_WINNT >= 0x0403)
|
|
static XCriticalSection s_CS( 4000 );
|
|
#else
|
|
static XCriticalSection s_CS;
|
|
#endif
|
|
|
|
volatile __declspec( thread ) LUA_INFO* pLuaLocalInfo = NULL;
|
|
|
|
static int _outputConsole(lua_State *L)
|
|
{
|
|
int n = lua_gettop(L); /* number of arguments */
|
|
for (int i = 1; i <= n; i++)
|
|
{
|
|
if( lua_isstring(L, i) )
|
|
{
|
|
LUA()->Log( (char*)lua_tostring( L, i ) );
|
|
continue;
|
|
}
|
|
|
|
if( lua_isnumber(L, i) )
|
|
{
|
|
char szTmp[30];
|
|
sprintf( szTmp, "%d", (int)lua_tonumber( L, i ) );
|
|
LUA()->Log( szTmp );
|
|
continue;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
static int _lua_alert(lua_State *L)
|
|
{
|
|
_outputConsole( L );
|
|
return 0;
|
|
}*/
|
|
|
|
struct _LOG_FUNC
|
|
{
|
|
void (*fp)( const char* );
|
|
};
|
|
|
|
LuaVM::LuaVM()
|
|
{
|
|
m_pLogFunc = new _LOG_FUNC;
|
|
|
|
m_pLogFunc->fp = NULL;
|
|
|
|
m_bInit = false;
|
|
}
|
|
|
|
LuaVM::~LuaVM()
|
|
{
|
|
delete m_pLogFunc;
|
|
}
|
|
|
|
bool LuaVM::Init()
|
|
{
|
|
if( m_bInit )
|
|
return false;
|
|
|
|
m_bInit = true;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool LuaVM::DeInit()
|
|
{
|
|
std::vector< struct LUA_INFO * >::iterator it;
|
|
|
|
for( it = m_vStateList.begin(); it != m_vStateList.end(); ++it )
|
|
{
|
|
lua_close( (*it)->pState );
|
|
|
|
delete (*it);
|
|
}
|
|
|
|
m_vStateList.clear();
|
|
|
|
return true;
|
|
}
|
|
|
|
bool LuaVM::InitThread()
|
|
{
|
|
THREAD_SYNCRONIZE( s_CS );
|
|
|
|
if( pLuaLocalInfo ) return false;
|
|
|
|
LUA_INFO * pLuaInfo = new LUA_INFO;
|
|
|
|
pLuaInfo->pState = luaL_newstate();
|
|
|
|
if( !pLuaInfo->pState )
|
|
{
|
|
assert( 0 && "lua_open() FAILED!!!" );
|
|
delete pLuaInfo;
|
|
return false;
|
|
}
|
|
|
|
luaopen_base ( pLuaInfo->pState );
|
|
luaopen_math ( pLuaInfo->pState );
|
|
luaopen_string ( pLuaInfo->pState );
|
|
luaopen_table ( pLuaInfo->pState );
|
|
|
|
lua_register( pLuaInfo->pState, "_ALERT", _outputConsole );
|
|
lua_register( pLuaInfo->pState, "cprint", _outputConsole );
|
|
|
|
{ // 스크립트 파일 로딩
|
|
std::set< std::string >::iterator it;
|
|
|
|
for( it = m_setScriptList.begin(); it != m_setScriptList.end(); ++it )
|
|
{
|
|
luaL_dofile( pLuaInfo->pState, (*it).c_str() );
|
|
}
|
|
}
|
|
|
|
{ // 함수들 등록
|
|
std::map< std::string, luaFunction >::iterator it;
|
|
|
|
for( it = m_mapFuncList.begin(); it != m_mapFuncList.end(); ++it )
|
|
{
|
|
lua_register( pLuaInfo->pState, it->first.c_str(), it->second );
|
|
}
|
|
}
|
|
|
|
pLuaLocalInfo = pLuaInfo;
|
|
|
|
m_vStateList.push_back( pLuaInfo );
|
|
|
|
return true;
|
|
}
|
|
|
|
bool LuaVM::DeInitThread()
|
|
{
|
|
THREAD_SYNCRONIZE( s_CS );
|
|
|
|
if( !pLuaLocalInfo ) return false;
|
|
|
|
lua_close( (lua_State*) pLuaLocalInfo->pState );
|
|
|
|
std::vector< struct LUA_INFO * >::iterator it = std::find( m_vStateList.begin(), m_vStateList.end(), pLuaLocalInfo );
|
|
|
|
if( it != m_vStateList.end() )
|
|
{
|
|
vector_fast_erase( &m_vStateList, it );
|
|
}
|
|
|
|
delete pLuaLocalInfo;
|
|
|
|
pLuaLocalInfo = NULL;
|
|
|
|
return true;
|
|
}
|
|
|
|
void LuaVM::BindLogOutputFunction( void (*fp)( const char* ) )
|
|
{
|
|
m_pLogFunc->fp = fp;
|
|
}
|
|
|
|
void LuaVM::Log( const char *szString )
|
|
{
|
|
if( m_pLogFunc->fp )
|
|
{
|
|
m_pLogFunc->fp( szString );
|
|
m_pLogFunc->fp( "\n" );
|
|
}
|
|
else
|
|
{
|
|
#ifndef _STOOL
|
|
#ifndef _RAC
|
|
// FILELOG( "%s", szString );
|
|
_cprint( "%s\n", szString );
|
|
#endif
|
|
#endif
|
|
}
|
|
}
|
|
|
|
void LuaVM::LogPrintf( const char *szString, ... )
|
|
{
|
|
char szBuf[2048];
|
|
va_list va;
|
|
va_start( va, szString );
|
|
_vsnprintf( szBuf, _countof(szBuf), szString, va );
|
|
va_end( va );
|
|
|
|
this->Log( szBuf );
|
|
}
|
|
|
|
bool LuaVM::LoadScript( const char* szFileName )
|
|
{
|
|
THREAD_SYNCRONIZE( s_CS );
|
|
|
|
std::vector< struct LUA_INFO * >::iterator it;
|
|
|
|
for( it = m_vStateList.begin(); it != m_vStateList.end(); ++it )
|
|
{
|
|
THREAD_SYNCRONIZE( (*it)->cs );
|
|
|
|
luaL_dofile( (*it)->pState, szFileName );
|
|
}
|
|
|
|
m_setScriptList.insert( szFileName );
|
|
|
|
return true;
|
|
}
|
|
|
|
bool LuaVM::RunFile( const char* szFileName )
|
|
{
|
|
LUA_INFO *pLuaInfo = getLuaInfo();
|
|
|
|
if( !pLuaInfo ) return false;
|
|
|
|
THREAD_SYNCRONIZE( pLuaInfo->cs );
|
|
|
|
luaL_dofile( pLuaInfo->pState, szFileName );
|
|
|
|
return true;
|
|
}
|
|
|
|
bool LuaVM::RunString( const char* szString )
|
|
{
|
|
LUA_INFO *pLuaInfo = getLuaInfo();
|
|
|
|
if( !pLuaInfo ) return false;
|
|
|
|
THREAD_SYNCRONIZE( pLuaInfo->cs );
|
|
|
|
luaL_dostring( pLuaInfo->pState, szString );
|
|
|
|
return true;
|
|
}
|
|
|
|
bool LuaVM::RunFunction( const char* szFunctionName, ... )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool LuaVM::RegisterFunction( const char* szFunctionName, luaFunction fp )
|
|
{
|
|
THREAD_SYNCRONIZE( s_CS );
|
|
|
|
std::vector< struct LUA_INFO * >::iterator it;
|
|
|
|
for( it = m_vStateList.begin(); it != m_vStateList.end(); ++it )
|
|
{
|
|
THREAD_SYNCRONIZE( (*it)->cs );
|
|
|
|
lua_register( (*it)->pState, szFunctionName, (lua_CFunction)fp );
|
|
}
|
|
|
|
m_mapFuncList[szFunctionName] = fp;
|
|
|
|
return true;
|
|
}
|
|
|
|
LUA_INFO * LuaVM::getLuaInfo()
|
|
{
|
|
if( !pLuaLocalInfo ) InitThread();
|
|
|
|
if( pLuaLocalInfo ) return const_cast< LUA_INFO * >( pLuaLocalInfo );
|
|
|
|
return NULL;
|
|
}
|
|
|
|
LuaVM* LuaVM::Inst()
|
|
{
|
|
static LuaVM inst;
|
|
return &inst;
|
|
} |