//---------------------------------------------------------------------------- // 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 ; 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 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) ; 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) ; 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 { std::string sTab, sField ; SplitFirst( sVar, ".", sTab, sField) ; lua_getglobal( L, sTab.c_str()) ; bool bOk = LuaGetTabFieldParam( L, -1, sField.c_str(), Val) ; lua_pop( L, 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 { std::string sTab, sField ; SplitFirst( sVar, ".", sTab, sField) ; lua_getglobal( L, sTab.c_str()) ; bool bOk = LuaSetTabFieldParam( L, -1, sField.c_str(), Val) ; lua_pop( L, 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 { std::string sTab, sField ; SplitFirst( sVar, ".", sTab, sField) ; lua_getglobal( L, sTab.c_str()) ; bool bOk = LuaSetTabFieldParam( L, -1, sField.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 ; }