Files
Include/EGnLuaAux.h
T
Dario Sassi 9d7e968fb7 Include :
- migliorie e correzioni a funzioni inline per accedere a variabili globali strutturate lua.
2024-12-05 17:38:36 +01:00

668 lines
19 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2015-2020
//----------------------------------------------------------------------------
// File : EGnLuaAux.h Data : 30.07.20 Versione : 2.2g1
// Contenuto : Funzioni per gestione parametri generali con LUA.
//
//
//
// Modifiche : 21.03.15 DS Creazione modulo.
// 30.07.20 DS Corretta LuaChangeNameGlobVar (mancava pop se non c'è var).
//
//----------------------------------------------------------------------------
#pragma once
#include "/EgtDev/Include/EGnStringUtils.h"
#include "/EgtDev/Include/EgtNumCollection.h"
#include "/EgtDev/Extern/Lua/Include/lua.hpp"
//----------------------------------------------------------------------------
#define LuaCheckParam(L,I,P) { if ( ! LuaGetParam(L,I,P)) \
return luaL_error( L, " Invalid Parameter # " #I) ;}
#define LuaCheckTabFieldParam(L,I,F,P) { if ( ! LuaGetTabFieldParam(L,I,F,P))\
return luaL_error( L, " Invalid Parameter # " #I " (field %s)",\
std::string( F).c_str()) ; }
//----------------------------------------------------------------------------
inline bool
LuaClearStack( lua_State* L)
{
int n = lua_gettop( L) ;
if ( n > 0)
lua_pop( L, n) ;
return true ;
}
//----------------------------------------------------------------------------
inline bool
LuaGetParam( lua_State* L, int nInd, bool& bPar)
{
if ( ! lua_isboolean( L, nInd))
return false ;
bPar = ( lua_toboolean( L, nInd) != 0) ;
return true ;
}
//----------------------------------------------------------------------------
inline bool
LuaGetParam( lua_State* L, int nInd, int& nPar)
{
if ( ! lua_isnumber( L, nInd))
return false ;
double dVal = lua_tonumber( L, nInd) ;
nPar = int( dVal + (( dVal > 0) ? 0.5 : - 0.5)) ;
return true ;
}
//----------------------------------------------------------------------------
inline bool
LuaGetParam( lua_State* L, int nInd, double& dPar)
{
if ( ! lua_isnumber( L, nInd))
return false ;
dPar = lua_tonumber( L, nInd) ;
return true ;
}
//----------------------------------------------------------------------------
inline bool
LuaGetParam( lua_State* L, int nInd, std::string& sPar)
{
if ( ! lua_isstring( L, nInd))
return false ;
sPar = lua_tostring( L, nInd) ;
return true ;
}
//----------------------------------------------------------------------------
template <size_t size>
bool
LuaGetParam( lua_State* L, int nInd, int (&nVal)[size])
{
if ( ! lua_istable( L, nInd))
return false ;
for ( int i = 1 ; i <= size ; ++ i) {
lua_rawgeti( L, nInd, i) ;
if ( ! lua_isnumber( L, -1)) {
lua_pop( L, 1) ;
return false ;
}
double dVal = lua_tonumber( L, -1) ;
nVal[i-1] = int( dVal + (( dVal > 0) ? 0.5 : - 0.5)) ;
lua_pop( L, 1) ;
}
return true ;
}
//----------------------------------------------------------------------------
template <size_t size>
bool
LuaGetParam( lua_State* L, int nInd, double (&dVal)[size])
{
if ( ! lua_istable( L, nInd))
return false ;
for ( int i = 1 ; i <= size ; ++ i) {
lua_rawgeti( L, nInd, i) ;
if ( ! lua_isnumber( L, -1)) {
lua_pop( L, 1) ;
return false ;
}
dVal[i-1] = lua_tonumber( L, -1) ;
lua_pop( L, 1) ;
}
return true ;
}
//----------------------------------------------------------------------------
inline bool
LuaGetParam( lua_State* L, int nInd, INTVECTOR& vPar)
{
vPar.clear() ;
if ( lua_isnumber( L, nInd)) {
int nVal = int( lua_tointeger( L, nInd)) ;
vPar.push_back( nVal) ;
return true ;
}
else if ( lua_istable( L, nInd)) {
// lunghezza della tavola
lua_len( L, nInd) ;
if ( ! lua_isnumber( L, -1)) {
lua_pop( L, 1) ;
return false ;
}
int nLen = int( lua_tointeger( L, -1)) ;
lua_pop( L, 1) ;
vPar.reserve( nLen) ;
for ( int i = 1 ; i <= nLen ; ++ i) {
lua_rawgeti( L, nInd, i) ;
if ( ! lua_isnumber( L, -1)) {
lua_pop( L, 1) ;
return false ;
}
int nVal = int( lua_tointeger( L, -1)) ;
vPar.push_back( nVal) ;
lua_pop( L, 1) ;
}
return true ;
}
else
return false ;
}
//----------------------------------------------------------------------------
inline bool
LuaGetParam( lua_State* L, int nInd, DBLVECTOR& vPar)
{
vPar.clear() ;
if ( lua_isnumber( L, nInd)) {
double dVal = lua_tonumber( L, nInd) ;
vPar.push_back( dVal) ;
return true ;
}
else if ( lua_istable( L, nInd)) {
// lunghezza della tavola
lua_len( L, nInd) ;
if ( ! lua_isnumber( L, -1)) {
lua_pop( L, 1) ;
return false ;
}
int nLen = int( lua_tointeger( L, -1)) ;
lua_pop( L, 1) ;
vPar.reserve( nLen) ;
for ( int i = 1 ; i <= nLen ; ++ i) {
lua_rawgeti( L, nInd, i) ;
if ( ! lua_isnumber( L, -1)) {
lua_pop( L, 1) ;
return false ;
}
double dVal = lua_tonumber( L, -1) ;
vPar.push_back( dVal) ;
lua_pop( L, 1) ;
}
return true ;
}
else
return false ;
}
//----------------------------------------------------------------------------
inline bool
LuaGetParam( lua_State* L, int nInd, STRVECTOR& vPar)
{
vPar.clear() ;
if ( lua_isstring( L, nInd)) {
std::string sVal = lua_tostring( L, nInd) ;
vPar.emplace_back( sVal) ;
return true ;
}
else if ( lua_istable( L, nInd)) {
// lunghezza della tavola
lua_len( L, nInd) ;
if ( ! lua_isnumber( L, -1)) {
lua_pop( L, 1) ;
return false ;
}
int nLen = int( lua_tointeger( L, -1)) ;
lua_pop( L, 1) ;
vPar.reserve( nLen) ;
for ( int i = 1 ; i <= nLen ; ++ i) {
lua_rawgeti( L, nInd, i) ;
if ( ! lua_isstring( L, -1)) {
lua_pop( L, 1) ;
return false ;
}
std::string sVal = lua_tostring( L, -1) ;
vPar.emplace_back( sVal) ;
lua_pop( L, 1) ;
}
return true ;
}
else
return false ;
}
//----------------------------------------------------------------------------
template <class T>
bool
LuaGetTabFieldParam( lua_State* L, int nInd, const char* szField, T& Val)
{
if ( ! lua_istable( L, nInd))
return false ;
int nField ;
if ( FromString( szField, nField))
lua_rawgeti( L, nInd, nField) ;
else
lua_getfield( L, nInd, szField) ;
bool bOk = LuaGetParam( L, -1, Val) ;
lua_pop( L, 1) ;
return bOk ;
}
//----------------------------------------------------------------------------
template <class T>
bool
LuaGetTabFieldParam( lua_State* L, int nInd, const std::string& sField, T& Val)
{
return LuaGetTabFieldParam( L, nInd, sField.c_str(), Val) ;
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
inline bool
LuaSetParam( lua_State* L)
{
try {
lua_pushnil( L) ;
}
catch ( ...) {
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
inline bool
LuaSetParam( lua_State* L, bool bPar)
{
try {
lua_pushboolean( L, ( bPar ? 1 : 0)) ;
}
catch ( ...) {
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
inline bool
LuaSetParam( lua_State* L, int nPar)
{
try {
lua_pushinteger( L, nPar) ;
}
catch ( ...) {
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
inline bool
LuaSetParam( lua_State* L, double dPar)
{
try {
lua_pushnumber( L, dPar) ;
}
catch ( ...) {
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
inline bool
LuaSetParam( lua_State* L, const char* szPar)
{
try {
lua_pushstring( L, szPar) ;
}
catch ( ...) {
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
inline bool
LuaSetParam( lua_State* L, const std::string& sPar)
{
try {
lua_pushstring( L, sPar.c_str()) ;
}
catch ( ...) {
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
inline bool
LuaSetParam( lua_State* L, const BOOLVECTOR& vPar)
{
try {
int nSize = int( vPar.size()) ;
lua_createtable( L, nSize, 0) ;
for ( int i = 1 ; i <= nSize ; ++ i) {
lua_pushboolean( L, ( vPar[i-1] ? 1 : 0)) ;
lua_rawseti( L, -2, i) ;
}
}
catch( ...) {
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
inline bool
LuaSetParam( lua_State* L, const INTVECTOR& vPar)
{
try {
int nSize = int( vPar.size()) ;
lua_createtable( L, nSize, 0) ;
for ( int i = 1 ; i <= nSize ; ++ i) {
lua_pushinteger( L, vPar[i-1]) ;
lua_rawseti( L, -2, i) ;
}
}
catch( ...) {
return false ;
}
return true ;
}
//-------------------------------------------------------------------------------
inline bool
LuaSetParam( lua_State* L, const INTMATRIX& vPar)
{
try {
// recupero prima dimensione
int nDim1 = int( vPar.size()) ;
// creo tavola principale
lua_createtable( L, nDim1, 0) ;
// creo e inserisco tavola per ogni componente
for ( int i = 1 ; i <= nDim1 ; ++ i) {
// recupero seconda dimensione
int nDim2 = int( vPar[i-1].size()) ;
// creo tavola componente
lua_createtable( L, nDim2, 0) ;
for ( int j = 1 ; j <= nDim2 ; ++ j) {
lua_pushinteger( L, vPar[i-1][j-1]) ;
lua_rawseti( L, -2, j) ;
}
// la metto nel vettore
lua_rawseti( L, -2, i) ;
}
}
catch( ...) {
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
inline bool
LuaSetParam( lua_State* L, const DBLVECTOR& vPar)
{
try {
int nSize = int( vPar.size()) ;
lua_createtable( L, nSize, 0) ;
for ( int i = 1 ; i <= nSize ; ++ i) {
lua_pushnumber( L, vPar[i-1]) ;
lua_rawseti( L, -2, i) ;
}
}
catch( ...) {
return false ;
}
return true ;
}
//-------------------------------------------------------------------------------
inline bool
LuaSetParam( lua_State* L, const DBLMATRIX& vPar)
{
try {
// recupero prima dimensione
int nDim1 = int( vPar.size()) ;
// creo tavola principale
lua_createtable( L, nDim1, 0) ;
// creo e inserisco tavola per ogni componente
for ( int i = 1 ; i <= nDim1 ; ++ i) {
// recupero seconda dimensione
int nDim2 = int( vPar[i-1].size()) ;
// creo tavola componente
lua_createtable( L, nDim2, 0) ;
for ( int j = 1 ; j <= nDim2 ; ++ j) {
lua_pushnumber( L, vPar[i-1][j-1]) ;
lua_rawseti( L, -2, j) ;
}
// la metto nel vettore
lua_rawseti( L, -2, i) ;
}
}
catch( ...) {
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
inline bool
LuaSetParam( lua_State* L, const STRVECTOR& vPar)
{
try {
int nSize = int( vPar.size()) ;
lua_createtable( L, nSize, 0) ;
for ( int i = 1 ; i <= nSize ; ++ i) {
lua_pushstring( L, vPar[i-1].c_str()) ;
lua_rawseti( L, -2, i) ;
}
}
catch( ...) {
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
inline bool
LuaSetTabFieldParam( lua_State* L, int nInd, const char* szField)
{
if ( ! lua_istable( L, nInd))
return false ;
if ( ! LuaSetParam( L))
return false ;
int nPos = ( nInd > 0 ? nInd : nInd - 1) ;
int nField ;
if ( FromString( szField, nField))
lua_rawseti( L, nPos, nField) ;
else
lua_setfield( L, nPos, szField) ;
return true ;
}
//----------------------------------------------------------------------------
inline bool
LuaSetTabFieldParam( lua_State* L, int nInd, const std::string& sField)
{
return LuaSetTabFieldParam( L, nInd, sField.c_str()) ;
}
//----------------------------------------------------------------------------
template <class T>
bool
LuaSetTabFieldParam( lua_State* L, int nInd, const char* szField, const T& Val)
{
if ( ! lua_istable( L, nInd))
return false ;
if ( ! LuaSetParam( L, Val))
return false ;
int nPos = ( nInd > 0 ? nInd : nInd - 1) ;
int nField ;
if ( FromString( szField, nField))
lua_rawseti( L, nPos, nField) ;
else
lua_setfield( L, nPos, szField) ;
return true ;
}
//----------------------------------------------------------------------------
template <class T>
bool
LuaSetTabFieldParam( lua_State* L, int nInd, const std::string& sField, const T& Val)
{
return LuaSetTabFieldParam( L, nInd, sField.c_str(), Val) ;
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
template <class T>
bool
LuaGetGlobVar( lua_State* L, const std::string& sVar, T& Val)
{
// se variabile standard
if ( sVar.find( '.') == std::string::npos) {
lua_getglobal( L, sVar.c_str()) ;
bool bOk = LuaGetParam( L, -1, Val) ;
lua_pop( L, 1) ;
return bOk ;
}
// altrimenti campo di tabella
else {
STRVECTOR vsTokens ;
Tokenize( sVar, ".", vsTokens) ;
int nTokenCnt = int( vsTokens.size()) ;
if ( nTokenCnt < 2)
return false ;
if ( lua_getglobal( L, vsTokens[0].c_str()) != LUA_TTABLE) {
lua_pop( L, 1) ;
return false ;
}
for ( int nInd = 1 ; nInd <= nTokenCnt - 2 ; ++ nInd) {
bool bOk ;
int nField ;
if ( FromString( vsTokens[nInd], nField))
bOk = ( lua_rawgeti( L, -1, nField) == LUA_TTABLE) ;
else
bOk = ( lua_getfield( L, -1, vsTokens[nInd].c_str()) == LUA_TTABLE) ;
if ( ! bOk) {
lua_pop( L, nInd + 1) ;
return false ;
}
}
bool bOk = LuaGetTabFieldParam( L, -1, vsTokens[nTokenCnt-1].c_str(), Val) ;
lua_pop( L, nTokenCnt - 1) ;
return bOk ;
}
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
template <class T>
bool
LuaSetGlobVar( lua_State* L, const std::string& sVar, const T& Val)
{
// se variabile standard
if ( sVar.find( '.') == std::string::npos) {
if ( ! LuaSetParam( L, Val))
return false ;
lua_setglobal( L, sVar.c_str()) ;
return true ;
}
// altrimenti campo di tabella
else {
STRVECTOR vsTokens ;
Tokenize( sVar, ".", vsTokens) ;
int nTokenCnt = int( vsTokens.size()) ;
if ( nTokenCnt < 2)
return false ;
if ( lua_getglobal( L, vsTokens[0].c_str()) != LUA_TTABLE) {
lua_pop( L, 1) ;
return false ;
}
for ( int nInd = 1 ; nInd <= nTokenCnt - 2 ; ++ nInd) {
int nField ;
bool bNumber = FromString( vsTokens[nInd], nField) ;
if ( ( bNumber ? lua_rawgeti( L, -1, nField) : lua_getfield( L, -1, vsTokens[nInd].c_str())) != LUA_TTABLE) {
lua_pop( L, 1) ;
lua_newtable( L) ;
lua_pushvalue( L, -1) ;
if ( bNumber)
lua_rawseti( L, -3, nField) ;
else
lua_setfield( L, -3, vsTokens[nInd].c_str()) ;
}
}
bool bOk = LuaSetTabFieldParam( L, -1, vsTokens[nTokenCnt-1].c_str(), Val) ;
lua_pop( L, nTokenCnt - 1) ;
return bOk ;
}
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
inline bool
LuaResetGlobVar( lua_State* L, const std::string& sVar)
{
// se variabile standard
if ( sVar.find( '.') == std::string::npos) {
if ( ! LuaSetParam( L))
return false ;
lua_setglobal( L, sVar.c_str()) ;
return true ;
}
// altrimenti campo di tabella
else {
STRVECTOR vsTokens ;
Tokenize( sVar, ".", vsTokens) ;
int nTokenCnt = int( vsTokens.size()) ;
if ( nTokenCnt < 2)
return false ;
if ( lua_getglobal( L, vsTokens[0].c_str()) != LUA_TTABLE) {
lua_pop( L, 1) ;
return false ;
}
for ( int nInd = 1 ; nInd <= nTokenCnt - 2 ; ++ nInd) {
int nField ;
bool bNumber = FromString( vsTokens[nInd], nField) ;
if ( ( bNumber ? lua_rawgeti( L, -1, nField) : lua_getfield( L, -1, vsTokens[nInd].c_str())) != LUA_TTABLE) {
lua_pop( L, 1) ;
lua_newtable( L) ;
lua_pushvalue( L, -1) ;
if ( bNumber)
lua_rawseti( L, -3, nField) ;
else
lua_setfield( L, -3, vsTokens[nInd].c_str()) ;
}
}
bool bOk = LuaSetTabFieldParam( L, -1, vsTokens[nTokenCnt-1].c_str()) ;
lua_pop( L, 1) ;
return bOk ;
}
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
inline bool
LuaChangeNameGlobVar( lua_State* L, const std::string& sOldVar, const std::string& sNewVar)
{
int nType = lua_getglobal( L, sOldVar.c_str()) ;
if ( nType == LUA_TNONE || nType == LUA_TNIL) {
lua_pop( L, 1) ;
return false ;
}
lua_setglobal( L, sNewVar.c_str()) ;
return true ;
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
inline bool
LuaCreateGlobTable( lua_State* L, const std::string& sVar)
{
try {
lua_newtable( L) ;
lua_setglobal( L, sVar.c_str()) ;
}
catch(...) {
return false ;
}
return true ;
}