void CMapEventManager::GetHandles ( CLuaMain* pLuaMain, const char* szName, lua_State* luaVM )
{
    unsigned int uiIndex = 0;
    EventsIterPair itPair = m_EventsMap.equal_range ( szName );
    for ( EventsIter iter = itPair.first ; iter != itPair.second ; ++iter )
    {
        CMapEvent* pMapEvent = iter->second;

        // Is it not being destroyed?
        if ( !pMapEvent->IsBeingDestroyed () )
        {
            // Same lua main?
            if ( pMapEvent->GetVM () == pLuaMain )
            {
                // Same name?
                dassert ( strcmp ( pMapEvent->GetName (), szName ) == 0 );
                {
                    lua_pushnumber ( luaVM, ++uiIndex );
                    lua_getref ( luaVM, pMapEvent->GetLuaFunction ().ToInt() );
                    lua_settable ( luaVM, -3 );
                }
            }
        }
    }
}
Beispiel #2
0
bool CMapEventManager::HandleExists ( CLuaMain* pLuaMain, const char* szName, int iLuaFunction )
{
    // Return true if we find an event which matches the handle
    list < CMapEvent* > ::const_iterator iter = m_Events.begin ();
    for ( ; iter != m_Events.end (); iter++ )
    {
        CMapEvent* pMapEvent = *iter;

        // Is it not being destroyed?
        if ( !pMapEvent->IsBeingDestroyed () )
        {
            // Same lua main?
            if ( pMapEvent->GetVM () == pLuaMain )
            {
                // Same name?
                if ( strcmp ( pMapEvent->GetName (), szName ) == 0 )
                {
                    // Same lua function?
                    if ( pMapEvent->GetLuaFunction () == iLuaFunction )
                    {
                        // It exists
                        return true;
                    }
                }
            }
        }
    }

    // Doesn't exist
    return false;
}
bool CMapEventManager::HandleExists ( CLuaMain* pLuaMain, const char* szName, const CLuaFunctionRef& iLuaFunction )
{
    // Return true if we find an event which matches the handle
    EventsIterPair itPair = m_EventsMap.equal_range ( szName );
    for ( EventsIter iter = itPair.first ; iter != itPair.second ; ++iter )
    {
        CMapEvent* pMapEvent = iter->second;

        // Is it not being destroyed?
        if ( !pMapEvent->IsBeingDestroyed () )
        {
            // Same lua main?
            if ( pMapEvent->GetVM () == pLuaMain )
            {
                // Same name?
                dassert ( strcmp ( pMapEvent->GetName (), szName ) == 0 );
                {
                    // Same lua function?
                    if ( pMapEvent->GetLuaFunction () == iLuaFunction )
                    {
                        // It exists
                        return true;
                    }
                }
            }
        }
    }

    // Doesn't exist
    return false;
}
bool CMapEventManager::Delete ( CLuaMain* pLuaMain, const char* szName, const CLuaFunctionRef& iLuaFunction )
{
    // Delete all the events with matching names
    bool bRemovedSomeone = false;

    EventsIter iter = m_EventsMap.begin ();
    while ( iter != m_EventsMap.end () )
    {
        CMapEvent* pMapEvent = iter->second;

        // Matching VM?
        if ( pLuaMain == pMapEvent->GetVM () )
        {
            // If name supplied, check name and function
            if ( !szName || ( ( strcmp ( pMapEvent->GetName (), szName ) == 0 ) && ( pMapEvent->GetLuaFunction () == iLuaFunction ) ) )
            {
                // Not alredy being destroyed?
                if ( !pMapEvent->IsBeingDestroyed () )
                {
                    // Are we in an event handler?
                    if ( m_bIteratingList )
                    {
                        // Put it in the trashcan
                        pMapEvent->SetBeingDestroyed ( true );
                        m_TrashCan.push_back ( pMapEvent );

                        // Remember that we deleted something
                        bRemovedSomeone = true;
                    }
                    else
                    {
                        // Delete the object
                        delete pMapEvent;

                        // Remove from list and remember that we deleted something
                        m_EventsMap.erase ( iter++ );
                        bRemovedSomeone = true;
                        continue;
                    }
                }
            }
        }

        // Increment iterator
        ++iter;
    }

    m_bHasEvents = !m_EventsMap.empty ();

    // Return whether we actually destroyed someone or not
    return bRemovedSomeone;
}
Beispiel #5
0
bool CMapEventManager::Delete ( CLuaMain* pLuaMain, const char* szName, int iLuaFunction )
{
    // Delete all the events with matching names
    bool bRemovedSomeone = false;
    CMapEvent* pMapEvent = NULL;
    list < CMapEvent* > ::iterator iter = m_Events.begin ();
    while ( iter != m_Events.end () )
    {
        pMapEvent = *iter;

        // Matching VM and name?
        if ( pLuaMain == pMapEvent->GetVM () &&
             strcmp ( pMapEvent->GetName (), szName ) == 0 )
        {
            // Same lua function?
            if ( pMapEvent->GetLuaFunction () == iLuaFunction )
            {
                // Not alredy being destroyed?
                if ( !pMapEvent->IsBeingDestroyed () )
                {
                    // Are we in an event handler?
                    if ( m_bIteratingList )
                    {
                        // Put it in the trashcan
                        pMapEvent->SetBeingDestroyed ( true );
                        m_TrashCan.push_back ( *iter );

                        // Remember that we deleted something
                        bRemovedSomeone = true;
                    }
                    else
                    {
                        // Delete the object
                        delete pMapEvent;

                        // Remove from list and remember that we deleted something
                        iter = m_Events.erase ( iter );
                        bRemovedSomeone = true;
                        continue;
                    }
                }
            }
        }

        // Increment iterator
        iter++;
    }

    // Return whether we actually destroyed someone or not
    return bRemovedSomeone;
}
void CMapEventManager::DeleteAll ( void )
{
    // Delete all the events
    EventsIter iter = m_EventsMap.begin ();
    while ( iter != m_EventsMap.end () )
    {
        CMapEvent* pMapEvent = iter->second;

        // Delete it if it's not already being destroyed
        if ( !pMapEvent->IsBeingDestroyed () )
        {
            delete pMapEvent;
            m_EventsMap.erase ( iter++ );
        }
        else
            ++iter;
    }
    m_bHasEvents = !m_EventsMap.empty ();
}
Beispiel #7
0
void CMapEventManager::Delete ( CLuaMain* pLuaMain )
{
    // Delete all the events with matching lua VM's
    CMapEvent* pMapEvent = NULL;
    list < CMapEvent* > ::iterator iter = m_Events.begin ();
    while ( iter != m_Events.end () )
    {
        pMapEvent = *iter;

        // Maching VM's?
        if ( pMapEvent->GetVM () == pLuaMain )
        {
            // Not already being destroyed?
            if ( !pMapEvent->IsBeingDestroyed () )
            {
                // Are we iterating the list?
                if ( m_bIteratingList )
                {
                    // Add it to trashcan and mark as being destroyed
                    pMapEvent->SetBeingDestroyed ( true );
                    m_TrashCan.push_back ( pMapEvent );
                }
                else
                {
                    // Delete the event and continue from where we left.
                    // Remember to subtract from our iterator or we'll delete only every other element.
                    delete pMapEvent;
                    iter = m_Events.erase ( iter );
                    continue;
                }
            }
        }

        // Increment iterator
        ++iter;
    }
}
bool CMapEventManager::Call ( const char* szName, const CLuaArguments& Arguments, class CClientEntity* pSource, class CClientEntity* pThis )
{
    // Check if no events
    if ( !m_bHasEvents )
        return false;

    // Check if no events with a name match
    EventsIterPair itPair = m_EventsMap.equal_range ( szName );
    if ( itPair.first == itPair.second )
        return false;

    TIMEUS startTimeCall = GetTimeUs ();
    SString strStatus;

    // Check for multi-threading slipups
    assert ( IsMainThread () );

    // Call all the events with matching names
    bool bCalled = false;
    bool bIsAlreadyIterating = m_bIteratingList;
    m_bIteratingList = true;

    // Copy the results into a array in case m_EventsMap is modified during the call
    std::vector< CMapEvent* > matchingEvents;
    for ( EventsIter iter = itPair.first ; iter != itPair.second ; ++iter )
        matchingEvents.push_back(iter->second);

    for ( std::vector< CMapEvent* >::iterator iter = matchingEvents.begin() ; iter != matchingEvents.end() ; ++iter )
    {
        CMapEvent* pMapEvent = *iter;

        // If it's not being destroyed
        if ( !pMapEvent->IsBeingDestroyed () )
        {
            // Compare the names
            dassert ( strcmp ( pMapEvent->GetName (), szName ) == 0 );
            {
                // Call if propagated?
                if ( pSource == pThis || pMapEvent->IsPropagated () )
                {
                    // Grab the current VM
                    lua_State* pState = pMapEvent->GetVM ()->GetVM ();

                    LUA_CHECKSTACK ( pState, 1 );   // Ensure some room

                    #if MTA_DEBUG
                        int luaStackPointer = lua_gettop ( pState );
                    #endif

                    TIMEUS startTime = GetTimeUs();

                    // Aspect ratio adjustment bodges
                    if ( pMapEvent->ShouldAllowAspectRatioAdjustment() )
                    {
                        g_bAllowAspectRatioAdjustment = true;
                        if ( pMapEvent->ShouldForceAspectRatioAdjustment() )
                            g_pCore->GetGraphics()->SetAspectRatioAdjustmentEnabled( true );
                    }

                    // Record event for the crash dump writer
                    static bool bEnabled = ( g_pCore->GetDiagnosticDebug () == EDiagnosticDebug::LUA_TRACE_0000 );
                    if ( bEnabled )
                        g_pCore->LogEvent ( 0, "Lua Event", pMapEvent->GetVM ()->GetScriptName (), szName );

                    // Store the current values of the globals
                    lua_getglobal ( pState, "source" );
                    CLuaArgument OldSource ( pState, -1 );
                    lua_pop( pState, 1 );

                    lua_getglobal ( pState, "this" );
                    CLuaArgument OldThis ( pState, -1 );
                    lua_pop( pState, 1 );

                    lua_getglobal ( pState, "sourceResource" );
                    CLuaArgument OldResource ( pState, -1 );
                    lua_pop( pState, 1 );

                    lua_getglobal ( pState, "sourceResourceRoot" );
                    CLuaArgument OldResourceRoot ( pState, -1 );
                    lua_pop( pState, 1 );

                    lua_getglobal ( pState, "eventName" );
                    CLuaArgument OldEventName ( pState, -1 );
                    lua_pop( pState, 1 );

                    // Set the "source", "this", "sourceResource" and the "sourceResourceRoot" globals on that VM
                    lua_pushelement ( pState, pSource );
                    lua_setglobal ( pState, "source" );

                    lua_pushelement ( pState, pThis );
                    lua_setglobal ( pState, "this" );

                    CLuaMain* pLuaMain = g_pClientGame->GetScriptDebugging()->GetTopLuaMain();
                    CResource* pSourceResource = pLuaMain ? pLuaMain->GetResource() : NULL;
                    if ( pSourceResource )
                    {
                        lua_pushresource ( pState, pSourceResource );
                        lua_setglobal ( pState, "sourceResource" );

                        lua_pushelement ( pState, pSourceResource->GetResourceDynamicEntity() );
                        lua_setglobal ( pState, "sourceResourceRoot" );
                    }
                    else
                    {
                        lua_pushnil ( pState );
                        lua_setglobal ( pState, "sourceResource" );

                        lua_pushnil ( pState );
                        lua_setglobal ( pState, "sourceResourceRoot" );
                    }

                    lua_pushstring ( pState, szName );
                    lua_setglobal ( pState, "eventName" );
                    
                    // Call it
                    pMapEvent->Call ( Arguments );
                    bCalled = true;

                    // Reset the globals on that VM
                    OldSource.Push ( pState );
                    lua_setglobal ( pState, "source" );

                    OldThis.Push ( pState );
                    lua_setglobal ( pState, "this" );                

                    OldResource.Push ( pState );
                    lua_setglobal ( pState, "sourceResource" );

                    OldResourceRoot.Push ( pState );
                    lua_setglobal ( pState, "sourceResourceRoot" );

                    OldEventName.Push ( pState );
                    lua_setglobal ( pState, "eventName" );

                    #if MTA_DEBUG
                        assert ( lua_gettop ( pState ) == luaStackPointer );
                    #endif

                    // Aspect ratio adjustment bodges
                    if ( pMapEvent->ShouldAllowAspectRatioAdjustment() )
                    {
                        g_pCore->GetGraphics()->SetAspectRatioAdjustmentEnabled( false );
                        g_bAllowAspectRatioAdjustment = false;
                    }

                    TIMEUS deltaTimeUs = GetTimeUs() - startTime;

                    if ( deltaTimeUs > 3000 ) 
                        if ( IS_TIMING_CHECKPOINTS() )
                            strStatus += SString ( " (%s %d ms)", pMapEvent->GetVM ()->GetScriptName (), deltaTimeUs / 1000 );

                    CClientPerfStatLuaTiming::GetSingleton ()->UpdateLuaTiming ( pMapEvent->GetVM (), szName, deltaTimeUs );
                }
            }
        }
    }

    // Clean out the trash if we're no longer calling events.
    if ( !bIsAlreadyIterating )
    {
        TakeOutTheTrash ();

        // We're no longer iterating the list
        m_bIteratingList = false;
    }

    if ( IS_TIMING_CHECKPOINTS() )
    {
        TIMEUS deltaTimeUs = GetTimeUs() - startTimeCall;
        if ( deltaTimeUs > 5000 )
            TIMING_DETAIL( SString ( "CMapEventManager::Call ( %s, ... ) took %d ms ( %s )", szName, deltaTimeUs / 1000, *strStatus ) );
    }

    // Return whether we called atleast one func or not
    return bCalled;
}
Beispiel #9
0
bool CMapEventManager::Call ( const char* szName, const CLuaArguments& Arguments, class CClientEntity* pSource, class CClientEntity* pThis )
{
    // Call all the events with matching names
    bool bCalled = false;
    CMapEvent* pMapEvent;
    bool bIsAlreadyIterating = m_bIteratingList;
    m_bIteratingList = true;
    list < CMapEvent* > ::const_iterator iter = m_Events.begin ();
    for ( ; iter != m_Events.end (); iter++ )
    {
        pMapEvent = *iter;

        // If it's not being destroyed
        if ( !pMapEvent->IsBeingDestroyed () )
        {
            // Compare the names
            if ( strcmp ( pMapEvent->GetName (), szName ) == 0 )
            {
                // Call if propagated?
                if ( pSource == pThis || pMapEvent->IsPropagated () )
                {
                    // Grab the current VM
                    lua_State* pState = pMapEvent->GetVM ()->GetVM ();
                    #if MTA_DEBUG
                        int luaStackPointer = lua_gettop ( pState );
                    #endif

                    // Store the current values of the globals
                    lua_getglobal ( pState, "source" );
                    CLuaArgument OldSource ( pState, -1 );
                    lua_pop( pState, 1 );

                    lua_getglobal ( pState, "this" );
                    CLuaArgument OldThis ( pState, -1 );
                    lua_pop( pState, 1 );

                    lua_getglobal ( pState, "sourceResource" );
                    CLuaArgument OldResource ( pState, -1 );
                    lua_pop( pState, 1 );

                    lua_getglobal ( pState, "sourceResourceRoot" );
                    CLuaArgument OldResourceRoot ( pState, -1 );
                    lua_pop( pState, 1 );

                    lua_getglobal ( pState, "eventName" );
                    CLuaArgument OldEventName ( pState, -1 );
                    lua_pop( pState, 1 );

                    // Set the "source", "this", "sourceResource" and the "sourceResourceRoot" globals on that VM
                    lua_pushelement ( pState, pSource );
                    lua_setglobal ( pState, "source" );

                    lua_pushelement ( pState, pThis );
                    lua_setglobal ( pState, "this" );

                    lua_pushresource ( pState, pMapEvent->GetVM()->GetResource() );
                    lua_setglobal ( pState, "sourceResource" );

                    lua_pushelement ( pState, pMapEvent->GetVM()->GetResource()->GetResourceDynamicEntity() );
                    lua_setglobal ( pState, "sourceResourceRoot" );

                    lua_pushstring ( pState, szName );
                    lua_setglobal ( pState, "eventName" );
                    
                    // Call it
                    pMapEvent->Call ( Arguments );
                    bCalled = true;

                    // Reset the globals on that VM
                    OldSource.Push ( pState );
                    lua_setglobal ( pState, "source" );

                    OldThis.Push ( pState );
                    lua_setglobal ( pState, "this" );                

                    OldResource.Push ( pState );
                    lua_setglobal ( pState, "sourceResource" );

                    OldResourceRoot.Push ( pState );
                    lua_setglobal ( pState, "sourceResourceRoot" );

                    OldEventName.Push ( pState );
                    lua_setglobal ( pState, "eventName" );

                    #if MTA_DEBUG
                        assert ( lua_gettop ( pState ) == luaStackPointer );
                    #endif
                }
            }
        }
    }

    // Clean out the trash if we're no longer calling events.
    if ( !bIsAlreadyIterating )\
    {
        TakeOutTheTrash ();

        // We're no longer iterating the list
        m_bIteratingList = false;
    }

    // Return whether we called atleast one func or not
    return bCalled;
}