66b23ecbef
- versione x64 compilata con Clang-cl/LLVM - modifiche varie per eliminare warning più gravi di questo compilatore.
311 lines
9.1 KiB
C++
311 lines
9.1 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2015-2017
|
|
//----------------------------------------------------------------------------
|
|
// File : LuaManager.cpp Data : 03.01.17 Versione : 1.6x1
|
|
// Contenuto : Implementazione della classe LuaMgr.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 21.03.15 DS Creazione modulo.
|
|
// 20.08.15 DS Controllo che il double di EvalExpr sia numero valido.
|
|
// 03.01.17 DS Aggiunti controlli validità ambiente lua.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "DllMain.h"
|
|
#include "/EgtDev/Include/EGnLuaMgr.h"
|
|
#include "/EgtDev/Include/EgtILogger.h"
|
|
#include "/EgtDev/Extern/Lua/Include/lua.hpp"
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
LuaMgr::Init( void)
|
|
{
|
|
// se già aperto, lo fermo per riavviarlo
|
|
if ( m_pL != nullptr) {
|
|
lua_close( m_pL) ;
|
|
m_pL = nullptr ;
|
|
}
|
|
// inizializzo Lua
|
|
m_pL = luaL_newstate() ;
|
|
if ( m_pL == nullptr) {
|
|
LOG_ERROR( GetEGnLogger(), "Error in Lua interpreter starting (LuaMgr::Init)")
|
|
return false ;
|
|
}
|
|
// carico le librerie standard
|
|
luaL_openlibs( m_pL) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
LuaMgr::Exit( void)
|
|
{
|
|
// verifico ambiente lua
|
|
if ( m_pL == nullptr)
|
|
return false ;
|
|
// termino Lua
|
|
lua_close( m_pL) ;
|
|
m_pL = nullptr ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
LuaMgr::GetVersion( string& sLuaVer) const
|
|
{
|
|
// verifico ambiente lua
|
|
if ( m_pL == nullptr)
|
|
return false ;
|
|
// verifico il parametro di ritorno
|
|
if ( &sLuaVer == nullptr)
|
|
return false ;
|
|
// recupero la versione di Lua
|
|
lua_getglobal( m_pL, "_VERSION") ;
|
|
if ( LuaGetParam( m_pL, - 1, sLuaVer))
|
|
return true ;
|
|
else
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
LuaMgr::SetLuaLibsDir( const string& sDir)
|
|
{
|
|
// verifico ambiente lua
|
|
if ( m_pL == nullptr)
|
|
return false ;
|
|
// salvo il direttorio
|
|
m_sLuaLibsDir = sDir ;
|
|
// recupero la stringa globale package.path
|
|
lua_getglobal( m_pL, "package") ;
|
|
lua_getfield( m_pL, -1, "path") ;
|
|
string sCurPath = lua_tostring( m_pL, -1) ;
|
|
// verifico se la dir ricevuta è già presente
|
|
if ( sCurPath.find( sDir) != string::npos) {
|
|
lua_pop( m_pL, 2) ;
|
|
return true ;
|
|
}
|
|
// imposto la nuova dir
|
|
sCurPath = sDir ;
|
|
sCurPath += "\\?.lua" ;
|
|
lua_pop( m_pL, 1) ;
|
|
lua_pushstring( m_pL, sCurPath.c_str()) ;
|
|
lua_setfield( m_pL, -2, "path") ;
|
|
lua_pop( m_pL, 1) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
LuaMgr::Require( const string& sFile)
|
|
{
|
|
// verifico ambiente lua
|
|
if ( m_pL == nullptr)
|
|
return false ;
|
|
// salvo nome libreria richiesta
|
|
m_sLastRequire = sFile ;
|
|
// eseguo
|
|
lua_getglobal( m_pL, "require") ;
|
|
lua_pushstring( m_pL, sFile.c_str()) ;
|
|
int nErr = lua_pcall( m_pL, 1, 1, 0) ; /* call 'require(sFile)' */
|
|
if ( nErr == LUA_OK) {
|
|
lua_setglobal( m_pL, sFile.c_str()) ; /* global[sFile] = require return */
|
|
m_sLastError.clear() ;
|
|
return true ;
|
|
}
|
|
else {
|
|
// recupero il messaggio di errore
|
|
const char* szErr = lua_tostring( m_pL, -1) ;
|
|
m_sLastError = ( szErr != nullptr) ? szErr : "Error unknown" ;
|
|
lua_pop( m_pL, 1) ;
|
|
// lo scrivo nel log
|
|
LOG_ERROR( GetEGnLogger(), m_sLastError.c_str())
|
|
return false ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
LuaMgr::RegisterFunction( const string& sFunName, PFLUA pFun)
|
|
{
|
|
// verifico ambiente lua
|
|
if ( m_pL == nullptr)
|
|
return false ;
|
|
if ( &sFunName == nullptr)
|
|
return false ;
|
|
try {
|
|
lua_register( m_pL, sFunName.c_str(), pFun) ;
|
|
}
|
|
catch ( ...) {
|
|
return false ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
LuaMgr::EvalExpr( const string& sExpr, double& dVal)
|
|
{
|
|
// verifico ambiente lua
|
|
if ( m_pL == nullptr)
|
|
return false ;
|
|
// completo la stringa da valutare
|
|
string sEval = "return " + sExpr ;
|
|
// valuto l'espressione
|
|
int nErr = luaL_loadstring( m_pL, sEval.c_str()) ;
|
|
if ( nErr == LUA_OK)
|
|
nErr = lua_pcall( m_pL, 0, 1, 0) ;
|
|
// senza errori
|
|
if ( nErr == LUA_OK && lua_type( m_pL, -1) == LUA_TNUMBER) {
|
|
dVal = lua_tonumber( m_pL, -1) ;
|
|
lua_pop( m_pL, 1) ;
|
|
if ( ! isinf( dVal) && ! isnan( dVal)) {
|
|
m_sLastError.clear() ;
|
|
return true ;
|
|
}
|
|
else {
|
|
m_sLastError = "EvalExpr(number): Error infinite or not a number" ;
|
|
// lo scrivo nel log
|
|
LOG_ERROR( GetEGnLogger(), m_sLastError.c_str())
|
|
return false ;
|
|
}
|
|
}
|
|
// altrimenti, errore
|
|
else {
|
|
// recupero il messaggio di errore
|
|
const char* szErr = lua_tostring( m_pL, -1) ;
|
|
m_sLastError = string( "EvalExpr(number): ") + (( szErr != nullptr) ? szErr : "Error not a number") ;
|
|
lua_pop( m_pL, 1) ;
|
|
// lo scrivo nel log
|
|
LOG_ERROR( GetEGnLogger(), m_sLastError.c_str())
|
|
return false ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
LuaMgr::EvalExpr( const string& sExpr, string& sVal)
|
|
{
|
|
// verifico ambiente lua
|
|
if ( m_pL == nullptr)
|
|
return false ;
|
|
// completo la stringa da valutare
|
|
string sEval = "return " + sExpr ;
|
|
// valuto l'espressione
|
|
int nErr = luaL_loadstring( m_pL, sEval.c_str()) ;
|
|
if ( nErr == LUA_OK)
|
|
nErr = lua_pcall( m_pL, 0, 1, 0) ;
|
|
// senza errori
|
|
if ( nErr == LUA_OK && lua_type( m_pL, -1) == LUA_TSTRING) {
|
|
sVal = lua_tostring( m_pL, -1) ;
|
|
lua_pop( m_pL, 1) ;
|
|
m_sLastError.clear() ;
|
|
return true ;
|
|
}
|
|
// altrimenti, errore
|
|
else {
|
|
// recupero il messaggio di errore
|
|
const char* szErr = lua_tostring( m_pL, -1) ;
|
|
m_sLastError = string( "EvalExpr(string): ") + (( szErr != nullptr) ? szErr : "Error not a string") ;
|
|
lua_pop( m_pL, 1) ;
|
|
// lo scrivo nel log
|
|
LOG_ERROR( GetEGnLogger(), m_sLastError.c_str())
|
|
return false ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
LuaMgr::ExecLine( const string& sLine)
|
|
{
|
|
// verifico ambiente lua
|
|
if ( m_pL == nullptr)
|
|
return false ;
|
|
// eseguo la linea
|
|
int nErr = luaL_loadstring( m_pL, sLine.c_str()) ;
|
|
if ( nErr == LUA_OK)
|
|
nErr = lua_pcall( m_pL, 0, LUA_MULTRET, 0) ;
|
|
// senza errori
|
|
if ( nErr == LUA_OK) {
|
|
m_sLastError.clear() ;
|
|
return true ;
|
|
}
|
|
// altrimenti, errore
|
|
else {
|
|
// recupero il messaggio di errore
|
|
const char* szErr = lua_tostring( m_pL, -1) ;
|
|
m_sLastError = string( "ExecLine: ") + (( szErr != nullptr) ? szErr : "Error unknown") ;
|
|
lua_pop( m_pL, 1) ;
|
|
// lo scrivo nel log
|
|
LOG_ERROR( GetEGnLogger(), m_sLastError.c_str())
|
|
return false ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
LuaMgr::ExecFile( const string& sFile)
|
|
{
|
|
// verifico ambiente lua
|
|
if ( m_pL == nullptr)
|
|
return false ;
|
|
// eseguo la linea
|
|
int nErr = luaL_loadfile( m_pL, sFile.c_str()) ;
|
|
if ( nErr == LUA_OK)
|
|
nErr = lua_pcall( m_pL, 0, LUA_MULTRET, 0) ;
|
|
// senza errori
|
|
if ( nErr == LUA_OK) {
|
|
m_sLastError.clear() ;
|
|
return true ;
|
|
}
|
|
// in caso di errore
|
|
else {
|
|
// recupero il messaggio di errore
|
|
const char* szErr = lua_tostring( m_pL, -1) ;
|
|
m_sLastError = (( szErr != nullptr) ? szErr : "Error unknown") ;
|
|
lua_pop( m_pL, 1) ;
|
|
// lo scrivo nel log
|
|
LOG_ERROR( GetEGnLogger(), m_sLastError.c_str())
|
|
return false ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
LuaMgr::ExistsFunction( const string& sFunName) const
|
|
{
|
|
// verifico ambiente lua
|
|
if ( m_pL == nullptr)
|
|
return false ;
|
|
// recupero la funzione
|
|
if ( sFunName.find( '.') == string::npos) {
|
|
// è direttamente il nome
|
|
lua_getglobal( m_pL, sFunName.c_str()) ;
|
|
}
|
|
else {
|
|
// è in una tavola
|
|
string sTab, sField ;
|
|
SplitFirst( sFunName, ".", sTab, sField) ;
|
|
lua_getglobal( m_pL, sTab.c_str()) ;
|
|
lua_getfield( m_pL, -1, sField.c_str()) ;
|
|
// porto la funzione uno slot sotto e diminuisco lo stack di uno (per essere come caso sopra)
|
|
lua_copy( m_pL, -1, -2) ;
|
|
lua_pop( m_pL, 1) ;
|
|
}
|
|
bool bOk = ( lua_isfunction( m_pL, -1) != 0) ;
|
|
lua_pop( m_pL, 1) ;
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
LuaMgr::LogError( const string& sErr) const
|
|
{
|
|
LOG_ERROR( GetEGnLogger(), sErr.c_str())
|
|
}
|