aboutsummaryrefslogtreecommitdiff
path: root/src/crepe/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/crepe/api')
-rw-r--r--src/crepe/api/BehaviorScript.cpp4
-rw-r--r--src/crepe/api/BehaviorScript.h1
-rw-r--r--src/crepe/api/CMakeLists.txt5
-rw-r--r--src/crepe/api/Engine.cpp61
-rw-r--r--src/crepe/api/Engine.h75
-rw-r--r--src/crepe/api/Engine.hpp12
-rw-r--r--src/crepe/api/GameObject.cpp16
-rw-r--r--src/crepe/api/GameObject.h21
-rw-r--r--src/crepe/api/GameObject.hpp2
-rw-r--r--src/crepe/api/LoopManager.cpp86
-rw-r--r--src/crepe/api/LoopManager.h122
-rw-r--r--src/crepe/api/LoopManager.hpp48
-rw-r--r--src/crepe/api/Script.cpp21
-rw-r--r--src/crepe/api/Script.h18
-rw-r--r--src/crepe/api/Script.hpp3
-rw-r--r--src/crepe/api/Transform.cpp10
-rw-r--r--src/crepe/api/Transform.h7
17 files changed, 233 insertions, 279 deletions
diff --git a/src/crepe/api/BehaviorScript.cpp b/src/crepe/api/BehaviorScript.cpp
index d22afdf..af7572c 100644
--- a/src/crepe/api/BehaviorScript.cpp
+++ b/src/crepe/api/BehaviorScript.cpp
@@ -10,6 +10,6 @@ BehaviorScript::BehaviorScript(game_object_id_t id, Mediator & mediator)
template <>
BehaviorScript & GameObject::add_component<BehaviorScript>() {
- ComponentManager & mgr = this->component_manager;
- return mgr.add_component<BehaviorScript>(this->id, mgr.mediator);
+ ComponentManager & mgr = this->mediator.component_manager;
+ return mgr.add_component<BehaviorScript>(this->id, this->mediator);
}
diff --git a/src/crepe/api/BehaviorScript.h b/src/crepe/api/BehaviorScript.h
index 3909b96..02d588a 100644
--- a/src/crepe/api/BehaviorScript.h
+++ b/src/crepe/api/BehaviorScript.h
@@ -9,6 +9,7 @@
namespace crepe {
class ScriptSystem;
+class Mediator;
class ComponentManager;
class Script;
diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt
index fb11c8d..48402ae 100644
--- a/src/crepe/api/CMakeLists.txt
+++ b/src/crepe/api/CMakeLists.txt
@@ -13,7 +13,7 @@ target_sources(crepe PUBLIC
Animator.cpp
BoxCollider.cpp
CircleCollider.cpp
- LoopManager.cpp
+ Engine.cpp
Asset.cpp
EventHandler.cpp
Script.cpp
@@ -44,7 +44,8 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES
EventHandler.h
EventHandler.hpp
Event.h
- LoopManager.h
+ Engine.h
+ Engine.hpp
Asset.h
Button.h
UIObject.h
diff --git a/src/crepe/api/Engine.cpp b/src/crepe/api/Engine.cpp
new file mode 100644
index 0000000..7ae89b9
--- /dev/null
+++ b/src/crepe/api/Engine.cpp
@@ -0,0 +1,61 @@
+#include "../util/Log.h"
+
+#include "Engine.h"
+
+using namespace crepe;
+using namespace std;
+
+void Engine::start() {
+ try {
+ this->setup();
+ } catch (const exception & e) {
+ Log::logf(Log::Level::ERROR, "Uncaught exception in setup: {}\n", e.what());
+ return;
+ }
+
+ try {
+ this->loop();
+ } catch (const exception & e) {
+ Log::logf(Log::Level::ERROR, "Uncaught exception in main loop: {}\n", e.what());
+ this->event_manager.trigger_event<ShutDownEvent>();
+ }
+}
+
+void Engine::setup() {
+ this->game_running = true;
+ this->loop_timer.start();
+ this->scene_manager.load_next_scene();
+
+ this->event_manager.subscribe<ShutDownEvent>([this](const ShutDownEvent & event) {
+ this->game_running = false;
+
+ // propagate to possible user ShutDownEvent listeners
+ return false;
+ });
+}
+
+void Engine::loop() {
+ LoopTimerManager & timer = this->loop_timer;
+ SystemManager & systems = this->system_manager;
+
+ while (game_running) {
+ timer.update();
+
+ while (timer.get_lag() >= timer.get_fixed_delta_time()) {
+ try {
+ systems.fixed_update();
+ } catch (const exception & e) {
+ Log::logf(Log::Level::WARNING, "Uncaught exception in fixed update function: {}\n", e.what());
+ }
+ timer.advance_fixed_elapsed_time();
+ }
+
+ try {
+ systems.frame_update();
+ } catch (const exception & e) {
+ Log::logf(Log::Level::WARNING, "Uncaught exception in frame update function: {}\n", e.what());
+ }
+ timer.enforce_frame_rate();
+ }
+}
+
diff --git a/src/crepe/api/Engine.h b/src/crepe/api/Engine.h
new file mode 100644
index 0000000..5421d60
--- /dev/null
+++ b/src/crepe/api/Engine.h
@@ -0,0 +1,75 @@
+#pragma once
+
+#include "../facade/SDLContext.h"
+#include "../manager/ComponentManager.h"
+#include "../manager/ReplayManager.h"
+#include "../manager/ResourceManager.h"
+#include "../manager/ResourceManager.h"
+#include "../manager/SaveManager.h"
+#include "../manager/SceneManager.h"
+#include "../manager/SystemManager.h"
+#include "../manager/LoopTimerManager.h"
+#include "../manager/EventManager.h"
+
+namespace crepe {
+
+/**
+ * \brief Main game entrypoint
+ *
+ * This class is responsible for managing the game loop, including initialization and updating.
+ */
+class Engine {
+public:
+ void start();
+
+ /**
+ * \brief Add a new concrete scene to the scene manager
+ *
+ * \tparam T Type of concrete scene
+ */
+ template <typename T>
+ void add_scene();
+
+private:
+ /**
+ * \brief Setup function for one-time initialization.
+ *
+ * This function initializes necessary components for the game.
+ */
+ void setup();
+ /**
+ * \brief Main game loop function.
+ *
+ * This function runs the main loop, handling game updates and rendering.
+ */
+ void loop();
+
+ bool game_running = false;
+
+private:
+ //! Global context
+ Mediator mediator;
+
+ //! Component manager instance
+ ComponentManager component_manager{mediator};
+ //! Scene manager instance
+ SceneManager scene_manager{mediator};
+ //! LoopTimerManager instance
+ LoopTimerManager loop_timer{mediator};
+ //! EventManager instance
+ EventManager event_manager{mediator};
+ //! Resource manager instance
+ ResourceManager resource_manager{mediator};
+ //! Save manager instance
+ SaveManager save_manager{mediator};
+ //! SDLContext instance
+ SDLContext sdl_context{mediator};
+ //! ReplayManager instance
+ ReplayManager replay_manager{mediator};
+ //! SystemManager
+ SystemManager system_manager{mediator};
+};
+
+} // namespace crepe
+
+#include "Engine.hpp"
diff --git a/src/crepe/api/Engine.hpp b/src/crepe/api/Engine.hpp
new file mode 100644
index 0000000..f2fdc0a
--- /dev/null
+++ b/src/crepe/api/Engine.hpp
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "Engine.h"
+
+namespace crepe {
+
+template <class T>
+void Engine::add_scene() {
+ this->scene_manager.add_scene<T>();
+}
+
+} // namespace crepe
diff --git a/src/crepe/api/GameObject.cpp b/src/crepe/api/GameObject.cpp
index 9ef4682..68b074e 100644
--- a/src/crepe/api/GameObject.cpp
+++ b/src/crepe/api/GameObject.cpp
@@ -7,20 +7,16 @@
using namespace crepe;
using namespace std;
-GameObject::GameObject(ComponentManager & component_manager, game_object_id_t id,
+GameObject::GameObject(Mediator & mediator, game_object_id_t id,
const std::string & name, const std::string & tag,
const vec2 & position, double rotation, double scale)
: id(id),
- component_manager(component_manager) {
-
- // Add Transform and Metadata components
- ComponentManager & mgr = this->component_manager;
- mgr.add_component<Transform>(this->id, position, rotation, scale);
- mgr.add_component<Metadata>(this->id, name, tag);
-}
+ mediator(mediator),
+ transform(mediator.component_manager->add_component<Transform>(this->id, position, rotation, scale)),
+ metadata(mediator.component_manager->add_component<Metadata>(this->id, name, tag)) { }
void GameObject::set_parent(const GameObject & parent) {
- ComponentManager & mgr = this->component_manager;
+ ComponentManager & mgr = this->mediator.component_manager;
// Set parent on own Metadata component
RefVector<Metadata> this_metadata = mgr.get_components_by_id<Metadata>(this->id);
@@ -32,7 +28,7 @@ void GameObject::set_parent(const GameObject & parent) {
}
void GameObject::set_persistent(bool persistent) {
- ComponentManager & mgr = this->component_manager;
+ ComponentManager & mgr = this->mediator.component_manager;
mgr.set_persistent(this->id, persistent);
}
diff --git a/src/crepe/api/GameObject.h b/src/crepe/api/GameObject.h
index ff80f49..6203f81 100644
--- a/src/crepe/api/GameObject.h
+++ b/src/crepe/api/GameObject.h
@@ -6,7 +6,9 @@
namespace crepe {
-class ComponentManager;
+class Mediator;
+class Transform;
+class Metadata;
/**
* \brief Represents a GameObject
@@ -20,7 +22,7 @@ private:
* This constructor creates a new GameObject. It creates a new Transform and Metadata
* component and adds them to the ComponentManager.
*
- * \param component_manager Reference to component_manager
+ * \param mediator Reference to mediator
* \param id The id of the GameObject
* \param name The name of the GameObject
* \param tag The tag of the GameObject
@@ -28,13 +30,20 @@ private:
* \param rotation The rotation of the GameObject
* \param scale The scale of the GameObject
*/
- GameObject(ComponentManager & component_manager, game_object_id_t id,
+ GameObject(Mediator & mediator, game_object_id_t id,
const std::string & name, const std::string & tag, const vec2 & position,
double rotation, double scale);
//! ComponentManager instances GameObject
friend class ComponentManager;
public:
+ //! The id of the GameObject
+ const game_object_id_t id;
+
+ Transform & transform;
+ Metadata & metadata;
+
+public:
/**
* \brief Set the parent of this GameObject
*
@@ -68,12 +77,8 @@ public:
*/
void set_persistent(bool persistent = true);
-public:
- //! The id of the GameObject
- const game_object_id_t id;
-
protected:
- ComponentManager & component_manager;
+ Mediator & mediator;
};
} // namespace crepe
diff --git a/src/crepe/api/GameObject.hpp b/src/crepe/api/GameObject.hpp
index a6b45b0..69f7d73 100644
--- a/src/crepe/api/GameObject.hpp
+++ b/src/crepe/api/GameObject.hpp
@@ -8,7 +8,7 @@ namespace crepe {
template <typename T, typename... Args>
T & GameObject::add_component(Args &&... args) {
- ComponentManager & mgr = this->component_manager;
+ ComponentManager & mgr = this->mediator.component_manager;
return mgr.add_component<T>(this->id, std::forward<Args>(args)...);
}
diff --git a/src/crepe/api/LoopManager.cpp b/src/crepe/api/LoopManager.cpp
deleted file mode 100644
index b5e5ff7..0000000
--- a/src/crepe/api/LoopManager.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-#include "../facade/SDLContext.h"
-#include "../manager/EventManager.h"
-#include "../manager/LoopTimerManager.h"
-#include "../system/AISystem.h"
-#include "../system/AnimatorSystem.h"
-#include "../system/AudioSystem.h"
-#include "../system/CollisionSystem.h"
-#include "../system/InputSystem.h"
-#include "../system/ParticleSystem.h"
-#include "../system/PhysicsSystem.h"
-#include "../system/RenderSystem.h"
-#include "../system/ScriptSystem.h"
-#include "../util/Log.h"
-
-#include "LoopManager.h"
-
-using namespace crepe;
-using namespace std;
-
-LoopManager::LoopManager() {
- this->load_system<AnimatorSystem>();
- this->load_system<CollisionSystem>();
- this->load_system<ParticleSystem>();
- this->load_system<PhysicsSystem>();
- this->load_system<RenderSystem>();
- this->load_system<ScriptSystem>();
- this->load_system<InputSystem>();
- this->event_manager.subscribe<ShutDownEvent>(
- [this](const ShutDownEvent & event) { return this->on_shutdown(event); });
- this->load_system<AudioSystem>();
- this->load_system<AISystem>();
-}
-void LoopManager::start() {
- this->setup();
- this->loop();
-}
-
-void LoopManager::setup() {
- this->game_running = true;
- this->loop_timer.start();
- this->scene_manager.load_next_scene();
-}
-
-void LoopManager::loop() {
- try {
- while (game_running) {
- this->loop_timer.update();
-
- while (this->loop_timer.get_lag() >= this->loop_timer.get_fixed_delta_time()) {
- this->fixed_update();
- this->loop_timer.advance_fixed_elapsed_time();
- }
-
- this->frame_update();
- this->loop_timer.enforce_frame_rate();
- }
- } catch (const exception & e) {
- Log::logf(Log::Level::ERROR, "Exception caught in main loop: {}", e.what());
- this->event_manager.trigger_event<ShutDownEvent>(ShutDownEvent{});
- }
-}
-
-// will be called at a fixed interval
-void LoopManager::fixed_update() {
- this->get_system<InputSystem>().update();
- this->event_manager.dispatch_events();
- this->get_system<ScriptSystem>().update();
- this->get_system<AISystem>().update();
- this->get_system<PhysicsSystem>().update();
- this->get_system<CollisionSystem>().update();
- this->get_system<AudioSystem>().update();
-}
-
-// will be called every frame
-void LoopManager::frame_update() {
- this->scene_manager.load_next_scene();
- this->get_system<AnimatorSystem>().update();
- //render
- this->get_system<RenderSystem>().update();
-}
-
-bool LoopManager::on_shutdown(const ShutDownEvent & e) {
- this->game_running = false;
- // propagate to possible user ShutDownEvent listeners
- return false;
-}
diff --git a/src/crepe/api/LoopManager.h b/src/crepe/api/LoopManager.h
deleted file mode 100644
index 40e6b38..0000000
--- a/src/crepe/api/LoopManager.h
+++ /dev/null
@@ -1,122 +0,0 @@
-#pragma once
-
-#include <memory>
-
-#include "../facade/SDLContext.h"
-#include "../manager/ComponentManager.h"
-#include "../manager/EventManager.h"
-#include "../manager/LoopTimerManager.h"
-#include "../manager/Mediator.h"
-#include "../manager/ResourceManager.h"
-#include "../manager/SaveManager.h"
-#include "../manager/SceneManager.h"
-#include "../system/System.h"
-
-namespace crepe {
-/**
- * \brief Main game loop manager
- *
- * This class is responsible for managing the game loop, including initialization and updating.
- */
-class LoopManager {
-public:
- LoopManager();
- /**
- * \brief Start the gameloop
- *
- * This is the start of the engine where the setup is called and then the loop keeps running until the game stops running.
- * The Game programmer needs to call this function to run the game. This should be done after creating and adding all scenes.
- */
- void start();
-
- /**
- * \brief Add a new concrete scene to the scene manager
- *
- * \tparam T Type of concrete scene
- */
- template <typename T>
- void add_scene();
-
-private:
- /**
- * \brief Setup function for one-time initialization.
- *
- * This function initializes necessary components for the game.
- */
- void setup();
- /**
- * \brief Main game loop function.
- *
- * This function runs the main loop, handling game updates and rendering.
- */
- void loop();
-
- /**
- * \brief Per-frame update.
- *
- * Updates the game state based on the elapsed time since the last frame.
- */
- virtual void frame_update();
-
- /**
- * \brief Fixed update executed at a fixed rate.
- *
- * This function updates physics and game logic based on LoopTimer's fixed_delta_time.
- */
- virtual void fixed_update();
-
- //! Indicates whether the game is running.
- bool game_running = false;
-
-private:
- //! Global context
- Mediator mediator;
-
- //! Component manager instance
- ComponentManager component_manager{mediator};
- //! Scene manager instance
- SceneManager scene_manager{mediator};
- //! LoopTimerManager instance
- LoopTimerManager loop_timer{mediator};
- //! EventManager instance
- EventManager event_manager{mediator};
- //! Resource manager instance
- ResourceManager resource_manager{mediator};
- //! Save manager instance
- SaveManager save_manager{mediator};
- //! SDLContext instance
- SDLContext sdl_context{mediator};
-
-private:
- /**
- * \brief Callback function for ShutDownEvent
- *
- * This function sets the game_running variable to false, stopping the gameloop and therefor quitting the game.
- */
- bool on_shutdown(const ShutDownEvent & e);
- /**
- * \brief Collection of System instances
- *
- * This map holds System instances indexed by the system's class typeid. It is filled in the
- * constructor of LoopManager using LoopManager::load_system.
- */
- std::unordered_map<std::type_index, std::unique_ptr<System>> systems;
- /**
- * \brief Initialize a system
- * \tparam T System type (must be derivative of \c System)
- */
- template <class T>
- void load_system();
- /**
- * \brief Retrieve a reference to ECS system
- * \tparam T System type
- * \returns Reference to system instance
- * \throws std::runtime_error if the System is not initialized
- */
- template <class T>
- T & get_system();
-};
-
-} // namespace crepe
-
-#include "LoopManager.hpp"
diff --git a/src/crepe/api/LoopManager.hpp b/src/crepe/api/LoopManager.hpp
deleted file mode 100644
index 266758a..0000000
--- a/src/crepe/api/LoopManager.hpp
+++ /dev/null
@@ -1,48 +0,0 @@
-#pragma once
-
-#include <cassert>
-#include <format>
-#include <memory>
-
-#include "../system/System.h"
-
-#include "LoopManager.h"
-
-namespace crepe {
-
-template <class T>
-void LoopManager::add_scene() {
- this->scene_manager.add_scene<T>();
-}
-
-template <class T>
-T & LoopManager::get_system() {
- using namespace std;
- static_assert(is_base_of<System, T>::value,
- "get_system must recieve a derivative class of System");
-
- const type_info & type = typeid(T);
- if (!this->systems.contains(type))
- throw runtime_error(format("LoopManager: {} is not initialized", type.name()));
-
- System * system = this->systems.at(type).get();
- T * concrete_system = dynamic_cast<T *>(system);
- assert(concrete_system != nullptr);
-
- return *concrete_system;
-}
-
-template <class T>
-void LoopManager::load_system() {
- using namespace std;
- static_assert(is_base_of<System, T>::value,
- "load_system must recieve a derivative class of 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/Script.cpp b/src/crepe/api/Script.cpp
index 753a9e3..8b95cc9 100644
--- a/src/crepe/api/Script.cpp
+++ b/src/crepe/api/Script.cpp
@@ -25,3 +25,24 @@ void Script::set_next_scene(const string & name) {
}
SaveManager & Script::get_save_manager() const { return this->mediator->save_manager; }
+
+void Script::replay::record_start() {
+ ReplayManager & mgr = this->mediator->replay_manager;
+ return mgr.record_start();
+}
+
+recording_t Script::replay::record_end() {
+ ReplayManager & mgr = this->mediator->replay_manager;
+ return mgr.record_end();
+}
+
+void Script::replay::play(recording_t recording) {
+ ReplayManager & mgr = this->mediator->replay_manager;
+ return mgr.play(recording);
+}
+
+void Script::replay::release(recording_t recording) {
+ ReplayManager & mgr = this->mediator->replay_manager;
+ return mgr.release(recording);
+}
+
diff --git a/src/crepe/api/Script.h b/src/crepe/api/Script.h
index 668e5d1..c797db0 100644
--- a/src/crepe/api/Script.h
+++ b/src/crepe/api/Script.h
@@ -2,6 +2,7 @@
#include <vector>
+#include "../manager/ReplayManager.h"
#include "../manager/EventManager.h"
#include "../manager/Mediator.h"
#include "../system/CollisionSystem.h"
@@ -135,6 +136,23 @@ protected:
//! Retrieve SaveManager reference
SaveManager & get_save_manager() const;
+ //! Replay management functions
+ struct replay { // NOLINT
+ //! \copydoc ReplayManager::record_start
+ void record_start();
+ //! \copydoc ReplayManager::record_end
+ recording_t record_end();
+ //! \copydoc ReplayManager::play
+ void play(recording_t);
+ //! \copydoc ReplayManager::release
+ void release(recording_t);
+
+ private:
+ OptionalRef<Mediator> & mediator;
+ replay(OptionalRef<Mediator> & mediator) : mediator(mediator) {}
+ friend class Script;
+ } replay{mediator};
+
//! \}
private:
diff --git a/src/crepe/api/Script.hpp b/src/crepe/api/Script.hpp
index 225a51c..547fb8b 100644
--- a/src/crepe/api/Script.hpp
+++ b/src/crepe/api/Script.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "../manager/ComponentManager.h"
+#include "../manager/ReplayManager.h"
#include "BehaviorScript.h"
#include "Script.h"
@@ -36,6 +37,8 @@ void Script::subscribe_internal(const EventHandler<EventType> & callback,
[this, callback](const EventType & data) -> bool {
bool & active = this->active;
if (!active) return false;
+ ReplayManager & replay = this->mediator->replay_manager;
+ if (replay.get_state() == ReplayManager::PLAYING) return false;
return callback(data);
},
channel);
diff --git a/src/crepe/api/Transform.cpp b/src/crepe/api/Transform.cpp
index a85b792..5fc886b 100644
--- a/src/crepe/api/Transform.cpp
+++ b/src/crepe/api/Transform.cpp
@@ -3,6 +3,7 @@
#include "Transform.h"
using namespace crepe;
+using namespace std;
Transform::Transform(game_object_id_t id, const vec2 & point, double rotation, double scale)
: Component(id),
@@ -11,3 +12,12 @@ Transform::Transform(game_object_id_t id, const vec2 & point, double rotation, d
scale(scale) {
dbg_trace();
}
+
+unique_ptr<Component> Transform::save() const {
+ return unique_ptr<Component>{new Transform(*this)};
+}
+
+void Transform::restore(const Component & snapshot) {
+ *this = static_cast<const Transform &>(snapshot);
+}
+
diff --git a/src/crepe/api/Transform.h b/src/crepe/api/Transform.h
index 7ee6d65..bbd23e0 100644
--- a/src/crepe/api/Transform.h
+++ b/src/crepe/api/Transform.h
@@ -35,6 +35,13 @@ protected:
virtual int get_instances_max() const { return 1; }
//! ComponentManager instantiates all components
friend class ComponentManager;
+
+protected:
+ virtual std::unique_ptr<Component> save() const;
+ Transform(const Transform &) = default;
+ virtual void restore(const Component & snapshot);
+ virtual Transform & operator=(const Transform &) = default;
+
};
} // namespace crepe