aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Doxyfile4
-rw-r--r--contributing.md56
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/crepe/CMakeLists.txt4
-rw-r--r--src/crepe/api/BehaviorScript.cpp6
-rw-r--r--src/crepe/api/BehaviorScript.h9
-rw-r--r--src/crepe/api/BehaviorScript.hpp10
-rw-r--r--src/crepe/api/CMakeLists.txt8
-rw-r--r--src/crepe/api/GameObject.hpp2
-rw-r--r--src/crepe/api/IKeyListener.h3
-rw-r--r--src/crepe/api/IMouseListener.h3
-rw-r--r--src/crepe/api/LoopManager.cpp24
-rw-r--r--src/crepe/api/LoopManager.h19
-rw-r--r--src/crepe/api/LoopManager.hpp7
-rw-r--r--src/crepe/api/LoopTimer.cpp4
-rw-r--r--src/crepe/api/Scene.h8
-rw-r--r--src/crepe/api/Script.cpp16
-rw-r--r--src/crepe/api/Script.h16
-rw-r--r--src/crepe/api/Script.hpp8
-rw-r--r--src/crepe/manager/CMakeLists.txt20
-rw-r--r--src/crepe/manager/ComponentManager.cpp (renamed from src/crepe/ComponentManager.cpp)11
-rw-r--r--src/crepe/manager/ComponentManager.h (renamed from src/crepe/ComponentManager.h)10
-rw-r--r--src/crepe/manager/ComponentManager.hpp (renamed from src/crepe/ComponentManager.hpp)0
-rw-r--r--src/crepe/manager/EventManager.cpp (renamed from src/crepe/api/EventManager.cpp)0
-rw-r--r--src/crepe/manager/EventManager.h (renamed from src/crepe/api/EventManager.h)4
-rw-r--r--src/crepe/manager/EventManager.hpp (renamed from src/crepe/api/EventManager.hpp)0
-rw-r--r--src/crepe/manager/Manager.cpp5
-rw-r--r--src/crepe/manager/Manager.h24
-rw-r--r--src/crepe/manager/Mediator.h34
-rw-r--r--src/crepe/manager/SaveManager.cpp (renamed from src/crepe/api/SaveManager.cpp)4
-rw-r--r--src/crepe/manager/SaveManager.h (renamed from src/crepe/api/SaveManager.h)0
-rw-r--r--src/crepe/manager/SceneManager.cpp (renamed from src/crepe/api/SceneManager.cpp)9
-rw-r--r--src/crepe/manager/SceneManager.h (renamed from src/crepe/api/SceneManager.h)11
-rw-r--r--src/crepe/manager/SceneManager.hpp (renamed from src/crepe/api/SceneManager.hpp)2
-rw-r--r--src/crepe/system/AnimatorSystem.cpp8
-rw-r--r--src/crepe/system/ParticleSystem.cpp8
-rw-r--r--src/crepe/system/PhysicsSystem.cpp4
-rw-r--r--src/crepe/system/RenderSystem.cpp8
-rw-r--r--src/crepe/system/ScriptSystem.cpp4
-rw-r--r--src/crepe/system/System.cpp2
-rw-r--r--src/crepe/system/System.h11
-rw-r--r--src/doc/features.dox6
-rw-r--r--src/doc/index.dox7
-rw-r--r--src/doc/layout.xml10
-rw-r--r--src/doc/style.css6
-rw-r--r--src/test/CMakeLists.txt4
-rw-r--r--src/test/DBTest.cpp3
-rw-r--r--src/test/ECSTest.cpp6
-rw-r--r--src/test/EventTest.cpp16
-rw-r--r--src/test/LoopManagerTest.cpp44
-rw-r--r--src/test/LoopTimerTest.cpp (renamed from src/test/loopTimerTest.cpp)22
-rw-r--r--src/test/ParticleTest.cpp10
-rw-r--r--src/test/PhysicsTest.cpp8
-rw-r--r--src/test/RenderSystemTest.cpp11
-rw-r--r--src/test/SceneManagerTest.cpp24
-rw-r--r--src/test/ScriptEventTest.cpp50
-rw-r--r--src/test/ScriptSceneTest.cpp30
-rw-r--r--src/test/ScriptTest.cpp150
-rw-r--r--src/test/ScriptTest.h31
-rw-r--r--src/test/loopManagerTest.cpp50
60 files changed, 570 insertions, 305 deletions
diff --git a/Doxyfile b/Doxyfile
index f2714cd..07c86d1 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -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 50c51ed..7da9dca 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
@@ -41,15 +38,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 9bedbcc..040cb93 100644
--- a/src/crepe/api/LoopManager.cpp
+++ b/src/crepe/api/LoopManager.cpp
@@ -1,22 +1,19 @@
-#include <iostream>
-
#include "../facade/SDLContext.h"
+
#include "../system/AnimatorSystem.h"
#include "../system/CollisionSystem.h"
#include "../system/ParticleSystem.h"
#include "../system/PhysicsSystem.h"
#include "../system/RenderSystem.h"
#include "../system/ScriptSystem.h"
+#include "../manager/EventManager.h"
-#include "../api/EventManager.h"
#include "LoopManager.h"
-#include "LoopTimer.h"
using namespace crepe;
using namespace std;
LoopManager::LoopManager() {
- this->loop_timer = make_unique<LoopTimer>();
this->load_system<AnimatorSystem>();
this->load_system<CollisionSystem>();
this->load_system<ParticleSystem>();
@@ -26,12 +23,11 @@ LoopManager::LoopManager() {
EventManager::get_instance().subscribe<ShutDownEvent>([this](const ShutDownEvent& event) {
return this->on_shutdown(event);
});
-
+ this->loop_timer = make_unique<LoopTimer>();
+ this->mediator.loop_timer = *loop_timer;
}
-void LoopManager::process_input() {
- SDLContext::get_instance().handle_events(this->game_running);
-}
+void LoopManager::process_input() { this->sdl_context.handle_events(this->game_running); }
void LoopManager::start() {
this->setup();
@@ -59,15 +55,17 @@ void LoopManager::loop() {
}
void LoopManager::setup() {
+
+
this->game_running = true;
this->loop_timer->start();
- this->loop_timer->set_target_fps(60);
+ this->loop_timer->set_target_fps(200);
}
void LoopManager::render() {
- if (this->game_running) {
- this->get_system<RenderSystem>().update();
- }
+ if (!this->game_running) return;
+
+ this->get_system<RenderSystem>().update();
}
bool LoopManager::on_shutdown(const ShutDownEvent & e){
this->game_running = false;
diff --git a/src/crepe/api/LoopManager.h b/src/crepe/api/LoopManager.h
index eb2b525..17bddd1 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 "manager/SceneManager.h"
+
#include "api/Event.h"
#include "api/LoopTimer.h"
@@ -84,14 +87,20 @@ 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};
-private:
+ //! SDL context \todo no more singletons!
+ SDLContext & sdl_context = SDLContext::get_instance();
//! loop timer instance
std::unique_ptr<LoopTimer> loop_timer;
+private:
+
//! callback function for shutdown event
bool on_shutdown(const ShutDownEvent & e);
/**
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/LoopTimer.cpp b/src/crepe/api/LoopTimer.cpp
index 15011ca..07f0f75 100644
--- a/src/crepe/api/LoopTimer.cpp
+++ b/src/crepe/api/LoopTimer.cpp
@@ -13,8 +13,10 @@ LoopTimer::LoopTimer() { dbg_trace(); }
void LoopTimer::start() {
this->last_frame_time = std::chrono::steady_clock::now();
+
this->elapsed_time = std::chrono::milliseconds(0);
- this->elapsed_fixed_time = std::chrono::milliseconds(0);
+ // by starting the elapsed_fixed_time at (0 - fixed_delta_time) in milliseconds it calls a fixed update at the start of the loop.
+ this->elapsed_fixed_time = -std::chrono::duration_cast<std::chrono::milliseconds>(fixed_delta_time);
this->delta_time = std::chrono::milliseconds(0);
}
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..cd96614
--- /dev/null
+++ b/src/crepe/manager/Mediator.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include "../util/OptionalRef.h"
+
+// TODO: remove these singletons:
+#include "EventManager.h"
+#include "SaveManager.h"
+
+namespace crepe {
+
+class ComponentManager;
+class SceneManager;
+class LoopTimer;
+/**
+ * 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();
+ OptionalRef<LoopTimer> loop_timer;
+};
+
+} // 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/features.dox b/src/doc/features.dox
index 96b7c6c..21a040a 100644
--- a/src/doc/features.dox
+++ b/src/doc/features.dox
@@ -17,12 +17,12 @@ feature.
\par Features
- Scripting
- - \ref feature_script <br>\copybrief feature_script
+ - \ref feature_script \n\copybrief feature_script
- Game flow management
- - \ref feature_scene <br>\copybrief feature_scene
+ - \ref feature_scene \n\copybrief feature_scene
- Entity
- - \ref feature_gameobject <br>\copybrief feature_gameobject
+ - \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 b126add..232c763 100644
--- a/src/test/CMakeLists.txt
+++ b/src/test/CMakeLists.txt
@@ -12,5 +12,7 @@ target_sources(test_main PUBLIC
ValueBrokerTest.cpp
DBTest.cpp
Vector2Test.cpp
- loopTimerTest.cpp
+ LoopManagerTest.cpp
+ LoopTimerTest.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 b0e6c9c..dccd554 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/LoopManagerTest.cpp b/src/test/LoopManagerTest.cpp
new file mode 100644
index 0000000..af6cb1c
--- /dev/null
+++ b/src/test/LoopManagerTest.cpp
@@ -0,0 +1,44 @@
+#include <gtest/gtest.h>
+#include <chrono>
+#include <thread>
+#define private public
+#define protected public
+#include "api/LoopTimer.h"
+#include "api/LoopManager.h"
+
+using namespace std::chrono;
+using namespace crepe;
+
+class LoopManagerTest : public ::testing::Test {
+protected:
+ LoopManager loop_manager;
+
+ void SetUp() override {
+ // Setting up loop manager and start the loop
+ loop_manager.loop_timer->set_target_fps(60);
+ }
+};
+
+//Test to check if exactly 5 fixed updates are done every second (50Hz)
+TEST_F(LoopManagerTest, FixedUpdate) {
+ loop_manager.loop_timer->fixed_delta_time = std::chrono::milliseconds(20);
+ loop_manager.loop_timer->set_target_fps(50);
+ int fixed_update_count = 0;
+ loop_manager.loop_timer->start();
+ // We want to simulate the game loop for about 1 second
+ auto start_time = steady_clock::now();
+
+ // Simulate the game loop for 1 second
+ while (duration_cast<milliseconds>(steady_clock::now() - start_time) < std::chrono::milliseconds(1000)) {
+ loop_manager.loop_timer->update();
+ // Simulate processing fixed updates while there's lag to advance
+ while (loop_manager.loop_timer->get_lag() >= loop_manager.loop_timer->get_fixed_delta_time()) {
+ fixed_update_count++;
+ loop_manager.loop_timer->advance_fixed_update();
+ }
+
+ loop_manager.loop_timer->enforce_frame_rate();
+ }
+ // gameloop is 99 because it first takes 20 millisecond to build the lag to execute the fixed loop
+ ASSERT_EQ(fixed_update_count, 50);
+}
diff --git a/src/test/loopTimerTest.cpp b/src/test/LoopTimerTest.cpp
index 9bbbff3..6e3f118 100644
--- a/src/test/loopTimerTest.cpp
+++ b/src/test/LoopTimerTest.cpp
@@ -57,3 +57,25 @@ TEST_F(LoopTimerTest, DeltaTimeCalculation) {
ASSERT_LE(delta_time, (elapsed_time + 2) / 1000.0);
}
+TEST_F(LoopTimerTest, getCurrentTime) {
+ // Set the target FPS to 60 (16.67 ms per frame)
+ loop_timer.set_target_fps(60);
+
+ auto start_time = steady_clock::now();
+
+ // Sleep for 500 milliseconds
+ std::this_thread::sleep_for(std::chrono::milliseconds(100));
+
+ loop_timer.update();
+
+ auto end_time = steady_clock::now();
+
+ // Get the elapsed time in seconds as a double
+ auto elapsed_time = duration_cast<std::chrono::duration<double>>(end_time - start_time).count();
+
+ ASSERT_NEAR(loop_timer.get_current_time(), elapsed_time, 0.001);
+
+
+}
+
+
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();
+};
diff --git a/src/test/loopManagerTest.cpp b/src/test/loopManagerTest.cpp
deleted file mode 100644
index 6e66ce7..0000000
--- a/src/test/loopManagerTest.cpp
+++ /dev/null
@@ -1,50 +0,0 @@
-#include <gtest/gtest.h>
-#include <chrono>
-#include <thread>
-#define private public
-#define protected public
-#include "api/LoopTimer.h"
-#include "api/LoopManager.h"
-
-using namespace std::chrono;
-using namespace crepe;
-
-class LoopTimerTest : public ::testing::Test {
-protected:
- LoopManager loop_manager;
-
- void SetUp() override {
- // Setting up loop manager and start the loop
- loop_manager.setup();
- loop_manager.loop_timer->set_target_fps(60);
- }
-};
-
-// Test to check if exactly 5 fixed updates are done every second (50Hz)
-TEST_F(LoopTimerTest, FixedUpdateCalledAt50Hz) {
- // Set target fixed delta time to 20ms (50Hz fixed updates)
- loop_manager.loop_timer->set_fixed_delta_time(milliseconds(20));
-
- int fixed_update_count = 0;
-
- // We want to simulate the game loop for about 1 second
- auto start_time = steady_clock::now();
-
- // Simulate the game loop for 1 second
- while (duration_cast<seconds>(steady_clock::now() - start_time).count() < 1) {
- loop_manager.loop_timer->update();
-
- // Simulate processing fixed updates while there's lag to advance
- while (loop_manager.loop_timer->get_lag() >= loop_manager.loop_timer->get_fixed_delta_time()) {
- loop_manager.fixed_update(); // Process fixed update
- fixed_update_count++; // Count the number of fixed updates
- loop_manager.loop_timer->advance_fixed_update();
- }
-
- // We do not need to call render or update for this test
- loop_manager.loop_timer->enforce_frame_rate(); // Enforce the frame rate (this would normally go to the display)
- }
-
- // We expect 5 fixed updates to occur in 1 second at 50Hz
- ASSERT_EQ(fixed_update_count, 5);
-}