Example #1
0
void ObjectUpdaterThread::Do()
{
    uint32 last_time = getMSTime();
    uint32 last_cTime = getMSTime();
    uint32 last_gTime = getMSTime();
    uint32 diff = 0;
    uint32 mstime = getMSTime();
    uint32 cFlipper = 1;
    uint32 gFlipper = 3;
    uint32 mapid = m_MapMgr->GetMapId();
    Creature * pCreature;
    GameObject * pGameObject;

    int result;

    int objectUpdate = 1;
    UpdateableCreaturesSet::iterator citr, citr_end, citr_last;
    UpdateableGameobjectsSet::iterator gitr, gitr_end, gitr_last;
    PlayerSet::iterator pitr, pitr_end;
    Player * pPlayer;

    SessionSet::iterator itr, it2;
    WorldSession *session;

    while(ThreadState != WOWD_THREADSTATE_TERMINATE)
    {
        // Provision for pausing this thread.
        if(ThreadState == WOWD_THREADSTATE_PAUSED)
        {
            while(ThreadState == WOWD_THREADSTATE_PAUSED)
            {
                Sleep(200);
            }
        }

        mstime = getMSTime();
        last_time = mstime;

        if(cFlipper == 1)
        {
            citr_end = creatures.end();

            // possible uint32 overflow ~50days
            if(last_cTime > mstime)
                diff = 100;
            else
                diff = mstime - last_cTime;

            citr_end = creatures.end();
            for(citr = creatures.begin(); citr != citr_end;)
            {
                pCreature = (*citr);
                citr_last = citr;
                ++citr;
                if(!pCreature->IsInWorld() || !pCreature->GetMapCell()->IsActive())
                {
                    creatureLock.Acquire();
                    creatures.erase(citr_last);
                    creatureLock.Release();
                }
                else
                    pCreature->Update(diff);
            }
            cFlipper = 0;   // 2 loops away now. :)
            
            // update event holder
            eventholder->Update(diff);

            // update players
            pitr_end = m_MapMgr->_players.end();
            pitr = m_MapMgr->_players.begin();
            for(; pitr != pitr_end;)
            {
                pPlayer = (*pitr);
                ++pitr;
                pPlayer->Update(diff);                
            }

            last_cTime = mstime;
        } else {
            cFlipper = 1;   // Next loop we can have our cake. :)
        }

        if(gFlipper == 3)
        {
            if(last_gTime > mstime)
                diff = 300;
            else
                diff = mstime - last_gTime;

            gitr_end = gameobjects.end();
            for(gitr = gameobjects.begin(); gitr != gitr_end;)
            {
                pGameObject = (*gitr);
                gitr_last = gitr;
                ++gitr;
                if(!pGameObject->IsInWorld() || !pGameObject->GetMapCell()->IsActive())
                {
                    gameobjectLock.Acquire();
                    gameobjects.erase(gitr_last);
                    gameobjectLock.Release();
                }
                else
                    pGameObject->Update(diff);
            }
            gFlipper = 0;
            last_gTime = mstime;
        } else {
            ++gFlipper;
        }

        for(itr = m_MapMgr->Sessions.begin(); itr != m_MapMgr->Sessions.end();)
        {
            session = (*itr);
            it2 = itr;
            ++itr;

            if(result = session->Update(50, m_MapMgr->GetMapId()))
            {
                if(result == 1)
                {
                    // complete deletion
                    sWorld.DeleteSession(session);
                }
                m_MapMgr->Sessions.erase(it2);
            }
        }

        // instance thread object updates are done here
        if(mapid > 1 && mapid != 530)
            m_MapMgr->_UpdateObjects();        

        // Execution time compensation. :)
        mstime = getMSTime();
        if(last_time > mstime)
        {
            Sleep(MAPMGR_SESSION_UPDATE_DELAY);    // uint32 overflow
        }
        else
        {
            mstime = mstime - last_time;
            if(mstime < MAPMGR_SESSION_UPDATE_DELAY)
            {
                mstime = MAPMGR_SESSION_UPDATE_DELAY - mstime;
                if(mstime > 20)
                    Sleep(mstime);
            }
        }
    }
}
Example #2
0
void MapMgr::_PerformObjectDuties()
{
	++mLoopCounter;
	uint32 mstime = getMSTime();
	uint32 difftime = mstime - lastUnitUpdate;
	if(difftime > 500)
		difftime = 500;

	// Update creatures.
	{
		CreatureSet::iterator itr = activeCreatures.begin();
		PetStorageMap::iterator it2 = m_PetStorage.begin();
		Creature * ptr;
		Pet * ptr2;

		for(; itr != activeCreatures.end();)
		{
			ptr = *itr;
			++itr;
			ptr->Update(difftime);
		}

		for(; it2 != m_PetStorage.end();)
		{
			ptr2 = it2->second;
			++it2;

			ptr2->Update(difftime);
		}		
	}

	// Update any events.
	eventHolder.Update(difftime);

	// Update players.
	{
		PlayerStorageMap::iterator itr = m_PlayerStorage.begin();
		Player* ptr;
		for(; itr != m_PlayerStorage.end(); )
		{
			ptr = static_cast< Player* >( (itr->second) );
			++itr;
			if( ptr != NULL )
				ptr->Update( difftime );
		}

		lastUnitUpdate = mstime;
	}

	// Update gameobjects (not on every loop, however)
	if( mLoopCounter % 2 )
	{
		difftime = mstime - lastGameobjectUpdate;

		GameObjectSet::iterator itr = activeGameObjects.begin();
		GameObject * ptr;
		for(; itr != activeGameObjects.end(); )
		{
			ptr = *itr;
			++itr;
			ptr->Update( difftime );
		}

		lastGameobjectUpdate = mstime;
	}	

	// Sessions are updated every loop.
	{
		int result;
		WorldSession * session;
		SessionSet::iterator itr = Sessions.begin();
		SessionSet::iterator it2;

		for(; itr != Sessions.end();)
		{
			session = (*itr);
			it2 = itr;
			++itr;

			if(session->GetInstance() != m_instanceID)
			{
				Sessions.erase(it2);
				continue;
			}

			// Don't update players not on our map.
			// If we abort in the handler, it means we will "lose" packets, or not process this.
			// .. and that could be diasterous to our client :P
			if(session->GetPlayer() && (session->GetPlayer()->GetMapMgr() != this && session->GetPlayer()->GetMapMgr() != 0))
			{
				continue;
			}

			if((result = session->Update(m_instanceID)))
			{
				if(result == 1)
				{
					// complete deletion
					sWorld.DeleteSession(session);
				}
				Sessions.erase(it2);
			}
		}
	}

	// Finally, A9 Building/Distribution
	_UpdateObjects();
}
Example #3
0
void MapMgr::_PerformObjectDuties()
{
	++mLoopCounter;
	uint32 mstime = getMSTime();
	uint32 difftime = mstime - lastUnitUpdate;
	if(difftime > 500)
		difftime = 500;

	// Update any events.
	// we make update of events before objects so in case there are 0 timediff events they do not get deleted after update but on next server update loop
	eventHolder.Update(difftime);

	// Update creatures.
	{
		creature_iterator = activeCreatures.begin();
		Creature* ptr;
		Pet* ptr2;

		for(; creature_iterator != activeCreatures.end();)
		{
			ptr = *creature_iterator;
			++creature_iterator;
			ptr->Update(difftime);
		}

		pet_iterator = m_PetStorage.begin();
		for(; pet_iterator != m_PetStorage.end();)
		{
			ptr2 = pet_iterator->second;
			++pet_iterator;
			ptr2->Update(difftime);
		}
	}

	// Update players.
	{
		PlayerStorageMap::iterator itr = m_PlayerStorage.begin();
		Player* ptr;
		for(; itr != m_PlayerStorage.end();)
		{
			ptr = itr->second;
			++itr;
			ptr->Update(difftime);
		}

		lastUnitUpdate = mstime;
	}

	// Dynamic objects
	//
	// We take the pointer, increment, and update in this order because during the update the DynamicObject might get deleted,
	// rendering the iterator unincrementable. Which causes a crash!
	{
		for(DynamicObjectStorageMap::iterator itr = m_DynamicObjectStorage.begin(); itr != m_DynamicObjectStorage.end();)
		{

			DynamicObject* o = itr->second;
			++itr;

			o->UpdateTargets();
		}
	}

	// Update gameobjects (not on every loop, however)
	if(mLoopCounter % 2)
	{
		difftime = mstime - lastGameobjectUpdate;

		GameObjectSet::iterator itr = activeGameObjects.begin();
		GameObject* ptr;
		for(; itr != activeGameObjects.end();)
		{
			ptr = *itr;
			++itr;
			if(ptr != NULL)
				ptr->Update(difftime);
		}

		lastGameobjectUpdate = mstime;
	}

	// Sessions are updated every loop.
	{
		int result;
		WorldSession* session;
		SessionSet::iterator itr = Sessions.begin();
		SessionSet::iterator it2;

		for(; itr != Sessions.end();)
		{
			session = (*itr);
			it2 = itr;
			++itr;

			if(session->GetInstance() != m_instanceID)
			{
				Sessions.erase(it2);
				continue;
			}

			// Don't update players not on our map.
			// If we abort in the handler, it means we will "lose" packets, or not process this.
			// .. and that could be disastrous to our client :P
			if(session->GetPlayer() && (session->GetPlayer()->GetMapMgr() != this && session->GetPlayer()->GetMapMgr() != 0))
			{
				continue;
			}

			if((result = session->Update(m_instanceID)) != 0)
			{
				if(result == 1)
				{
					// complete deletion
					sWorld.DeleteSession(session);
				}
				Sessions.erase(it2);
			}
		}
	}

	// Finally, A9 Building/Distribution
	_UpdateObjects();
}