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 ); } } } } }
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::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::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; }
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; }
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; }
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; }