parent
3bf8200d0f
commit
773329605b
|
|
@ -33,6 +33,7 @@ class Component {
|
||||||
struct Entity {
|
struct Entity {
|
||||||
std::vector<std::shared_ptr<Component>> components;
|
std::vector<std::shared_ptr<Component>> components;
|
||||||
GameContext *context = nullptr;
|
GameContext *context = nullptr;
|
||||||
|
bool queuedForFree = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injects the global game context/state so the entity and its components can
|
* Injects the global game context/state so the entity and its components can
|
||||||
|
|
@ -93,4 +94,20 @@ struct Entity {
|
||||||
c->Update(dt);
|
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.
|
* @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 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
|
* @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.
|
* @param nextScene The new scene to switch to.
|
||||||
*/
|
*/
|
||||||
void ChangeScene(std::unique_ptr<Scene> nextScene);
|
void ChangeScene(std::unique_ptr<Scene> nextScene);
|
||||||
|
void QueueSceneChange(std::unique_ptr<Scene> nextScene);
|
||||||
void Update(float dt);
|
void Update(float dt);
|
||||||
void Draw();
|
void Draw();
|
||||||
|
|
||||||
|
|
@ -54,6 +56,7 @@ class SceneManager {
|
||||||
// use unique_ptr to enforce single ownership and ensure proper cleanup on
|
// use unique_ptr to enforce single ownership and ensure proper cleanup on
|
||||||
// scene change
|
// scene change
|
||||||
std::unique_ptr<Scene> current;
|
std::unique_ptr<Scene> current;
|
||||||
|
std::unique_ptr<Scene> queued;
|
||||||
};
|
};
|
||||||
|
|
||||||
class StartMenuScene;
|
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) {
|
inline void SceneManager::Update(float dt) {
|
||||||
|
if (queued) {
|
||||||
|
ChangeScene(std::move(queued));
|
||||||
|
}
|
||||||
|
|
||||||
if (current) {
|
if (current) {
|
||||||
current->Update(dt);
|
current->Update(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (queued) {
|
||||||
|
ChangeScene(std::move(queued));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void SceneManager::Draw() {
|
inline void SceneManager::Draw() {
|
||||||
|
|
@ -114,7 +129,7 @@ inline void SceneManager::Draw() {
|
||||||
|
|
||||||
inline void StartMenuScene::Update(float) {
|
inline void StartMenuScene::Update(float) {
|
||||||
if (IsKeyPressed(KEY_ENTER) || IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
|
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) {
|
inline void GameplayScene::Update(float dt) {
|
||||||
UpdateAllSystems(entities, context, dt);
|
UpdateAllSystems(entities, context, dt);
|
||||||
if (wantsDeathScene) {
|
if (wantsDeathScene) {
|
||||||
manager.ChangeScene<DeathScene>();
|
manager.QueueSceneChange<DeathScene>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -198,12 +213,12 @@ inline void GameplayScene::Draw() {
|
||||||
|
|
||||||
inline void DeathScene::Update(float) {
|
inline void DeathScene::Update(float) {
|
||||||
if (IsKeyPressed(KEY_ENTER) || IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
|
if (IsKeyPressed(KEY_ENTER) || IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
|
||||||
manager.ChangeScene<GameplayScene>();
|
manager.QueueSceneChange<GameplayScene>();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsKeyPressed(KEY_ESCAPE)) {
|
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) {
|
template <typename T, typename... Args> inline void SceneManager::ChangeScene(Args &&...args) {
|
||||||
ChangeScene(std::make_unique<T>(*this, std::forward<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 "Entity.hpp"
|
||||||
#include "GameContext.hpp"
|
#include "GameContext.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#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