diff options
| author | WBoerenkamps <wrj.boerenkamps@student.avans.nl> | 2024-12-04 21:50:45 +0100 | 
|---|---|---|
| committer | WBoerenkamps <wrj.boerenkamps@student.avans.nl> | 2024-12-04 21:50:45 +0100 | 
| commit | d941f497c10bb9146bb83c5c4e59e844d0641a04 (patch) | |
| tree | 7dfdf691175caf8e43a9c7a7e07a1cdd6bfed0ff | |
| parent | d10f220ff6c5d62bb51793a0ef4ee37090161d89 (diff) | |
| parent | cfb67ffddb9f4bb0357c2b9df4239bfee7364c5a (diff) | |
merge master
57 files changed, 540 insertions, 263 deletions
| @@ -17,11 +17,10 @@ GENERATE_LATEX = NO  LAYOUT_FILE = src/doc/layout.xml  TAB_SIZE = 2 -HTML_INDEX_NUM_ENTRIES = 2 +HTML_INDEX_NUM_ENTRIES = 999  HTML_EXTRA_STYLESHEET = src/doc/style.css  SHOW_HEADERFILE = NO -USE_MDFILE_AS_MAINPAGE = ./readme.md  REPEAT_BRIEF = NO  EXTRACT_STATIC = YES @@ -29,6 +28,7 @@ HIDE_UNDOC_NAMESPACES = YES  HIDE_UNDOC_CLASSES = YES  QUIET = YES +WARNINGS = NO  # set these to NO for user-only docs  INTERNAL_DOCS = YES diff --git a/contributing.md b/contributing.md index b0f623b..7dedaa7 100644 --- a/contributing.md +++ b/contributing.md @@ -635,15 +635,21 @@ that you can click on to open them.    </summary><table><tr><th>Good</th><th>Bad</th></tr><tr><td>    ```cpp +  void Foo::bar() { } +    void Foo::set_value(int value) {      this->value = value; +    this->bar();    }    ```    </td><td>    ```cpp +  void Foo::bar() { } +    void Foo::set_value(int new_value) {      value = new_value; +    bar();    }    ```    </td></tr></table></details> @@ -868,6 +874,8 @@ that you can click on to open them.  # Documentation +[Doxygen commands](https://www.doxygen.nl/manual/commands.html) +  - All documentation is written in U.S. English  - <details><summary>    Doxygen commands are used with a backslash instead of an at-sign. @@ -953,6 +961,52 @@ that you can click on to open them.    Foo & operator=(Foo &&) = delete;    ```    </td></tr></table></details> +- Do not use markdown headings in Doxygen + +## Documenting features + +Engine features are small 'building blocks' that the user (game developer) may +reference when building a game with the engine. Features do not necessarily map +1-1 to engine components or systems. If a component or system has a single, +distinct feature it should be named after that feature, not the component or +system itself. + +The sources for these pages are located under `src/doc/feature/`, and have the +following format: + +- A feature description which explains— +  - the purpose and function of the feature (focus on what it enables or +    achieves for the user) +  - additional information about when to implement the feature, such as specific +    use cases or scenarios +- A list of 'see also' references to relevant classes and/or types +- A **minimal** example to demonstrate how the feature is used. The example +  should be written such that the following is clear to the reader: +  - Which headers need to be included to utilize the feature +  - *Why* the example works, not what is happening in the example +  - Where is this code supposed to be called (e.g. inside scene/script +    functions) +  - Which restrictions should be kept in mind (e.g. copy/move semantics, max +    component instances, speed considerations) + +Features should be documented as clear and concise as possible, so the following +points should be kept in mind: + +- <details><summary> +  If a page expands on an example from another page, directly reference the +  other page using a cross-reference (`\ref`) in a `\note` block at the top of +  the page. +  </summary> + +  ``` +  \note This page builds on top of the example shown in \ref feature_script +  ``` +  </details> +- When explaining the usage of specific functions, qualify them such that +  Doxygen is able to add a cross-reference or manually add a reference using the +  `\ref` command. +- Users will likely copy-paste examples as-is, so do this yourself to check if +  the example code actually works!  # Libraries @@ -960,4 +1014,6 @@ that you can click on to open them.    subdirectory  - When adding new submodules, please set the `shallow` option to `true` in the    [.gitmodules](./.gitmodules) file +- When adding new libraries, please update the library version table in +  [readme\.md](./readme.md) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c3f29da..97b21f0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -40,5 +40,6 @@ install(  target_link_libraries(test_main  	PRIVATE gtest +	PRIVATE gmock  	PUBLIC crepe  ) diff --git a/src/crepe/CMakeLists.txt b/src/crepe/CMakeLists.txt index 7e176e7..da9d492 100644 --- a/src/crepe/CMakeLists.txt +++ b/src/crepe/CMakeLists.txt @@ -1,13 +1,10 @@  target_sources(crepe PUBLIC  	Particle.cpp -	ComponentManager.cpp  	Component.cpp  	Collider.cpp  )  target_sources(crepe PUBLIC FILE_SET HEADERS FILES -	ComponentManager.h -	ComponentManager.hpp  	Component.h  	Collider.h  	ValueBroker.h @@ -16,6 +13,7 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES  add_subdirectory(api)  add_subdirectory(facade) +add_subdirectory(manager)  add_subdirectory(system)  add_subdirectory(util) diff --git a/src/crepe/api/BehaviorScript.cpp b/src/crepe/api/BehaviorScript.cpp index 7bbace0..d22afdf 100644 --- a/src/crepe/api/BehaviorScript.cpp +++ b/src/crepe/api/BehaviorScript.cpp @@ -4,12 +4,12 @@  using namespace crepe; -BehaviorScript::BehaviorScript(game_object_id_t id, ComponentManager & mgr) +BehaviorScript::BehaviorScript(game_object_id_t id, Mediator & mediator)  	: Component(id), -	  component_manager(mgr) {} +	  mediator(mediator) {}  template <>  BehaviorScript & GameObject::add_component<BehaviorScript>() {  	ComponentManager & mgr = this->component_manager; -	return mgr.add_component<BehaviorScript>(this->id, mgr); +	return mgr.add_component<BehaviorScript>(this->id, mgr.mediator);  } diff --git a/src/crepe/api/BehaviorScript.h b/src/crepe/api/BehaviorScript.h index d556fe5..3909b96 100644 --- a/src/crepe/api/BehaviorScript.h +++ b/src/crepe/api/BehaviorScript.h @@ -23,14 +23,13 @@ class BehaviorScript : public Component {  protected:  	/**  	 * \param id Parent \c GameObject id -	 * \param component_manager Reference to component manager (passed through to \c Script -	 * instance) +	 * \param mediator Mediator reference  	 *  	 * \note Calls to this constructor (should) always pass through \c GameObject::add_component,  	 * which has an exception for this specific component type. This was done so the user does  	 * not have to pass references used within \c Script to each \c BehaviorScript instance.  	 */ -	BehaviorScript(game_object_id_t id, ComponentManager & component_manager); +	BehaviorScript(game_object_id_t id, Mediator & mediator);  	//! Only ComponentManager is allowed to instantiate BehaviorScript  	friend class ComponentManager; @@ -55,8 +54,8 @@ protected:  	friend class ScriptSystem;  protected: -	//! Reference to component manager (passed to Script) -	ComponentManager & component_manager; +	//! Reference mediator +	Mediator & mediator;  };  /** diff --git a/src/crepe/api/BehaviorScript.hpp b/src/crepe/api/BehaviorScript.hpp index bd59337..b9bb1e2 100644 --- a/src/crepe/api/BehaviorScript.hpp +++ b/src/crepe/api/BehaviorScript.hpp @@ -13,14 +13,12 @@ template <class T, typename... Args>  BehaviorScript & BehaviorScript::set_script(Args &&... args) {  	dbg_trace();  	static_assert(std::is_base_of<Script, T>::value); -	Script * s = new T(std::forward<Args>(args)...); +	this->script = std::unique_ptr<Script>(new T(std::forward<Args>(args)...)); -	s->game_object_id = this->game_object_id; -	s->active = this->active; -	s->component_manager = this->component_manager; -	s->event_manager = EventManager::get_instance(); +	this->script->game_object_id = this->game_object_id; +	this->script->active = this->active; +	this->script->mediator = this->mediator; -	this->script = std::unique_ptr<Script>(s);  	return *this;  } diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt index 25a9439..ac8f301 100644 --- a/src/crepe/api/CMakeLists.txt +++ b/src/crepe/api/CMakeLists.txt @@ -9,13 +9,10 @@ target_sources(crepe PUBLIC  	Texture.cpp  	AssetManager.cpp  	Sprite.cpp -	SaveManager.cpp  	Config.cpp  	Metadata.cpp -	SceneManager.cpp  	Camera.cpp  	Animator.cpp -	EventManager.cpp  	IKeyListener.cpp  	IMouseListener.cpp  	LoopManager.cpp @@ -43,15 +40,10 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES  	Texture.h   	AssetManager.h   	AssetManager.hpp -	SaveManager.h  	Scene.h  	Metadata.h -	SceneManager.h -	SceneManager.hpp  	Camera.h  	Animator.h -	EventManager.h -	EventManager.hpp  	EventHandler.h  	EventHandler.hpp  	Event.h diff --git a/src/crepe/api/GameObject.hpp b/src/crepe/api/GameObject.hpp index 17b17d7..a6b45b0 100644 --- a/src/crepe/api/GameObject.hpp +++ b/src/crepe/api/GameObject.hpp @@ -1,6 +1,6 @@  #pragma once -#include "../ComponentManager.h" +#include "../manager/ComponentManager.h"  #include "GameObject.h" diff --git a/src/crepe/api/IKeyListener.h b/src/crepe/api/IKeyListener.h index 328a4c2..6ded107 100644 --- a/src/crepe/api/IKeyListener.h +++ b/src/crepe/api/IKeyListener.h @@ -1,8 +1,9 @@  #pragma once +#include "../manager/EventManager.h" +  #include "Event.h"  #include "EventHandler.h" -#include "EventManager.h"  namespace crepe { diff --git a/src/crepe/api/IMouseListener.h b/src/crepe/api/IMouseListener.h index 15e1619..9e4fdf7 100644 --- a/src/crepe/api/IMouseListener.h +++ b/src/crepe/api/IMouseListener.h @@ -1,8 +1,9 @@  #pragma once +#include "../manager/EventManager.h" +  #include "Event.h"  #include "EventHandler.h" -#include "EventManager.h"  namespace crepe { diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp index b343250..dc2d9e0 100644 --- a/src/crepe/api/LoopManager.cpp +++ b/src/crepe/api/LoopManager.cpp @@ -1,5 +1,3 @@ -#include "../facade/SDLContext.h" -  #include "../system/AnimatorSystem.h"  #include "../system/CollisionSystem.h"  #include "../system/InputSystem.h" @@ -9,12 +7,14 @@  #include "../system/ScriptSystem.h"  #include "LoopManager.h" -#include "LoopTimer.h"  using namespace crepe;  using namespace std;  LoopManager::LoopManager() { +	this->mediator.component_manager = this->component_manager; +	this->mediator.scene_manager = this->scene_manager; +  	this->load_system<AnimatorSystem>();  	this->load_system<CollisionSystem>();  	this->load_system<ParticleSystem>(); @@ -35,7 +35,7 @@ void LoopManager::set_running(bool running) { this->game_running = running; }  void LoopManager::fixed_update() {}  void LoopManager::loop() { -	LoopTimer & timer = LoopTimer::get_instance(); +	LoopTimer & timer = this->loop_timer;  	timer.start();  	while (game_running) { @@ -55,15 +55,17 @@ void LoopManager::loop() {  }  void LoopManager::setup() { +	LoopTimer & timer = this->loop_timer; +  	this->game_running = true; -	LoopTimer::get_instance().start(); -	LoopTimer::get_instance().set_fps(200); +	timer.start(); +	timer.set_fps(200);  }  void LoopManager::render() { -	if (this->game_running) { -		this->get_system<RenderSystem>().update(); -	} +	if (!this->game_running) return; + +	this->get_system<RenderSystem>().update();  } -void LoopManager::update() { LoopTimer & timer = LoopTimer::get_instance(); } +void LoopManager::update() {} diff --git a/src/crepe/api/LoopManager.h b/src/crepe/api/LoopManager.h index 13e6dac..d8910a0 100644 --- a/src/crepe/api/LoopManager.h +++ b/src/crepe/api/LoopManager.h @@ -2,9 +2,12 @@  #include <memory> -#include "../ComponentManager.h" +#include "../facade/SDLContext.h" +#include "../manager/ComponentManager.h" +#include "../manager/SceneManager.h"  #include "../system/System.h" -#include "api/SceneManager.h" + +#include "LoopTimer.h"  namespace crepe { @@ -85,10 +88,18 @@ private:  	bool game_running = false;  private: +	//! Global context +	Mediator mediator; +  	//! Component manager instance -	ComponentManager component_manager{}; +	ComponentManager component_manager{mediator};  	//! Scene manager instance -	SceneManager scene_manager{component_manager}; +	SceneManager scene_manager{mediator}; + +	//! SDL context \todo no more singletons! +	SDLContext & sdl_context = SDLContext::get_instance(); +	//! Loop timer \todo no more singletons! +	LoopTimer & loop_timer = LoopTimer::get_instance();  private:  	/** diff --git a/src/crepe/api/LoopManager.hpp b/src/crepe/api/LoopManager.hpp index 9cf470b..266758a 100644 --- a/src/crepe/api/LoopManager.hpp +++ b/src/crepe/api/LoopManager.hpp @@ -38,8 +38,11 @@ void LoopManager::load_system() {  	static_assert(is_base_of<System, T>::value,  				  "load_system must recieve a derivative class of System"); -	System * system = new T(this->component_manager); -	this->systems[typeid(T)] = unique_ptr<System>(system); +	const type_info & type = typeid(T); +	if (this->systems.contains(type)) +		throw runtime_error(format("LoopManager: {} is already initialized", type.name())); +	System * system = new T(this->mediator); +	this->systems[type] = unique_ptr<System>(system);  }  } // namespace crepe diff --git a/src/crepe/api/Scene.h b/src/crepe/api/Scene.h index f6fdb2a..9f1e8ce 100644 --- a/src/crepe/api/Scene.h +++ b/src/crepe/api/Scene.h @@ -2,6 +2,7 @@  #include <string> +#include "../manager/Mediator.h"  #include "../util/OptionalRef.h"  namespace crepe { @@ -34,6 +35,9 @@ public:  	 */  	virtual std::string get_name() const = 0; +	// TODO: Late references should ALWAYS be private! This is currently kept as-is so unit tests +	// keep passing, but this reference should not be directly accessible by the user!!! +  protected:  	/**  	 * \name Late references @@ -46,8 +50,8 @@ protected:  	 *  	 * \{  	 */ -	//! Reference to the ComponentManager -	OptionalRef<ComponentManager> component_manager; +	//! Mediator reference +	OptionalRef<Mediator> mediator;  	//! \}  }; diff --git a/src/crepe/api/Script.cpp b/src/crepe/api/Script.cpp index fcbe4c7..4091fd4 100644 --- a/src/crepe/api/Script.cpp +++ b/src/crepe/api/Script.cpp @@ -1,11 +1,17 @@ +#include <string> + +#include "../manager/SceneManager.h" +  #include "Script.h"  using namespace crepe; +using namespace std;  Script::~Script() { -	EventManager & evmgr = this->event_manager; +	Mediator & mediator = this->mediator; +	EventManager & mgr = mediator.event_manager;  	for (auto id : this->listeners) { -		evmgr.unsubscribe(id); +		mgr.unsubscribe(id);  	}  } @@ -13,3 +19,9 @@ template <>  void Script::subscribe(const EventHandler<CollisionEvent> & callback) {  	this->subscribe_internal(callback, this->game_object_id);  } + +void Script::set_next_scene(const string & name) { +	Mediator & mediator = this->mediator; +	SceneManager & mgr = mediator.scene_manager; +	mgr.set_next_scene(name); +} diff --git a/src/crepe/api/Script.h b/src/crepe/api/Script.h index a0870cb..1b339b0 100644 --- a/src/crepe/api/Script.h +++ b/src/crepe/api/Script.h @@ -2,11 +2,11 @@  #include <vector> +#include "../manager/EventManager.h" +#include "../manager/Mediator.h"  #include "../types.h"  #include "../util/OptionalRef.h" -#include "EventManager.h" -  namespace crepe {  class ScriptSystem; @@ -106,6 +106,12 @@ protected:  	template <typename EventType>  	void subscribe(const EventHandler<EventType> & callback); +	/** +	 * \brief Set the next scene using SceneManager +	 * \see SceneManager::set_next_scene +	 */ +	void set_next_scene(const std::string & name); +  	//! \}  private: @@ -160,10 +166,8 @@ private:  	game_object_id_t game_object_id;  	//! Reference to parent component  	OptionalRef<bool> active; -	//! Reference to component manager instance -	OptionalRef<ComponentManager> component_manager; -	//! Reference to event manager instance -	OptionalRef<EventManager> event_manager; +	//! Mediator reference +	OptionalRef<Mediator> mediator;  	//! \}  private: diff --git a/src/crepe/api/Script.hpp b/src/crepe/api/Script.hpp index a2463bf..45f1ff1 100644 --- a/src/crepe/api/Script.hpp +++ b/src/crepe/api/Script.hpp @@ -1,6 +1,6 @@  #pragma once -#include "../ComponentManager.h" +#include "../manager/ComponentManager.h"  #include "BehaviorScript.h"  #include "Script.h" @@ -20,7 +20,8 @@ T & Script::get_component() const {  template <typename T>  RefVector<T> Script::get_components() const { -	ComponentManager & mgr = this->component_manager; +	Mediator & mediator = this->mediator; +	ComponentManager & mgr = mediator.component_manager;  	return mgr.get_components_by_id<T>(this->game_object_id);  } @@ -33,7 +34,8 @@ void Script::logf(Args &&... args) {  template <typename EventType>  void Script::subscribe_internal(const EventHandler<EventType> & callback,  								event_channel_t channel) { -	EventManager & mgr = this->event_manager; +	Mediator & mediator = this->mediator; +	EventManager & mgr = mediator.event_manager;  	subscription_t listener = mgr.subscribe<EventType>(  		[this, callback](const EventType & data) -> bool {  			bool & active = this->active; diff --git a/src/crepe/manager/CMakeLists.txt b/src/crepe/manager/CMakeLists.txt new file mode 100644 index 0000000..517b8a2 --- /dev/null +++ b/src/crepe/manager/CMakeLists.txt @@ -0,0 +1,20 @@ +target_sources(crepe PUBLIC +	ComponentManager.cpp +	EventManager.cpp +	Manager.cpp +	SaveManager.cpp +	SceneManager.cpp +) + +target_sources(crepe PUBLIC FILE_SET HEADERS FILES +	ComponentManager.h +	ComponentManager.hpp +	EventManager.h +	EventManager.hpp +	Manager.h +	Mediator.h +	SaveManager.h +	SceneManager.h +	SceneManager.hpp +) + diff --git a/src/crepe/ComponentManager.cpp b/src/crepe/manager/ComponentManager.cpp index 5b73009..80cf8b4 100644 --- a/src/crepe/ComponentManager.cpp +++ b/src/crepe/manager/ComponentManager.cpp @@ -1,13 +1,16 @@ -#include "api/GameObject.h" -#include "util/Log.h" +#include "../api/GameObject.h" +#include "../types.h" +#include "../util/Log.h"  #include "ComponentManager.h" -#include "types.h"  using namespace crepe;  using namespace std; -ComponentManager::ComponentManager() { dbg_trace(); } +ComponentManager::ComponentManager(Mediator & mediator) : Manager(mediator) { +	mediator.component_manager = *this; +	dbg_trace(); +}  ComponentManager::~ComponentManager() { dbg_trace(); }  void ComponentManager::delete_all_components_of_id(game_object_id_t id) { diff --git a/src/crepe/ComponentManager.h b/src/crepe/manager/ComponentManager.h index 480124f..ad37586 100644 --- a/src/crepe/ComponentManager.h +++ b/src/crepe/manager/ComponentManager.h @@ -5,8 +5,10 @@  #include <unordered_map>  #include <vector> -#include "Component.h" -#include "types.h" +#include "../Component.h" +#include "../types.h" + +#include "Manager.h"  namespace crepe { @@ -17,7 +19,7 @@ class GameObject;   *    * This class manages all components. It provides methods to add, delete and get components.   */ -class ComponentManager { +class ComponentManager : public Manager {  	// TODO: This relation should be removed! I (loek) believe that the scene manager should  	// create/destroy components because the GameObject's are stored in concrete Scene classes,  	// which will in turn call GameObject's destructor, which will in turn call @@ -26,7 +28,7 @@ class ComponentManager {  	friend class SceneManager;  public: -	ComponentManager(); // dbg_trace +	ComponentManager(Mediator & mediator);  	~ComponentManager(); // dbg_trace  	/** diff --git a/src/crepe/ComponentManager.hpp b/src/crepe/manager/ComponentManager.hpp index ffb38ec..ffb38ec 100644 --- a/src/crepe/ComponentManager.hpp +++ b/src/crepe/manager/ComponentManager.hpp diff --git a/src/crepe/api/EventManager.cpp b/src/crepe/manager/EventManager.cpp index 20f0dd3..20f0dd3 100644 --- a/src/crepe/api/EventManager.cpp +++ b/src/crepe/manager/EventManager.cpp diff --git a/src/crepe/api/EventManager.h b/src/crepe/manager/EventManager.h index 1a33023..d634f54 100644 --- a/src/crepe/api/EventManager.h +++ b/src/crepe/manager/EventManager.h @@ -5,8 +5,8 @@  #include <unordered_map>  #include <vector> -#include "Event.h" -#include "EventHandler.h" +#include "../api/Event.h" +#include "../api/EventHandler.h"  namespace crepe { diff --git a/src/crepe/api/EventManager.hpp b/src/crepe/manager/EventManager.hpp index a5f4556..a5f4556 100644 --- a/src/crepe/api/EventManager.hpp +++ b/src/crepe/manager/EventManager.hpp diff --git a/src/crepe/manager/Manager.cpp b/src/crepe/manager/Manager.cpp new file mode 100644 index 0000000..1182785 --- /dev/null +++ b/src/crepe/manager/Manager.cpp @@ -0,0 +1,5 @@ +#include "Manager.h" + +using namespace crepe; + +Manager::Manager(Mediator & mediator) : mediator(mediator) {} diff --git a/src/crepe/manager/Manager.h b/src/crepe/manager/Manager.h new file mode 100644 index 0000000..84d80fe --- /dev/null +++ b/src/crepe/manager/Manager.h @@ -0,0 +1,24 @@ +#pragma once + +#include "Mediator.h" + +namespace crepe { + +/** + * \brief Base manager class + * + * Managers are used for various tasks that fall outside the ECS system category. All managers + * are required to register themselves to the mediator passed to the constructor, and this + * mutable reference is saved for convenience, even though not all managers use the mediator + * directly. + */ +class Manager { +public: +	Manager(Mediator & mediator); +	virtual ~Manager() = default; + +protected: +	Mediator & mediator; +}; + +} // namespace crepe diff --git a/src/crepe/manager/Mediator.h b/src/crepe/manager/Mediator.h new file mode 100644 index 0000000..71bd1c9 --- /dev/null +++ b/src/crepe/manager/Mediator.h @@ -0,0 +1,33 @@ +#pragma once + +#include "../util/OptionalRef.h" + +// TODO: remove these singletons: +#include "EventManager.h" +#include "SaveManager.h" + +namespace crepe { + +class ComponentManager; +class SceneManager; + +/** + * Struct to pass references to classes that would otherwise need to be singletons down to + * other classes within the engine hierarchy. Made to prevent constant changes to subclasses to + * pass specific references through dependency injection. All references on this struct + * *should* be explicitly checked for availability as this struct does not guarantee anything. + * + * \note Dereferencing members of this struct should be deferred. If you are a user of this + * class, keep a reference to this mediator instead of just picking references from it when you + * receive an instance. + * + * \warning This class should never be directly accessible from the API + */ +struct Mediator { +	OptionalRef<ComponentManager> component_manager; +	OptionalRef<SceneManager> scene_manager; +	OptionalRef<SaveManager> save_manager = SaveManager::get_instance(); +	OptionalRef<EventManager> event_manager = EventManager::get_instance(); +}; + +} // namespace crepe diff --git a/src/crepe/api/SaveManager.cpp b/src/crepe/manager/SaveManager.cpp index c5f43ea..d4ed1c1 100644 --- a/src/crepe/api/SaveManager.cpp +++ b/src/crepe/manager/SaveManager.cpp @@ -1,9 +1,9 @@ +#include "../ValueBroker.h" +#include "../api/Config.h"  #include "../facade/DB.h"  #include "../util/Log.h" -#include "Config.h"  #include "SaveManager.h" -#include "ValueBroker.h"  using namespace std;  using namespace crepe; diff --git a/src/crepe/api/SaveManager.h b/src/crepe/manager/SaveManager.h index 3d8c852..3d8c852 100644 --- a/src/crepe/api/SaveManager.h +++ b/src/crepe/manager/SaveManager.h diff --git a/src/crepe/api/SceneManager.cpp b/src/crepe/manager/SceneManager.cpp index 1f783ad..50a9fbb 100644 --- a/src/crepe/api/SceneManager.cpp +++ b/src/crepe/manager/SceneManager.cpp @@ -1,14 +1,15 @@  #include <algorithm>  #include <memory> -#include "../ComponentManager.h" - +#include "ComponentManager.h"  #include "SceneManager.h"  using namespace crepe;  using namespace std; -SceneManager::SceneManager(ComponentManager & mgr) : component_manager(mgr) {} +SceneManager::SceneManager(Mediator & mediator) : Manager(mediator) { +	mediator.scene_manager = *this; +}  void SceneManager::set_next_scene(const string & name) { next_scene = name; } @@ -26,7 +27,7 @@ void SceneManager::load_next_scene() {  	unique_ptr<Scene> & scene = *it;  	// Delete all components of the current scene -	ComponentManager & mgr = this->component_manager; +	ComponentManager & mgr = this->mediator.component_manager;  	mgr.delete_all_components();  	// Load the new scene diff --git a/src/crepe/api/SceneManager.h b/src/crepe/manager/SceneManager.h index f6f62cd..e0955c2 100644 --- a/src/crepe/api/SceneManager.h +++ b/src/crepe/manager/SceneManager.h @@ -3,7 +3,9 @@  #include <memory>  #include <vector> -#include "Scene.h" +#include "../api/Scene.h" + +#include "Manager.h"  namespace crepe { @@ -15,10 +17,9 @@ class ComponentManager;   * This class manages scenes. It can add new scenes and load them. It also manages the current scene   * and the next scene.   */ -class SceneManager { +class SceneManager : public Manager {  public: -	//! \param mgr  Reference to the ComponentManager -	SceneManager(ComponentManager & mgr); +	SceneManager(Mediator & mediator);  public:  	/** @@ -44,8 +45,6 @@ private:  	std::vector<std::unique_ptr<Scene>> scenes;  	//! Next scene to load  	std::string next_scene; -	//! Reference to the ComponentManager -	ComponentManager & component_manager;  };  } // namespace crepe diff --git a/src/crepe/api/SceneManager.hpp b/src/crepe/manager/SceneManager.hpp index 5c8e417..dff4e51 100644 --- a/src/crepe/api/SceneManager.hpp +++ b/src/crepe/manager/SceneManager.hpp @@ -12,7 +12,7 @@ void SceneManager::add_scene(Args &&... args) {  	Scene * scene = new T(std::forward<Args>(args)...);  	unique_ptr<Scene> unique_scene(scene); -	unique_scene->component_manager = this->component_manager; +	unique_scene->mediator = this->mediator;  	this->scenes.emplace_back(std::move(unique_scene)); diff --git a/src/crepe/system/AnimatorSystem.cpp b/src/crepe/system/AnimatorSystem.cpp index 4c40940..8bb6465 100644 --- a/src/crepe/system/AnimatorSystem.cpp +++ b/src/crepe/system/AnimatorSystem.cpp @@ -1,15 +1,15 @@  #include <cstdint> -#include "api/Animator.h" -#include "facade/SDLContext.h" +#include "../api/Animator.h" +#include "../facade/SDLContext.h" +#include "../manager/ComponentManager.h"  #include "AnimatorSystem.h" -#include "ComponentManager.h"  using namespace crepe;  void AnimatorSystem::update() { -	ComponentManager & mgr = this->component_manager; +	ComponentManager & mgr = this->mediator.component_manager;  	RefVector<Animator> animations = mgr.get_components_by_type<Animator>(); diff --git a/src/crepe/system/ParticleSystem.cpp b/src/crepe/system/ParticleSystem.cpp index 0e62a57..b14c52f 100644 --- a/src/crepe/system/ParticleSystem.cpp +++ b/src/crepe/system/ParticleSystem.cpp @@ -2,17 +2,17 @@  #include <cstdlib>  #include <ctime> -#include "api/ParticleEmitter.h" -#include "api/Transform.h" +#include "../api/ParticleEmitter.h" +#include "../api/Transform.h" +#include "../manager/ComponentManager.h" -#include "ComponentManager.h"  #include "ParticleSystem.h"  using namespace crepe;  void ParticleSystem::update() {  	// Get all emitters -	ComponentManager & mgr = this->component_manager; +	ComponentManager & mgr = this->mediator.component_manager;  	RefVector<ParticleEmitter> emitters = mgr.get_components_by_type<ParticleEmitter>();  	for (ParticleEmitter & emitter : emitters) { diff --git a/src/crepe/system/PhysicsSystem.cpp b/src/crepe/system/PhysicsSystem.cpp index 514a4b3..bebcf3d 100644 --- a/src/crepe/system/PhysicsSystem.cpp +++ b/src/crepe/system/PhysicsSystem.cpp @@ -1,17 +1,17 @@  #include <cmath> -#include "../ComponentManager.h"  #include "../api/Config.h"  #include "../api/Rigidbody.h"  #include "../api/Transform.h"  #include "../api/Vector2.h" +#include "../manager/ComponentManager.h"  #include "PhysicsSystem.h"  using namespace crepe;  void PhysicsSystem::update() { -	ComponentManager & mgr = this->component_manager; +	ComponentManager & mgr = this->mediator.component_manager;  	RefVector<Rigidbody> rigidbodies = mgr.get_components_by_type<Rigidbody>();  	RefVector<Transform> transforms = mgr.get_components_by_type<Transform>(); diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp index 11c9669..92dba43 100644 --- a/src/crepe/system/RenderSystem.cpp +++ b/src/crepe/system/RenderSystem.cpp @@ -5,12 +5,12 @@  #include <stdexcept>  #include <vector> -#include "../ComponentManager.h"  #include "../api/Camera.h"  #include "../api/ParticleEmitter.h"  #include "../api/Sprite.h"  #include "../api/Transform.h"  #include "../facade/SDLContext.h" +#include "../manager/ComponentManager.h"  #include "RenderSystem.h" @@ -22,7 +22,7 @@ void RenderSystem::clear_screen() { this->context.clear_screen(); }  void RenderSystem::present_screen() { this->context.present_screen(); }  const Camera & RenderSystem::update_camera() { -	ComponentManager & mgr = this->component_manager; +	ComponentManager & mgr = this->mediator.component_manager;  	RefVector<Camera> cameras = mgr.get_components_by_type<Camera>(); @@ -62,7 +62,7 @@ void RenderSystem::update() {  bool RenderSystem::render_particle(const Sprite & sprite, const Camera & cam,  								   const double & scale) { -	ComponentManager & mgr = this->component_manager; +	ComponentManager & mgr = this->mediator.component_manager;  	vector<reference_wrapper<ParticleEmitter>> emitters  		= mgr.get_components_by_id<ParticleEmitter>(sprite.game_object_id); @@ -102,7 +102,7 @@ void RenderSystem::render_normal(const Sprite & sprite, const Camera & cam,  }  void RenderSystem::render() { -	ComponentManager & mgr = this->component_manager; +	ComponentManager & mgr = this->mediator.component_manager;  	const Camera & cam = this->update_camera();  	RefVector<Sprite> sprites = mgr.get_components_by_type<Sprite>(); diff --git a/src/crepe/system/ScriptSystem.cpp b/src/crepe/system/ScriptSystem.cpp index 20a83f7..d6b2ca1 100644 --- a/src/crepe/system/ScriptSystem.cpp +++ b/src/crepe/system/ScriptSystem.cpp @@ -1,6 +1,6 @@ -#include "../ComponentManager.h"  #include "../api/BehaviorScript.h"  #include "../api/Script.h" +#include "../manager/ComponentManager.h"  #include "ScriptSystem.h" @@ -10,7 +10,7 @@ using namespace crepe;  void ScriptSystem::update() {  	dbg_trace(); -	ComponentManager & mgr = this->component_manager; +	ComponentManager & mgr = this->mediator.component_manager;  	RefVector<BehaviorScript> behavior_scripts = mgr.get_components_by_type<BehaviorScript>();  	for (BehaviorScript & behavior_script : behavior_scripts) { diff --git a/src/crepe/system/System.cpp b/src/crepe/system/System.cpp index 937a423..f68549b 100644 --- a/src/crepe/system/System.cpp +++ b/src/crepe/system/System.cpp @@ -4,4 +4,4 @@  using namespace crepe; -System::System(ComponentManager & mgr) : component_manager(mgr) { dbg_trace(); } +System::System(const Mediator & mediator) : mediator(mediator) { dbg_trace(); } diff --git a/src/crepe/system/System.h b/src/crepe/system/System.h index 28ea20e..063dfbf 100644 --- a/src/crepe/system/System.h +++ b/src/crepe/system/System.h @@ -1,5 +1,7 @@  #pragma once +#include "../manager/Mediator.h" +  namespace crepe {  class ComponentManager; @@ -7,9 +9,8 @@ class ComponentManager;  /**   * \brief Base ECS system class   * - * This class is used as the base for all system classes. Classes derived from - * System must implement the System::update() method and copy Script::Script - * with the `using`-syntax. + * This class is used as the base for all system classes. Classes derived from System must + * implement the System::update() method and copy Script::Script with the `using`-syntax.   */  class System {  public: @@ -19,11 +20,11 @@ public:  	virtual void update() = 0;  public: -	System(ComponentManager &); +	System(const Mediator & m);  	virtual ~System() = default;  protected: -	ComponentManager & component_manager; +	const Mediator & mediator;  };  } // namespace crepe diff --git a/src/doc/feature/scene.dox b/src/doc/feature/scene.dox index d81df4c..4124e37 100644 --- a/src/doc/feature/scene.dox +++ b/src/doc/feature/scene.dox @@ -6,10 +6,11 @@ namespace crepe {  \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). +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 for this purpose).  \see SceneManager  \see GameObject @@ -18,19 +19,25 @@ GameObjects during runtime of a Scene (use \ref feature_script "Scripting" for t  \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. +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> diff --git a/src/doc/features.dox b/src/doc/features.dox index 4786bed..21a040a 100644 --- a/src/doc/features.dox +++ b/src/doc/features.dox @@ -1,10 +1,28 @@  // vim:ft=doxygen  /** +\htmlonly +<style> +table.memberdecls { display: none; } +ul { margin: 1ex 0pt; } +</style> +\endhtmlonly +  \defgroup feature Features  \brief Engine components  This page lists engine features and contains usage instructions for each  feature. +\par Features + +- Scripting +	- \ref feature_script \n\copybrief feature_script + +- Game flow management +	- \ref feature_scene \n\copybrief feature_scene + +- Entity +	- \ref feature_gameobject \n\copybrief feature_gameobject +  */ diff --git a/src/doc/index.dox b/src/doc/index.dox index 5ec7889..7796f34 100644 --- a/src/doc/index.dox +++ b/src/doc/index.dox @@ -8,3 +8,10 @@ Welcome to the documentation for the crêpe game engine.  \see feature  */ + +/** + +\namespace crepe +\brief Engine namespace + +*/ diff --git a/src/doc/layout.xml b/src/doc/layout.xml index fb4cc0c..6336655 100644 --- a/src/doc/layout.xml +++ b/src/doc/layout.xml @@ -11,7 +11,7 @@  			<tab type="modulelist" visible="yes" title="" intro=""/>  			<tab type="modulemembers" visible="yes" title="" intro=""/>  		</tab> -		<tab type="namespaces" visible="no" title=""> +		<tab type="namespaces" visible="yes" title="">  			<tab type="namespacelist" visible="yes" title="" intro=""/>  			<tab type="namespacemembers" visible="yes" title="" intro=""/>  		</tab> @@ -56,10 +56,10 @@  			<interfaces title=""/>  			<publicslots title=""/>  			<signals title=""/> -			<publicmethods title=""/> -			<publicstaticmethods title=""/>  			<publicattributes title=""/>  			<publicstaticattributes title=""/> +			<publicmethods title=""/> +			<publicstaticmethods title=""/>  			<protectedtypes title=""/>  			<protectedslots title=""/>  			<protectedmethods title=""/> @@ -102,11 +102,12 @@  	</class>  	<namespace>  		<briefdescription visible="yes"/> +		<detaileddescription title=""/>  		<memberdecl>  			<nestednamespaces visible="yes" title=""/>  			<constantgroups visible="yes" title=""/>  			<interfaces visible="yes" title=""/> -			<classes visible="yes" title=""/> +			<classes visible="no" title=""/>  			<concepts visible="yes" title=""/>  			<structs visible="yes" title=""/>  			<exceptions visible="yes" title=""/> @@ -119,7 +120,6 @@  			<properties title=""/>  			<membergroups visible="yes"/>  		</memberdecl> -		<detaileddescription title=""/>  		<memberdef>  			<inlineclasses title=""/>  			<typedefs title=""/> diff --git a/src/doc/style.css b/src/doc/style.css index daabd39..c12240c 100644 --- a/src/doc/style.css +++ b/src/doc/style.css @@ -1,6 +1,6 @@  #titlearea, -address { -	display: none; -} +address, +a[href="namespaces.html"] +{ display: none; }  h2.groupheader { margin-top: revert; } diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index dd4a754..e19d7de 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -13,4 +13,6 @@ target_sources(test_main PUBLIC  	DBTest.cpp  	Vector2Test.cpp  	InputTest.cpp +	ScriptEventTest.cpp +	ScriptSceneTest.cpp  ) diff --git a/src/test/DBTest.cpp b/src/test/DBTest.cpp index e80814c..99dedff 100644 --- a/src/test/DBTest.cpp +++ b/src/test/DBTest.cpp @@ -1,6 +1,7 @@ -#include <crepe/facade/DB.h>  #include <gtest/gtest.h> +#include <crepe/facade/DB.h> +  using namespace std;  using namespace crepe;  using namespace testing; diff --git a/src/test/ECSTest.cpp b/src/test/ECSTest.cpp index af9d6f2..3e6c61c 100644 --- a/src/test/ECSTest.cpp +++ b/src/test/ECSTest.cpp @@ -2,18 +2,20 @@  #define protected public -#include <crepe/ComponentManager.h>  #include <crepe/api/GameObject.h>  #include <crepe/api/Metadata.h>  #include <crepe/api/Transform.h>  #include <crepe/api/Vector2.h> +#include <crepe/manager/ComponentManager.h>  using namespace std;  using namespace crepe;  class ECSTest : public ::testing::Test { +	Mediator m; +  public: -	ComponentManager mgr{}; +	ComponentManager mgr{m};  };  TEST_F(ECSTest, createGameObject) { diff --git a/src/test/EventTest.cpp b/src/test/EventTest.cpp index c75bcc1..4a4872d 100644 --- a/src/test/EventTest.cpp +++ b/src/test/EventTest.cpp @@ -1,10 +1,11 @@ - -#include "api/Event.h" -#include "api/EventManager.h" -#include "api/IKeyListener.h" -#include "api/IMouseListener.h"  #include <gmock/gmock.h>  #include <gtest/gtest.h> + +#include <crepe/api/Event.h> +#include <crepe/api/IKeyListener.h> +#include <crepe/api/IMouseListener.h> +#include <crepe/manager/EventManager.h> +  using namespace std;  using namespace std::chrono_literals;  using namespace crepe; @@ -36,10 +37,7 @@ public:  };  TEST_F(EventManagerTest, EventSubscription) { -	EventHandler<KeyPressEvent> key_handler = [](const KeyPressEvent & e) { -		std::cout << "Key Event Triggered" << std::endl; -		return true; -	}; +	EventHandler<KeyPressEvent> key_handler = [](const KeyPressEvent & e) { return true; };  	// Subscribe to KeyPressEvent  	EventManager::get_instance().subscribe<KeyPressEvent>(key_handler, 1); diff --git a/src/test/ParticleTest.cpp b/src/test/ParticleTest.cpp index 976f9a1..a659fe5 100644 --- a/src/test/ParticleTest.cpp +++ b/src/test/ParticleTest.cpp @@ -1,12 +1,12 @@ -#include "api/Texture.h" -#include <crepe/ComponentManager.h>  #include <crepe/Particle.h>  #include <crepe/api/Config.h>  #include <crepe/api/GameObject.h>  #include <crepe/api/ParticleEmitter.h>  #include <crepe/api/Rigidbody.h>  #include <crepe/api/Sprite.h> +#include <crepe/api/Texture.h>  #include <crepe/api/Transform.h> +#include <crepe/manager/ComponentManager.h>  #include <crepe/system/ParticleSystem.h>  #include <gtest/gtest.h>  #include <math.h> @@ -16,9 +16,11 @@ using namespace std::chrono_literals;  using namespace crepe;  class ParticlesTest : public ::testing::Test { +	Mediator m; +  public: -	ComponentManager component_manager; -	ParticleSystem particle_system{component_manager}; +	ComponentManager component_manager{m}; +	ParticleSystem particle_system{m};  	void SetUp() override {  		ComponentManager & mgr = this->component_manager; diff --git a/src/test/PhysicsTest.cpp b/src/test/PhysicsTest.cpp index 33b6020..43af8e4 100644 --- a/src/test/PhysicsTest.cpp +++ b/src/test/PhysicsTest.cpp @@ -1,8 +1,8 @@ -#include <crepe/ComponentManager.h>  #include <crepe/api/Config.h>  #include <crepe/api/GameObject.h>  #include <crepe/api/Rigidbody.h>  #include <crepe/api/Transform.h> +#include <crepe/manager/ComponentManager.h>  #include <crepe/system/PhysicsSystem.h>  #include <gtest/gtest.h> @@ -11,9 +11,11 @@ using namespace std::chrono_literals;  using namespace crepe;  class PhysicsTest : public ::testing::Test { +	Mediator m; +  public: -	ComponentManager component_manager; -	PhysicsSystem system{component_manager}; +	ComponentManager component_manager{m}; +	PhysicsSystem system{m};  	void SetUp() override {  		ComponentManager & mgr = this->component_manager; diff --git a/src/test/RenderSystemTest.cpp b/src/test/RenderSystemTest.cpp index bb5b81a..c105dcb 100644 --- a/src/test/RenderSystemTest.cpp +++ b/src/test/RenderSystemTest.cpp @@ -1,4 +1,3 @@ -#include "types.h"  #include <functional>  #include <gtest/gtest.h>  #include <memory> @@ -7,12 +6,12 @@  #define private public  #define protected public -#include "crepe/api/Camera.h" -#include <crepe/ComponentManager.h> +#include <crepe/api/Camera.h>  #include <crepe/api/Color.h>  #include <crepe/api/GameObject.h>  #include <crepe/api/Sprite.h>  #include <crepe/api/Texture.h> +#include <crepe/manager/ComponentManager.h>  #include <crepe/system/RenderSystem.h> @@ -21,9 +20,11 @@ using namespace crepe;  using namespace testing;  class RenderSystemTest : public Test { +	Mediator m; +  public: -	ComponentManager mgr{}; -	RenderSystem sys{mgr}; +	ComponentManager mgr{m}; +	RenderSystem sys{m};  	GameObject entity1 = this->mgr.new_object("name");  	GameObject entity2 = this->mgr.new_object("name");  	GameObject entity3 = this->mgr.new_object("name"); diff --git a/src/test/SceneManagerTest.cpp b/src/test/SceneManagerTest.cpp index 62b7d33..9bb260c 100644 --- a/src/test/SceneManagerTest.cpp +++ b/src/test/SceneManagerTest.cpp @@ -1,12 +1,13 @@ -#include "types.h" -#include <crepe/ComponentManager.h> +#include <gtest/gtest.h> +  #include <crepe/api/GameObject.h>  #include <crepe/api/Metadata.h>  #include <crepe/api/Scene.h> -#include <crepe/api/SceneManager.h>  #include <crepe/api/Transform.h>  #include <crepe/api/Vector2.h> -#include <gtest/gtest.h> +#include <crepe/manager/ComponentManager.h> +#include <crepe/manager/SceneManager.h> +#include <crepe/types.h>  using namespace std;  using namespace crepe; @@ -14,7 +15,8 @@ using namespace crepe;  class ConcreteScene1 : public Scene {  public:  	void load_scene() { -		ComponentManager & mgr = this->component_manager; +		Mediator & mediator = this->mediator; +		ComponentManager & mgr = mediator.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,7 +28,8 @@ public:  class ConcreteScene2 : public Scene {  public:  	void load_scene() { -		ComponentManager & mgr = this->component_manager; +		Mediator & mediator = this->mediator; +		ComponentManager & mgr = mediator.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); @@ -41,7 +44,8 @@ public:  	ConcreteScene3(const string & name) : name(name) {}  	void load_scene() { -		ComponentManager & mgr = this->component_manager; +		Mediator & mediator = this->mediator; +		ComponentManager & mgr = mediator.component_manager;  		GameObject object1 = mgr.new_object("scene_3", "tag_scene_3", vec2{0, 0}, 0, 1);  	} @@ -52,9 +56,11 @@ private:  };  class SceneManagerTest : public ::testing::Test { +	Mediator m; +  public: -	ComponentManager component_mgr{}; -	SceneManager scene_mgr{component_mgr}; +	ComponentManager component_mgr{m}; +	SceneManager scene_mgr{m};  };  TEST_F(SceneManagerTest, loadScene) { diff --git a/src/test/ScriptEventTest.cpp b/src/test/ScriptEventTest.cpp new file mode 100644 index 0000000..5da31e7 --- /dev/null +++ b/src/test/ScriptEventTest.cpp @@ -0,0 +1,50 @@ +#include <gtest/gtest.h> + +// stupid hack to allow access to private/protected members under test +#define private public +#define protected public + +#include <crepe/api/BehaviorScript.h> +#include <crepe/api/Event.h> +#include <crepe/api/GameObject.h> +#include <crepe/api/Script.h> +#include <crepe/api/Vector2.h> +#include <crepe/manager/ComponentManager.h> +#include <crepe/manager/EventManager.h> +#include <crepe/system/ScriptSystem.h> + +#include "ScriptTest.h" + +using namespace std; +using namespace crepe; +using namespace testing; + +class ScriptEventTest : public ScriptTest { +public: +	EventManager & event_manager = mediator.event_manager; + +	class MyEvent : public Event {}; +}; + +TEST_F(ScriptEventTest, Inactive) { +	BehaviorScript & behaviorscript = this->behaviorscript; +	MyScript & script = this->script; +	EventManager & evmgr = this->event_manager; + +	unsigned event_count = 0; +	script.subscribe<MyEvent>([&](const MyEvent &) { +		event_count++; +		return true; +	}); + +	system.update(); +	behaviorscript.active = false; +	EXPECT_EQ(0, event_count); + +	evmgr.trigger_event<MyEvent>(); +	EXPECT_EQ(0, event_count); + +	behaviorscript.active = true; +	evmgr.trigger_event<MyEvent>(); +	EXPECT_EQ(1, event_count); +} diff --git a/src/test/ScriptSceneTest.cpp b/src/test/ScriptSceneTest.cpp new file mode 100644 index 0000000..9ee1e52 --- /dev/null +++ b/src/test/ScriptSceneTest.cpp @@ -0,0 +1,30 @@ +#include <gtest/gtest.h> + +// stupid hack to allow access to private/protected members under test +#define private public +#define protected public + +#include "ScriptTest.h" +#include <crepe/manager/SceneManager.h> + +using namespace std; +using namespace crepe; +using namespace testing; + +class ScriptSceneTest : public ScriptTest { +public: +	SceneManager scene_manager{mediator}; + +	class MyScene : public Scene {}; +}; + +TEST_F(ScriptSceneTest, Inactive) { +	BehaviorScript & behaviorscript = this->behaviorscript; +	MyScript & script = this->script; + +	const char * non_default_value = "foo"; +	ASSERT_NE(non_default_value, scene_manager.next_scene); + +	script.set_next_scene(non_default_value); +	EXPECT_EQ(non_default_value, scene_manager.next_scene); +} diff --git a/src/test/ScriptTest.cpp b/src/test/ScriptTest.cpp index 78d5061..1d2d6dd 100644 --- a/src/test/ScriptTest.cpp +++ b/src/test/ScriptTest.cpp @@ -1,129 +1,77 @@ +#include <gmock/gmock.h>  #include <gtest/gtest.h>  // stupid hack to allow access to private/protected members under test  #define private public  #define protected public -#include <crepe/ComponentManager.h> -#include <crepe/api/BehaviorScript.h> -#include <crepe/api/Event.h> -#include <crepe/api/EventManager.h> +#include "ScriptTest.h"  #include <crepe/api/GameObject.h> -#include <crepe/api/Script.h> -#include <crepe/api/Vector2.h> -#include <crepe/system/ScriptSystem.h>  using namespace std;  using namespace crepe;  using namespace testing; -class MyEvent : public Event {}; - -class ScriptTest : public Test { -public: -	ComponentManager component_manager{}; -	ScriptSystem system{component_manager}; -	EventManager & event_manager = EventManager::get_instance(); - -	class MyScript : public Script { -		// NOTE: default (private) visibility of init and update shouldn't cause -		// issues! -		void init() { -			this->init_count++; - -			subscribe<MyEvent>([this](const MyEvent &) { -				this->event_count++; -				return true; -			}); - -			// init should never be called more than once -			EXPECT_LE(this->init_count, 1); -		} -		void update() { this->update_count++; } - -	public: -		unsigned init_count = 0; -		unsigned update_count = 0; -		unsigned event_count = 0; -	}; - -	OptionalRef<BehaviorScript> behaviorscript; -	OptionalRef<MyScript> script; - -	void SetUp() override { -		auto & mgr = this->component_manager; -		GameObject entity = mgr.new_object("name"); -		BehaviorScript & component = entity.add_component<BehaviorScript>(); - -		this->behaviorscript = component; -		ASSERT_TRUE(this->behaviorscript); -		EXPECT_EQ(component.script.get(), nullptr); -		component.set_script<MyScript>(); -		ASSERT_NE(component.script.get(), nullptr); - -		this->script = *(MyScript *) component.script.get(); -		ASSERT_TRUE(this->script); - -		// sanity -		MyScript & script = this->script; -		ASSERT_EQ(script.init_count, 0); -		ASSERT_EQ(script.update_count, 0); -		ASSERT_EQ(script.event_count, 0); -	} -}; +void ScriptTest::SetUp() { +	auto & mgr = this->component_manager; +	GameObject entity = mgr.new_object("name"); +	BehaviorScript & component = entity.add_component<BehaviorScript>(); + +	this->behaviorscript = component; +	ASSERT_TRUE(this->behaviorscript); +	EXPECT_EQ(component.script.get(), nullptr); +	component.set_script<NiceMock<MyScript>>(); +	ASSERT_NE(component.script.get(), nullptr); + +	this->script = *(MyScript *) component.script.get(); +	ASSERT_TRUE(this->script); +}  TEST_F(ScriptTest, Default) {  	MyScript & script = this->script; -	EXPECT_EQ(0, script.init_count); -	EXPECT_EQ(0, script.update_count); -	EXPECT_EQ(0, script.event_count); +	EXPECT_CALL(script, init()).Times(0); +	EXPECT_CALL(script, update()).Times(0);  }  TEST_F(ScriptTest, UpdateOnce) {  	MyScript & script = this->script; -	system.update(); -	EXPECT_EQ(1, script.init_count); -	EXPECT_EQ(1, script.update_count); -	EXPECT_EQ(0, script.event_count); +	{ +		InSequence seq; + +		EXPECT_CALL(script, init()).Times(1); +		EXPECT_CALL(script, update()).Times(1); +		system.update(); +	} + +	{ +		InSequence seq; + +		EXPECT_CALL(script, init()).Times(0); +		EXPECT_CALL(script, update()).Times(1); +		system.update(); +	}  }  TEST_F(ScriptTest, UpdateInactive) {  	BehaviorScript & behaviorscript = this->behaviorscript;  	MyScript & script = this->script; -	behaviorscript.active = false; -	system.update(); -	EXPECT_EQ(0, script.init_count); -	EXPECT_EQ(0, script.update_count); -	EXPECT_EQ(0, script.event_count); - -	behaviorscript.active = true; -	system.update(); -	EXPECT_EQ(1, script.init_count); -	EXPECT_EQ(1, script.update_count); -	EXPECT_EQ(0, script.event_count); -} +	{ +		InSequence seq; -TEST_F(ScriptTest, EventInactive) { -	BehaviorScript & behaviorscript = this->behaviorscript; -	MyScript & script = this->script; -	EventManager & evmgr = this->event_manager; - -	system.update(); -	behaviorscript.active = false; -	EXPECT_EQ(1, script.init_count); -	EXPECT_EQ(1, script.update_count); -	EXPECT_EQ(0, script.event_count); - -	evmgr.trigger_event<MyEvent>(); -	EXPECT_EQ(1, script.init_count); -	EXPECT_EQ(1, script.update_count); -	EXPECT_EQ(0, script.event_count); - -	behaviorscript.active = true; -	evmgr.trigger_event<MyEvent>(); -	EXPECT_EQ(1, script.init_count); -	EXPECT_EQ(1, script.update_count); -	EXPECT_EQ(1, script.event_count); +		EXPECT_CALL(script, init()).Times(0); +		EXPECT_CALL(script, update()).Times(0); +		behaviorscript.active = false; +		system.update(); +	} + +	{ +		InSequence seq; + +		EXPECT_CALL(script, init()).Times(1); +		EXPECT_CALL(script, update()).Times(1); +		behaviorscript.active = true; +		system.update(); +	}  } diff --git a/src/test/ScriptTest.h b/src/test/ScriptTest.h new file mode 100644 index 0000000..1bbfdd3 --- /dev/null +++ b/src/test/ScriptTest.h @@ -0,0 +1,31 @@ +#pragma once + +#include <gmock/gmock.h> +#include <gtest/gtest.h> + +#include <crepe/api/BehaviorScript.h> +#include <crepe/api/Script.h> +#include <crepe/manager/ComponentManager.h> +#include <crepe/system/ScriptSystem.h> + +class ScriptTest : public testing::Test { +protected: +	crepe::Mediator mediator; + +public: +	crepe::ComponentManager component_manager{mediator}; +	crepe::ScriptSystem system{mediator}; + +	class MyScript : public crepe::Script { +		// NOTE: explicitly stating `public:` is not required on actual scripts + +	public: +		MOCK_METHOD(void, init, (), (override)); +		MOCK_METHOD(void, update, (), (override)); +	}; + +	crepe::OptionalRef<crepe::BehaviorScript> behaviorscript; +	crepe::OptionalRef<MyScript> script; + +	virtual void SetUp(); +}; |