From 7c21e34ae1898fce8c8051b5f1380e268da32140 Mon Sep 17 00:00:00 2001 From: max-001 Date: Fri, 22 Nov 2024 09:36:35 +0100 Subject: Replaced ComponentManager reference by OptionalRef for late binding --- src/crepe/api/CMakeLists.txt | 1 - src/crepe/api/Scene.cpp | 5 ----- src/crepe/api/Scene.h | 22 ++++++++++++++++------ src/crepe/api/SceneManager.h | 4 ++-- src/crepe/api/SceneManager.hpp | 9 ++++++--- src/test/SceneManagerTest.cpp | 8 ++------ 6 files changed, 26 insertions(+), 23 deletions(-) delete mode 100644 src/crepe/api/Scene.cpp (limited to 'src') diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt index d6b6801..4025a63 100644 --- a/src/crepe/api/CMakeLists.txt +++ b/src/crepe/api/CMakeLists.txt @@ -12,7 +12,6 @@ target_sources(crepe PUBLIC SaveManager.cpp Config.cpp Metadata.cpp - Scene.cpp SceneManager.cpp Vector2.cpp Camera.cpp diff --git a/src/crepe/api/Scene.cpp b/src/crepe/api/Scene.cpp deleted file mode 100644 index 849945e..0000000 --- a/src/crepe/api/Scene.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "Scene.h" - -using namespace crepe; - -Scene::Scene(ComponentManager & mgr) : component_manager(mgr) {} diff --git a/src/crepe/api/Scene.h b/src/crepe/api/Scene.h index 869bf6f..22aadab 100644 --- a/src/crepe/api/Scene.h +++ b/src/crepe/api/Scene.h @@ -1,5 +1,6 @@ #pragma once +#include "util/OptionalRef.h" #include namespace crepe { @@ -15,11 +16,8 @@ class ComponentManager; */ class Scene { protected: - //TODO: Use Loek's custom reference class to set ComponentManger via SceneManager instead of via constructor - /** - * \param mgr Reference to the ComponentManager - */ - Scene(ComponentManager & mgr); + // NOTE: This must be the only constructor on Scene, see "Late references" below + Scene() = default; //! SceneManager instances Scene friend class SceneManager; @@ -36,8 +34,20 @@ public: virtual std::string get_name() const = 0; protected: + /** + * \name Late references + * + * These references are set by SceneManager immediately after calling the constructor of Scene. + * + * \note Scene must have a constructor without arguments so the game programmer doesn't need to + * manually add `using Scene::Scene` to their concrete scene class, if they want to add a + * constructor with arguments (e.g. for passing references to their own concrete Scene classes). + * + * \{ + */ //! Reference to the ComponentManager - ComponentManager & component_manager; + OptionalRef component_manager; + //! \} }; } // namespace crepe diff --git a/src/crepe/api/SceneManager.h b/src/crepe/api/SceneManager.h index 45ba668..f6f62cd 100644 --- a/src/crepe/api/SceneManager.h +++ b/src/crepe/api/SceneManager.h @@ -26,8 +26,8 @@ public: * * \tparam T Type of concrete scene */ - template - void add_scene(); + template + void add_scene(Args &&... args); /** * \brief Set the next scene * diff --git a/src/crepe/api/SceneManager.hpp b/src/crepe/api/SceneManager.hpp index 94e5946..1edaa7d 100644 --- a/src/crepe/api/SceneManager.hpp +++ b/src/crepe/api/SceneManager.hpp @@ -4,12 +4,15 @@ namespace crepe { -template -void SceneManager::add_scene() { +template +void SceneManager::add_scene(Args &&... args) { using namespace std; static_assert(is_base_of::value, "T must be derived from Scene"); - Scene * scene = new T(this->component_manager); + Scene * scene = new T(std::forward(args)...); + + scene->component_manager = this->component_manager; + this->scenes.emplace_back(unique_ptr(scene)); // The first scene added, is the one that will be loaded at the beginning diff --git a/src/test/SceneManagerTest.cpp b/src/test/SceneManagerTest.cpp index 1efcfb2..1706de0 100644 --- a/src/test/SceneManagerTest.cpp +++ b/src/test/SceneManagerTest.cpp @@ -12,10 +12,8 @@ using namespace crepe; class ConcreteScene1 : public Scene { public: - using Scene::Scene; - void load_scene() { - auto & mgr = this->component_manager; + ComponentManager & mgr = this->component_manager; GameObject object1 = mgr.new_object("scene_1", "tag_scene_1", Vector2{0, 0}, 0, 1); GameObject object2 = mgr.new_object("scene_1", "tag_scene_1", Vector2{1, 0}, 0, 1); GameObject object3 = mgr.new_object("scene_1", "tag_scene_1", Vector2{2, 0}, 0, 1); @@ -26,10 +24,8 @@ public: class ConcreteScene2 : public Scene { public: - using Scene::Scene; - void load_scene() { - auto & mgr = this->component_manager; + ComponentManager & mgr = this->component_manager; GameObject object1 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 0}, 0, 1); GameObject object2 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 1}, 0, 1); GameObject object3 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 2}, 0, 1); -- cgit v1.2.3 From 7f1ba9e90ddcdbcd3b6ab11c5796ef8043f71cc1 Mon Sep 17 00:00:00 2001 From: max-001 Date: Fri, 22 Nov 2024 09:39:23 +0100 Subject: Updated documentation --- src/doc/feature/scene.dox | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src') diff --git a/src/doc/feature/scene.dox b/src/doc/feature/scene.dox index 5f34446..5d765f9 100644 --- a/src/doc/feature/scene.dox +++ b/src/doc/feature/scene.dox @@ -42,10 +42,8 @@ using namespace crepe; class MyScene : public Scene { public: - using Scene::Scene; - void load_scene() { - auto & mgr = this->component_manager; + ComponentManager & mgr = this->component_manager; GameObject object1 = mgr.new_object("object1", "tag_my_scene", Vector2{0, 0}, 0, 1); GameObject object2 = mgr.new_object("object2", "tag_my_scene", Vector2{1, 0}, 0, 1); } -- cgit v1.2.3 From ef6acbee3bd00c322a56221d992d08a64e15e3b9 Mon Sep 17 00:00:00 2001 From: max-001 Date: Fri, 22 Nov 2024 09:46:10 +0100 Subject: Little fix (typo) --- src/crepe/api/SceneManager.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/crepe/api/SceneManager.hpp b/src/crepe/api/SceneManager.hpp index 1edaa7d..ccc755f 100644 --- a/src/crepe/api/SceneManager.hpp +++ b/src/crepe/api/SceneManager.hpp @@ -9,7 +9,7 @@ void SceneManager::add_scene(Args &&... args) { using namespace std; static_assert(is_base_of::value, "T must be derived from Scene"); - Scene * scene = new T(std::forward(args)...); + Scene * scene = new T(std::forward(args)...); scene->component_manager = this->component_manager; -- cgit v1.2.3 From 2052988dba049cfa2032d01ff9e6f7bb53d084fe Mon Sep 17 00:00:00 2001 From: max-001 Date: Fri, 22 Nov 2024 09:46:35 +0100 Subject: Added perfect forwarding test --- src/test/SceneManagerTest.cpp | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'src') diff --git a/src/test/SceneManagerTest.cpp b/src/test/SceneManagerTest.cpp index 1706de0..cd3b827 100644 --- a/src/test/SceneManagerTest.cpp +++ b/src/test/SceneManagerTest.cpp @@ -35,6 +35,21 @@ public: string get_name() const { return "scene2"; } }; +class ConcreteScene3 : public Scene { +public: + ConcreteScene3(const string & name) : name(name) {} + + void load_scene() { + ComponentManager & mgr = this->component_manager; + GameObject object1 = mgr.new_object("scene_3", "tag_scene_3", Vector2{0, 0}, 0, 1); + } + + string get_name() const { return name; } + +private: + const string name; +}; + class SceneManagerTest : public ::testing::Test { public: ComponentManager component_mgr{}; @@ -120,3 +135,25 @@ TEST_F(SceneManagerTest, loadScene) { EXPECT_EQ(transform[3].get().position.x, 0); EXPECT_EQ(transform[3].get().position.y, 3); } + +TEST_F(SceneManagerTest, perfectForwarding) { + scene_mgr.add_scene("scene3"); + + scene_mgr.load_next_scene(); + + vector> metadata + = component_mgr.get_components_by_type(); + vector> transform + = component_mgr.get_components_by_type(); + + EXPECT_EQ(metadata.size(), 1); + EXPECT_EQ(transform.size(), 1); + + EXPECT_EQ(metadata[0].get().game_object_id, 0); + EXPECT_EQ(metadata[0].get().name, "scene_3"); + EXPECT_EQ(metadata[0].get().tag, "tag_scene_3"); + EXPECT_EQ(metadata[0].get().parent, -1); + EXPECT_EQ(metadata[0].get().children.size(), 0); + EXPECT_EQ(transform[0].get().position.x, 0); + EXPECT_EQ(transform[0].get().position.y, 0); +} -- cgit v1.2.3 From 2f10649bf08bbe507458fa4da8be1dd7b02213da Mon Sep 17 00:00:00 2001 From: max-001 Date: Sun, 24 Nov 2024 11:52:48 +0100 Subject: Implemented feedback --- src/crepe/api/SceneManager.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/crepe/api/SceneManager.hpp b/src/crepe/api/SceneManager.hpp index ccc755f..5c8e417 100644 --- a/src/crepe/api/SceneManager.hpp +++ b/src/crepe/api/SceneManager.hpp @@ -10,10 +10,11 @@ void SceneManager::add_scene(Args &&... args) { static_assert(is_base_of::value, "T must be derived from Scene"); Scene * scene = new T(std::forward(args)...); + unique_ptr unique_scene(scene); - scene->component_manager = this->component_manager; + unique_scene->component_manager = this->component_manager; - this->scenes.emplace_back(unique_ptr(scene)); + this->scenes.emplace_back(std::move(unique_scene)); // The first scene added, is the one that will be loaded at the beginning if (next_scene.empty()) { -- cgit v1.2.3 From 1a56d7dcbf0c7375c2f0b1bb2dcd2b108a489fa8 Mon Sep 17 00:00:00 2001 From: max-001 Date: Sun, 24 Nov 2024 12:03:21 +0100 Subject: Make format --- src/test/SceneManagerTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/test/SceneManagerTest.cpp b/src/test/SceneManagerTest.cpp index 3b61d5c..62b7d33 100644 --- a/src/test/SceneManagerTest.cpp +++ b/src/test/SceneManagerTest.cpp @@ -139,7 +139,7 @@ TEST_F(SceneManagerTest, loadScene) { TEST_F(SceneManagerTest, perfectForwarding) { scene_mgr.add_scene("scene3"); - + scene_mgr.load_next_scene(); vector> metadata -- cgit v1.2.3