parent
3bf8200d0f
commit
773329605b
|
|
@ -33,6 +33,7 @@ class Component {
|
|||
struct Entity {
|
||||
std::vector<std::shared_ptr<Component>> components;
|
||||
GameContext *context = nullptr;
|
||||
bool queuedForFree = false;
|
||||
|
||||
/**
|
||||
* Injects the global game context/state so the entity and its components can
|
||||
|
|
@ -93,4 +94,20 @@ struct Entity {
|
|||
c->Update(dt);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the entity for deferred destruction at the end of a systems tick.
|
||||
* Inspired by Godot!
|
||||
*/
|
||||
void QueueFree() { queuedForFree = true; }
|
||||
|
||||
/**
|
||||
* Propagates cleanup call to all owned components so they can release any
|
||||
* resources or references before the entity is destroyed.
|
||||
*/
|
||||
void Cleanup() {
|
||||
for (auto &c : components) {
|
||||
c->Cleanup();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ class SceneManager {
|
|||
* @param args Arguments forwarded to the constructor of the new scene.
|
||||
*/
|
||||
template <typename T, typename... Args> void ChangeScene(Args &&...args);
|
||||
template <typename T, typename... Args> void QueueSceneChange(Args &&...args);
|
||||
|
||||
/**
|
||||
* @brief Changes to the provided next scene, invoking `Exit` on the old scene and
|
||||
|
|
@ -47,6 +48,7 @@ class SceneManager {
|
|||
* @param nextScene The new scene to switch to.
|
||||
*/
|
||||
void ChangeScene(std::unique_ptr<Scene> nextScene);
|
||||
void QueueSceneChange(std::unique_ptr<Scene> nextScene);
|
||||
void Update(float dt);
|
||||
void Draw();
|
||||
|
||||
|
|
@ -54,6 +56,7 @@ class SceneManager {
|
|||
// use unique_ptr to enforce single ownership and ensure proper cleanup on
|
||||
// scene change
|
||||
std::unique_ptr<Scene> current;
|
||||
std::unique_ptr<Scene> queued;
|
||||
};
|
||||
|
||||
class StartMenuScene;
|
||||
|
|
@ -100,10 +103,22 @@ inline void SceneManager::ChangeScene(std::unique_ptr<Scene> nextScene) {
|
|||
}
|
||||
}
|
||||
|
||||
inline void SceneManager::QueueSceneChange(std::unique_ptr<Scene> nextScene) {
|
||||
queued = std::move(nextScene);
|
||||
}
|
||||
|
||||
inline void SceneManager::Update(float dt) {
|
||||
if (queued) {
|
||||
ChangeScene(std::move(queued));
|
||||
}
|
||||
|
||||
if (current) {
|
||||
current->Update(dt);
|
||||
}
|
||||
|
||||
if (queued) {
|
||||
ChangeScene(std::move(queued));
|
||||
}
|
||||
}
|
||||
|
||||
inline void SceneManager::Draw() {
|
||||
|
|
@ -114,7 +129,7 @@ inline void SceneManager::Draw() {
|
|||
|
||||
inline void StartMenuScene::Update(float) {
|
||||
if (IsKeyPressed(KEY_ENTER) || IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
|
||||
manager.ChangeScene<GameplayScene>();
|
||||
manager.QueueSceneChange<GameplayScene>();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -154,7 +169,7 @@ inline void GameplayScene::Enter() {
|
|||
inline void GameplayScene::Update(float dt) {
|
||||
UpdateAllSystems(entities, context, dt);
|
||||
if (wantsDeathScene) {
|
||||
manager.ChangeScene<DeathScene>();
|
||||
manager.QueueSceneChange<DeathScene>();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -198,12 +213,12 @@ inline void GameplayScene::Draw() {
|
|||
|
||||
inline void DeathScene::Update(float) {
|
||||
if (IsKeyPressed(KEY_ENTER) || IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
|
||||
manager.ChangeScene<GameplayScene>();
|
||||
manager.QueueSceneChange<GameplayScene>();
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_ESCAPE)) {
|
||||
manager.ChangeScene<StartMenuScene>();
|
||||
manager.QueueSceneChange<StartMenuScene>();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -217,3 +232,7 @@ inline void DeathScene::Draw() {
|
|||
template <typename T, typename... Args> inline void SceneManager::ChangeScene(Args &&...args) {
|
||||
ChangeScene(std::make_unique<T>(*this, std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
template <typename T, typename... Args> inline void SceneManager::QueueSceneChange(Args &&...args) {
|
||||
QueueSceneChange(std::make_unique<T>(*this, std::forward<Args>(args)...));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include "Entity.hpp"
|
||||
#include "GameContext.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
|
|
@ -60,4 +61,19 @@ void UpdateAllSystems(std::vector<std::shared_ptr<Entity>> &entities, GameContex
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto remover = [](const std::shared_ptr<Entity> &entity) {
|
||||
if (!entity) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (entity->queuedForFree) {
|
||||
entity->Cleanup();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
entities.erase(std::remove_if(entities.begin(), entities.end(), remover), entities.end());
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue