//---------------------------------------------------------------------------- // 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 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 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 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 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 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 bool LuaSetTabFieldParam( lua_State* L, int nInd, const std::string& sField, const T& Val) { return LuaSetTabFieldParam( L, nInd, sField.c_str(), Val) ; } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- template 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 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 ; }