From 3e94ecb3dac5003a3d58210ed1a4d1f1cb2083d1 Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Tue, 12 Nov 2024 22:43:32 +0100
Subject: add script unit tests + major refactoring

---
 src/test/CMakeLists.txt  |  6 ++--
 src/test/PhysicsTest.cpp |  4 ++-
 src/test/ScriptTest.cpp  | 73 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/test/audio.cpp       | 10 -------
 src/test/dummy.cpp       |  3 --
 src/test/main.cpp        | 15 ++++++++++
 6 files changed, 94 insertions(+), 17 deletions(-)
 create mode 100644 src/test/ScriptTest.cpp
 delete mode 100644 src/test/audio.cpp
 delete mode 100644 src/test/dummy.cpp
 create mode 100644 src/test/main.cpp

(limited to 'src/test')

diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt
index 0e4eaed..9d303bc 100644
--- a/src/test/CMakeLists.txt
+++ b/src/test/CMakeLists.txt
@@ -1,6 +1,6 @@
 target_sources(test_main PUBLIC
-	dummy.cpp
-	# audio.cpp
-	PhysicsTest.cpp
+	main.cpp
+	# PhysicsTest.cpp
+	ScriptTest.cpp
 )
 
diff --git a/src/test/PhysicsTest.cpp b/src/test/PhysicsTest.cpp
index 5385962..538d244 100644
--- a/src/test/PhysicsTest.cpp
+++ b/src/test/PhysicsTest.cpp
@@ -11,9 +11,11 @@ using namespace std::chrono_literals;
 using namespace crepe;
 
 class PhysicsTest : public ::testing::Test {
-protected:
+public:
 	GameObject * game_object;
+	ComponentManager component_manager;
 	PhysicsSystem physics_system;
+
 	void SetUp() override {
 		ComponentManager & mgr = ComponentManager::get_instance();
 		std::vector<std::reference_wrapper<Transform>> transforms
diff --git a/src/test/ScriptTest.cpp b/src/test/ScriptTest.cpp
new file mode 100644
index 0000000..ea49a35
--- /dev/null
+++ b/src/test/ScriptTest.cpp
@@ -0,0 +1,73 @@
+#include <gtest/gtest.h>
+
+// stupid hack to allow access to private/protected members under test
+#define private public
+#define protected public
+
+#include <crepe/ComponentManager.h>
+#include <crepe/system/ScriptSystem.h>
+#include <crepe/api/BehaviorScript.h>
+#include <crepe/api/Script.h>
+#include <crepe/api/GameObject.h>
+#include <crepe/api/Vector2.h>
+
+using namespace std;
+using namespace crepe;
+using namespace testing;
+
+class ScriptTest : public Test {
+public:
+	ComponentManager component_manager {};
+	ScriptSystem system { component_manager };
+
+	class MyScript : public Script {
+		// NOTE: default (private) visibility of init and update shouldn't cause
+		// issues!
+		void init() { this->init_count++; }
+		void update() { this->update_count++; }
+
+	public:
+		unsigned init_count = 0;
+		unsigned update_count = 0;
+	};
+
+	BehaviorScript * behaviorscript_ref = nullptr;
+	MyScript * script_ref = nullptr;
+
+	void SetUp() override {
+		auto & mgr = this->component_manager;
+		GameObject & entity = mgr.new_object("name");
+		BehaviorScript & component = entity.add_component<BehaviorScript>();
+
+		this->behaviorscript_ref = &component;
+		EXPECT_EQ(this->behaviorscript_ref->script.get(), nullptr);
+		component.set_script<MyScript>();
+		ASSERT_NE(this->behaviorscript_ref->script.get(), nullptr);
+
+		this->script_ref = (MyScript *) this->behaviorscript_ref->script.get();
+		ASSERT_NE(this->script_ref, nullptr);
+	}
+};
+
+TEST_F(ScriptTest, Default) {
+	EXPECT_EQ(0, this->script_ref->init_count);
+	EXPECT_EQ(0, this->script_ref->update_count);
+}
+
+TEST_F(ScriptTest, UpdateOnce) {
+	EXPECT_EQ(0, this->script_ref->init_count);
+	EXPECT_EQ(0, this->script_ref->update_count);
+
+	this->system.update();
+	EXPECT_EQ(1, this->script_ref->init_count);
+	EXPECT_EQ(1, this->script_ref->update_count);
+}
+
+TEST_F(ScriptTest, ListScripts) {
+	size_t script_count = 0;
+	for (auto & _ : this->system.get_scripts()) {
+		script_count++;
+	}
+	ASSERT_EQ(1, script_count);
+}
+
diff --git a/src/test/audio.cpp b/src/test/audio.cpp
deleted file mode 100644
index d6ff689..0000000
--- a/src/test/audio.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-#include <gtest/gtest.h>
-
-using namespace std;
-using namespace std::chrono_literals;
-
-// using namespace crepe;
-
-// TODO: mock internal audio class
-
-TEST(audio, play) { ASSERT_TRUE(true); }
diff --git a/src/test/dummy.cpp b/src/test/dummy.cpp
deleted file mode 100644
index a00a9c6..0000000
--- a/src/test/dummy.cpp
+++ /dev/null
@@ -1,3 +0,0 @@
-#include <gtest/gtest.h>
-
-TEST(dummy, foo) { ASSERT_TRUE(1); }
diff --git a/src/test/main.cpp b/src/test/main.cpp
new file mode 100644
index 0000000..6830a01
--- /dev/null
+++ b/src/test/main.cpp
@@ -0,0 +1,15 @@
+#include <crepe/api/Config.h>
+
+#include <gtest/gtest.h>
+
+using namespace crepe;
+using namespace testing;
+
+int main(int argc, char **argv) {
+  InitGoogleTest(&argc, argv);
+
+	auto & cfg = Config::get_instance();
+	cfg.log.level = LogLevel::ERROR;
+
+  return RUN_ALL_TESTS();
+}
-- 
cgit v1.2.3


From 455bb50a5007daf46b8719fff2a6292da6a294bf Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Wed, 13 Nov 2024 11:39:45 +0100
Subject: fix physics test

---
 src/crepe/Component.cpp             |  2 +-
 src/crepe/Component.h               | 22 +++++----------
 src/crepe/ComponentManager.h        |  7 ++++-
 src/crepe/ComponentManager.hpp      |  5 +---
 src/crepe/api/Animator.cpp          |  4 +--
 src/crepe/api/Animator.h            |  2 +-
 src/crepe/api/BehaviorScript.cpp    |  3 ++
 src/crepe/api/BehaviorScript.h      |  3 +-
 src/crepe/api/BehaviorScript.hpp    |  1 +
 src/crepe/api/CMakeLists.txt        |  6 ++--
 src/crepe/api/Camera.cpp            |  4 +--
 src/crepe/api/Camera.h              |  2 +-
 src/crepe/api/GameObject.cpp        |  8 ++++++
 src/crepe/api/GameObject.h          | 13 +++++++++
 src/crepe/api/Metadata.cpp          |  4 +--
 src/crepe/api/Metadata.h            |  2 +-
 src/crepe/api/ParticleEmitter.cpp   |  4 +--
 src/crepe/api/ParticleEmitter.h     |  2 +-
 src/crepe/api/Rigidbody.cpp         |  4 +--
 src/crepe/api/Rigidbody.h           |  2 +-
 src/crepe/api/SceneManager.cpp      | 17 +++++-------
 src/crepe/api/SceneManager.h        | 16 +++++------
 src/crepe/api/Script.h              |  7 ++++-
 src/crepe/api/Script.hpp            |  4 +--
 src/crepe/api/Sprite.cpp            |  4 +--
 src/crepe/api/Sprite.h              |  2 +-
 src/crepe/api/Transform.cpp         |  4 +--
 src/crepe/api/Transform.h           | 28 +++++++++----------
 src/crepe/api/Vector2.cpp           | 15 +---------
 src/crepe/api/Vector2.h             | 15 +++-------
 src/crepe/system/CMakeLists.txt     |  6 ++--
 src/crepe/system/ParticleSystem.cpp |  5 ++--
 src/crepe/system/ParticleSystem.h   | 15 ++++++----
 src/crepe/system/PhysicsSystem.cpp  |  2 +-
 src/crepe/system/PhysicsSystem.h    | 12 ++++----
 src/crepe/system/ScriptSystem.h     |  3 +-
 src/example/script.cpp              | 10 +++----
 src/test/CMakeLists.txt             |  2 +-
 src/test/PhysicsTest.cpp            | 55 ++++++++++++++++++++-----------------
 39 files changed, 164 insertions(+), 158 deletions(-)

(limited to 'src/test')

diff --git a/src/crepe/Component.cpp b/src/crepe/Component.cpp
index c133739..d11a37e 100644
--- a/src/crepe/Component.cpp
+++ b/src/crepe/Component.cpp
@@ -2,5 +2,5 @@
 
 using namespace crepe;
 
-Component::Component(const Data & data) : data(data) {}
+Component::Component(game_object_id_t id) : game_object_id(id) {}
 
diff --git a/src/crepe/Component.h b/src/crepe/Component.h
index c6d72df..12c10cb 100644
--- a/src/crepe/Component.h
+++ b/src/crepe/Component.h
@@ -14,23 +14,20 @@ class ComponentManager;
  */
 class Component {
 public:
-	struct Data {
-		//! The ID of the GameObject this component belongs to
-		const game_object_id_t id;
-		//! The manager of this component
-		ComponentManager & component_manager;
-	};
+	//! Whether the component is active
+	bool active = true;
+	//! The id of the GameObject this component belongs to
+	const game_object_id_t game_object_id;
 
 protected:
 	/**
-	 * \param base Data
+	 * \param id The id of the GameObject this component belongs to
 	 */
-	Component(const Data & base);
+	Component(game_object_id_t id);
 	//! Only the ComponentManager can create components
-	friend class crepe::ComponentManager;
+	friend class ComponentManager;
 
 public:
-	virtual ~Component() = default;
 	/**
 	 * \brief Get the maximum number of instances for this component
 	 *
@@ -41,11 +38,6 @@ public:
 	 * \return The maximum number of instances for this component
 	 */
 	virtual int get_instances_max() const { return -1; }
-
-public:
-	Data data;
-	//! Whether the component is active
-	bool active = true;
 };
 
 } // namespace crepe
diff --git a/src/crepe/ComponentManager.h b/src/crepe/ComponentManager.h
index e37bc4a..1d67e69 100644
--- a/src/crepe/ComponentManager.h
+++ b/src/crepe/ComponentManager.h
@@ -24,7 +24,7 @@ public:
 	ComponentManager(); // dbg_trace
 	~ComponentManager(); // dbg_trace
 
-public:
+protected:
 	/**
 	 * \brief Add a component to the ComponentManager
 	 * 
@@ -39,6 +39,11 @@ public:
 	 */
 	template <typename T, typename... Args>
 	T & add_component(game_object_id_t id, Args &&... args);
+	//! GameObject is used as an interface to add components instead of the
+	// component manager directly
+	friend class GameObject;
+
+public:
 	/**
 	 * \brief Delete all components of a specific type and id
 	 * 
diff --git a/src/crepe/ComponentManager.hpp b/src/crepe/ComponentManager.hpp
index 89a8536..98efb49 100644
--- a/src/crepe/ComponentManager.hpp
+++ b/src/crepe/ComponentManager.hpp
@@ -31,10 +31,7 @@ T & ComponentManager::add_component(game_object_id_t id, Args &&... args) {
 
 	// Create a new component of type T (arguments directly forwarded). The
 	// constructor must be called by ComponentManager.
-	T * instance_ptr = new T(Component::Data {
-		.id = id,
-		.component_manager = *this,
-	}, forward<Args>(args)...);
+	T * instance_ptr = new T(id, forward<Args>(args)...);
 	if (instance_ptr == nullptr) throw std::bad_alloc();
 
 	T & instance_ref = *instance_ptr;
diff --git a/src/crepe/api/Animator.cpp b/src/crepe/api/Animator.cpp
index ad60981..cbf415d 100644
--- a/src/crepe/api/Animator.cpp
+++ b/src/crepe/api/Animator.cpp
@@ -9,8 +9,8 @@
 
 using namespace crepe;
 
-Animator::Animator(const Component::Data & data, Sprite & ss, int row, int col, int col_animator)
-	: Component(data),
+Animator::Animator(game_object_id_t id, Sprite & ss, int row, int col, int col_animator)
+	: Component(id),
 	  spritesheet(ss),
 	  row(row),
 	  col(col) {
diff --git a/src/crepe/api/Animator.h b/src/crepe/api/Animator.h
index f66dc1a..75b8139 100644
--- a/src/crepe/api/Animator.h
+++ b/src/crepe/api/Animator.h
@@ -36,7 +36,7 @@ public:
 	 *
 	 * This constructor sets up the Animator with the given parameters, and initializes the animation system.
 	 */
-	Animator(const Component::Data & data, 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/BehaviorScript.cpp b/src/crepe/api/BehaviorScript.cpp
index ce1cfde..41c144c 100644
--- a/src/crepe/api/BehaviorScript.cpp
+++ b/src/crepe/api/BehaviorScript.cpp
@@ -1,4 +1,7 @@
 #include "BehaviorScript.h"
+#include "Component.h"
 
 using namespace crepe;
 
+BehaviorScript::BehaviorScript(game_object_id_t id, ComponentManager & mgr) : Component(id), component_manager(mgr) {}
+
diff --git a/src/crepe/api/BehaviorScript.h b/src/crepe/api/BehaviorScript.h
index 8d21a72..f156081 100644
--- a/src/crepe/api/BehaviorScript.h
+++ b/src/crepe/api/BehaviorScript.h
@@ -12,7 +12,7 @@ class Script;
 
 class BehaviorScript : public Component {
 protected:
-	using Component::Component;
+	BehaviorScript(game_object_id_t id, ComponentManager & component_manager);
 	//! Only ComponentManager is allowed to instantiate BehaviorScript
 	friend class ComponentManager;
 
@@ -36,6 +36,7 @@ protected:
 	//! Flag to indicate if script->init() has been called already
 	bool initialized = false;
 	std::unique_ptr<Script> script = nullptr;
+	ComponentManager & component_manager;
 
 private:
 	//! Script accesses the component manager directly via its parent
diff --git a/src/crepe/api/BehaviorScript.hpp b/src/crepe/api/BehaviorScript.hpp
index bb5d829..2bed1b7 100644
--- a/src/crepe/api/BehaviorScript.hpp
+++ b/src/crepe/api/BehaviorScript.hpp
@@ -15,6 +15,7 @@ BehaviorScript & BehaviorScript::set_script() {
 	static_assert(std::is_base_of<Script, T>::value);
 	Script * s = new T();
 	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/CMakeLists.txt b/src/crepe/api/CMakeLists.txt
index d9cda57..ee77947 100644
--- a/src/crepe/api/CMakeLists.txt
+++ b/src/crepe/api/CMakeLists.txt
@@ -14,7 +14,7 @@ target_sources(crepe PUBLIC
 	Config.cpp
 	Metadata.cpp
 	Scene.cpp
-	# SceneManager.cpp
+	SceneManager.cpp
 	Vector2.cpp
 	Camera.cpp
 	Animator.cpp
@@ -40,8 +40,8 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES
 	SaveManager.h
 	Scene.h
 	Metadata.h
-	# SceneManager.h
-	# SceneManager.hpp
+	SceneManager.h
+	SceneManager.hpp
 	Camera.h
 	Animator.h
 	# LoopManager.h
diff --git a/src/crepe/api/Camera.cpp b/src/crepe/api/Camera.cpp
index fece199..232c922 100644
--- a/src/crepe/api/Camera.cpp
+++ b/src/crepe/api/Camera.cpp
@@ -6,8 +6,8 @@
 
 using namespace crepe;
 
-Camera::Camera(const Component::Data & data, const Color & bg_color)
-	: Component(data),
+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 a52f2f7..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(const Component::Data & data, 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 bba1f26..dd20b7f 100644
--- a/src/crepe/api/GameObject.cpp
+++ b/src/crepe/api/GameObject.cpp
@@ -2,6 +2,7 @@
 
 #include "GameObject.h"
 #include "Metadata.h"
+#include "BehaviorScript.h"
 
 using namespace crepe;
 using namespace std;
@@ -30,3 +31,10 @@ void GameObject::set_parent(const GameObject & parent) {
 		= mgr.get_components_by_id<Metadata>(parent.id);
 	parent_metadata.at(0).get().children.push_back(this->id);
 }
+
+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/GameObject.h b/src/crepe/api/GameObject.h
index d09938a..7751fd0 100644
--- a/src/crepe/api/GameObject.h
+++ b/src/crepe/api/GameObject.h
@@ -8,6 +8,7 @@
 namespace crepe {
 
 class ComponentManager;
+class BehaviorScript;
 
 /**
  * \brief Represents a GameObject
@@ -67,6 +68,18 @@ protected:
 	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 "GameObject.hpp"
diff --git a/src/crepe/api/Metadata.cpp b/src/crepe/api/Metadata.cpp
index 6f0a280..d421de5 100644
--- a/src/crepe/api/Metadata.cpp
+++ b/src/crepe/api/Metadata.cpp
@@ -3,7 +3,7 @@
 using namespace crepe;
 using namespace std;
 
-Metadata::Metadata(const Component::Data & data, const string & name, const string & tag)
-	: Component(data),
+Metadata::Metadata(game_object_id_t id, const string & name, const string & tag)
+	: Component(id),
 	  name(name),
 	  tag(tag) {}
diff --git a/src/crepe/api/Metadata.h b/src/crepe/api/Metadata.h
index 8c91797..c61e006 100644
--- a/src/crepe/api/Metadata.h
+++ b/src/crepe/api/Metadata.h
@@ -20,7 +20,7 @@ public:
 	 * \param name The name of the GameObject
 	 * \param tag The tag of the GameObject
 	 */
-	Metadata(const Component::Data & data, const std::string & name,
+	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 ed4fec8..0bc2197 100644
--- a/src/crepe/api/ParticleEmitter.cpp
+++ b/src/crepe/api/ParticleEmitter.cpp
@@ -6,12 +6,12 @@
 
 using namespace crepe;
 
-ParticleEmitter::ParticleEmitter(const Component::Data & data, uint32_t max_particles,
+ParticleEmitter::ParticleEmitter(game_object_id_t id, uint32_t max_particles,
 								 uint32_t emission_rate, uint32_t speed,
 								 uint32_t speed_offset, uint32_t angle,
 								 uint32_t angleOffset, float begin_lifespan,
 								 float end_lifespan)
-	: Component(data),
+	: Component(id),
 	  max_particles(max_particles),
 	  emission_rate(emission_rate),
 	  speed(speed),
diff --git a/src/crepe/api/ParticleEmitter.h b/src/crepe/api/ParticleEmitter.h
index ba89538..5939723 100644
--- a/src/crepe/api/ParticleEmitter.h
+++ b/src/crepe/api/ParticleEmitter.h
@@ -10,7 +10,7 @@ namespace crepe {
 
 class ParticleEmitter : public Component {
 public:
-	ParticleEmitter(const Component::Data & data, uint32_t max_particles,
+	ParticleEmitter(game_object_id_t id, uint32_t max_particles,
 					uint32_t emission_rate, uint32_t speed,
 					uint32_t speed_offset, uint32_t angle, uint32_t angleOffset,
 					float begin_lifespan, float end_lifespan);
diff --git a/src/crepe/api/Rigidbody.cpp b/src/crepe/api/Rigidbody.cpp
index be6bb93..6b87695 100644
--- a/src/crepe/api/Rigidbody.cpp
+++ b/src/crepe/api/Rigidbody.cpp
@@ -2,8 +2,8 @@
 
 using namespace crepe;
 
-crepe::Rigidbody::Rigidbody(const Component::Data & component_data, const Data & data)
-	: Component(component_data),
+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 99837a6..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(const Component::Data & component_data, 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..814b7d7 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,18 @@ 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..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:
 	/**
@@ -37,12 +35,12 @@ public:
 	//! Load a new scene (if there is one)
 	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 d543df8..c5e3cc4 100644
--- a/src/crepe/api/Script.h
+++ b/src/crepe/api/Script.h
@@ -9,6 +9,7 @@ class ScriptSystem;
 namespace crepe {
 
 class BehaviorScript;
+class ComponentManager;
 
 class Script {
 	//! ScriptSystem calls \c update()
@@ -31,14 +32,18 @@ protected:
 	template <typename T>
 	std::vector<std::reference_wrapper<T>> get_components();
 
-protected:
+private:
 	// 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;
+
+	// 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 68bcc29..ee8c380 100644
--- a/src/crepe/api/Script.hpp
+++ b/src/crepe/api/Script.hpp
@@ -19,9 +19,9 @@ T & Script::get_component() {
 template <typename T>
 std::vector<std::reference_wrapper<T>> Script::get_components() {
 	auto & parent = *this->parent_ref;
-	auto & mgr = parent.data.component_manager;
+	auto & mgr = *this->component_manager_ref;
 
-	return mgr.get_components_by_id<T>(parent.data.id);
+	return mgr.get_components_by_id<T>(parent.game_object_id);
 }
 
 } // namespace crepe
diff --git a/src/crepe/api/Sprite.cpp b/src/crepe/api/Sprite.cpp
index 716609f..6f0433f 100644
--- a/src/crepe/api/Sprite.cpp
+++ b/src/crepe/api/Sprite.cpp
@@ -10,9 +10,9 @@
 using namespace std;
 using namespace crepe;
 
-Sprite::Sprite(const Component::Data & data, const shared_ptr<Texture> image,
+Sprite::Sprite(game_object_id_t id, const shared_ptr<Texture> image,
 			   const Color & color, const FlipSettings & flip)
-	: Component(data),
+	: Component(id),
 	  color(color),
 	  flip(flip),
 	  sprite_image(image) {
diff --git a/src/crepe/api/Sprite.h b/src/crepe/api/Sprite.h
index 171dfeb..deb3f93 100644
--- a/src/crepe/api/Sprite.h
+++ b/src/crepe/api/Sprite.h
@@ -43,7 +43,7 @@ public:
 	 * \param color Color tint applied to the sprite.
 	 * \param flip Flip settings for horizontal and vertical orientation.
 	 */
-	Sprite(const Component::Data & data, const std::shared_ptr<Texture> image,
+	Sprite(game_object_id_t id, const std::shared_ptr<Texture> image,
 		   const Color & color, const FlipSettings & flip);
 
 	/**
diff --git a/src/crepe/api/Transform.cpp b/src/crepe/api/Transform.cpp
index 9645d03..e401120 100644
--- a/src/crepe/api/Transform.cpp
+++ b/src/crepe/api/Transform.cpp
@@ -4,9 +4,9 @@
 
 using namespace crepe;
 
-Transform::Transform(const Component::Data & data, const Vector2 & point,
+Transform::Transform(game_object_id_t id, const Vector2 & point,
 					 double rotation, double scale)
-	: Component(data),
+	: Component(id),
 	  position(point),
 	  rotation(rotation),
 	  scale(scale) {
diff --git a/src/crepe/api/Transform.h b/src/crepe/api/Transform.h
index a7bcd89..a1ef406 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(const Component::Data & data, 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..aa391fa 100644
--- a/src/crepe/api/Vector2.cpp
+++ b/src/crepe/api/Vector2.cpp
@@ -1,57 +1,44 @@
 #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;
diff --git a/src/crepe/system/CMakeLists.txt b/src/crepe/system/CMakeLists.txt
index 9ee12f6..2fb58dc 100644
--- a/src/crepe/system/CMakeLists.txt
+++ b/src/crepe/system/CMakeLists.txt
@@ -1,8 +1,8 @@
 target_sources(crepe PUBLIC
 	System.cpp
-	# ParticleSystem.cpp
+	ParticleSystem.cpp
 	ScriptSystem.cpp
-	# PhysicsSystem.cpp
+	PhysicsSystem.cpp
 	# CollisionSystem.cpp
 	# RenderSystem.cpp
 	# AnimatorSystem.cpp
@@ -11,7 +11,7 @@ target_sources(crepe PUBLIC
 target_sources(crepe PUBLIC FILE_SET HEADERS FILES
 	System.h
 	ScriptSystem.h
-	# PhysicsSystem.h
+	PhysicsSystem.h
 	# CollisionSystem.h
 	# RenderSystem.h
 	# AnimatorSystem.h
diff --git a/src/crepe/system/ParticleSystem.cpp b/src/crepe/system/ParticleSystem.cpp
index 397b586..64fee4e 100644
--- a/src/crepe/system/ParticleSystem.cpp
+++ b/src/crepe/system/ParticleSystem.cpp
@@ -8,10 +8,8 @@
 
 using namespace crepe;
 
-ParticleSystem::ParticleSystem() : elapsed_time(0.0f) {}
-
 void ParticleSystem::update() {
-	ComponentManager & mgr = ComponentManager::get_instance();
+	ComponentManager & mgr = this->component_manager;
 	std::vector<std::reference_wrapper<ParticleEmitter>> emitters
 		= mgr.get_components_by_type<ParticleEmitter>();
 	float delta_time = 0.10;
@@ -60,3 +58,4 @@ void ParticleSystem::emit_particle(ParticleEmitter & emitter) {
 		}
 	}
 }
+
diff --git a/src/crepe/system/ParticleSystem.h b/src/crepe/system/ParticleSystem.h
index 3ac1d3f..f171c62 100644
--- a/src/crepe/system/ParticleSystem.h
+++ b/src/crepe/system/ParticleSystem.h
@@ -2,17 +2,22 @@
 
 #include "../api/ParticleEmitter.h"
 
+#include "System.h"
+
 namespace crepe {
 
-class ParticleSystem {
+class ParticleSystem : public System {
 public:
-	ParticleSystem();
-	void update();
+	using System::System;
+	void update() override;
 
 private:
-	void emit_particle(ParticleEmitter & emitter); //emits a new particle
+	//! Emits a new particle
+	void emit_particle(ParticleEmitter & emitter);
 
-	float elapsed_time; //elapsed time since the last emission
+	//! Elapsed time since the last emission
+	float elapsed_time = 0.0;
+	// TODO: to std::chrono::duration
 };
 
 } // namespace crepe
diff --git a/src/crepe/system/PhysicsSystem.cpp b/src/crepe/system/PhysicsSystem.cpp
index eb54ad3..da79707 100644
--- a/src/crepe/system/PhysicsSystem.cpp
+++ b/src/crepe/system/PhysicsSystem.cpp
@@ -11,7 +11,7 @@
 using namespace crepe;
 
 void PhysicsSystem::update() {
-	ComponentManager & mgr = ComponentManager::get_instance();
+	ComponentManager & mgr = this->component_manager;
 	std::vector<std::reference_wrapper<Rigidbody>> rigidbodies
 		= mgr.get_components_by_type<Rigidbody>();
 	std::vector<std::reference_wrapper<Transform>> transforms
diff --git a/src/crepe/system/PhysicsSystem.h b/src/crepe/system/PhysicsSystem.h
index cc13b70..5433a0f 100644
--- a/src/crepe/system/PhysicsSystem.h
+++ b/src/crepe/system/PhysicsSystem.h
@@ -1,24 +1,24 @@
 #pragma once
 
+#include "System.h"
+
 namespace crepe {
+
 /**
  * \brief System that controls all physics
  * 
  * This class is a physics system that uses a rigidbody and transform
  * to add physics to a game object.
  */
-class PhysicsSystem {
+class PhysicsSystem : public System {
 public:
-	/**
-	 * Constructor is default
-	 */
-	PhysicsSystem() = default;
+	using System::System;
 	/**
 	 * \brief updates the physics system.
 	 * 
 	 * It calculates new velocties and changes the postion in the transform.
 	 */
-	void update();
+	void update() override;
 };
 
 } // namespace crepe
diff --git a/src/crepe/system/ScriptSystem.h b/src/crepe/system/ScriptSystem.h
index b52e825..b0b4185 100644
--- a/src/crepe/system/ScriptSystem.h
+++ b/src/crepe/system/ScriptSystem.h
@@ -7,12 +7,11 @@
 namespace crepe {
 
 class Script;
-class BehaviorScript;
 
 class ScriptSystem : public System {
 public:
 	using System::System;
-	void update();
+	void update() override;
 
 private:
 	std::forward_list<std::reference_wrapper<Script>> get_scripts();
diff --git a/src/example/script.cpp b/src/example/script.cpp
index 9e8b147..4ba2b4b 100644
--- a/src/example/script.cpp
+++ b/src/example/script.cpp
@@ -35,15 +35,15 @@ class MyScript : public Script {
 };
 
 int main() {
+	ComponentManager component_manager {};
+	ScriptSystem system { component_manager };
+
 	// Create game object with Transform and BehaviorScript components
-	auto obj = GameObject(0, "name", "tag", Vector2{1.2, 3.4}, 0, 1);
+	auto & obj = component_manager.new_object("name");
 	obj.add_component<BehaviorScript>().set_script<MyScript>();
 
-	// Get ScriptSystem singleton instance (this would normally be done from the
-	// game loop)
-	ScriptSystem sys;
 	// Update all scripts. This should result in MyScript::update being called
-	sys.update();
+	system.update();
 
 	return EXIT_SUCCESS;
 }
diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt
index 9d303bc..4dd5010 100644
--- a/src/test/CMakeLists.txt
+++ b/src/test/CMakeLists.txt
@@ -1,6 +1,6 @@
 target_sources(test_main PUBLIC
 	main.cpp
-	# PhysicsTest.cpp
+	PhysicsTest.cpp
 	ScriptTest.cpp
 )
 
diff --git a/src/test/PhysicsTest.cpp b/src/test/PhysicsTest.cpp
index 538d244..5399d54 100644
--- a/src/test/PhysicsTest.cpp
+++ b/src/test/PhysicsTest.cpp
@@ -12,17 +12,16 @@ using namespace crepe;
 
 class PhysicsTest : public ::testing::Test {
 public:
-	GameObject * game_object;
 	ComponentManager component_manager;
-	PhysicsSystem physics_system;
+	PhysicsSystem system { component_manager };
 
 	void SetUp() override {
-		ComponentManager & mgr = ComponentManager::get_instance();
-		std::vector<std::reference_wrapper<Transform>> transforms
+		ComponentManager & mgr = this->component_manager;
+		vector<reference_wrapper<Transform>> transforms
 			= mgr.get_components_by_id<Transform>(0);
 		if (transforms.empty()) {
-			game_object = new GameObject(0, "", "", Vector2{0, 0}, 0, 0);
-			game_object->add_component<Rigidbody>(Rigidbody::Data{
+			auto & entity = mgr.new_object("", "", Vector2{0, 0}, 0, 0);
+			entity.add_component<Rigidbody>(Rigidbody::Data{
 				.mass = 1,
 				.gravity_scale = 1,
 				.body_type = Rigidbody::BodyType::DYNAMIC,
@@ -38,7 +37,7 @@ public:
 		transform.position.x = 0.0;
 		transform.position.y = 0.0;
 		transform.rotation = 0.0;
-		std::vector<std::reference_wrapper<Rigidbody>> rigidbodies
+		vector<reference_wrapper<Rigidbody>> rigidbodies
 			= mgr.get_components_by_id<Rigidbody>(0);
 		Rigidbody & rigidbody = rigidbodies.front().get();
 		rigidbody.data.angular_velocity = 0;
@@ -49,34 +48,37 @@ public:
 
 TEST_F(PhysicsTest, gravity) {
 	Config::get_instance().physics.gravity = 1;
-	ComponentManager & mgr = ComponentManager::get_instance();
-	std::vector<std::reference_wrapper<Transform>> transforms
-		= mgr.get_components_by_id<Transform>(0);
+	ComponentManager & mgr = this->component_manager;
+	vector<reference_wrapper<Transform>> transforms = mgr.get_components_by_id<Transform>(0);
 	const Transform & transform = transforms.front().get();
 	ASSERT_FALSE(transforms.empty());
 	EXPECT_EQ(transform.position.y, 0);
-	physics_system.update();
+
+	system.update();
 	EXPECT_EQ(transform.position.y, 1);
-	physics_system.update();
+
+	system.update();
 	EXPECT_EQ(transform.position.y, 3);
 }
 
 TEST_F(PhysicsTest, max_velocity) {
-	ComponentManager & mgr = ComponentManager::get_instance();
-	std::vector<std::reference_wrapper<Rigidbody>> rigidbodies
+	ComponentManager & mgr = this->component_manager;
+	vector<reference_wrapper<Rigidbody>> rigidbodies
 		= mgr.get_components_by_id<Rigidbody>(0);
 	Rigidbody & rigidbody = rigidbodies.front().get();
 	ASSERT_FALSE(rigidbodies.empty());
 	EXPECT_EQ(rigidbody.data.linear_velocity.y, 0);
+
 	rigidbody.add_force_linear({100, 100});
 	rigidbody.add_force_angular(100);
-	physics_system.update();
+	system.update();
 	EXPECT_EQ(rigidbody.data.linear_velocity.y, 10);
 	EXPECT_EQ(rigidbody.data.linear_velocity.x, 10);
 	EXPECT_EQ(rigidbody.data.angular_velocity, 10);
+
 	rigidbody.add_force_linear({-100, -100});
 	rigidbody.add_force_angular(-100);
-	physics_system.update();
+	system.update();
 	EXPECT_EQ(rigidbody.data.linear_velocity.y, -10);
 	EXPECT_EQ(rigidbody.data.linear_velocity.x, -10);
 	EXPECT_EQ(rigidbody.data.angular_velocity, -10);
@@ -84,39 +86,42 @@ TEST_F(PhysicsTest, max_velocity) {
 
 TEST_F(PhysicsTest, movement) {
 	Config::get_instance().physics.gravity = 0;
-	ComponentManager & mgr = ComponentManager::get_instance();
-	std::vector<std::reference_wrapper<Rigidbody>> rigidbodies
-		= mgr.get_components_by_id<Rigidbody>(0);
+	ComponentManager & mgr = this->component_manager;
+	vector<reference_wrapper<Rigidbody>> rigidbodies = mgr.get_components_by_id<Rigidbody>(0);
 	Rigidbody & rigidbody = rigidbodies.front().get();
-	std::vector<std::reference_wrapper<Transform>> transforms
-		= mgr.get_components_by_id<Transform>(0);
+	vector<reference_wrapper<Transform>> transforms = mgr.get_components_by_id<Transform>(0);
 	const Transform & transform = transforms.front().get();
 	ASSERT_FALSE(rigidbodies.empty());
 	ASSERT_FALSE(transforms.empty());
+
 	rigidbody.add_force_linear({1, 1});
 	rigidbody.add_force_angular(1);
-	physics_system.update();
+	system.update();
 	EXPECT_EQ(transform.position.x, 1);
 	EXPECT_EQ(transform.position.y, 1);
 	EXPECT_EQ(transform.rotation, 1);
+
 	rigidbody.data.constraints = {1, 1, 1};
 	EXPECT_EQ(transform.position.x, 1);
 	EXPECT_EQ(transform.position.y, 1);
 	EXPECT_EQ(transform.rotation, 1);
+
 	rigidbody.data.linear_damping.x = 0.5;
 	rigidbody.data.linear_damping.y = 0.5;
 	rigidbody.data.angular_damping = 0.5;
-	physics_system.update();
+	system.update();
 	EXPECT_EQ(rigidbody.data.linear_velocity.x, 0.5);
 	EXPECT_EQ(rigidbody.data.linear_velocity.y, 0.5);
 	EXPECT_EQ(rigidbody.data.angular_velocity, 0.5);
+
 	rigidbody.data.constraints = {1, 1, 0};
 	rigidbody.data.angular_damping = 0;
 	rigidbody.data.max_angular_velocity = 1000;
 	rigidbody.data.angular_velocity = 360;
-	physics_system.update();
+	system.update();
 	EXPECT_EQ(transform.rotation, 1);
+
 	rigidbody.data.angular_velocity = -360;
-	physics_system.update();
+	system.update();
 	EXPECT_EQ(transform.rotation, 1);
 }
-- 
cgit v1.2.3


From 87c74782e486647c46f9ca4d2f857094006e563c Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Wed, 13 Nov 2024 12:19:56 +0100
Subject: `make format`

---
 src/crepe/Collider.cpp               |  1 -
 src/crepe/Component.cpp              |  1 -
 src/crepe/ComponentManager.cpp       |  9 ++++++---
 src/crepe/ComponentManager.h         |  7 +++++--
 src/crepe/api/Animator.cpp           |  3 ++-
 src/crepe/api/AssetManager.h         |  3 ++-
 src/crepe/api/BehaviorScript.cpp     |  5 +++--
 src/crepe/api/GameObject.cpp         |  9 +++++----
 src/crepe/api/GameObject.h           |  6 ++++--
 src/crepe/api/LoopManager.h          |  5 ++---
 src/crepe/api/LoopManager.hpp        | 10 ++++++----
 src/crepe/api/SceneManager.cpp       | 10 +++++-----
 src/crepe/api/Script.cpp             |  1 -
 src/crepe/api/Script.h               |  1 -
 src/crepe/api/Transform.h            |  2 +-
 src/crepe/api/Vector2.cpp            |  1 -
 src/crepe/facade/SDLContext.cpp      |  2 +-
 src/crepe/facade/Sound.cpp           |  3 +--
 src/crepe/facade/SoundContext.cpp    |  1 -
 src/crepe/facade/SoundContext.h      |  8 ++++----
 src/crepe/system/CollisionSystem.cpp |  1 -
 src/crepe/system/ParticleSystem.cpp  |  1 -
 src/crepe/system/ScriptSystem.cpp    |  1 -
 src/crepe/system/System.cpp          |  5 +----
 src/example/rendering.cpp            |  6 ++++--
 src/example/script.cpp               |  4 ++--
 src/test/PhysicsTest.cpp             | 11 +++++++----
 src/test/ScriptTest.cpp              |  9 ++++-----
 src/test/main.cpp                    |  6 +++---
 29 files changed, 68 insertions(+), 64 deletions(-)

(limited to 'src/test')

diff --git a/src/crepe/Collider.cpp b/src/crepe/Collider.cpp
index b408609..113ba61 100644
--- a/src/crepe/Collider.cpp
+++ b/src/crepe/Collider.cpp
@@ -1,4 +1,3 @@
 #include "Collider.h"
 
 using namespace crepe;
-
diff --git a/src/crepe/Component.cpp b/src/crepe/Component.cpp
index d11a37e..acfd35c 100644
--- a/src/crepe/Component.cpp
+++ b/src/crepe/Component.cpp
@@ -3,4 +3,3 @@
 using namespace crepe;
 
 Component::Component(game_object_id_t id) : game_object_id(id) {}
-
diff --git a/src/crepe/ComponentManager.cpp b/src/crepe/ComponentManager.cpp
index f6acc1a..8f8437b 100644
--- a/src/crepe/ComponentManager.cpp
+++ b/src/crepe/ComponentManager.cpp
@@ -25,10 +25,13 @@ void ComponentManager::delete_all_components() {
 ComponentManager::ComponentManager() { dbg_trace(); }
 ComponentManager::~ComponentManager() { dbg_trace(); }
 
-GameObject & ComponentManager::new_object(const string & name, const string & tag, const Vector2 & position, double rotation, double scale) {
-	GameObject * object = new GameObject(*this, this->next_id, name, tag, position, rotation, scale);
+GameObject & ComponentManager::new_object(const string & name,
+										  const string & tag,
+										  const Vector2 & position,
+										  double rotation, double scale) {
+	GameObject * object = new GameObject(*this, this->next_id, name, tag,
+										 position, rotation, scale);
 	this->objects.push_front(unique_ptr<GameObject>(object));
 	this->next_id++;
 	return *object;
 }
-
diff --git a/src/crepe/ComponentManager.h b/src/crepe/ComponentManager.h
index 1d67e69..75606e0 100644
--- a/src/crepe/ComponentManager.h
+++ b/src/crepe/ComponentManager.h
@@ -1,10 +1,10 @@
 #pragma once
 
+#include <forward_list>
 #include <memory>
 #include <typeindex>
 #include <unordered_map>
 #include <vector>
-#include <forward_list>
 
 #include "Component.h"
 #include "api/Vector2.h"
@@ -101,7 +101,10 @@ public:
 	std::vector<std::reference_wrapper<T>> get_components_by_type() const;
 
 	// TODO: doxygen
-	GameObject & new_object(const std::string & name, const std::string & tag = "", const Vector2 & position = { 0, 0 }, double rotation = 0, double scale = 0);
+	GameObject & new_object(const std::string & name,
+							const std::string & tag = "",
+							const Vector2 & position = {0, 0},
+							double rotation = 0, double scale = 0);
 
 private:
 	/**
diff --git a/src/crepe/api/Animator.cpp b/src/crepe/api/Animator.cpp
index cbf415d..fcc07ef 100644
--- a/src/crepe/api/Animator.cpp
+++ b/src/crepe/api/Animator.cpp
@@ -9,7 +9,8 @@
 
 using namespace crepe;
 
-Animator::Animator(game_object_id_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/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 41c144c..c5fecef 100644
--- a/src/crepe/api/BehaviorScript.cpp
+++ b/src/crepe/api/BehaviorScript.cpp
@@ -3,5 +3,6 @@
 
 using namespace crepe;
 
-BehaviorScript::BehaviorScript(game_object_id_t id, ComponentManager & mgr) : Component(id), component_manager(mgr) {}
-
+BehaviorScript::BehaviorScript(game_object_id_t id, ComponentManager & mgr)
+	: Component(id),
+	  component_manager(mgr) {}
diff --git a/src/crepe/api/GameObject.cpp b/src/crepe/api/GameObject.cpp
index dd20b7f..e05cea1 100644
--- a/src/crepe/api/GameObject.cpp
+++ b/src/crepe/api/GameObject.cpp
@@ -1,16 +1,18 @@
 #include "api/Transform.h"
 
+#include "BehaviorScript.h"
 #include "GameObject.h"
 #include "Metadata.h"
-#include "BehaviorScript.h"
 
 using namespace crepe;
 using namespace std;
 
-GameObject::GameObject(ComponentManager & component_manager, 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), component_manager(component_manager) {
+	: id(id),
+	  component_manager(component_manager) {
 
 	// Add Transform and Metadata components
 	ComponentManager & mgr = this->component_manager;
@@ -37,4 +39,3 @@ BehaviorScript & GameObject::add_component<BehaviorScript>() {
 	ComponentManager & mgr = this->component_manager;
 	return mgr.add_component<BehaviorScript>(this->id, mgr);
 }
-
diff --git a/src/crepe/api/GameObject.h b/src/crepe/api/GameObject.h
index 7751fd0..e4a2539 100644
--- a/src/crepe/api/GameObject.h
+++ b/src/crepe/api/GameObject.h
@@ -2,8 +2,8 @@
 
 #include <string>
 
-#include "types.h"
 #include "Vector2.h"
+#include "types.h"
 
 namespace crepe {
 
@@ -31,7 +31,9 @@ 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 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;
 
diff --git a/src/crepe/api/LoopManager.h b/src/crepe/api/LoopManager.h
index ef1c14f..288dca2 100644
--- a/src/crepe/api/LoopManager.h
+++ b/src/crepe/api/LoopManager.h
@@ -2,8 +2,8 @@
 
 #include <memory>
 
-#include "../system/System.h"
 #include "../ComponentManager.h"
+#include "../system/System.h"
 
 namespace crepe {
 
@@ -74,7 +74,7 @@ protected:
 	T & get_system();
 
 private:
-	ComponentManager component_manager;
+	ComponentManager component_manager{};
 	std::unordered_map<std::type_index, std::unique_ptr<System>> systems;
 
 private:
@@ -85,4 +85,3 @@ private:
 } // namespace crepe
 
 #include "LoopManager.hpp"
-
diff --git a/src/crepe/api/LoopManager.hpp b/src/crepe/api/LoopManager.hpp
index 20e8d1c..8fb9aa3 100644
--- a/src/crepe/api/LoopManager.hpp
+++ b/src/crepe/api/LoopManager.hpp
@@ -3,8 +3,8 @@
 #include <cassert>
 #include <memory>
 
-#include "../system/System.h"
 #include "../Exception.h"
+#include "../system/System.h"
 
 #include "LoopManager.h"
 
@@ -13,8 +13,9 @@ 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");
-	
+	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());
@@ -29,7 +30,8 @@ T & LoopManager::get_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");
+	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);
diff --git a/src/crepe/api/SceneManager.cpp b/src/crepe/api/SceneManager.cpp
index 814b7d7..4a38787 100644
--- a/src/crepe/api/SceneManager.cpp
+++ b/src/crepe/api/SceneManager.cpp
@@ -16,11 +16,11 @@ 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;
diff --git a/src/crepe/api/Script.cpp b/src/crepe/api/Script.cpp
index 0423315..390cec7 100644
--- a/src/crepe/api/Script.cpp
+++ b/src/crepe/api/Script.cpp
@@ -1,4 +1,3 @@
 #include "Script.h"
 
 using namespace crepe;
-
diff --git a/src/crepe/api/Script.h b/src/crepe/api/Script.h
index c5e3cc4..837420f 100644
--- a/src/crepe/api/Script.h
+++ b/src/crepe/api/Script.h
@@ -49,4 +49,3 @@ private:
 } // namespace crepe
 
 #include "Script.hpp"
-
diff --git a/src/crepe/api/Transform.h b/src/crepe/api/Transform.h
index a1ef406..902dafa 100644
--- a/src/crepe/api/Transform.h
+++ b/src/crepe/api/Transform.h
@@ -15,7 +15,7 @@ namespace crepe {
 class Transform : public Component {
 public:
 	//! Translation (shift)
-	Vector2 position = { 0, 0 };
+	Vector2 position = {0, 0};
 	//! Rotation, in degrees
 	double rotation = 0;
 	//! Multiplication factor
diff --git a/src/crepe/api/Vector2.cpp b/src/crepe/api/Vector2.cpp
index aa391fa..7da202a 100644
--- a/src/crepe/api/Vector2.cpp
+++ b/src/crepe/api/Vector2.cpp
@@ -41,4 +41,3 @@ bool Vector2::operator==(const Vector2 & other) const {
 bool Vector2::operator!=(const Vector2 & other) const {
 	return !(*this == other);
 }
-
diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp
index 46230b4..236bf8c 100644
--- a/src/crepe/facade/SDLContext.cpp
+++ b/src/crepe/facade/SDLContext.cpp
@@ -159,7 +159,7 @@ SDLContext::texture_from_path(const std::string & path) {
 
 	SDL_Surface * tmp = IMG_Load(path.c_str());
 	if (tmp == nullptr) {
-		tmp = IMG_Load("../asset/texture/ERROR.png");	
+		tmp = IMG_Load("../asset/texture/ERROR.png");
 	}
 
 	std::unique_ptr<SDL_Surface, std::function<void(SDL_Surface *)>>
diff --git a/src/crepe/facade/Sound.cpp b/src/crepe/facade/Sound.cpp
index 3a6e1e1..b8ea71a 100644
--- a/src/crepe/facade/Sound.cpp
+++ b/src/crepe/facade/Sound.cpp
@@ -1,7 +1,7 @@
 #include <memory>
 
-#include "../util/log.h"
 #include "../Asset.h"
+#include "../util/log.h"
 
 #include "Sound.h"
 #include "SoundContext.h"
@@ -56,4 +56,3 @@ void Sound::set_looping(bool looping) {
 	if (!ctx.engine.isValidVoiceHandle(this->handle)) return;
 	ctx.engine.setLooping(this->handle, this->looping);
 }
-
diff --git a/src/crepe/facade/SoundContext.cpp b/src/crepe/facade/SoundContext.cpp
index c89fb03..b5f3db3 100644
--- a/src/crepe/facade/SoundContext.cpp
+++ b/src/crepe/facade/SoundContext.cpp
@@ -13,4 +13,3 @@ SoundContext::~SoundContext() {
 	dbg_trace();
 	engine.deinit();
 }
-
diff --git a/src/crepe/facade/SoundContext.h b/src/crepe/facade/SoundContext.h
index c360fb8..8d9e396 100644
--- a/src/crepe/facade/SoundContext.h
+++ b/src/crepe/facade/SoundContext.h
@@ -11,10 +11,10 @@ public:
 	SoundContext();
 	virtual ~SoundContext();
 
-  SoundContext(const SoundContext &) = delete;
-  SoundContext(SoundContext &&) = delete;
-  SoundContext & operator=(const SoundContext &) = delete;
-  SoundContext & operator=(SoundContext &&) = delete;
+	SoundContext(const SoundContext &) = delete;
+	SoundContext(SoundContext &&) = delete;
+	SoundContext & operator=(const SoundContext &) = delete;
+	SoundContext & operator=(SoundContext &&) = delete;
 
 private:
 	SoLoud::Soloud engine;
diff --git a/src/crepe/system/CollisionSystem.cpp b/src/crepe/system/CollisionSystem.cpp
index 67f535a..c74ca1d 100644
--- a/src/crepe/system/CollisionSystem.cpp
+++ b/src/crepe/system/CollisionSystem.cpp
@@ -3,4 +3,3 @@
 using namespace crepe;
 
 void CollisionSystem::update() {}
-
diff --git a/src/crepe/system/ParticleSystem.cpp b/src/crepe/system/ParticleSystem.cpp
index 64fee4e..fe02682 100644
--- a/src/crepe/system/ParticleSystem.cpp
+++ b/src/crepe/system/ParticleSystem.cpp
@@ -58,4 +58,3 @@ void ParticleSystem::emit_particle(ParticleEmitter & emitter) {
 		}
 	}
 }
-
diff --git a/src/crepe/system/ScriptSystem.cpp b/src/crepe/system/ScriptSystem.cpp
index 0a87fcc..644e96e 100644
--- a/src/crepe/system/ScriptSystem.cpp
+++ b/src/crepe/system/ScriptSystem.cpp
@@ -44,4 +44,3 @@ forward_list<reference_wrapper<Script>> ScriptSystem::get_scripts() {
 
 	return scripts;
 }
-
diff --git a/src/crepe/system/System.cpp b/src/crepe/system/System.cpp
index 31b1337..201b9ad 100644
--- a/src/crepe/system/System.cpp
+++ b/src/crepe/system/System.cpp
@@ -4,7 +4,4 @@
 
 using namespace crepe;
 
-System::System(ComponentManager & mgr) : component_manager(mgr) {
-	dbg_trace();
-}
-
+System::System(ComponentManager & mgr) : component_manager(mgr) { dbg_trace(); }
diff --git a/src/example/rendering.cpp b/src/example/rendering.cpp
index e02f6a3..493169b 100644
--- a/src/example/rendering.cpp
+++ b/src/example/rendering.cpp
@@ -34,7 +34,9 @@ int main() {
 	}
 	{
 		Color color(0, 0, 0, 0);
-		obj1.add_component<Sprite>(make_shared<Texture>("../asset/texture/second.png"), color, FlipSettings{true, true});
+		obj1.add_component<Sprite>(
+			make_shared<Texture>("../asset/texture/second.png"), color,
+			FlipSettings{true, true});
 	}
 
 	/*
@@ -45,7 +47,7 @@ int main() {
 	}
 	*/
 
-	auto & sys = crepe::RenderSystem::get_instance();
+	auto & sys = crepe::AssetManager::get_instance();
 	auto start = std::chrono::steady_clock::now();
 	while (std::chrono::steady_clock::now() - start < std::chrono::seconds(5)) {
 		sys.update();
diff --git a/src/example/script.cpp b/src/example/script.cpp
index 4ba2b4b..69d1ce1 100644
--- a/src/example/script.cpp
+++ b/src/example/script.cpp
@@ -35,8 +35,8 @@ class MyScript : public Script {
 };
 
 int main() {
-	ComponentManager component_manager {};
-	ScriptSystem system { component_manager };
+	ComponentManager component_manager{};
+	ScriptSystem system{component_manager};
 
 	// Create game object with Transform and BehaviorScript components
 	auto & obj = component_manager.new_object("name");
diff --git a/src/test/PhysicsTest.cpp b/src/test/PhysicsTest.cpp
index 5399d54..9ac99aa 100644
--- a/src/test/PhysicsTest.cpp
+++ b/src/test/PhysicsTest.cpp
@@ -13,7 +13,7 @@ using namespace crepe;
 class PhysicsTest : public ::testing::Test {
 public:
 	ComponentManager component_manager;
-	PhysicsSystem system { component_manager };
+	PhysicsSystem system{component_manager};
 
 	void SetUp() override {
 		ComponentManager & mgr = this->component_manager;
@@ -49,7 +49,8 @@ public:
 TEST_F(PhysicsTest, gravity) {
 	Config::get_instance().physics.gravity = 1;
 	ComponentManager & mgr = this->component_manager;
-	vector<reference_wrapper<Transform>> transforms = mgr.get_components_by_id<Transform>(0);
+	vector<reference_wrapper<Transform>> transforms
+		= mgr.get_components_by_id<Transform>(0);
 	const Transform & transform = transforms.front().get();
 	ASSERT_FALSE(transforms.empty());
 	EXPECT_EQ(transform.position.y, 0);
@@ -87,9 +88,11 @@ TEST_F(PhysicsTest, max_velocity) {
 TEST_F(PhysicsTest, movement) {
 	Config::get_instance().physics.gravity = 0;
 	ComponentManager & mgr = this->component_manager;
-	vector<reference_wrapper<Rigidbody>> rigidbodies = mgr.get_components_by_id<Rigidbody>(0);
+	vector<reference_wrapper<Rigidbody>> rigidbodies
+		= mgr.get_components_by_id<Rigidbody>(0);
 	Rigidbody & rigidbody = rigidbodies.front().get();
-	vector<reference_wrapper<Transform>> transforms = mgr.get_components_by_id<Transform>(0);
+	vector<reference_wrapper<Transform>> transforms
+		= mgr.get_components_by_id<Transform>(0);
 	const Transform & transform = transforms.front().get();
 	ASSERT_FALSE(rigidbodies.empty());
 	ASSERT_FALSE(transforms.empty());
diff --git a/src/test/ScriptTest.cpp b/src/test/ScriptTest.cpp
index ea49a35..bab9e52 100644
--- a/src/test/ScriptTest.cpp
+++ b/src/test/ScriptTest.cpp
@@ -5,11 +5,11 @@
 #define protected public
 
 #include <crepe/ComponentManager.h>
-#include <crepe/system/ScriptSystem.h>
 #include <crepe/api/BehaviorScript.h>
-#include <crepe/api/Script.h>
 #include <crepe/api/GameObject.h>
+#include <crepe/api/Script.h>
 #include <crepe/api/Vector2.h>
+#include <crepe/system/ScriptSystem.h>
 
 using namespace std;
 using namespace crepe;
@@ -17,8 +17,8 @@ using namespace testing;
 
 class ScriptTest : public Test {
 public:
-	ComponentManager component_manager {};
-	ScriptSystem system { component_manager };
+	ComponentManager component_manager{};
+	ScriptSystem system{component_manager};
 
 	class MyScript : public Script {
 		// NOTE: default (private) visibility of init and update shouldn't cause
@@ -70,4 +70,3 @@ TEST_F(ScriptTest, ListScripts) {
 	}
 	ASSERT_EQ(1, script_count);
 }
-
diff --git a/src/test/main.cpp b/src/test/main.cpp
index 6830a01..a54d239 100644
--- a/src/test/main.cpp
+++ b/src/test/main.cpp
@@ -5,11 +5,11 @@
 using namespace crepe;
 using namespace testing;
 
-int main(int argc, char **argv) {
-  InitGoogleTest(&argc, argv);
+int main(int argc, char ** argv) {
+	InitGoogleTest(&argc, argv);
 
 	auto & cfg = Config::get_instance();
 	cfg.log.level = LogLevel::ERROR;
 
-  return RUN_ALL_TESTS();
+	return RUN_ALL_TESTS();
 }
-- 
cgit v1.2.3


From 6c35bd16f254f687f2b415234e36b13f0f8897a8 Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Wed, 13 Nov 2024 18:47:18 +0100
Subject: fix unit tests

---
 src/test/PhysicsTest.cpp | 2 +-
 src/test/ScriptTest.cpp  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

(limited to 'src/test')

diff --git a/src/test/PhysicsTest.cpp b/src/test/PhysicsTest.cpp
index 9ac99aa..edb76e9 100644
--- a/src/test/PhysicsTest.cpp
+++ b/src/test/PhysicsTest.cpp
@@ -20,7 +20,7 @@ public:
 		vector<reference_wrapper<Transform>> transforms
 			= mgr.get_components_by_id<Transform>(0);
 		if (transforms.empty()) {
-			auto & entity = mgr.new_object("", "", Vector2{0, 0}, 0, 0);
+			auto entity = mgr.new_object("", "", Vector2{0, 0}, 0, 0);
 			entity.add_component<Rigidbody>(Rigidbody::Data{
 				.mass = 1,
 				.gravity_scale = 1,
diff --git a/src/test/ScriptTest.cpp b/src/test/ScriptTest.cpp
index bab9e52..19fef6d 100644
--- a/src/test/ScriptTest.cpp
+++ b/src/test/ScriptTest.cpp
@@ -36,7 +36,7 @@ public:
 
 	void SetUp() override {
 		auto & mgr = this->component_manager;
-		GameObject & entity = mgr.new_object("name");
+		GameObject entity = mgr.new_object("name");
 		BehaviorScript & component = entity.add_component<BehaviorScript>();
 
 		this->behaviorscript_ref = &component;
-- 
cgit v1.2.3