diff options
| -rw-r--r-- | src/crepe/api/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/crepe/api/Scene.cpp | 5 | ||||
| -rw-r--r-- | src/crepe/api/Scene.h | 22 | ||||
| -rw-r--r-- | src/crepe/api/SceneManager.h | 4 | ||||
| -rw-r--r-- | src/crepe/api/SceneManager.hpp | 9 | ||||
| -rw-r--r-- | src/doc/feature/scene.dox | 6 | ||||
| -rw-r--r-- | src/test/SceneManagerTest.cpp | 46 | 
7 files changed, 66 insertions, 27 deletions
| diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt index c3e0b37..50c51ed 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  	Camera.cpp  	Animator.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 <string>  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<ComponentManager> 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 <typename T> -	void add_scene(); +	template <typename T, typename... Args> +	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..ccc755f 100644 --- a/src/crepe/api/SceneManager.hpp +++ b/src/crepe/api/SceneManager.hpp @@ -4,12 +4,15 @@  namespace crepe { -template <typename T> -void SceneManager::add_scene() { +template <typename T, typename... Args> +void SceneManager::add_scene(Args &&... args) {  	using namespace std;  	static_assert(is_base_of<Scene, T>::value, "T must be derived from Scene"); -	Scene * scene = new T(this->component_manager); +	Scene * scene = new T(std::forward<Args>(args)...); + +	scene->component_manager = this->component_manager; +  	this->scenes.emplace_back(unique_ptr<Scene>(scene));  	// The first scene added, is the one that will be loaded at the beginning diff --git a/src/doc/feature/scene.dox b/src/doc/feature/scene.dox index eedc69a..bac1c87 100644 --- a/src/doc/feature/scene.dox +++ b/src/doc/feature/scene.dox @@ -36,16 +36,14 @@ concrete scene to be added.  #include <crepe/api/LoopManager.h>  #include <crepe/api/GameObject.h>  #include <crepe/api/Scene.h> -#include <crepe/api/Vector2.h> +#include <crepe/util/types.h>  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", vec2{0, 0}, 0, 1);  		GameObject object2 = mgr.new_object("object2", "tag_my_scene", vec2{1, 0}, 0, 1);  	} diff --git a/src/test/SceneManagerTest.cpp b/src/test/SceneManagerTest.cpp index f3d2387..3b61d5c 100644 --- a/src/test/SceneManagerTest.cpp +++ b/src/test/SceneManagerTest.cpp @@ -1,3 +1,4 @@ +#include "types.h"  #include <crepe/ComponentManager.h>  #include <crepe/api/GameObject.h>  #include <crepe/api/Metadata.h> @@ -12,10 +13,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", vec2{0, 0}, 0, 1);  		GameObject object2 = mgr.new_object("scene_1", "tag_scene_1", vec2{1, 0}, 0, 1);  		GameObject object3 = mgr.new_object("scene_1", "tag_scene_1", vec2{2, 0}, 0, 1); @@ -26,10 +25,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", vec2{0, 0}, 0, 1);  		GameObject object2 = mgr.new_object("scene_2", "tag_scene_2", vec2{0, 1}, 0, 1);  		GameObject object3 = mgr.new_object("scene_2", "tag_scene_2", vec2{0, 2}, 0, 1); @@ -39,6 +36,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", vec2{0, 0}, 0, 1); +	} + +	string get_name() const { return name; } + +private: +	const string name; +}; +  class SceneManagerTest : public ::testing::Test {  public:  	ComponentManager component_mgr{}; @@ -124,3 +136,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<ConcreteScene3>("scene3"); +	 +	scene_mgr.load_next_scene(); + +	vector<reference_wrapper<Metadata>> metadata +		= component_mgr.get_components_by_type<Metadata>(); +	vector<reference_wrapper<Transform>> transform +		= component_mgr.get_components_by_type<Transform>(); + +	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); +} |