Files
EgtGeneral/LuaManager.cpp
T
DarioS 66b23ecbef EgtGeneral 2.3g1 :
- versione x64 compilata con Clang-cl/LLVM
- modifiche varie per eliminare warning più gravi di questo compilatore.
2021-07-20 17:57:45 +02:00

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())
}