Skip to content

Commit 2c7d4cb

Browse files
authored
Scene switching entity clean up bug (#29)
Fixing bug with scene switching where all scene nodes weren't being cleaned up.
1 parent 7c4f9f2 commit 2c7d4cb

File tree

6 files changed

+148
-122
lines changed

6 files changed

+148
-122
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ RELEASE_FLAGS = -DHAVE_SNPRINTF=1
2525
BUILD_OBJECT := $(PROJECT_NAME).exe
2626
TEST_BUILD_OBJECT := test_$(PROJECT_NAME).exe
2727

28-
SRC = $(wildcard src/main.cpp src/core/*.cpp src/core/math/*.cpp src/core/utils/*.cpp src/core/rendering/*.cpp src/core/rendering/shader/*.cpp src/core/input/*.cpp src/core/audio/*.cpp src/core/timer/*.cpp src/core/scripting/python/*.cpp src/core/ecs/*.cpp src/core/ecs/system/systems/*.cpp src/core/networking/*.cpp include/stb_image/*.cpp)
28+
SRC = $(wildcard src/main.cpp src/core/*.cpp src/core/math/*.cpp src/core/utils/*.cpp src/core/rendering/*.cpp src/core/rendering/shader/*.cpp src/core/input/*.cpp src/core/audio/*.cpp src/core/timer/*.cpp src/core/scripting/python/*.cpp src/core/ecs/*.cpp src/core/ecs/system/systems/*.cpp src/core/scene/*.cpp src/core/networking/*.cpp include/stb_image/*.cpp)
2929
SRC_C = $(wildcard lib/glad.c include/kuba_zip/zip.c)
3030

3131
OBJ = $(SRC:.cpp=.o)
3232
OBJ_C = $(SRC_C:.c=.o)
3333

34-
TEST_SRC = $(wildcard src/test/*.cpp src/test/unit/*.cpp src/core/*.cpp src/core/math/*.cpp src/core/utils/*.cpp src/core/rendering/*.cpp src/core/rendering/shader/*.cpp src/core/input/*.cpp src/core/timer/*.cpp src/core/scripting/python/*.cpp src/core/audio/*.cpp src/core/ecs/*.cpp src/core/ecs/system/systems/*.cpp src/core/networking/*.cpp include/stb_image/*.cpp)
34+
TEST_SRC = $(wildcard src/test/*.cpp src/test/unit/*.cpp src/core/*.cpp src/core/math/*.cpp src/core/utils/*.cpp src/core/rendering/*.cpp src/core/rendering/shader/*.cpp src/core/input/*.cpp src/core/timer/*.cpp src/core/scripting/python/*.cpp src/core/audio/*.cpp src/core/ecs/*.cpp src/core/ecs/system/systems/*.cpp src/core/scene/*.cpp src/core/networking/*.cpp include/stb_image/*.cpp)
3535
TEST_OBJ = $(TEST_SRC:.cpp=.o)
3636

3737
EXPORT_PACKAGE_DIR := export_package

_version.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"version": "0.50.0"
2+
"version": "0.51.0"
33
}

src/core/ecs/entity_component_orchestrator.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,6 @@ void EntityComponentOrchestrator::NewEntity(SceneNode sceneNode) {
1818
}
1919
}
2020

21-
void EntityComponentOrchestrator::NewEntityAddChild(Entity parent, Entity child) {
22-
SceneNode childNode = SceneNode{.entity = child, .parent = parent};
23-
AddChildToEntityScene(childNode.parent, childNode.entity);
24-
NodeComponent nodeComponent = componentManager->GetComponent<NodeComponent>(childNode.entity);
25-
nodeNameToEntityMap.emplace(nodeComponent.name, childNode.entity);
26-
entitySystemManager->OnEntityTagsUpdatedSystemsHook(child, {}, nodeComponent.tags);
27-
CallStartOnScriptInstances(childNode);
28-
}
29-
3021
void EntityComponentOrchestrator::QueueEntityForDeletion(Entity entity) {
3122
entitiesQueuedForDeletion.emplace_back(entity);
3223
}
@@ -99,6 +90,16 @@ void EntityComponentOrchestrator::AddChildToEntityScene(Entity parentEntity, Ent
9990
sceneManager->AddChild(parentEntity, childEntity);
10091
}
10192

93+
// Used when adding a new entity to a scene from scripting
94+
void EntityComponentOrchestrator::NewEntityAddChild(Entity parent, Entity child) {
95+
SceneNode childNode = SceneNode{.entity = child, .parent = parent};
96+
AddChildToEntityScene(childNode.parent, childNode.entity);
97+
NodeComponent nodeComponent = componentManager->GetComponent<NodeComponent>(childNode.entity);
98+
nodeNameToEntityMap.emplace(nodeComponent.name, childNode.entity);
99+
entitySystemManager->OnEntityTagsUpdatedSystemsHook(child, {}, nodeComponent.tags);
100+
CallStartOnScriptInstances(childNode);
101+
}
102+
102103
// Will be the function to initialize stuff for a scene
103104
void EntityComponentOrchestrator::RegisterSceneNodeInstances(SceneNode sceneNode) {
104105
AddChildToEntityScene(sceneNode.parent, sceneNode.entity);

src/core/scene/scene.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define SCENE_H
33

44
#include <vector>
5+
#include "../ecs/entity/entity.h"
56

67
struct SceneNode {
78
Entity entity = NULL_ENTITY;

src/core/scene/scene_manager.cpp

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,120 @@
11
#include "scene_manager.h"
2+
3+
SceneManager::SceneManager(SceneContext *vSceneContext, EntityManager *vEntityManager, ComponentManager *vComponentManager, AssetManager *vAssetManager) :
4+
sceneContext(vSceneContext), entityManager(vEntityManager), componentManager(vComponentManager), assetManager(vAssetManager) {
5+
timerManager = TimerManager::GetInstance();
6+
archiveLoader = ArchiveLoader::GetInstance();
7+
sceneNodeJsonParser = SceneNodeJsonParser(entityManager, componentManager, assetManager, timerManager);
8+
}
9+
10+
Scene SceneManager::GetCurrentScene() {
11+
return currentScene;
12+
}
13+
14+
SceneNode SceneManager::GetEntitySceneNode(Entity entity) {
15+
if (!HasEntitySceneNode(entity)) {
16+
Logger::GetInstance()->Error("Doesn't have entity " + std::to_string(entity));
17+
}
18+
assert(HasEntitySceneNode(entity) && "Tried to get scene node that doesn't exist!");
19+
return entityToSceneNodeMap[entity];
20+
}
21+
22+
bool SceneManager::HasEntitySceneNode(Entity entity) const {
23+
return entityToSceneNodeMap.count(entity) > 0;
24+
}
25+
26+
//void SceneManager::AddSingletonScene(Entity singletonEntity) {
27+
// SceneNode sceneNode = SceneNode{.entity = singletonEntity};
28+
// Scene scene = Scene{.rootNode = sceneNode};
29+
// entityToMainScenesMap.emplace(singletonEntity, scene);
30+
//}
31+
32+
void SceneManager::ChangeToScene(Scene scene) {
33+
currentScene = scene;
34+
sceneContext->currentSceneEntity = currentScene.rootNode.entity;
35+
entityToMainScenesMap.emplace(currentScene.rootNode.entity, currentScene);
36+
AddChild(NULL_ENTITY, currentScene.rootNode.entity);
37+
}
38+
39+
void SceneManager::AddChild(Entity parent, Entity child) {
40+
SceneNode childNode = SceneNode{.entity = child, .parent = parent};
41+
if (parent != NULL_ENTITY) {
42+
assert((entityToSceneNodeMap.count(parent) > 0) && "Parent scene node doesn't exist!");
43+
entityToSceneNodeMap.emplace(childNode.entity, childNode);
44+
Entity currentParent = parent;
45+
Entity currentChild = child;
46+
while (currentParent != NULL_ENTITY) {
47+
entityToSceneNodeMap[currentParent].children.emplace_back(entityToSceneNodeMap[currentChild]);
48+
if (currentParent == currentScene.rootNode.entity) {
49+
currentScene.rootNode.children.emplace_back(childNode);
50+
}
51+
currentChild = entityToSceneNodeMap[currentParent].entity;
52+
currentParent = entityToSceneNodeMap[currentParent].parent;
53+
}
54+
} else {
55+
entityToSceneNodeMap.emplace(childNode.entity, childNode);
56+
}
57+
}
58+
59+
std::vector<Entity> SceneManager::GetAllChildEntities(Entity entity) {
60+
std::vector<Entity> childrenEntities;
61+
SceneNode parentNode = GetEntitySceneNode(entity);
62+
for (SceneNode childNode : parentNode.children) {
63+
if (IsEntityInScene(childNode.entity)) {
64+
childrenEntities.emplace_back(childNode.entity);
65+
}
66+
}
67+
return childrenEntities;
68+
}
69+
70+
Entity SceneManager::GetParent(Entity entity) {
71+
if (IsEntityInScene(entity)) {
72+
SceneNode sceneNode = entityToSceneNodeMap[entity];
73+
return sceneNode.parent;
74+
}
75+
return NULL_ENTITY;
76+
}
77+
78+
void SceneManager::RemoveNode(SceneNode sceneNode) {
79+
for (SceneNode childNode : sceneNode.children) {
80+
RemoveNode(childNode);
81+
}
82+
entityToSceneNodeMap.erase(sceneNode.entity);
83+
entityToMainScenesMap.erase(sceneNode.entity);
84+
entitiesRecentlyRemoved.emplace_back(sceneNode.entity);
85+
}
86+
87+
//void SceneManager::RemoveNode(Entity entity) {
88+
// if (entityToSceneNodeMap.count(entity) > 0) {
89+
// RemoveNode(entityToSceneNodeMap[entity]);
90+
// } else {
91+
// Logger::GetInstance()->Warn("Tried to remove non existent entity");
92+
// }
93+
//}
94+
95+
std::vector<Entity> SceneManager::FlushRemovedEntities() {
96+
std::vector<Entity> removedEntitiesCopy = entitiesRecentlyRemoved;
97+
entitiesRecentlyRemoved.clear();
98+
return removedEntitiesCopy;
99+
}
100+
101+
bool SceneManager::IsEntityInScene(Entity entity) const {
102+
return entityToSceneNodeMap.count(entity) > 0;
103+
}
104+
105+
Scene SceneManager::LoadSceneFromFile(const std::string &filePath) {
106+
nlohmann::json sceneJson = JsonFileHelper::LoadJsonFile(filePath);
107+
SceneNode rootNode = sceneNodeJsonParser.ParseSceneJson(sceneJson, true);
108+
Scene loadedScene = Scene{.rootNode = rootNode};
109+
ChangeToScene(loadedScene);
110+
return loadedScene;
111+
}
112+
113+
Scene SceneManager::LoadSceneFromMemory(const std::string &filePath) {
114+
const std::string &sceneArchiveJsonString = archiveLoader->LoadAsString(filePath);
115+
nlohmann::json sceneJson = JsonFileHelper::ConvertStringToJson(sceneArchiveJsonString);
116+
SceneNode rootNode = sceneNodeJsonParser.ParseSceneJson(sceneJson, true);
117+
Scene loadedScene = Scene{.rootNode = rootNode};
118+
ChangeToScene(loadedScene);
119+
return loadedScene;
120+
}

src/core/scene/scene_manager.h

Lines changed: 15 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -465,116 +465,21 @@ class SceneManager {
465465
ArchiveLoader *archiveLoader = nullptr;
466466

467467
public:
468-
SceneManager(SceneContext *vSceneContext, EntityManager *vEntityManager, ComponentManager *vComponentManager, AssetManager *vAssetManager) :
469-
sceneContext(vSceneContext), entityManager(vEntityManager), componentManager(vComponentManager), assetManager(vAssetManager) {
470-
timerManager = TimerManager::GetInstance();
471-
archiveLoader = ArchiveLoader::GetInstance();
472-
sceneNodeJsonParser = SceneNodeJsonParser(entityManager, componentManager, assetManager, timerManager);
473-
}
474-
475-
Scene GetCurrentScene() {
476-
return currentScene;
477-
}
478-
479-
SceneNode GetEntitySceneNode(Entity entity) {
480-
assert(HasEntitySceneNode(entity) && "Tried to get scene node that doesn't exist!");
481-
return entityToSceneNodeMap[entity];
482-
}
483-
484-
bool HasEntitySceneNode(Entity entity) {
485-
return entityToSceneNodeMap.count(entity) > 0;
486-
}
487-
488-
void AddSingletonScene(Entity singletonEntity) {
489-
SceneNode sceneNode = SceneNode{.entity = singletonEntity};
490-
Scene scene = Scene{.rootNode = sceneNode};
491-
entityToMainScenesMap.emplace(singletonEntity, scene);
492-
}
493-
494-
void ChangeToScene(Scene scene) {
495-
currentScene = scene;
496-
sceneContext->currentSceneEntity = currentScene.rootNode.entity;
497-
entityToMainScenesMap.emplace(currentScene.rootNode.entity, currentScene);
498-
AddChild(NULL_ENTITY, currentScene.rootNode.entity);
499-
}
500-
501-
void AddChild(Entity parent, Entity child) {
502-
SceneNode childNode = SceneNode{.entity = child, .parent = parent};
503-
if (parent != NULL_ENTITY) {
504-
assert((entityToSceneNodeMap.count(parent) > 0) && "Parent scene node doesn't exist!");
505-
SceneNode parentNode = entityToSceneNodeMap[parent];
506-
parentNode.children.emplace_back(childNode);
507-
entityToSceneNodeMap[parent] = parentNode;
508-
if (parentNode.entity == currentScene.rootNode.entity) {
509-
currentScene.rootNode.children.emplace_back(childNode);
510-
}
511-
}
512-
// assert((entityToSceneNodeMap.count(child) <= 0) && "Child already exists!");
513-
entityToSceneNodeMap.emplace(childNode.entity, childNode);
514-
}
515-
516-
std::vector<Entity> GetAllChildEntities(Entity entity) {
517-
std::vector<Entity> childrenEntities;
518-
SceneNode parentNode = GetEntitySceneNode(entity);
519-
for (SceneNode childNode : parentNode.children) {
520-
if (IsEntityInScene(childNode.entity)) {
521-
childrenEntities.emplace_back(childNode.entity);
522-
}
523-
}
524-
return childrenEntities;
525-
}
526-
527-
Entity GetParent(Entity entity) {
528-
if (IsEntityInScene(entity)) {
529-
SceneNode sceneNode = entityToSceneNodeMap[entity];
530-
return sceneNode.parent;
531-
}
532-
return NULL_ENTITY;
533-
}
534-
535-
void RemoveNode(SceneNode sceneNode) {
536-
entityToSceneNodeMap.erase(sceneNode.entity);
537-
entityToMainScenesMap.erase(sceneNode.entity);
538-
entitiesRecentlyRemoved.emplace_back(sceneNode.entity);
539-
for (SceneNode childNode : sceneNode.children) {
540-
RemoveNode(childNode);
541-
}
542-
}
543-
544-
void RemoveNode(Entity entity) {
545-
if (entityToSceneNodeMap.count(entity) > 0) {
546-
RemoveNode(entityToSceneNodeMap[entity]);
547-
} else {
548-
Logger::GetInstance()->Warn("Tried to remove non existent entity");
549-
}
550-
}
551-
552-
std::vector<Entity> FlushRemovedEntities() {
553-
std::vector<Entity> removedEntitiesCopy = entitiesRecentlyRemoved;
554-
entitiesRecentlyRemoved.clear();
555-
return removedEntitiesCopy;
556-
}
557-
558-
bool IsEntityInScene(Entity entity) {
559-
return entityToSceneNodeMap.count(entity) > 0;
560-
}
561-
562-
Scene LoadSceneFromFile(const std::string &filePath) {
563-
nlohmann::json sceneJson = JsonFileHelper::LoadJsonFile(filePath);
564-
SceneNode rootNode = sceneNodeJsonParser.ParseSceneJson(sceneJson, true);
565-
Scene loadedScene = Scene{.rootNode = rootNode};
566-
ChangeToScene(loadedScene);
567-
return loadedScene;
568-
}
569-
570-
Scene LoadSceneFromMemory(const std::string &filePath) {
571-
const std::string &sceneArchiveJsonString = archiveLoader->LoadAsString(filePath);
572-
nlohmann::json sceneJson = JsonFileHelper::ConvertStringToJson(sceneArchiveJsonString);
573-
SceneNode rootNode = sceneNodeJsonParser.ParseSceneJson(sceneJson, true);
574-
Scene loadedScene = Scene{.rootNode = rootNode};
575-
ChangeToScene(loadedScene);
576-
return loadedScene;
577-
}
468+
SceneManager(SceneContext *vSceneContext, EntityManager *vEntityManager, ComponentManager *vComponentManager, AssetManager *vAssetManager);
469+
Scene GetCurrentScene();
470+
SceneNode GetEntitySceneNode(Entity entity);
471+
bool HasEntitySceneNode(Entity entity) const;
472+
// void AddSingletonScene(Entity singletonEntity);
473+
void ChangeToScene(Scene scene);
474+
void AddChild(Entity parent, Entity child);
475+
std::vector<Entity> GetAllChildEntities(Entity entity);
476+
Entity GetParent(Entity entity);
477+
void RemoveNode(SceneNode sceneNode);
478+
// void RemoveNode(Entity entity);
479+
std::vector<Entity> FlushRemovedEntities();
480+
bool IsEntityInScene(Entity entity) const;
481+
Scene LoadSceneFromFile(const std::string &filePath);
482+
Scene LoadSceneFromMemory(const std::string &filePath);
578483
};
579484

580485
class SceneNodeHelper {

0 commit comments

Comments
 (0)