Files
Destrum/destrum/src/Scene/SceneManager.cpp
T

167 lines
4.3 KiB
C++

#include <destrum/Scene/SceneManager.h>
#include <algorithm>
#include <iterator>
#include <stdexcept>
#include <destrum/Scene/Scene.h>
#include <destrum/Util/DeltaTime.h>
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<int>(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<std::size_t>(index)]);
m_activeScenes.back()->LoadBindings();
}
void SceneManager::AddActiveScene(int index) {
if (index < 0 || index >= static_cast<int>(m_scenes.size())) {
throw std::out_of_range("Scene index out of range");
}
const auto& scene = m_scenes[static_cast<std::size_t>(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<int>(m_scenes.size())) {
throw std::out_of_range("Scene index out of range");
}
const auto& scene = m_scenes[static_cast<std::size_t>(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<int>(std::distance(m_scenes.begin(), it));
}
Scene& SceneManager::CreateScene(const std::string& name) {
const auto scene = std::shared_ptr<Scene>(new Scene(name));
m_scenes.push_back(scene);
if (m_scenes.size() == 1) {
m_activeScenes.push_back(scene);
}
return *scene;
}