// Handle filename/line number in string
void CScriptDebugging::LogPCallError( lua_State* luaVM, const SString& strRes, bool bInitialCall )
{   
    std::vector < SString > vecSplit;
    strRes.Split( ":", vecSplit );
                
    if ( vecSplit.size() >= 3 )
    {
        // File+line info present
        SString strFile = vecSplit[ 0 ];
        int     iLine   = atoi( vecSplit[ 1 ] );
        
        // Get the message string (we cannot use vecSplit here as the message itself could contain ':')
        auto pos = strRes.find ( ':', vecSplit[0].length () + vecSplit[1].length () ) ;
        SString strMsg = strRes.SubStr ( pos+2 );
        
        if ( iLine == 0 && bInitialCall )
        {
            // Location hint for compiled scripts
            LogError ( SLuaDebugInfo( strFile, iLine ), "(global scope) %s", *strMsg );
        }
        else
            LogError ( SLuaDebugInfo( strFile, iLine ), "%s", *strMsg );
    }
    else
    {
        // File+line info not present
        LogError( luaVM, "%s", strRes.c_str () );
    }
}
Beispiel #2
0
// Handle filename/line number in string
void CScriptDebugging::LogPCallError( lua_State* luaVM, const SString& strRes, bool bInitialCall )
{   
    std::vector < SString > vecSplit;
    strRes.Split( ":", vecSplit );
                
    if ( vecSplit.size() >= 3 )
    {
        // File+line info present
        SString strFile = vecSplit[ 0 ];
        int     iLine   = atoi( vecSplit[ 1 ] );
        SString strMsg  = vecSplit[2].SubStr( 1 );
                    
        if ( iLine == 0 && bInitialCall )
        {
            // Location hint for compiled scripts
            LogError ( SLuaDebugInfo( strFile, iLine ), "(global scope) %s", *strMsg );
        }
        else
            LogError ( SLuaDebugInfo( strFile, iLine ), "%s", *strMsg );
    }
    else
    {
        // File+line info not present
        LogError( luaVM, "%s", strRes.c_str () );
    }
}
Beispiel #3
0
void CLuaTimerManager::DoPulse ( CLuaMain* pLuaMain )
{
    assert ( m_ProcessQueue.empty () );
    assert ( !m_pPendingDelete );
    assert ( !m_pProcessingTimer );

    CTickCount llCurrentTime = CTickCount::Now ();

    // Use a separate queue to avoid trouble
    // What kind of problems are we trying to avoid? Doing a copy each frame isn't quite efficient
    for ( CFastList < CLuaTimer* > ::const_iterator iter = m_TimerList.begin () ; iter != m_TimerList.end () ; ++iter )
        m_ProcessQueue.push_back ( *iter );

    while ( !m_ProcessQueue.empty () )
    {
        m_pProcessingTimer = m_ProcessQueue.front ();
        m_ProcessQueue.pop_front ();

        CTickCount llStartTime = m_pProcessingTimer->GetStartTime ();
        CTickCount llDelay = m_pProcessingTimer->GetDelay ();
        unsigned int uiRepeats = m_pProcessingTimer->GetRepeats ();

        // Is the time up and is not being deleted
        if ( llCurrentTime >= ( llStartTime + llDelay ) )
        {
            // Set our debug info
            g_pGame->GetScriptDebugging()->SaveLuaDebugInfo ( m_pProcessingTimer->GetLuaDebugInfo ( ) );
            
            m_pProcessingTimer->ExecuteTimer ( pLuaMain );
            // Reset
            g_pGame->GetScriptDebugging()->SaveLuaDebugInfo ( SLuaDebugInfo() );

            // If this is the last repeat, remove
            if ( uiRepeats == 1 )
            {
                RemoveTimer ( m_pProcessingTimer );
            }
            else
            {
                // Decrease repeats if not infinite
                if ( uiRepeats != 0 )
                    m_pProcessingTimer->SetRepeats ( uiRepeats - 1 );

                m_pProcessingTimer->SetStartTime ( llCurrentTime );
            }
        }

        // Finally cleanup timer if it was removed during processing
        if ( m_pPendingDelete )
        {
            assert ( m_pPendingDelete == m_pProcessingTimer );
            m_pProcessingTimer = NULL;
            delete m_pPendingDelete;
            m_pPendingDelete = NULL;
        }
        else
            m_pProcessingTimer = NULL;
    }
}
//
// Get best debug info we possibly can from the relevent lua state
//
const SLuaDebugInfo& CScriptDebugging::GetLuaDebugInfo( lua_State * luaVM )
{
    static SLuaDebugInfo scriptDebugInfo;
    scriptDebugInfo = SLuaDebugInfo();

    // Get a VM from somewhere
    if ( !luaVM && !m_LuaMainStack.empty () )
        luaVM = m_LuaMainStack.back ()->GetVM ();

    // Lua oop found at level 4 added one just in case it somehow ends up deeper due to nested calls
    for ( int level = 1; level <= 5; level++ )
    {
        lua_Debug debugInfo;
        if ( luaVM && lua_getstack ( luaVM, level, &debugInfo ) )
        {
            lua_getinfo ( luaVM, "nlS", &debugInfo );
            // Lua oop handlers get marked as "C", ignore these as the information we want is further up the stack (typically level 4+)
            if ( strcmp(debugInfo.source, "=[C]") != 0 )
            {
                 // Make sure this function isn't defined in a string (eg: from runcode)
                if ( debugInfo.source[0] == '@' )
                {
                    // Get and store the location of the debug message
                    scriptDebugInfo.strFile = debugInfo.source + 1;
                    scriptDebugInfo.iLine = debugInfo.currentline;
                    scriptDebugInfo.infoType = DEBUG_INFO_FILE_AND_LINE;
                    // Stop here as we now have the best info
                    break;
                }
                else
                {
                    scriptDebugInfo.strShortSrc = debugInfo.short_src;
                    scriptDebugInfo.infoType = DEBUG_INFO_SHORT_SRC;
                    // Try other levels to see if we can get the calling file
                }
            }
        }
        else
        {
            // Use saved info if set
            if ( m_SavedLuaDebugInfo.infoType != DEBUG_INFO_NONE )
            {
                scriptDebugInfo = m_SavedLuaDebugInfo;
            }
            // No point in trying other levels as lua_getstack will fail
            break;
        }
    }

    return scriptDebugInfo;
}