#include #include #include #include #include #include Scene& SceneManager::GetCurrentScene() const { if (m_activeScenes.empty()) { throw std::out_of_range("No active scenes are available"); } return *m_activeScenes.front(); } void SceneManager::Update(float dt) { for (const auto& scene : m_activeScenes) { if (m_playing) { scene->Update(dt); } else { scene->CommitPendingAdditions(); } } } void SceneManager::FixedUpdate(float dt) { if (!m_playing) { return; } for (const auto& scene : m_activeScenes) { scene->FixedUpdate(dt); } } void SceneManager::LateUpdate(float dt) { if (!m_playing) { return; } for (const auto& scene : m_activeScenes) { scene->LateUpdate(dt); } } void SceneManager::Render(const RenderContext& ctx) { for (const auto& scene : m_activeScenes) { scene->Render(ctx); } } void SceneManager::RenderImgui(bool* open) { for (const auto& scene : m_activeScenes) { scene->RenderImgui(open); } } void SceneManager::HandleGameObjectDestroy() { for (const auto& scene : m_scenes) { scene->CleanupDestroyedGameObjects(); } } void SceneManager::DestroyGameObjects() { for (const auto& scene : m_scenes) { scene->DestroyGameObjects(); } } void SceneManager::UnloadAllScenes() { for (const auto& scene : m_scenes) { scene->Unload(); } } void SceneManager::HandleSceneDestroy() { for (auto it = m_scenes.begin(); it != m_scenes.end();) { if ((*it)->IsBeingUnloaded()) { const auto activeIt = std::find(m_activeScenes.begin(), m_activeScenes.end(), *it); if (activeIt != m_activeScenes.end()) { m_activeScenes.erase(activeIt); } it = m_scenes.erase(it); } else { ++it; } } // Remove any stale active scenes that are no longer in the scene list. std::erase_if(m_activeScenes, [this](const auto& scene) { return std::find(m_scenes.begin(), m_scenes.end(), scene) == m_scenes.end(); }); } void SceneManager::HandleScene() { HandleGameObjectDestroy(); HandleSceneDestroy(); } void SceneManager::Destroy() { if (m_scenes.empty()) { return; } UnloadAllScenes(); DestroyGameObjects(); HandleGameObjectDestroy(); HandleSceneDestroy(); } void SceneManager::SwitchScene(int index) { if (index < 0 || index >= static_cast(m_scenes.size())) { throw std::out_of_range("Scene index out of range"); } for (const auto& scene : m_activeScenes) { scene->UnloadBindings(); } m_activeScenes.clear(); m_activeScenes.push_back(m_scenes[static_cast(index)]); m_activeScenes.back()->LoadBindings(); } void SceneManager::AddActiveScene(int index) { if (index < 0 || index >= static_cast(m_scenes.size())) { throw std::out_of_range("Scene index out of range"); } const auto& scene = m_scenes[static_cast(index)]; if (std::find(m_activeScenes.begin(), m_activeScenes.end(), scene) == m_activeScenes.end()) { scene->LoadBindings(); m_activeScenes.push_back(scene); } } void SceneManager::RemoveActiveScene(int index) { if (index < 0 || index >= static_cast(m_scenes.size())) { throw std::out_of_range("Scene index out of range"); } const auto& scene = m_scenes[static_cast(index)]; const auto it = std::find(m_activeScenes.begin(), m_activeScenes.end(), scene); if (it != m_activeScenes.end()) { (*it)->UnloadBindings(); m_activeScenes.erase(it); } } int SceneManager::GetActiveSceneId() const { if (m_scenes.empty() || m_activeScenes.empty()) { return -1; } const auto it = std::find(m_scenes.begin(), m_scenes.end(), m_activeScenes.front()); if (it == m_scenes.end()) { return -1; } return static_cast(std::distance(m_scenes.begin(), it)); } Scene& SceneManager::CreateScene(const std::string& name) { const auto scene = std::shared_ptr(new Scene(name)); m_scenes.push_back(scene); if (m_scenes.size() == 1) { m_activeScenes.push_back(scene); } return *scene; }