aboutsummaryrefslogtreecommitdiff
path: root/src/crepe/api
diff options
context:
space:
mode:
authorheavydemon21 <nielsstunnebrink1@gmail.com>2024-11-18 14:27:58 +0100
committerheavydemon21 <nielsstunnebrink1@gmail.com>2024-11-18 14:27:58 +0100
commit03e493012edc106b00bc5676c1830ce2085a7ff9 (patch)
treeff06d4314552e82f98d08c52d7a15edb3a74436e /src/crepe/api
parent21f5b66d0bcc13d903800adf3bb614e380ff8591 (diff)
parent121b64b1cb6cfead5814070c8b0185d3d7308095 (diff)
Merge remote-tracking branch 'origin/master' into niels/sorting_rendering
Diffstat (limited to 'src/crepe/api')
-rw-r--r--src/crepe/api/Animator.cpp6
-rw-r--r--src/crepe/api/Animator.h23
-rw-r--r--src/crepe/api/AssetManager.cpp2
-rw-r--r--src/crepe/api/AssetManager.h25
-rw-r--r--src/crepe/api/AssetManager.hpp6
-rw-r--r--src/crepe/api/AudioSource.cpp23
-rw-r--r--src/crepe/api/AudioSource.h39
-rw-r--r--src/crepe/api/BehaviorScript.cpp15
-rw-r--r--src/crepe/api/BehaviorScript.h52
-rw-r--r--src/crepe/api/BehaviorScript.hpp7
-rw-r--r--src/crepe/api/CMakeLists.txt1
-rw-r--r--src/crepe/api/Camera.cpp7
-rw-r--r--src/crepe/api/Camera.h9
-rw-r--r--src/crepe/api/Config.h28
-rw-r--r--src/crepe/api/GameObject.cpp15
-rw-r--r--src/crepe/api/GameObject.h36
-rw-r--r--src/crepe/api/GameObject.hpp2
-rw-r--r--src/crepe/api/LoopManager.cpp20
-rw-r--r--src/crepe/api/LoopManager.h42
-rw-r--r--src/crepe/api/LoopManager.hpp40
-rw-r--r--src/crepe/api/LoopTimer.cpp27
-rw-r--r--src/crepe/api/LoopTimer.h145
-rw-r--r--src/crepe/api/Metadata.h7
-rw-r--r--src/crepe/api/ParticleEmitter.cpp3
-rw-r--r--src/crepe/api/ParticleEmitter.h12
-rw-r--r--src/crepe/api/Rigidbody.cpp4
-rw-r--r--src/crepe/api/Rigidbody.h12
-rw-r--r--src/crepe/api/SaveManager.cpp11
-rw-r--r--src/crepe/api/SaveManager.h11
-rw-r--r--src/crepe/api/Scene.cpp4
-rw-r--r--src/crepe/api/Scene.h15
-rw-r--r--src/crepe/api/SceneManager.cpp16
-rw-r--r--src/crepe/api/SceneManager.h13
-rw-r--r--src/crepe/api/SceneManager.hpp9
-rw-r--r--src/crepe/api/Script.cpp3
-rw-r--r--src/crepe/api/Script.h76
-rw-r--r--src/crepe/api/Script.hpp17
-rw-r--r--src/crepe/api/Sprite.cpp6
-rw-r--r--src/crepe/api/Sprite.h12
-rw-r--r--src/crepe/api/Texture.cpp4
-rw-r--r--src/crepe/api/Texture.h12
-rw-r--r--src/crepe/api/Transform.cpp5
-rw-r--r--src/crepe/api/Transform.h30
-rw-r--r--src/crepe/api/Vector2.cpp36
-rw-r--r--src/crepe/api/Vector2.h15
45 files changed, 490 insertions, 413 deletions
diff --git a/src/crepe/api/Animator.cpp b/src/crepe/api/Animator.cpp
index 58fee2a..464b0fd 100644
--- a/src/crepe/api/Animator.cpp
+++ b/src/crepe/api/Animator.cpp
@@ -1,7 +1,5 @@
-#include <cstdint>
-
-#include "util/log.h"
+#include "util/Log.h"
#include "Animator.h"
#include "Component.h"
@@ -9,7 +7,7 @@
using namespace crepe;
-Animator::Animator(uint32_t id, Sprite & ss, int row, int col, int col_animator)
+Animator::Animator(game_object_id_t id, Sprite & ss, int row, int col, int col_animator)
: Component(id),
spritesheet(ss),
row(row),
diff --git a/src/crepe/api/Animator.h b/src/crepe/api/Animator.h
index def0240..53f4b91 100644
--- a/src/crepe/api/Animator.h
+++ b/src/crepe/api/Animator.h
@@ -1,20 +1,19 @@
#pragma once
-#include <cstdint>
-
#include "Component.h"
#include "Sprite.h"
namespace crepe {
+
class AnimatorSystem;
class SDLContext;
/**
- * \brief The Animator component is used to animate sprites by managing the movement
- * and frame changes within a sprite sheet.
+ * \brief The Animator component is used to animate sprites by managing the movement and frame
+ * changes within a sprite sheet.
*
- * This component allows for controlling sprite animation through rows and columns of a sprite sheet.
- * It can be used to play animations, loop them, or stop them.
+ * This component allows for controlling sprite animation through rows and columns of a sprite
+ * sheet. It can be used to play animations, loop them, or stop them.
*/
class Animator : public Component {
@@ -28,15 +27,17 @@ public:
* \brief Constructs an Animator object that will control animations for a sprite sheet.
*
* \param id The unique identifier for the component, typically assigned automatically.
- * \param spritesheet A reference to the Sprite object which holds the sprite sheet for animation.
+ * \param spritesheet A reference to the Sprite object which holds the sprite sheet for
+ * animation.
* \param row The maximum number of rows in the sprite sheet.
* \param col The maximum number of columns in the sprite sheet.
- * \param col__animate The specific col index of the sprite sheet to animate. This allows selecting which col to animate from multiple col in the sheet.
+ * \param col_animate The specific col index of the sprite sheet to animate. This allows
+ * selecting which col to animate from multiple col in the sheet.
*
- * This constructor sets up the Animator with the given parameters, and initializes the animation system.
+ * This constructor sets up the Animator with the given parameters, and initializes the
+ * animation system.
*/
- Animator(uint32_t id, Sprite & spritesheet, int row, int col,
- int col_animate);
+ Animator(uint32_t id, Sprite & spritesheet, int row, int col, int col_animate);
~Animator(); // dbg_trace
Animator(const Animator &) = delete;
diff --git a/src/crepe/api/AssetManager.cpp b/src/crepe/api/AssetManager.cpp
index b891760..3925758 100644
--- a/src/crepe/api/AssetManager.cpp
+++ b/src/crepe/api/AssetManager.cpp
@@ -1,4 +1,4 @@
-#include "util/log.h"
+#include "util/Log.h"
#include "AssetManager.h"
diff --git a/src/crepe/api/AssetManager.h b/src/crepe/api/AssetManager.h
index 86a9902..fee6780 100644
--- a/src/crepe/api/AssetManager.h
+++ b/src/crepe/api/AssetManager.h
@@ -8,13 +8,12 @@
namespace crepe {
/**
- * \brief The AssetManager is responsible for storing and managing assets over
- * multiple scenes.
+ * \brief The AssetManager is responsible for storing and managing assets over multiple scenes.
*
- * The AssetManager ensures that assets are loaded once and can be accessed
- * across different scenes. It caches assets to avoid reloading them every time
- * a scene is loaded. Assets are retained in memory until the AssetManager is
- * destroyed, at which point the cached assets are cleared.
+ * The AssetManager ensures that assets are loaded once and can be accessed across different
+ * scenes. It caches assets to avoid reloading them every time a scene is loaded. Assets are
+ * retained in memory until the AssetManager is destroyed, at which point the cached assets are
+ * cleared.
*/
class AssetManager {
@@ -44,20 +43,18 @@ public:
* \brief Caches an asset by loading it from the given file path.
*
* \param file_path The path to the asset file to load.
- * \param reload If true, the asset will be reloaded from the file, even if
- * it is already cached.
+ * \param reload If true, the asset will be reloaded from the file, even if it is already
+ * cached.
* \tparam T The type of asset to cache (e.g., texture, sound, etc.).
*
* \return A shared pointer to the cached asset.
*
- * This template function caches the asset at the given file path. If the
- * asset is already cached and `reload` is false, the existing cached version
- * will be returned. Otherwise, the asset will be reloaded and added to the
- * cache.
+ * This template function caches the asset at the given file path. If the asset is already
+ * cached and `reload` is false, the existing cached version will be returned. Otherwise, the
+ * asset will be reloaded and added to the cache.
*/
template <typename T>
- std::shared_ptr<T> cache(const std::string & file_path,
- bool reload = false);
+ std::shared_ptr<T> cache(const std::string & file_path, bool reload = false);
};
} // namespace crepe
diff --git a/src/crepe/api/AssetManager.hpp b/src/crepe/api/AssetManager.hpp
index 977b4e1..1c0e978 100644
--- a/src/crepe/api/AssetManager.hpp
+++ b/src/crepe/api/AssetManager.hpp
@@ -5,16 +5,14 @@
namespace crepe {
template <typename asset>
-std::shared_ptr<asset> AssetManager::cache(const std::string & file_path,
- bool reload) {
+std::shared_ptr<asset> AssetManager::cache(const std::string & file_path, bool reload) {
auto it = asset_cache.find(file_path);
if (!reload && it != asset_cache.end()) {
return std::any_cast<std::shared_ptr<asset>>(it->second);
}
- std::shared_ptr<asset> new_asset
- = std::make_shared<asset>(file_path.c_str());
+ std::shared_ptr<asset> new_asset = std::make_shared<asset>(file_path.c_str());
asset_cache[file_path] = new_asset;
diff --git a/src/crepe/api/AudioSource.cpp b/src/crepe/api/AudioSource.cpp
deleted file mode 100644
index 63fd0d7..0000000
--- a/src/crepe/api/AudioSource.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-#include <memory>
-
-#include "../facade/Sound.h"
-
-#include "AudioSource.h"
-
-using namespace crepe;
-
-AudioSource::AudioSource(std::unique_ptr<Asset> audio_clip) {
- this->sound = std::make_unique<crepe::Sound>(std::move(audio_clip));
-}
-
-void AudioSource::play() { return this->play(false); }
-
-void AudioSource::play(bool looping) {
- this->sound->set_looping(looping);
- this->sound->play();
-}
-
-void AudioSource::stop() {
- this->sound->pause();
- this->sound->rewind();
-}
diff --git a/src/crepe/api/AudioSource.h b/src/crepe/api/AudioSource.h
deleted file mode 100644
index 1e24ae8..0000000
--- a/src/crepe/api/AudioSource.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#pragma once
-
-#include <memory>
-
-#include "../Asset.h"
-#include "../Component.h"
-
-namespace crepe {
-
-class Sound;
-
-//! Audio source component
-class AudioSource : public Component {
-public:
- AudioSource(std::unique_ptr<Asset> audio_clip);
- virtual ~AudioSource() = default;
-
-public:
- //! Start or resume this audio source
- void play();
- void play(bool looping);
- //! Stop this audio source
- void stop();
-
-public:
- //! Sample file location
- std::unique_ptr<Asset> audio_clip;
- //! TODO: ?????
- bool play_on_awake;
- //! Repeat the current audio clip during playback
- bool loop;
- //! Normalized volume (0.0 - 1.0)
- float volume;
-
-private:
- std::unique_ptr<Sound> sound;
-};
-
-} // namespace crepe
diff --git a/src/crepe/api/BehaviorScript.cpp b/src/crepe/api/BehaviorScript.cpp
index e69de29..7bbace0 100644
--- a/src/crepe/api/BehaviorScript.cpp
+++ b/src/crepe/api/BehaviorScript.cpp
@@ -0,0 +1,15 @@
+#include "BehaviorScript.h"
+#include "Component.h"
+#include "GameObject.h"
+
+using namespace crepe;
+
+BehaviorScript::BehaviorScript(game_object_id_t id, ComponentManager & mgr)
+ : Component(id),
+ component_manager(mgr) {}
+
+template <>
+BehaviorScript & GameObject::add_component<BehaviorScript>() {
+ ComponentManager & mgr = this->component_manager;
+ return mgr.add_component<BehaviorScript>(this->id, mgr);
+}
diff --git a/src/crepe/api/BehaviorScript.h b/src/crepe/api/BehaviorScript.h
index 6b1fec7..9d85d4c 100644
--- a/src/crepe/api/BehaviorScript.h
+++ b/src/crepe/api/BehaviorScript.h
@@ -4,29 +4,69 @@
#include "../Component.h"
+#include "GameObject.h"
+
namespace crepe {
class ScriptSystem;
class ComponentManager;
class Script;
+/**
+ * \brief Script component
+ *
+ * This class acts as a (component) wrapper around an instance of (a class derivatived from) \c
+ * Script. \c BehaviorScript is the only ECS component that stores member function
+ * implementations as data.
+ */
class BehaviorScript : public Component {
protected:
- friend class crepe::ComponentManager;
- using Component::Component;
-
-public:
- virtual ~BehaviorScript() = default;
+ /**
+ * \param id Parent \c GameObject id
+ * \param component_manager Reference to component manager (passed through to \c Script
+ * instance)
+ *
+ * \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);
+ //! Only ComponentManager is allowed to instantiate BehaviorScript
+ friend class ComponentManager;
public:
+ /**
+ * \brief Set the concrete script of this component
+ *
+ * \tparam T Concrete script type (derived from \c crepe::Script)
+ *
+ * \returns Reference to BehaviorScript component (`*this`)
+ */
template <class T>
BehaviorScript & set_script();
protected:
- friend class crepe::ScriptSystem;
+ //! Script instance
std::unique_ptr<Script> script = nullptr;
+ //! ScriptSystem needs direct access to the script instance
+ friend class ScriptSystem;
+
+protected:
+ //! Reference to component manager (passed to Script)
+ ComponentManager & component_manager;
};
+/**
+ * \brief Add a BehaviorScript component to this game object
+ *
+ * The \c BehaviorScript class is the only exception to the ECS harmony, and requires a
+ * reference to the component manager passed to its constructor in order to function normally.
+ * This is because the \c BehaviorScript (and \c Script) classes are the only component-related
+ * classes that store implemented member functions as data.
+ */
+template <>
+BehaviorScript & GameObject::add_component<BehaviorScript>();
+
} // namespace crepe
#include "BehaviorScript.hpp"
diff --git a/src/crepe/api/BehaviorScript.hpp b/src/crepe/api/BehaviorScript.hpp
index 4751607..d80321d 100644
--- a/src/crepe/api/BehaviorScript.hpp
+++ b/src/crepe/api/BehaviorScript.hpp
@@ -2,7 +2,7 @@
#include <type_traits>
-#include "../util/log.h"
+#include "../util/Log.h"
#include "BehaviorScript.h"
#include "Script.h"
@@ -11,10 +11,11 @@ namespace crepe {
template <class T>
BehaviorScript & BehaviorScript::set_script() {
- static_assert(std::is_base_of<Script, T>::value);
dbg_trace();
+ static_assert(std::is_base_of<Script, T>::value);
Script * s = new T();
- s->parent = this;
+ s->game_object_id = this->game_object_id;
+ s->component_manager_ref = &this->component_manager;
this->script = std::unique_ptr<Script>(s);
return *this;
}
diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt
index 85696c4..f9b370f 100644
--- a/src/crepe/api/CMakeLists.txt
+++ b/src/crepe/api/CMakeLists.txt
@@ -1,7 +1,6 @@
target_sources(crepe PUBLIC
# AudioSource.cpp
BehaviorScript.cpp
- Script.cpp
GameObject.cpp
Rigidbody.cpp
ParticleEmitter.cpp
diff --git a/src/crepe/api/Camera.cpp b/src/crepe/api/Camera.cpp
index 6355a03..5835bdd 100644
--- a/src/crepe/api/Camera.cpp
+++ b/src/crepe/api/Camera.cpp
@@ -1,7 +1,4 @@
-
-#include <cstdint>
-
-#include "util/log.h"
+#include "util/Log.h"
#include "Camera.h"
#include "Color.h"
@@ -9,7 +6,7 @@
using namespace crepe;
-Camera::Camera(uint32_t id, const Color & bg_color)
+Camera::Camera(game_object_id_t id, const Color & bg_color)
: Component(id),
bg_color(bg_color) {
dbg_trace();
diff --git a/src/crepe/api/Camera.h b/src/crepe/api/Camera.h
index ba3a9ef..e0cda34 100644
--- a/src/crepe/api/Camera.h
+++ b/src/crepe/api/Camera.h
@@ -1,7 +1,5 @@
#pragma once
-#include <cstdint>
-
#include "Color.h"
#include "Component.h"
@@ -11,9 +9,8 @@ namespace crepe {
* \class Camera
* \brief Represents a camera component for rendering in the game.
*
- * The Camera class defines the view parameters, including background color,
- * aspect ratio, position, and zoom level. It controls what part of the game
- * world is visible on the screen.
+ * The Camera class defines the view parameters, including background color, aspect ratio,
+ * position, and zoom level. It controls what part of the game world is visible on the screen.
*/
class Camera : public Component {
@@ -23,7 +20,7 @@ public:
* \param id Unique identifier for the camera component.
* \param bg_color Background color for the camera view.
*/
- Camera(uint32_t id, const Color & bg_color);
+ Camera(game_object_id_t id, const Color & bg_color);
~Camera(); // dbg_trace only
public:
diff --git a/src/crepe/api/Config.h b/src/crepe/api/Config.h
index 8c9e643..3ab877a 100644
--- a/src/crepe/api/Config.h
+++ b/src/crepe/api/Config.h
@@ -1,19 +1,24 @@
#pragma once
-#include "../util/log.h"
+#include "../util/Log.h"
namespace crepe {
+/**
+ * \brief Global configuration interface
+ *
+ * This class stores engine default settings. Properties on this class are only supposed to be
+ * modified *before* execution is handed over from the game programmer to the engine (i.e. the
+ * main loop is started).
+ */
class Config {
-private:
- Config() = default;
-
-public:
- ~Config() = default;
-
public:
//! Retrieve handle to global Config instance
static Config & get_instance();
+
+private:
+ Config() = default;
+
// singleton
Config(const Config &) = delete;
Config(Config &&) = delete;
@@ -26,10 +31,9 @@ public:
/**
* \brief Log level
*
- * Only messages with equal or higher priority than this value will be
- * logged.
+ * Only messages with equal or higher priority than this value will be logged.
*/
- LogLevel level = LogLevel::INFO;
+ Log::Level level = Log::Level::INFO;
/**
* \brief Colored log output
*
@@ -43,8 +47,8 @@ public:
/**
* \brief Save file location
*
- * This location is used by the constructor of SaveManager, and should be
- * set before save manager functionality is attempted to be used.
+ * This location is used by the constructor of SaveManager, and should be set before save
+ * manager functionality is attempted to be used.
*/
std::string location = "save.crepe.db";
} savemgr;
diff --git a/src/crepe/api/GameObject.cpp b/src/crepe/api/GameObject.cpp
index d252e77..287e81d 100644
--- a/src/crepe/api/GameObject.cpp
+++ b/src/crepe/api/GameObject.cpp
@@ -1,23 +1,26 @@
#include "api/Transform.h"
+#include "BehaviorScript.h"
#include "GameObject.h"
#include "Metadata.h"
using namespace crepe;
using namespace std;
-GameObject::GameObject(game_object_id_t id, const std::string & name,
- const std::string & tag, const Vector2 & position,
- double rotation, double scale)
- : id(id) {
+GameObject::GameObject(ComponentManager & component_manager, game_object_id_t id,
+ const std::string & name, const std::string & tag,
+ const Vector2 & position, double rotation, double scale)
+ : id(id),
+ component_manager(component_manager) {
+
// Add Transform and Metadata components
- ComponentManager & mgr = ComponentManager::get_instance();
+ ComponentManager & mgr = this->component_manager;
mgr.add_component<Transform>(this->id, position, rotation, scale);
mgr.add_component<Metadata>(this->id, name, tag);
}
void GameObject::set_parent(const GameObject & parent) {
- ComponentManager & mgr = ComponentManager::get_instance();
+ ComponentManager & mgr = this->component_manager;
// Set parent on own Metadata component
vector<reference_wrapper<Metadata>> this_metadata
diff --git a/src/crepe/api/GameObject.h b/src/crepe/api/GameObject.h
index d703730..34ef8bb 100644
--- a/src/crepe/api/GameObject.h
+++ b/src/crepe/api/GameObject.h
@@ -2,25 +2,26 @@
#include <string>
+#include "Vector2.h"
#include "types.h"
namespace crepe {
-class Vector2;
+class ComponentManager;
/**
* \brief Represents a GameObject
*
- * This class represents a GameObject. The GameObject class is only used
- * as an interface for the game programmer. The actual implementation is
- * done in the ComponentManager.
+ * This class represents a GameObject. The GameObject class is only used as an interface for
+ * the game programmer. The actual implementation is done in the ComponentManager.
*/
class GameObject {
-public:
+private:
/**
- * This constructor creates a new GameObject. It creates a new
- * Transform and Metadata component and adds them to the ComponentManager.
+ * 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 id The id of the GameObject
* \param name The name of the GameObject
* \param tag The tag of the GameObject
@@ -28,15 +29,19 @@ public:
* \param rotation The rotation of the GameObject
* \param scale The scale of the GameObject
*/
- GameObject(game_object_id_t id, const std::string & name,
- const std::string & tag, const Vector2 & position,
+ GameObject(ComponentManager & component_manager, game_object_id_t id,
+ const std::string & name, const std::string & tag, const Vector2 & position,
double rotation, double scale);
+ //! ComponentManager instances GameObject
+ friend class ComponentManager;
+
+public:
/**
* \brief Set the parent of this GameObject
*
- * This method sets the parent of this GameObject. It sets the parent
- * in the Metadata component of this GameObject and adds this GameObject
- * to the children list of the parent GameObject.
+ * This method sets the parent of this GameObject. It sets the parent in the Metadata
+ * component of this GameObject and adds this GameObject to the children list of the parent
+ * GameObject.
*
* \param parent The parent GameObject
*/
@@ -44,8 +49,8 @@ public:
/**
* \brief Add a component to the GameObject
*
- * This method adds a component to the GameObject. It forwards the
- * arguments to the ComponentManager.
+ * This method adds a component to the GameObject. It forwards the arguments to the
+ * ComponentManager.
*
* \tparam T The type of the component
* \tparam Args The types of the arguments
@@ -58,6 +63,9 @@ public:
public:
//! The id of the GameObject
const game_object_id_t id;
+
+protected:
+ ComponentManager & component_manager;
};
} // namespace crepe
diff --git a/src/crepe/api/GameObject.hpp b/src/crepe/api/GameObject.hpp
index bfba7fe..17b17d7 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 = ComponentManager::get_instance();
+ ComponentManager & mgr = this->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
index 2e9823f..a64366f 100644
--- a/src/crepe/api/LoopManager.cpp
+++ b/src/crepe/api/LoopManager.cpp
@@ -1,5 +1,9 @@
-
#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"
@@ -7,11 +11,21 @@
#include "LoopTimer.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>();
+}
-LoopManager::LoopManager() {}
void LoopManager::process_input() {
SDLContext::get_instance().handle_events(this->game_running);
}
+
void LoopManager::start() {
this->setup();
this->loop();
@@ -48,7 +62,7 @@ void LoopManager::setup() {
void LoopManager::render() {
if (this->game_running) {
- RenderSystem::get_instance().update();
+ this->get_system<RenderSystem>().update();
}
}
diff --git a/src/crepe/api/LoopManager.h b/src/crepe/api/LoopManager.h
index 2f03193..f6904be 100644
--- a/src/crepe/api/LoopManager.h
+++ b/src/crepe/api/LoopManager.h
@@ -2,15 +2,9 @@
#include <memory>
-class RenderSystem;
-class SDLContext;
-class LoopTimer;
-class ScriptSystem;
-class SoundSystem;
-class ParticleSystem;
-class PhysicsSystem;
-class AnimatorSystem;
-class CollisionSystem;
+#include "../ComponentManager.h"
+#include "../system/System.h"
+
namespace crepe {
class LoopManager {
@@ -73,7 +67,35 @@ private:
void render();
bool game_running = false;
- //#TODO add system instances
+
+private:
+ //! Component manager instance
+ ComponentManager component_manager{};
+
+private:
+ /**
+ * \brief Collection of System instances
+ *
+ * This map holds System instances indexed by the system's class typeid. It is filled in the
+ * constructor of \c 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
new file mode 100644
index 0000000..0b14fdb
--- /dev/null
+++ b/src/crepe/api/LoopManager.hpp
@@ -0,0 +1,40 @@
+#pragma once
+
+#include <cassert>
+#include <format>
+#include <memory>
+
+#include "../system/System.h"
+
+#include "LoopManager.h"
+
+namespace crepe {
+
+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");
+
+ System * system = new T(this->component_manager);
+ this->systems[typeid(T)] = unique_ptr<System>(system);
+}
+
+} // namespace crepe
diff --git a/src/crepe/api/LoopTimer.cpp b/src/crepe/api/LoopTimer.cpp
index 8f09e41..a9800b7 100644
--- a/src/crepe/api/LoopTimer.cpp
+++ b/src/crepe/api/LoopTimer.cpp
@@ -1,7 +1,7 @@
#include <chrono>
#include "../facade/SDLContext.h"
-#include "../util/log.h"
+#include "../util/Log.h"
#include "LoopTimer.h"
@@ -24,9 +24,8 @@ void LoopTimer::start() {
void LoopTimer::update() {
auto current_frame_time = std::chrono::steady_clock::now();
// Convert to duration in seconds for delta time
- this->delta_time
- = std::chrono::duration_cast<std::chrono::duration<double>>(
- current_frame_time - last_frame_time);
+ this->delta_time = std::chrono::duration_cast<std::chrono::duration<double>>(
+ current_frame_time - last_frame_time);
if (this->delta_time > this->maximum_delta_time) {
this->delta_time = this->maximum_delta_time;
@@ -39,17 +38,11 @@ void LoopTimer::update() {
double LoopTimer::get_delta_time() const { return this->delta_time.count(); }
-double LoopTimer::get_current_time() const {
- return this->elapsed_time.count();
-}
+double LoopTimer::get_current_time() const { return this->elapsed_time.count(); }
-void LoopTimer::advance_fixed_update() {
- this->elapsed_fixed_time += this->fixed_delta_time;
-}
+void LoopTimer::advance_fixed_update() { this->elapsed_fixed_time += this->fixed_delta_time; }
-double LoopTimer::get_fixed_delta_time() const {
- return this->fixed_delta_time.count();
-}
+double LoopTimer::get_fixed_delta_time() const { return this->fixed_delta_time.count(); }
void LoopTimer::set_fps(int fps) {
this->fps = fps;
@@ -66,13 +59,13 @@ void LoopTimer::enforce_frame_rate() {
std::chrono::steady_clock::time_point current_frame_time
= std::chrono::steady_clock::now();
std::chrono::milliseconds frame_duration
- = std::chrono::duration_cast<std::chrono::milliseconds>(
- current_frame_time - this->last_frame_time);
+ = std::chrono::duration_cast<std::chrono::milliseconds>(current_frame_time
+ - this->last_frame_time);
if (frame_duration < this->frame_target_time) {
std::chrono::milliseconds delay_time
- = std::chrono::duration_cast<std::chrono::milliseconds>(
- this->frame_target_time - frame_duration);
+ = std::chrono::duration_cast<std::chrono::milliseconds>(this->frame_target_time
+ - frame_duration);
if (delay_time.count() > 0) {
SDLContext::get_instance().delay(delay_time.count());
}
diff --git a/src/crepe/api/LoopTimer.h b/src/crepe/api/LoopTimer.h
index 85687be..f277d7b 100644
--- a/src/crepe/api/LoopTimer.h
+++ b/src/crepe/api/LoopTimer.h
@@ -1,124 +1,123 @@
#pragma once
#include <chrono>
-#include <cstdint>
namespace crepe {
class LoopTimer {
public:
/**
- * \brief Get the singleton instance of LoopTimer.
- *
- * \return A reference to the LoopTimer instance.
- */
+ * \brief Get the singleton instance of LoopTimer.
+ *
+ * \return A reference to the LoopTimer instance.
+ */
static LoopTimer & get_instance();
/**
- * \brief Get the current delta time for the current frame.
- *
- * \return Delta time in seconds since the last frame.
- */
+ * \brief Get the current delta time for the current frame.
+ *
+ * \return Delta time in seconds since the last frame.
+ */
double get_delta_time() const;
/**
- * \brief Get the current game time.
- *
- * \note The current game time may vary from real-world elapsed time.
- * It is the cumulative sum of each frame's delta time.
- *
- * \return Elapsed game time in seconds.
- */
+ * \brief Get the current game time.
+ *
+ * \note The current game time may vary from real-world elapsed time. It is the cumulative
+ * sum of each frame's delta time.
+ *
+ * \return Elapsed game time in seconds.
+ */
double get_current_time() const;
/**
- * \brief Set the target frames per second (FPS).
- *
- * \param fps The desired frames rendered per second.
- */
+ * \brief Set the target frames per second (FPS).
+ *
+ * \param fps The desired frames rendered per second.
+ */
void set_fps(int fps);
/**
- * \brief Get the current frames per second (FPS).
- *
- * \return Current FPS.
- */
+ * \brief Get the current frames per second (FPS).
+ *
+ * \return Current FPS.
+ */
int get_fps() const;
/**
- * \brief Get the current game scale.
- *
- * \return The current game scale, where 0 = paused, 1 = normal speed, and values > 1 speed up the game.
- */
+ * \brief Get the current game scale.
+ *
+ * \return The current game scale, where 0 = paused, 1 = normal speed, and values > 1 speed
+ * up the game.
+ */
double get_game_scale() const;
/**
- * \brief Set the game scale.
- *
- * \param game_scale The desired game scale (0 = pause, 1 = normal speed, > 1 = speed up).
- */
+ * \brief Set the game scale.
+ *
+ * \param game_scale The desired game scale (0 = pause, 1 = normal speed, > 1 = speed up).
+ */
void set_game_scale(double game_scale);
private:
friend class LoopManager;
/**
- * \brief Start the loop timer.
- *
- * Initializes the timer to begin tracking frame times.
- */
+ * \brief Start the loop timer.
+ *
+ * Initializes the timer to begin tracking frame times.
+ */
void start();
/**
- * \brief Enforce the frame rate limit.
- *
- * Ensures that the game loop does not exceed the target FPS by delaying
- * frame updates as necessary.
- */
+ * \brief Enforce the frame rate limit.
+ *
+ * Ensures that the game loop does not exceed the target FPS by delaying frame updates as
+ * necessary.
+ */
void enforce_frame_rate();
/**
- * \brief Get the fixed delta time for consistent updates.
- *
- * Fixed delta time is used for operations that require uniform time steps,
- * such as physics calculations.
- *
- * \return Fixed delta time in seconds.
- */
+ * \brief Get the fixed delta time for consistent updates.
+ *
+ * Fixed delta time is used for operations that require uniform time steps, such as physics
+ * calculations.
+ *
+ * \return Fixed delta time in seconds.
+ */
double get_fixed_delta_time() const;
/**
- * \brief Get the accumulated lag in the game loop.
- *
- * Lag represents the difference between the target frame time and the
- * actual frame time, useful for managing fixed update intervals.
- *
- * \return Accumulated lag in seconds.
- */
+ * \brief Get the accumulated lag in the game loop.
+ *
+ * Lag represents the difference between the target frame time and the actual frame time,
+ * useful for managing fixed update intervals.
+ *
+ * \return Accumulated lag in seconds.
+ */
double get_lag() const;
/**
- * \brief Construct a new LoopTimer object.
- *
- * Private constructor for singleton pattern to restrict instantiation
- * outside the class.
- */
+ * \brief Construct a new LoopTimer object.
+ *
+ * Private constructor for singleton pattern to restrict instantiation outside the class.
+ */
LoopTimer();
/**
- * \brief Update the timer to the current frame.
- *
- * Calculates and updates the delta time for the current frame and adds it to
- * the cumulative game time.
- */
+ * \brief Update the timer to the current frame.
+ *
+ * Calculates and updates the delta time for the current frame and adds it to the cumulative
+ * game time.
+ */
void update();
/**
- * \brief Advance the game loop by a fixed update interval.
- *
- * This method progresses the game state by a consistent, fixed time step,
- * allowing for stable updates independent of frame rate fluctuations.
- */
+ * \brief Advance the game loop by a fixed update interval.
+ *
+ * This method progresses the game state by a consistent, fixed time step, allowing for
+ * stable updates independent of frame rate fluctuations.
+ */
void advance_fixed_update();
private:
@@ -131,11 +130,9 @@ private:
//! Delta time for the current frame in seconds
std::chrono::duration<double> delta_time{0.0};
//! Target time per frame in seconds
- std::chrono::duration<double> frame_target_time
- = std::chrono::seconds(1) / fps;
+ std::chrono::duration<double> frame_target_time = std::chrono::seconds(1) / fps;
//! Fixed delta time for fixed updates in seconds
- std::chrono::duration<double> fixed_delta_time
- = std::chrono::seconds(1) / 50;
+ std::chrono::duration<double> fixed_delta_time = std::chrono::seconds(1) / 50;
//! Total elapsed game time in seconds
std::chrono::duration<double> elapsed_time{0.0};
//! Total elapsed time for fixed updates in seconds
diff --git a/src/crepe/api/Metadata.h b/src/crepe/api/Metadata.h
index c61e006..235d42f 100644
--- a/src/crepe/api/Metadata.h
+++ b/src/crepe/api/Metadata.h
@@ -10,8 +10,8 @@ namespace crepe {
/**
* \brief Metadata component
*
- * This class represents the Metadata component. It stores the name, tag, parent
- * and children of a GameObject.
+ * This class represents the Metadata component. It stores the name, tag, parent and children
+ * of a GameObject.
*/
class Metadata : public Component {
public:
@@ -20,8 +20,7 @@ public:
* \param name The name of the GameObject
* \param tag The tag of the GameObject
*/
- Metadata(game_object_id_t id, const std::string & name,
- const std::string & tag);
+ Metadata(game_object_id_t id, const std::string & name, const std::string & tag);
/**
* \brief Get the maximum number of instances for this component
*
diff --git a/src/crepe/api/ParticleEmitter.cpp b/src/crepe/api/ParticleEmitter.cpp
index 35f960d..90b77a0 100644
--- a/src/crepe/api/ParticleEmitter.cpp
+++ b/src/crepe/api/ParticleEmitter.cpp
@@ -2,8 +2,7 @@
using namespace crepe;
-ParticleEmitter::ParticleEmitter(game_object_id_t game_object_id,
- const Data & data)
+ParticleEmitter::ParticleEmitter(game_object_id_t game_object_id, const Data & data)
: Component(game_object_id),
data(data) {
for (size_t i = 0; i < this->data.max_particles; i++) {
diff --git a/src/crepe/api/ParticleEmitter.h b/src/crepe/api/ParticleEmitter.h
index a9e872f..33112e1 100644
--- a/src/crepe/api/ParticleEmitter.h
+++ b/src/crepe/api/ParticleEmitter.h
@@ -13,16 +13,16 @@ class Sprite;
/**
* \brief Data holder for particle emission parameters.
*
- * The ParticleEmitter class stores configuration data for particle properties,
- * defining the characteristics and boundaries of particle emissions.
+ * The ParticleEmitter class stores configuration data for particle properties, defining the
+ * characteristics and boundaries of particle emissions.
*/
class ParticleEmitter : public Component {
public:
/**
* \brief Defines the boundary within which particles are constrained.
*
- * This structure specifies the boundary's size and offset, as well as the
- * behavior of particles upon reaching the boundary limits.
+ * This structure specifies the boundary's size and offset, as well as the behavior of
+ * particles upon reaching the boundary limits.
*/
struct Boundary {
//! boundary width (midpoint is emitter location)
@@ -38,8 +38,8 @@ public:
/**
* \brief Holds parameters that control particle emission.
*
- * Contains settings for the emitter’s position, particle speed, angle, lifespan,
- * boundary, and the sprite used for rendering particles.
+ * Contains settings for the emitter’s position, particle speed, angle, lifespan, boundary,
+ * and the sprite used for rendering particles.
*/
struct Data {
//! position of the emitter
diff --git a/src/crepe/api/Rigidbody.cpp b/src/crepe/api/Rigidbody.cpp
index 3bf1c5b..6b87695 100644
--- a/src/crepe/api/Rigidbody.cpp
+++ b/src/crepe/api/Rigidbody.cpp
@@ -2,8 +2,8 @@
using namespace crepe;
-crepe::Rigidbody::Rigidbody(uint32_t game_object_id, const Data & data)
- : Component(game_object_id),
+crepe::Rigidbody::Rigidbody(game_object_id_t id, const Data & data)
+ : Component(id),
data(data) {}
void crepe::Rigidbody::add_force_linear(const Vector2 & force) {
diff --git a/src/crepe/api/Rigidbody.h b/src/crepe/api/Rigidbody.h
index 68481f4..3e5c7a3 100644
--- a/src/crepe/api/Rigidbody.h
+++ b/src/crepe/api/Rigidbody.h
@@ -1,7 +1,5 @@
#pragma once
-#include <cstdint>
-
#include "../Component.h"
#include "Vector2.h"
@@ -11,8 +9,8 @@ namespace crepe {
/**
* \brief Rigidbody class
*
- * This class is used by the physics sytem and collision system.
- * It configures how to system interact with the gameobject for movement and collisions.
+ * This class is used by the physics sytem and collision system. It configures how to system
+ * interact with the gameobject for movement and collisions.
*/
class Rigidbody : public Component {
public:
@@ -32,8 +30,8 @@ public:
/**
* \brief PhysicsConstraints to constrain movement
*
- * This struct configures the movement constraint for this object.
- * If a constraint is enabled the systems will not move the object.
+ * This struct configures the movement constraint for this object. If a constraint is enabled
+ * the systems will not move the object.
*/
struct PhysicsConstraints {
//! X constraint
@@ -82,7 +80,7 @@ public:
* \param game_object_id id of the gameobject the rigibody is added to.
* \param data struct to configure the rigidbody.
*/
- Rigidbody(uint32_t game_object_id, const Data & data);
+ Rigidbody(game_object_id_t id, const Data & data);
//! struct to hold data of rigidbody
Data data;
diff --git a/src/crepe/api/SaveManager.cpp b/src/crepe/api/SaveManager.cpp
index 43276c5..c5f43ea 100644
--- a/src/crepe/api/SaveManager.cpp
+++ b/src/crepe/api/SaveManager.cpp
@@ -1,5 +1,5 @@
#include "../facade/DB.h"
-#include "../util/log.h"
+#include "../util/Log.h"
#include "Config.h"
#include "SaveManager.h"
@@ -139,14 +139,11 @@ ValueBroker<T> SaveManager::get(const string & key, const T & default_value) {
}
template ValueBroker<uint8_t> SaveManager::get(const string &, const uint8_t &);
template ValueBroker<int8_t> SaveManager::get(const string &, const int8_t &);
-template ValueBroker<uint16_t> SaveManager::get(const string &,
- const uint16_t &);
+template ValueBroker<uint16_t> SaveManager::get(const string &, const uint16_t &);
template ValueBroker<int16_t> SaveManager::get(const string &, const int16_t &);
-template ValueBroker<uint32_t> SaveManager::get(const string &,
- const uint32_t &);
+template ValueBroker<uint32_t> SaveManager::get(const string &, const uint32_t &);
template ValueBroker<int32_t> SaveManager::get(const string &, const int32_t &);
-template ValueBroker<uint64_t> SaveManager::get(const string &,
- const uint64_t &);
+template ValueBroker<uint64_t> SaveManager::get(const string &, const uint64_t &);
template ValueBroker<int64_t> SaveManager::get(const string &, const int64_t &);
template ValueBroker<float> SaveManager::get(const string &, const float &);
template ValueBroker<double> SaveManager::get(const string &, const double &);
diff --git a/src/crepe/api/SaveManager.h b/src/crepe/api/SaveManager.h
index 4be85fb..3d8c852 100644
--- a/src/crepe/api/SaveManager.h
+++ b/src/crepe/api/SaveManager.h
@@ -24,7 +24,8 @@ public:
* \brief Get a read/write reference to a value and initialize it if it does not yet exist
*
* \param key The value key
- * \param default_value Value to initialize \c key with if it does not already exist in the database
+ * \param default_value Value to initialize \c key with if it does not already exist in the
+ * database
*
* \return Read/write reference to the value
*/
@@ -38,8 +39,8 @@ public:
*
* \return Read/write reference to the value
*
- * \note Attempting to read this value before it is initialized (i.e. set)
- * will result in an exception
+ * \note Attempting to read this value before it is initialized (i.e. set) will result in an
+ * exception
*/
template <typename T>
ValueBroker<T> get(const std::string & key);
@@ -102,8 +103,8 @@ private:
*
* \returns DB instance
*
- * This function exists because DB is a facade class, which can't directly be
- * used in the API without workarounds
+ * This function exists because DB is a facade class, which can't directly be used in the API
+ * without workarounds
*
* TODO: better solution
*/
diff --git a/src/crepe/api/Scene.cpp b/src/crepe/api/Scene.cpp
index 933edf4..88aa82d 100644
--- a/src/crepe/api/Scene.cpp
+++ b/src/crepe/api/Scene.cpp
@@ -2,4 +2,6 @@
using namespace crepe;
-Scene::Scene(const std::string & name) : name(name) {}
+Scene::Scene(ComponentManager & mgr, const std::string & name)
+ : component_manager(mgr),
+ name(name) {}
diff --git a/src/crepe/api/Scene.h b/src/crepe/api/Scene.h
index f8bcc3d..0e516b6 100644
--- a/src/crepe/api/Scene.h
+++ b/src/crepe/api/Scene.h
@@ -4,14 +4,23 @@
namespace crepe {
+class SceneManager;
+class ComponentManager;
+
class Scene {
+protected:
+ Scene(ComponentManager & mgr, const std::string & name);
+ friend class SceneManager;
+
public:
- Scene(const std::string & name);
virtual ~Scene() = default;
- virtual void load_scene() = 0;
public:
- std::string name;
+ virtual void load_scene() = 0;
+ const std::string name;
+
+protected:
+ ComponentManager & component_manager;
};
} // namespace crepe
diff --git a/src/crepe/api/SceneManager.cpp b/src/crepe/api/SceneManager.cpp
index dfed6ee..7fb5cb0 100644
--- a/src/crepe/api/SceneManager.cpp
+++ b/src/crepe/api/SceneManager.cpp
@@ -8,10 +8,7 @@
using namespace crepe;
using namespace std;
-SceneManager & SceneManager::get_instance() {
- static SceneManager instance;
- return instance;
-}
+SceneManager::SceneManager(ComponentManager & mgr) : component_manager(mgr) {}
void SceneManager::set_next_scene(const string & name) { next_scene = name; }
@@ -19,18 +16,17 @@ void SceneManager::load_next_scene() {
// next scene not set
if (this->next_scene.empty()) return;
- auto it
- = find_if(this->scenes.begin(), this->scenes.end(),
- [&next_scene = this->next_scene](unique_ptr<Scene> & scene) {
- return scene->name == next_scene;
- });
+ auto it = find_if(this->scenes.begin(), this->scenes.end(),
+ [&next_scene = this->next_scene](unique_ptr<Scene> & scene) {
+ return scene->name == next_scene;
+ });
// next scene not found
if (it == this->scenes.end()) return;
unique_ptr<Scene> & scene = *it;
// Delete all components of the current scene
- ComponentManager & mgr = ComponentManager::get_instance();
+ ComponentManager & mgr = this->component_manager;
mgr.delete_all_components();
// Load the new scene
diff --git a/src/crepe/api/SceneManager.h b/src/crepe/api/SceneManager.h
index 1e0e670..e854794 100644
--- a/src/crepe/api/SceneManager.h
+++ b/src/crepe/api/SceneManager.h
@@ -8,14 +8,11 @@
namespace crepe {
+class ComponentManager;
+
class SceneManager {
public:
- // Singleton
- static SceneManager & get_instance();
- SceneManager(const SceneManager &) = delete;
- SceneManager(SceneManager &&) = delete;
- SceneManager & operator=(const SceneManager &) = delete;
- SceneManager & operator=(SceneManager &&) = delete;
+ SceneManager(ComponentManager & mgr);
public:
/**
@@ -38,11 +35,9 @@ public:
void load_next_scene();
private:
- SceneManager() = default;
-
-private:
std::vector<std::unique_ptr<Scene>> scenes;
std::string next_scene;
+ ComponentManager & component_manager;
};
} // namespace crepe
diff --git a/src/crepe/api/SceneManager.hpp b/src/crepe/api/SceneManager.hpp
index 8bad7b2..714f690 100644
--- a/src/crepe/api/SceneManager.hpp
+++ b/src/crepe/api/SceneManager.hpp
@@ -1,13 +1,16 @@
+#pragma once
+
#include "SceneManager.h"
namespace crepe {
template <typename T>
void SceneManager::add_scene(const std::string & name) {
- static_assert(std::is_base_of<Scene, T>::value,
- "T must be derived from Scene");
+ using namespace std;
+ static_assert(is_base_of<Scene, T>::value, "T must be derived from Scene");
- scenes.emplace_back(make_unique<T>(name));
+ Scene * scene = new T(this->component_manager, name);
+ this->scenes.emplace_back(unique_ptr<Scene>(scene));
// The first scene added, is the one that will be loaded at the beginning
if (next_scene.empty()) {
diff --git a/src/crepe/api/Script.cpp b/src/crepe/api/Script.cpp
deleted file mode 100644
index 390cec7..0000000
--- a/src/crepe/api/Script.cpp
+++ /dev/null
@@ -1,3 +0,0 @@
-#include "Script.h"
-
-using namespace crepe;
diff --git a/src/crepe/api/Script.h b/src/crepe/api/Script.h
index 49e625f..2b70379 100644
--- a/src/crepe/api/Script.h
+++ b/src/crepe/api/Script.h
@@ -2,35 +2,85 @@
#include <vector>
-namespace crepe {
-class ScriptSystem;
-}
+#include "../types.h"
namespace crepe {
+class ScriptSystem;
class BehaviorScript;
+class ComponentManager;
+/**
+ * \brief Script interface
+ *
+ * This class is used as a base class for user-defined scripts that can be added to game
+ * objects using the \c BehaviorScript component.
+ *
+ * \note Additional *events* (like Unity's OnDisable and OnEnable) should be implemented as
+ * member or lambda methods in derivative user script classes and registered in \c init().
+ */
class Script {
- friend class crepe::ScriptSystem;
-
protected:
+ /**
+ * \brief Script initialization function
+ *
+ * This function is called during the ScriptSystem::update() routine *before*
+ * Script::update() if it (a) has not yet been called and (b) the \c BehaviorScript component
+ * holding this script instance is active.
+ */
virtual void init() {}
+ /**
+ * \brief Script update function
+ *
+ * This function is called during the ScriptSystem::update() routine if the \c BehaviorScript
+ * component holding this script instance is active.
+ */
virtual void update() {}
- // NOTE: additional *events* (like unity's OnDisable and OnEnable) should be
- // implemented as member methods in derivative user script classes and
- // registered in init(), otherwise this class will balloon in size with each
- // added event.
+ //! ScriptSystem calls \c init() and \c update()
+ friend class crepe::ScriptSystem;
protected:
+ /**
+ * \brief Get single component of type \c T on this game object (utility)
+ *
+ * \tparam T Type of component
+ *
+ * \returns Reference to component
+ *
+ * \throws nullptr if this game object does not have a component matching type \c T
+ */
template <typename T>
- T & get_component();
+ 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 (utility)
+ *
+ * \tparam T Type of component
+ *
+ * \returns List of component references
+ */
template <typename T>
- std::vector<std::reference_wrapper<T>> get_components();
+ std::vector<std::reference_wrapper<T>> get_components() const;
+
+protected:
+ // NOTE: Script must have a constructor without arguments so the game programmer doesn't need
+ // to manually add `using Script::Script` to their concrete script class.
+ Script() = default;
+ //! Only \c BehaviorScript instantiates Script
+ friend class BehaviorScript;
+
+private:
+ // These references are set by BehaviorScript immediately after calling the constructor of
+ // Script.
+ game_object_id_t game_object_id = -1;
+ ComponentManager * component_manager_ref = nullptr;
+ // TODO: use OptionalRef instead of pointer
private:
- friend class crepe::BehaviorScript;
- BehaviorScript * parent = nullptr;
+ //! Flag to indicate if \c init() has been called already
+ bool initialized = false;
};
} // namespace crepe
diff --git a/src/crepe/api/Script.hpp b/src/crepe/api/Script.hpp
index d96c0e8..a064a90 100644
--- a/src/crepe/api/Script.hpp
+++ b/src/crepe/api/Script.hpp
@@ -8,18 +8,21 @@
namespace crepe {
template <typename T>
-T & Script::get_component() {
- std::vector<std::reference_wrapper<T>> all_components
- = this->get_components<T>();
- if (all_components.size() < 1) throw nullptr; // TODO
+T & Script::get_component() const {
+ using namespace std;
+ vector<reference_wrapper<T>> all_components = this->get_components<T>();
+ if (all_components.size() < 1)
+ throw runtime_error(
+ format("Script: no component found with type = {}", typeid(T).name()));
return all_components.back().get();
}
template <typename T>
-std::vector<std::reference_wrapper<T>> Script::get_components() {
- ComponentManager & mgr = ComponentManager::get_instance();
- return mgr.get_components_by_id<T>(this->parent->game_object_id);
+std::vector<std::reference_wrapper<T>> Script::get_components() const {
+ auto & mgr = *this->component_manager_ref;
+
+ return mgr.get_components_by_id<T>(this->game_object_id);
}
} // namespace crepe
diff --git a/src/crepe/api/Sprite.cpp b/src/crepe/api/Sprite.cpp
index 6f0433f..bd2d5cf 100644
--- a/src/crepe/api/Sprite.cpp
+++ b/src/crepe/api/Sprite.cpp
@@ -1,6 +1,6 @@
#include <memory>
-#include "../util/log.h"
+#include "../util/Log.h"
#include "facade/SDLContext.h"
#include "Component.h"
@@ -10,8 +10,8 @@
using namespace std;
using namespace crepe;
-Sprite::Sprite(game_object_id_t id, const shared_ptr<Texture> image,
- const Color & color, const FlipSettings & flip)
+Sprite::Sprite(game_object_id_t id, const shared_ptr<Texture> image, const Color & color,
+ const FlipSettings & flip)
: Component(id),
color(color),
flip(flip),
diff --git a/src/crepe/api/Sprite.h b/src/crepe/api/Sprite.h
index deb3f93..0192793 100644
--- a/src/crepe/api/Sprite.h
+++ b/src/crepe/api/Sprite.h
@@ -1,6 +1,5 @@
#pragma once
-#include <cstdint>
#include <memory>
#include "Color.h"
@@ -28,8 +27,8 @@ class AnimatorSystem;
/**
* \brief Represents a renderable sprite component.
*
- * A renderable sprite that can be displayed in the game. It includes a texture,
- * color, and flip settings, and is managed in layers with defined sorting orders.
+ * A renderable sprite that can be displayed in the game. It includes a texture, color, and
+ * flip settings, and is managed in layers with defined sorting orders.
*/
class Sprite : public Component {
@@ -43,8 +42,8 @@ public:
* \param color Color tint applied to the sprite.
* \param flip Flip settings for horizontal and vertical orientation.
*/
- Sprite(game_object_id_t id, const std::shared_ptr<Texture> image,
- const Color & color, const FlipSettings & flip);
+ Sprite(game_object_id_t id, const std::shared_ptr<Texture> image, const Color & color,
+ const FlipSettings & flip);
/**
* \brief Destroys the Sprite instance.
@@ -81,7 +80,8 @@ private:
//! Reads the all the variables plus the sprite_rect
friend class AnimatorSystem;
- //! Render area of the sprite this will also be adjusted by the AnimatorSystem if an Animator object is present in GameObject
+ //! Render area of the sprite this will also be adjusted by the AnimatorSystem if an Animator
+ // object is present in GameObject
Rect sprite_rect;
};
diff --git a/src/crepe/api/Texture.cpp b/src/crepe/api/Texture.cpp
index 5ebd23d..de0d0ea 100644
--- a/src/crepe/api/Texture.cpp
+++ b/src/crepe/api/Texture.cpp
@@ -1,7 +1,7 @@
#include <SDL2/SDL_render.h>
#include "../facade/SDLContext.h"
-#include "../util/log.h"
+#include "../util/Log.h"
#include "Asset.h"
#include "Texture.h"
@@ -26,7 +26,7 @@ Texture::~Texture() {
void Texture::load(unique_ptr<Asset> res) {
SDLContext & ctx = SDLContext::get_instance();
- this->texture = std::move(ctx.texture_from_path(res->canonical()));
+ this->texture = std::move(ctx.texture_from_path(res->get_canonical()));
}
int Texture::get_width() const {
diff --git a/src/crepe/api/Texture.h b/src/crepe/api/Texture.h
index b89bc17..6965223 100644
--- a/src/crepe/api/Texture.h
+++ b/src/crepe/api/Texture.h
@@ -1,8 +1,7 @@
#pragma once
-// FIXME: this header can't be included because this is an API header, and SDL2
-// development headers won't be bundled with crepe. Why is this facade in the
-// API namespace?
+// FIXME: this header can't be included because this is an API header, and SDL2 development
+// headers won't be bundled with crepe. Why is this facade in the API namespace?
#include <SDL2/SDL_render.h>
#include <functional>
@@ -19,8 +18,8 @@ class Animator;
* \class Texture
* \brief Manages texture loading and properties.
*
- * The Texture class is responsible for loading an image from a source
- * and providing access to its dimensions. Textures can be used for rendering.
+ * The Texture class is responsible for loading an image from a source and providing access to
+ * its dimensions. Textures can be used for rendering.
*/
class Texture {
@@ -41,8 +40,7 @@ public:
* \brief Destroys the Texture instance, freeing associated resources.
*/
~Texture();
- // FIXME: this constructor shouldn't be necessary because this class doesn't
- // manage memory
+ // FIXME: this constructor shouldn't be necessary because this class doesn't manage memory
/**
* \brief Gets the width of the texture.
diff --git a/src/crepe/api/Transform.cpp b/src/crepe/api/Transform.cpp
index e401120..cd944bd 100644
--- a/src/crepe/api/Transform.cpp
+++ b/src/crepe/api/Transform.cpp
@@ -1,11 +1,10 @@
-#include "util/log.h"
+#include "../util/Log.h"
#include "Transform.h"
using namespace crepe;
-Transform::Transform(game_object_id_t id, const Vector2 & point,
- double rotation, double scale)
+Transform::Transform(game_object_id_t id, const Vector2 & point, double rotation, double scale)
: Component(id),
position(point),
rotation(rotation),
diff --git a/src/crepe/api/Transform.h b/src/crepe/api/Transform.h
index 756e45b..18aa293 100644
--- a/src/crepe/api/Transform.h
+++ b/src/crepe/api/Transform.h
@@ -9,33 +9,33 @@ namespace crepe {
/**
* \brief Transform component
*
- * This class represents the Transform component. It stores the position,
- * rotation and scale of a GameObject.
+ * This class represents the Transform component. It stores the position, rotation and scale of
+ * a GameObject.
*/
class Transform : public Component {
public:
+ //! Translation (shift)
+ Vector2 position = {0, 0};
+ //! Rotation, in degrees
+ double rotation = 0;
+ //! Multiplication factor
+ double scale = 0;
+
+protected:
/**
* \param id The id of the GameObject this component belongs to
* \param point The position of the GameObject
* \param rotation The rotation of the GameObject
* \param scale The scale of the GameObject
*/
- Transform(game_object_id_t id, const Vector2 & point, double rotation,
- double scale);
+ Transform(game_object_id_t id, const Vector2 & point, double rotation, double scale);
/**
- * \brief Get the maximum number of instances for this component
- *
- * \return The maximum number of instances for this component
+ * There is always exactly one transform component per entity
+ * \return 1
*/
virtual int get_instances_max() const { return 1; }
-
-public:
- //! Translation (shift)
- Vector2 position;
- //! Rotation, in degrees
- double rotation;
- //! Multiplication factor
- double scale;
+ //! ComponentManager instantiates all components
+ friend class ComponentManager;
};
} // namespace crepe
diff --git a/src/crepe/api/Vector2.cpp b/src/crepe/api/Vector2.cpp
index 09b3fa3..30b968e 100644
--- a/src/crepe/api/Vector2.cpp
+++ b/src/crepe/api/Vector2.cpp
@@ -1,57 +1,33 @@
#include "Vector2.h"
-namespace crepe {
+using namespace crepe;
-// Constructor with initial values
-Vector2::Vector2(double x, double y) : x(x), y(y) {}
+Vector2 Vector2::operator-(const Vector2 & other) const { return {x - other.x, y - other.y}; }
-// Subtracts another vector from this vector and returns the result.
-Vector2 Vector2::operator-(const Vector2 & other) const {
- return {x - other.x, y - other.y};
-}
-
-// Adds another vector to this vector and returns the result.
-Vector2 Vector2::operator+(const Vector2 & other) const {
- return {x + other.x, y + other.y};
-}
+Vector2 Vector2::operator+(const Vector2 & other) const { return {x + other.x, y + other.y}; }
-// Multiplies this vector by a scalar and returns the result.
-Vector2 Vector2::operator*(double scalar) const {
- return {x * scalar, y * scalar};
-}
+Vector2 Vector2::operator*(double scalar) const { return {x * scalar, y * scalar}; }
-// Multiplies this vector by another vector element-wise and updates this vector.
Vector2 & Vector2::operator*=(const Vector2 & other) {
x *= other.x;
y *= other.y;
return *this;
}
-// Adds another vector to this vector and updates this vector.
Vector2 & Vector2::operator+=(const Vector2 & other) {
x += other.x;
y += other.y;
return *this;
}
-// Adds a scalar value to both components of this vector and updates this vector.
Vector2 & Vector2::operator+=(double other) {
x += other;
y += other;
return *this;
}
-// Returns the negation of this vector.
Vector2 Vector2::operator-() const { return {-x, -y}; }
-// Checks if this vector is equal to another vector.
-bool Vector2::operator==(const Vector2 & other) const {
- return x == other.x && y == other.y;
-}
-
-// Checks if this vector is not equal to another vector.
-bool Vector2::operator!=(const Vector2 & other) const {
- return !(*this == other);
-}
+bool Vector2::operator==(const Vector2 & other) const { return x == other.x && y == other.y; }
-} // namespace crepe
+bool Vector2::operator!=(const Vector2 & other) const { return !(*this == other); }
diff --git a/src/crepe/api/Vector2.h b/src/crepe/api/Vector2.h
index 5a57484..2fb6136 100644
--- a/src/crepe/api/Vector2.h
+++ b/src/crepe/api/Vector2.h
@@ -2,19 +2,12 @@
namespace crepe {
-//! Vector2 class
-class Vector2 {
-public:
+//! 2D vector
+struct Vector2 {
//! X component of the vector
- double x;
+ double x = 0;
//! Y component of the vector
- double y;
-
- //! Default constructor
- Vector2() = default;
-
- //! Constructor with initial values
- Vector2(double x, double y);
+ double y = 0;
//! Subtracts another vector from this vector and returns the result.
Vector2 operator-(const Vector2 & other) const;