diff options
| -rw-r--r-- | src/crepe/api/LoopManager.h | 18 | ||||
| -rw-r--r-- | src/crepe/api/LoopManager.hpp | 5 | ||||
| -rw-r--r-- | src/crepe/api/Scene.cpp | 4 | ||||
| -rw-r--r-- | src/crepe/api/Scene.h | 21 | ||||
| -rw-r--r-- | src/crepe/api/SceneManager.cpp | 2 | ||||
| -rw-r--r-- | src/crepe/api/SceneManager.h | 14 | ||||
| -rw-r--r-- | src/crepe/api/SceneManager.hpp | 6 | ||||
| -rw-r--r-- | src/doc/feature/gameobject.dox | 18 | ||||
| -rw-r--r-- | src/doc/feature/scene.dox | 67 | ||||
| -rw-r--r-- | src/test/SceneManagerTest.cpp | 8 | 
10 files changed, 149 insertions, 14 deletions
| diff --git a/src/crepe/api/LoopManager.h b/src/crepe/api/LoopManager.h index f6904be..13e6dac 100644 --- a/src/crepe/api/LoopManager.h +++ b/src/crepe/api/LoopManager.h @@ -4,14 +4,28 @@  #include "../ComponentManager.h"  #include "../system/System.h" +#include "api/SceneManager.h"  namespace crepe { +/** + * \brief Main game loop manager + * + * This class is responsible for managing the game loop, including initialization and updating. + */  class LoopManager {  public:  	void start();  	LoopManager(); +	/** +	 * \brief Add a new concrete scene to the scene manager +	 * +	 * \tparam T  Type of concrete scene +	 */ +	template <typename T> +	void add_scene(); +  private:  	/**  	 * \brief Setup function for one-time initialization. @@ -53,12 +67,14 @@ private:  	 * This function updates physics and game logic based on LoopTimer's fixed_delta_time.  	 */  	void fixed_update(); +  	/**  	 * \brief Set game running variable  	 *  	 * \param running running (false = game shutdown, true = game running)  	 */  	void set_running(bool running); +  	/**  	 * \brief Function for executing render-related systems.  	 * @@ -71,6 +87,8 @@ private:  private:  	//! Component manager instance  	ComponentManager component_manager{}; +	//! Scene manager instance +	SceneManager scene_manager{component_manager};  private:  	/** diff --git a/src/crepe/api/LoopManager.hpp b/src/crepe/api/LoopManager.hpp index 0b14fdb..9cf470b 100644 --- a/src/crepe/api/LoopManager.hpp +++ b/src/crepe/api/LoopManager.hpp @@ -11,6 +11,11 @@  namespace crepe {  template <class T> +void LoopManager::add_scene() { +	this->scene_manager.add_scene<T>(); +} + +template <class T>  T & LoopManager::get_system() {  	using namespace std;  	static_assert(is_base_of<System, T>::value, diff --git a/src/crepe/api/Scene.cpp b/src/crepe/api/Scene.cpp index 88aa82d..849945e 100644 --- a/src/crepe/api/Scene.cpp +++ b/src/crepe/api/Scene.cpp @@ -2,6 +2,4 @@  using namespace crepe; -Scene::Scene(ComponentManager & mgr, const std::string & name) -	: component_manager(mgr), -	  name(name) {} +Scene::Scene(ComponentManager & mgr) : component_manager(mgr) {} diff --git a/src/crepe/api/Scene.h b/src/crepe/api/Scene.h index 0e516b6..869bf6f 100644 --- a/src/crepe/api/Scene.h +++ b/src/crepe/api/Scene.h @@ -7,19 +7,36 @@ namespace crepe {  class SceneManager;  class ComponentManager; +/** + * \brief Represents a Scene + *  + * This class represents a Scene. The Scene class is only used as an interface for the game + * programmer. + */  class Scene {  protected: -	Scene(ComponentManager & mgr, const std::string & name); +	//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); +	//! SceneManager instances Scene  	friend class SceneManager;  public:  	virtual ~Scene() = default;  public: +	//! Load the scene  	virtual void load_scene() = 0; -	const std::string name; +	/** +	 * \brief Get the scene's name +	 * \return The scene's name +	 */ +	virtual std::string get_name() const = 0;  protected: +	//! Reference to the ComponentManager  	ComponentManager & component_manager;  }; diff --git a/src/crepe/api/SceneManager.cpp b/src/crepe/api/SceneManager.cpp index 7fb5cb0..1f783ad 100644 --- a/src/crepe/api/SceneManager.cpp +++ b/src/crepe/api/SceneManager.cpp @@ -18,7 +18,7 @@ void SceneManager::load_next_scene() {  	auto it = find_if(this->scenes.begin(), this->scenes.end(),  					  [&next_scene = this->next_scene](unique_ptr<Scene> & scene) { -						  return scene->name == next_scene; +						  return scene.get()->get_name() == next_scene;  					  });  	// next scene not found diff --git a/src/crepe/api/SceneManager.h b/src/crepe/api/SceneManager.h index e854794..45ba668 100644 --- a/src/crepe/api/SceneManager.h +++ b/src/crepe/api/SceneManager.h @@ -1,7 +1,6 @@  #pragma once  #include <memory> -#include <queue>  #include <vector>  #include "Scene.h" @@ -10,8 +9,15 @@ namespace crepe {  class ComponentManager; +/** + * \brief Manages scenes + * + * This class manages scenes. It can add new scenes and load them. It also manages the current scene + * and the next scene. + */  class SceneManager {  public: +	//! \param mgr  Reference to the ComponentManager  	SceneManager(ComponentManager & mgr);  public: @@ -19,10 +25,9 @@ public:  	 * \brief Add a new concrete scene to the scene manager  	 *  	 * \tparam T  Type of concrete scene -	 * \param name  Name of new scene  	 */  	template <typename T> -	void add_scene(const std::string & name); +	void add_scene();  	/**  	 * \brief Set the next scene  	 * @@ -35,8 +40,11 @@ public:  	void load_next_scene();  private: +	//! Vector of concrete scenes (added by add_scene())  	std::vector<std::unique_ptr<Scene>> scenes; +	//! Next scene to load  	std::string next_scene; +	//! Reference to the ComponentManager  	ComponentManager & component_manager;  }; diff --git a/src/crepe/api/SceneManager.hpp b/src/crepe/api/SceneManager.hpp index 714f690..94e5946 100644 --- a/src/crepe/api/SceneManager.hpp +++ b/src/crepe/api/SceneManager.hpp @@ -5,16 +5,16 @@  namespace crepe {  template <typename T> -void SceneManager::add_scene(const std::string & name) { +void SceneManager::add_scene() {  	using namespace std;  	static_assert(is_base_of<Scene, T>::value, "T must be derived from Scene"); -	Scene * scene = new T(this->component_manager, name); +	Scene * scene = new T(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  	if (next_scene.empty()) { -		next_scene = name; +		next_scene = scene->get_name();  	}  } diff --git a/src/doc/feature/gameobject.dox b/src/doc/feature/gameobject.dox new file mode 100644 index 0000000..c561874 --- /dev/null +++ b/src/doc/feature/gameobject.dox @@ -0,0 +1,18 @@ +// vim:ft=doxygen +namespace crepe { +/** + +\defgroup feature_gameobject GameObjects +\ingroup feature +\brief GameObject to create a Scene + +GameObjects are the fundamental building blocks of a Scene. They represent entities +in the game world and can have various components attached to them to define their +behavior and properties. GameObjects can be created and modified within the +Scene, allowing for a flexible and dynamic game environment. + +\see Component +\see Scene + +*/ +} diff --git a/src/doc/feature/scene.dox b/src/doc/feature/scene.dox new file mode 100644 index 0000000..5f34446 --- /dev/null +++ b/src/doc/feature/scene.dox @@ -0,0 +1,67 @@ +// vim:ft=doxygen +namespace crepe { +/** + +\defgroup feature_scene Scenes +\ingroup feature +\brief User-defined scenes + +Scenes can be used to implement game environments, and allow arbitrary game objects to be organized +as part of the game structure. Scenes are implemented as derivative classes of Scene, which are +added to the game using the SceneManager. Scenes describe the start of a Scene and cannot modify +GameObjects during runtime of a Scene (use \ref feature_script "Scripting" for this purpose). + +\see SceneManager +\see GameObject +\see Script +\see Scene + +\par Example + +This example demonstrates how to define and add scenes to the loop/scene manager in the `crepe` framework. +Each concrete scene should be derived from Scene. In the example below, the concrete scene is named MyScene. +A concrete scene should, at least, implement (override) two methods, namely load_scene() and get_name(). The +scene is build (using GameObjects) in the load_scene() method. GameObjects should be made using the +component_manager::new_object(). In the example below, two GameObjects (named object1 and object2) are added +to MyScene. object1 and object2 do not have any non-default Components attached to them, however, if needed, +this should also be done in load_scene(). Each concrete scene must have a unique name. This unique name is +used to load a new concrete scene (via a Script). The unique name is set using the get_name() method. In the +example below, MyScene's unique name is my_scene. +After setting up one or more concrete scene(s), the concrete scene(s) should be added to the loop/scene manager. +This is done in your main(). Firstly, the LoopManager should be instantiated. Than, all the concrete scene(s) +should be added to the loop/scene manger via loop_mgr::add_scene<>(). The templated argument should define the +concrete scene to be added. + +```cpp +#include <crepe/api/LoopManager.h> +#include <crepe/api/GameObject.h> +#include <crepe/api/Scene.h> +#include <crepe/api/Vector2.h> + +using namespace crepe; + +class MyScene : public Scene { +public: +	using Scene::Scene; + +	void load_scene() { +		auto & 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); +	} + +	string get_name() const { return "my_scene"; } +}; + +int main() { +	LoopManager loop_mgr; +	 +	// Add the scenes to the loop manager +	loop_mgr.add_scene<MyScene>(); + +	loop_mgr.start(); +} +``` + +*/ +} diff --git a/src/test/SceneManagerTest.cpp b/src/test/SceneManagerTest.cpp index 69e1171..dab2ce9 100644 --- a/src/test/SceneManagerTest.cpp +++ b/src/test/SceneManagerTest.cpp @@ -20,6 +20,8 @@ public:  		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);  	} + +	string get_name() const { return "scene1";}  };  class ConcreteScene2 : public Scene { @@ -33,6 +35,8 @@ public:  		GameObject object3 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 2}, 0, 1);  		GameObject object4 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 3}, 0, 1);  	} + +	string get_name() const { return "scene2";}  };  class SceneManagerTest : public ::testing::Test { @@ -42,8 +46,8 @@ public:  };  TEST_F(SceneManagerTest, loadScene) { -	scene_mgr.add_scene<ConcreteScene1>("scene1"); -	scene_mgr.add_scene<ConcreteScene2>("scene2"); +	scene_mgr.add_scene<ConcreteScene1>(); +	scene_mgr.add_scene<ConcreteScene2>();  	scene_mgr.load_next_scene(); |