Files
Leviathan/Client/Game/engine/Lua/LuaVM.cpp
T
2026-06-01 12:46:52 +02:00

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;
}