void GSMain::Update() { static Lurker* lurker = TheLurker::Instance(); static Game* game = TheGame::Instance(); SceneGraph* scenegraph = GetGameSceneGraph(); lurker->Update(); // Disable pause button if Lurk msg showing // Freeze if displaying tutorial text if (lurker->IsDisplayingMsg()) { m_pauseButton->SetVisible(false); scenegraph->Update(); // DO still update the scene graph? // TODO Also still update Bird? GameObjects* objs = game->GetGameObjects(); for (auto it = objs->begin(); it != objs->end(); ++it) { GameObject* obj = it->second; if (dynamic_cast<Bird*>(obj)) { obj->Update(); } } } else if (m_exitState == IS_EXITING) { m_pauseButton->SetVisible(false); scenegraph->Update(); // DO still update the scene graph? // TODO Also still update Bird? GameObjects* objs = game->GetGameObjects(); for (auto it = objs->begin(); it != objs->end(); ++it) { GameObject* obj = it->second; if (dynamic_cast<Player*>(obj)) { obj->Update(); } Pet* pet = dynamic_cast<Pet*>(obj); if (pet && pet->IsTeleporting()) { pet->Update(); } if (dynamic_cast<Exit*>(obj)) { obj->Update(); } } } else { if (m_exitState == FINISHED_EXITING) { m_exitTimer += TheTimer::Instance()->GetDt(); static const float EXIT_DELAY_2 = ROConfig()->GetFloat("exit-delay-2"); if (m_exitTimer > EXIT_DELAY_2) { game->SetCurrentState(TheGSLevelComplete::Instance()); } } else { m_pauseButton->SetVisible(true); Player* player = Player::GetPlayer(AMJU_P1); float y = -(player->GetPos().y); DepthUpdate(y); TheProcGen::Instance()->AddLayerWhenReady(player->GetPos().x); ThePowerUpManager::Instance()->Update(); game->UpdateGameObjects(); DeleteDeadObjects(); TheCollisionManager::Instance()->Update(); scenegraph->Update(); TheShadowManager::Instance()->Update(); } } }
void ezWorld::Update() { CheckForWriteAccess(); EZ_LOG_BLOCK(m_Data.m_sName.GetData()); { ezStringBuilder sStatName; sStatName.Format("World Update/{0}/Game Object Count", m_Data.m_sName); ezStringBuilder sStatValue; ezStats::SetStat(sStatName, GetObjectCount()); } m_Data.m_Clock.SetPaused(!m_Data.m_bSimulateWorld); m_Data.m_Clock.Update(); // initialize phase { EZ_PROFILE_SCOPE("Initialize Phase"); ProcessComponentsToInitialize(); ProcessUpdateFunctionsToRegister(); ProcessQueuedMessages(ezObjectMsgQueueType::AfterInitialized); } // pre-async phase { EZ_PROFILE_SCOPE("Pre-Async Phase"); ProcessQueuedMessages(ezObjectMsgQueueType::NextFrame); UpdateSynchronous(m_Data.m_UpdateFunctions[ezComponentManagerBase::UpdateFunctionDesc::Phase::PreAsync]); } // async phase { // remove write marker but keep the read marker. Thus no one can mark the world for writing now. Only reading is allowed in async phase. m_Data.m_WriteThreadID = (ezThreadID)0; EZ_PROFILE_SCOPE("Async Phase"); UpdateAsynchronous(); // restore write marker m_Data.m_WriteThreadID = ezThreadUtils::GetCurrentThreadID(); } // post-async phase { EZ_PROFILE_SCOPE("Post-Async Phase"); ProcessQueuedMessages(ezObjectMsgQueueType::PostAsync); UpdateSynchronous(m_Data.m_UpdateFunctions[ezComponentManagerBase::UpdateFunctionDesc::Phase::PostAsync]); } // delete dead objects and update the object hierarchy { EZ_PROFILE_SCOPE("Delete Dead Objects"); DeleteDeadObjects(); DeleteDeadComponents(); } // update transforms { float fInvDelta = 0.0f; // when the clock is paused just use zero const float fDelta = (float)m_Data.m_Clock.GetTimeDiff().GetSeconds(); if (fDelta > 0.0f) fInvDelta = 1.0f / fDelta; EZ_PROFILE_SCOPE("Update Transforms"); m_Data.UpdateGlobalTransforms(fInvDelta); } // post-transform phase { EZ_PROFILE_SCOPE("Post-Transform Phase"); ProcessQueuedMessages(ezObjectMsgQueueType::PostTransform); UpdateSynchronous(m_Data.m_UpdateFunctions[ezComponentManagerBase::UpdateFunctionDesc::Phase::PostTransform]); } // Process again so new component can receive render messages, otherwise we introduce a frame delay. { EZ_PROFILE_SCOPE("Initialize Phase 2"); ProcessComponentsToInitialize(); ProcessQueuedMessages(ezObjectMsgQueueType::AfterInitialized); } // Swap our double buffered stack allocator m_Data.m_StackAllocator.Swap(); }