aboutsummaryrefslogtreecommitdiff
path: root/src/crepe/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/crepe/api')
-rw-r--r--src/crepe/api/Animator.cpp3
-rw-r--r--src/crepe/api/Animator.h3
-rw-r--r--src/crepe/api/AssetManager.h3
-rw-r--r--src/crepe/api/BehaviorScript.cpp15
-rw-r--r--src/crepe/api/BehaviorScript.h37
-rw-r--r--src/crepe/api/BehaviorScript.hpp5
-rw-r--r--src/crepe/api/Camera.cpp5
-rw-r--r--src/crepe/api/Camera.h2
-rw-r--r--src/crepe/api/GameObject.cpp12
-rw-r--r--src/crepe/api/GameObject.h19
-rw-r--r--src/crepe/api/GameObject.hpp2
-rw-r--r--src/crepe/api/LoopManager.cpp24
-rw-r--r--src/crepe/api/LoopManager.h28
-rw-r--r--src/crepe/api/LoopManager.hpp40
-rw-r--r--src/crepe/api/Rigidbody.cpp4
-rw-r--r--src/crepe/api/Rigidbody.h2
-rw-r--r--src/crepe/api/SceneManager.cpp7
-rw-r--r--src/crepe/api/SceneManager.h16
-rw-r--r--src/crepe/api/Script.h16
-rw-r--r--src/crepe/api/Script.hpp6
-rw-r--r--src/crepe/api/Transform.h28
-rw-r--r--src/crepe/api/Vector2.cpp16
-rw-r--r--src/crepe/api/Vector2.h15
23 files changed, 210 insertions, 98 deletions
diff --git a/src/crepe/api/Animator.cpp b/src/crepe/api/Animator.cpp
index 863dce6..54b2ec3 100644
--- a/src/crepe/api/Animator.cpp
+++ b/src/crepe/api/Animator.cpp
@@ -9,7 +9,8 @@
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..75b8139 100644
--- a/src/crepe/api/Animator.h
+++ b/src/crepe/api/Animator.h
@@ -6,6 +6,7 @@
#include "Sprite.h"
namespace crepe {
+
class AnimatorSystem;
class SDLContext;
@@ -35,7 +36,7 @@ public:
*
* 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,
+ Animator(game_object_id_t id, Sprite & spritesheet, int row, int col,
int col_animate);
~Animator(); // dbg_trace
diff --git a/src/crepe/api/AssetManager.h b/src/crepe/api/AssetManager.h
index dbfaef3..86a9902 100644
--- a/src/crepe/api/AssetManager.h
+++ b/src/crepe/api/AssetManager.h
@@ -56,7 +56,8 @@ public:
* 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/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 4160a72..2982358 100644
--- a/src/crepe/api/BehaviorScript.h
+++ b/src/crepe/api/BehaviorScript.h
@@ -3,6 +3,7 @@
#include <memory>
#include "../Component.h"
+#include "GameObject.h"
namespace crepe {
@@ -19,22 +20,52 @@ class Script;
*/
class BehaviorScript : public Component {
protected:
- friend class crepe::ComponentManager;
- using Component::Component;
+ BehaviorScript(game_object_id_t id, ComponentManager & component_manager);
+ //! Only ComponentManager is allowed to instantiate BehaviorScript
+ friend class ComponentManager;
public:
~BehaviorScript() = default;
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;
+ //! ScriptSystem needs direct access to the script instance
+ friend class ScriptSystem;
+ //! Flag to indicate if script->init() has been called already
+ bool initialized = false;
//! Script instance
std::unique_ptr<Script> script = nullptr;
+ //! Reference to component manager
+ ComponentManager & component_manager;
+
+private:
+ //! Script accesses the component manager directly via its parent
+ // (BehaviorScript) reference
+ friend class Script;
};
+/**
+ * \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 bc157fd..eec26da 100644
--- a/src/crepe/api/BehaviorScript.hpp
+++ b/src/crepe/api/BehaviorScript.hpp
@@ -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->parent_ref = this;
+ s->component_manager_ref = &this->component_manager;
this->script = std::unique_ptr<Script>(s);
return *this;
}
diff --git a/src/crepe/api/Camera.cpp b/src/crepe/api/Camera.cpp
index 6f0deb1..5835bdd 100644
--- a/src/crepe/api/Camera.cpp
+++ b/src/crepe/api/Camera.cpp
@@ -1,6 +1,3 @@
-
-#include <cstdint>
-
#include "util/Log.h"
#include "Camera.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..d8c08a6 100644
--- a/src/crepe/api/Camera.h
+++ b/src/crepe/api/Camera.h
@@ -23,7 +23,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/GameObject.cpp b/src/crepe/api/GameObject.cpp
index d252e77..4f3c639 100644
--- a/src/crepe/api/GameObject.cpp
+++ b/src/crepe/api/GameObject.cpp
@@ -1,23 +1,27 @@
#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,
+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) {
+ : 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..73ff0b8 100644
--- a/src/crepe/api/GameObject.h
+++ b/src/crepe/api/GameObject.h
@@ -2,11 +2,12 @@
#include <string>
+#include "Vector2.h"
#include "types.h"
namespace crepe {
-class Vector2;
+class ComponentManager;
/**
* \brief Represents a GameObject
@@ -16,11 +17,12 @@ class Vector2;
* 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.
*
+ * \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,9 +30,13 @@ 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,
- double rotation, double scale);
+ 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
*
@@ -58,6 +64,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..f0788ab 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,25 @@
#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>();
+}
+
+ComponentManager & LoopManager::get_component_manager() {
+ return this->component_manager;
+}
-LoopManager::LoopManager() {}
void LoopManager::process_input() {
SDLContext::get_instance().handle_events(this->game_running);
}
+
void LoopManager::start() {
this->setup();
this->loop();
@@ -48,7 +66,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..288dca2 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,21 @@ private:
void render();
bool game_running = false;
- //#TODO add system instances
+
+protected:
+ ComponentManager & get_component_manager();
+ template <class T>
+ T & get_system();
+
+private:
+ ComponentManager component_manager{};
+ std::unordered_map<std::type_index, std::unique_ptr<System>> systems;
+
+private:
+ template <class T>
+ void load_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..8fb9aa3
--- /dev/null
+++ b/src/crepe/api/LoopManager.hpp
@@ -0,0 +1,40 @@
+#pragma once
+
+#include <cassert>
+#include <memory>
+
+#include "../Exception.h"
+#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 Exception("LoopManager: %s 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/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..2e20288 100644
--- a/src/crepe/api/Rigidbody.h
+++ b/src/crepe/api/Rigidbody.h
@@ -82,7 +82,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/SceneManager.cpp b/src/crepe/api/SceneManager.cpp
index dfed6ee..4a38787 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; }
@@ -30,7 +27,7 @@ void SceneManager::load_next_scene() {
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..553194f 100644
--- a/src/crepe/api/SceneManager.h
+++ b/src/crepe/api/SceneManager.h
@@ -8,14 +8,12 @@
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);
+ virtual ~SceneManager() = default;
public:
/**
@@ -38,11 +36,11 @@ public:
void load_next_scene();
private:
- SceneManager() = default;
-
-private:
std::vector<std::unique_ptr<Scene>> scenes;
std::string next_scene;
+
+protected:
+ ComponentManager & component_manager;
};
} // namespace crepe
diff --git a/src/crepe/api/Script.h b/src/crepe/api/Script.h
index e6fbb5c..68a46d7 100644
--- a/src/crepe/api/Script.h
+++ b/src/crepe/api/Script.h
@@ -6,6 +6,7 @@ namespace crepe {
class ScriptSystem;
class BehaviorScript;
+class ComponentManager;
/**
* \brief Script interface
@@ -14,6 +15,7 @@ class BehaviorScript;
* added to game objects using the \c BehaviorScript component.
*/
class Script {
+ //! ScriptSystem calls \c update()
friend class crepe::ScriptSystem;
protected:
@@ -61,9 +63,19 @@ protected:
template <typename T>
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:
- friend class crepe::BehaviorScript;
- BehaviorScript * parent = nullptr;
+ // These references are set by BehaviorScript immediately after calling the
+ // constructor of Script.
+ BehaviorScript * parent_ref = nullptr;
+ ComponentManager * component_manager_ref = nullptr;
};
} // namespace crepe
diff --git a/src/crepe/api/Script.hpp b/src/crepe/api/Script.hpp
index 7ec3ebe..aceb38b 100644
--- a/src/crepe/api/Script.hpp
+++ b/src/crepe/api/Script.hpp
@@ -21,8 +21,10 @@ T & Script::get_component() const {
template <typename T>
std::vector<std::reference_wrapper<T>> Script::get_components() const {
- ComponentManager & mgr = ComponentManager::get_instance();
- return mgr.get_components_by_id<T>(this->parent->game_object_id);
+ auto & parent = *this->parent_ref;
+ auto & mgr = *this->component_manager_ref;
+
+ return mgr.get_components_by_id<T>(parent.game_object_id);
}
} // namespace crepe
diff --git a/src/crepe/api/Transform.h b/src/crepe/api/Transform.h
index 756e45b..902dafa 100644
--- a/src/crepe/api/Transform.h
+++ b/src/crepe/api/Transform.h
@@ -14,28 +14,26 @@ namespace crepe {
*/
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);
- /**
- * \brief Get the maximum number of instances for this component
- *
- * \return The maximum number of instances for this component
- */
+ Transform(game_object_id_t id, const Vector2 & point, double rotation = 0,
+ double scale = 0);
+ //! There is always exactly one transform component per entity
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 09bb59b..7da202a 100644
--- a/src/crepe/api/Vector2.cpp
+++ b/src/crepe/api/Vector2.cpp
@@ -1,57 +1,43 @@
#include "Vector2.h"
-namespace crepe {
+using namespace crepe;
-// Constructor with initial values
-Vector2::Vector2(float x, float y) : x(x), y(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};
}
-// Multiplies this vector by a scalar and returns the result.
Vector2 Vector2::operator*(float 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+=(float 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);
}
-
-} // namespace crepe
diff --git a/src/crepe/api/Vector2.h b/src/crepe/api/Vector2.h
index 741951b..a069a57 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
- float x;
+ float x = 0;
//! Y component of the vector
- float y;
-
- //! Default constructor
- Vector2() = default;
-
- //! Constructor with initial values
- Vector2(float x, float y);
+ float y = 0;
//! Subtracts another vector from this vector and returns the result.
Vector2 operator-(const Vector2 & other) const;