aboutsummaryrefslogtreecommitdiff
path: root/src/crepe/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/crepe/api')
-rw-r--r--src/crepe/api/Animator.cpp2
-rw-r--r--src/crepe/api/BehaviorScript.cpp4
-rw-r--r--src/crepe/api/BehaviorScript.hpp3
-rw-r--r--src/crepe/api/CMakeLists.txt5
-rw-r--r--src/crepe/api/Camera.cpp2
-rw-r--r--src/crepe/api/Engine.cpp63
-rw-r--r--src/crepe/api/Engine.h78
-rw-r--r--src/crepe/api/Engine.hpp12
-rw-r--r--src/crepe/api/GameObject.cpp21
-rw-r--r--src/crepe/api/GameObject.h25
-rw-r--r--src/crepe/api/GameObject.hpp2
-rw-r--r--src/crepe/api/LoopManager.cpp87
-rw-r--r--src/crepe/api/LoopManager.h122
-rw-r--r--src/crepe/api/LoopManager.hpp48
-rw-r--r--src/crepe/api/ParticleEmitter.cpp14
-rw-r--r--src/crepe/api/ParticleEmitter.h6
-rw-r--r--src/crepe/api/Script.cpp20
-rw-r--r--src/crepe/api/Script.h99
-rw-r--r--src/crepe/api/Script.hpp34
-rw-r--r--src/crepe/api/Sprite.cpp2
-rw-r--r--src/crepe/api/Transform.cpp11
-rw-r--r--src/crepe/api/Transform.h6
22 files changed, 334 insertions, 332 deletions
diff --git a/src/crepe/api/Animator.cpp b/src/crepe/api/Animator.cpp
index 4ce4bf0..203cef3 100644
--- a/src/crepe/api/Animator.cpp
+++ b/src/crepe/api/Animator.cpp
@@ -1,5 +1,5 @@
-#include "util/Log.h"
+#include "util/dbg.h"
#include "Animator.h"
#include "Component.h"
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.hpp b/src/crepe/api/BehaviorScript.hpp
index b9bb1e2..353d5e2 100644
--- a/src/crepe/api/BehaviorScript.hpp
+++ b/src/crepe/api/BehaviorScript.hpp
@@ -2,8 +2,6 @@
#include <type_traits>
-#include "../util/Log.h"
-
#include "BehaviorScript.h"
#include "Script.h"
@@ -11,7 +9,6 @@ namespace crepe {
template <class T, typename... Args>
BehaviorScript & BehaviorScript::set_script(Args &&... args) {
- dbg_trace();
static_assert(std::is_base_of<Script, T>::value);
this->script = std::unique_ptr<Script>(new T(std::forward<Args>(args)...));
diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt
index 8f84f06..18d6942 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
@@ -46,7 +46,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/Camera.cpp b/src/crepe/api/Camera.cpp
index 179dc18..19a3296 100644
--- a/src/crepe/api/Camera.cpp
+++ b/src/crepe/api/Camera.cpp
@@ -1,4 +1,4 @@
-#include "util/Log.h"
+#include "util/dbg.h"
#include "Camera.h"
#include "Component.h"
diff --git a/src/crepe/api/Engine.cpp b/src/crepe/api/Engine.cpp
new file mode 100644
index 0000000..bbb4494
--- /dev/null
+++ b/src/crepe/api/Engine.cpp
@@ -0,0 +1,63 @@
+#include "../util/Log.h"
+
+#include "Engine.h"
+
+using namespace crepe;
+using namespace std;
+
+int Engine::main() noexcept {
+ try {
+ this->setup();
+ } catch (const exception & e) {
+ Log::logf(Log::Level::ERROR, "Uncaught exception in setup: {}\n", e.what());
+ return EXIT_FAILURE;
+ }
+
+ 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>();
+ }
+
+ return EXIT_SUCCESS;
+}
+
+void Engine::setup() {
+ 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..3145723
--- /dev/null
+++ b/src/crepe/api/Engine.h
@@ -0,0 +1,78 @@
+#pragma once
+
+#include "../facade/SDLContext.h"
+#include "../manager/ComponentManager.h"
+#include "../manager/EventManager.h"
+#include "../manager/LoopTimerManager.h"
+#include "../manager/ReplayManager.h"
+#include "../manager/ResourceManager.h"
+#include "../manager/SaveManager.h"
+#include "../manager/SceneManager.h"
+#include "../manager/SystemManager.h"
+
+namespace crepe {
+
+/**
+ * \brief Main game entrypoint
+ *
+ * This class is responsible for managing the game loop, including initialization and updating.
+ */
+class Engine {
+public:
+ /**
+ * \brief Engine entrypoint
+ *
+ * This function is called by the game programmer after registering all scenes
+ *
+ * \returns process exit code
+ */
+ int main() noexcept;
+
+ //! \copydoc SceneManager::add_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();
+
+ //! Game loop condition
+ bool game_running = true;
+
+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..9b94cad 100644
--- a/src/crepe/api/GameObject.cpp
+++ b/src/crepe/api/GameObject.cpp
@@ -7,20 +7,17 @@
using namespace crepe;
using namespace std;
-GameObject::GameObject(ComponentManager & component_manager, game_object_id_t id,
- const std::string & name, const std::string & tag,
- const vec2 & position, double rotation, double scale)
+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 +29,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..572ce3a 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,
- const std::string & name, const std::string & tag, const vec2 & position,
- double rotation, double scale);
+ 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;
+ //! This entity's transform
+ Transform & transform;
+ //! This entity's metadata
+ 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 7a78019..0000000
--- a/src/crepe/api/LoopManager.cpp
+++ /dev/null
@@ -1,87 +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<ParticleSystem>().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/ParticleEmitter.cpp b/src/crepe/api/ParticleEmitter.cpp
index 4f54bbd..9a70334 100644
--- a/src/crepe/api/ParticleEmitter.cpp
+++ b/src/crepe/api/ParticleEmitter.cpp
@@ -2,6 +2,7 @@
#include "api/Sprite.h"
using namespace crepe;
+using namespace std;
ParticleEmitter::ParticleEmitter(game_object_id_t game_object_id, const Sprite & sprite,
const Data & data)
@@ -12,3 +13,16 @@ ParticleEmitter::ParticleEmitter(game_object_id_t game_object_id, const Sprite &
this->particles.emplace_back();
}
}
+
+unique_ptr<Component> ParticleEmitter::save() const {
+ return unique_ptr<Component>{new ParticleEmitter(*this)};
+}
+
+void ParticleEmitter::restore(const Component & snapshot) {
+ *this = static_cast<const ParticleEmitter &>(snapshot);
+}
+
+ParticleEmitter & ParticleEmitter::operator=(const ParticleEmitter & other) {
+ this->particles = other.particles;
+ return *this;
+}
diff --git a/src/crepe/api/ParticleEmitter.h b/src/crepe/api/ParticleEmitter.h
index 8ac2e72..1edd2b5 100644
--- a/src/crepe/api/ParticleEmitter.h
+++ b/src/crepe/api/ParticleEmitter.h
@@ -84,6 +84,12 @@ public:
//! Configuration data for particle emission settings.
Data data;
+protected:
+ virtual std::unique_ptr<Component> save() const;
+ ParticleEmitter(const ParticleEmitter &) = default;
+ virtual void restore(const Component & snapshot);
+ virtual ParticleEmitter & operator=(const ParticleEmitter &);
+
private:
//! Only ParticleSystem can move and read particles
friend ParticleSystem;
diff --git a/src/crepe/api/Script.cpp b/src/crepe/api/Script.cpp
index 583c04f..ee76011 100644
--- a/src/crepe/api/Script.cpp
+++ b/src/crepe/api/Script.cpp
@@ -26,6 +26,26 @@ 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);
+}
+
const keyboard_state_t & Script::get_keyboard_state() const {
SDLContext & sdl_context = this->mediator->sdl_context;
return sdl_context.get_keyboard_state();
diff --git a/src/crepe/api/Script.h b/src/crepe/api/Script.h
index 65306cd..2750df0 100644
--- a/src/crepe/api/Script.h
+++ b/src/crepe/api/Script.h
@@ -5,8 +5,10 @@
#include "../api/KeyCodes.h"
#include "../manager/EventManager.h"
#include "../manager/Mediator.h"
+#include "../manager/ReplayManager.h"
#include "../system/CollisionSystem.h"
#include "../types.h"
+#include "../util/Log.h"
#include "../util/OptionalRef.h"
namespace crepe {
@@ -58,83 +60,105 @@ protected:
protected:
/**
- * \name Utility functions
+ * \name Component query functions
+ * \see ComponentManager
* \{
*/
-
/**
* \brief Get single component of type \c T on this game object
- *
* \tparam T Type of component
- *
* \returns Reference to component
- *
* \throws std::runtime_error if this game object does not have a component with type \c T
*/
template <typename T>
T & get_component() const;
- // TODO: make get_component calls for component types that can have more than 1 instance
- // cause compile-time errors
-
/**
* \brief Get all components of type \c T on this game object
- *
* \tparam T Type of component
- *
* \returns List of component references
*/
template <typename T>
RefVector<T> get_components() const;
-
- /**
- * \copydoc ComponentManager::get_components_by_id
- * \see ComponentManager::get_components_by_id
- */
+ //! \copydoc ComponentManager::get_components_by_id
template <typename T>
RefVector<T> get_components_by_id(game_object_id_t id) const;
- /**
- * \copydoc ComponentManager::get_components_by_name
- * \see ComponentManager::get_components_by_name
- */
+ //! \copydoc ComponentManager::get_components_by_name
template <typename T>
RefVector<T> get_components_by_name(const std::string & name) const;
- /**
- * \copydoc ComponentManager::get_components_by_tag
- * \see ComponentManager::get_components_by_tag
- */
+ //! \copydoc ComponentManager::get_components_by_tag
template <typename T>
RefVector<T> get_components_by_tag(const std::string & tag) const;
+ //! \}
/**
- * \brief Log a message using Log::logf
- *
- * \tparam Args Log::logf parameters
- * \param args Log::logf parameters
+ * \name Logging functions
+ * \see Log
+ * \{
*/
- template <typename... Args>
- void logf(Args &&... args);
+ //! \copydoc Log::logf
+ template <class... Args>
+ void logf(const Log::Level & level, std::format_string<Args...> fmt, Args &&... args);
+ //! \copydoc Log::logf
+ template <class... Args>
+ void logf(std::format_string<Args...> fmt, Args &&... args);
+ // \}
/**
- * \brief Subscribe to an event with an explicit channel
- * \see EventManager::subscribe
+ * \name Event manager functions
+ * \see EventManager
+ * \{
*/
+ //! \copydoc EventManager::subscribe
template <typename EventType>
void subscribe(const EventHandler<EventType> & callback, event_channel_t channel);
- /**
- * \brief Subscribe to an event on EventManager::CHANNEL_ALL
- * \see EventManager::subscribe
- */
+ //! \copydoc EventManager::subscribe
template <typename EventType>
void subscribe(const EventHandler<EventType> & callback);
+ //! \copydoc EventManager::trigger_event
+ template <typename EventType>
+ void trigger_event(const EventType & event = {},
+ event_channel_t channel = EventManager::CHANNEL_ALL);
+ //! \copydoc EventManager::queue_event
+ template <typename EventType>
+ void queue_event(const EventType & event = {},
+ event_channel_t channel = EventManager::CHANNEL_ALL);
+ //! \}
/**
- * \brief Set the next scene using SceneManager
- * \see SceneManager::set_next_scene
+ * \name Scene-related functions
+ * \see SceneManager
+ * \{
*/
+ //! \copydoc SceneManager::set_next_scene
void set_next_scene(const std::string & name);
+ //! \}
+ /**
+ * \name Save data management functions
+ * \see SaveManager
+ * \{
+ */
//! 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};
+
/**
* \brief Utility function to retrieve the keyboard state
* \see SDLContext::get_keyboard_state
@@ -151,7 +175,6 @@ protected:
*
*/
bool get_key_state(Keycode key) const noexcept;
- //! \}
private:
/**
diff --git a/src/crepe/api/Script.hpp b/src/crepe/api/Script.hpp
index 225a51c..4462a41 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"
@@ -23,9 +24,14 @@ RefVector<T> Script::get_components() const {
return this->get_components_by_id<T>(this->game_object_id);
}
-template <typename... Args>
-void Script::logf(Args &&... args) {
- Log::logf(std::forward<Args>(args)...);
+template <class... Args>
+void Script::logf(const Log::Level & level, std::format_string<Args...> fmt, Args &&... args) {
+ Log::logf(level, fmt, std::forward<Args>(args)...);
+}
+
+template <class... Args>
+void Script::logf(std::format_string<Args...> fmt, Args &&... args) {
+ Log::logf(fmt, std::forward<Args>(args)...);
}
template <typename EventType>
@@ -34,8 +40,18 @@ void Script::subscribe_internal(const EventHandler<EventType> & callback,
EventManager & mgr = this->mediator->event_manager;
subscription_t listener = mgr.subscribe<EventType>(
[this, callback](const EventType & data) -> bool {
+ // check if (parent) BehaviorScript component is active
bool & active = this->active;
if (!active) return false;
+
+ // check if replay manager is playing (if initialized)
+ try {
+ ReplayManager & replay = this->mediator->replay_manager;
+ if (replay.get_state() == ReplayManager::PLAYING) return false;
+ } catch (const std::runtime_error &) {
+ }
+
+ // call user-provided callback
return callback(data);
},
channel);
@@ -52,6 +68,18 @@ void Script::subscribe(const EventHandler<EventType> & callback) {
this->subscribe_internal(callback, EventManager::CHANNEL_ALL);
}
+template <typename EventType>
+void Script::trigger_event(const EventType & event, event_channel_t channel) {
+ EventManager & mgr = this->mediator->event_manager;
+ mgr.trigger_event(event, channel);
+}
+
+template <typename EventType>
+void Script::queue_event(const EventType & event, event_channel_t channel) {
+ EventManager & mgr = this->mediator->event_manager;
+ mgr.queue_event(event, channel);
+}
+
template <typename T>
RefVector<T> Script::get_components_by_id(game_object_id_t id) const {
Mediator & mediator = this->mediator;
diff --git a/src/crepe/api/Sprite.cpp b/src/crepe/api/Sprite.cpp
index ba684ba..0107c7b 100644
--- a/src/crepe/api/Sprite.cpp
+++ b/src/crepe/api/Sprite.cpp
@@ -1,6 +1,6 @@
#include <cmath>
-#include "../util/Log.h"
+#include "../util/dbg.h"
#include "api/Asset.h"
#include "Component.h"
diff --git a/src/crepe/api/Transform.cpp b/src/crepe/api/Transform.cpp
index a85b792..fcfce14 100644
--- a/src/crepe/api/Transform.cpp
+++ b/src/crepe/api/Transform.cpp
@@ -1,8 +1,9 @@
-#include "../util/Log.h"
+#include "../util/dbg.h"
#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,11 @@ 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..a6f3486 100644
--- a/src/crepe/api/Transform.h
+++ b/src/crepe/api/Transform.h
@@ -35,6 +35,12 @@ 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