#include "LuaVM.h" #include #include #include #include #ifndef _STOOL #ifndef _RAC #include "FileLog.h" #endif #endif #include 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; }