From ace974504e410eb7d98ca021d75511d8f84b9bdc Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Thu, 7 Nov 2024 20:58:54 +0100
Subject: start cleanup

---
 src/makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src')

diff --git a/src/makefile b/src/makefile
index b9c44c8..ee189e3 100644
--- a/src/makefile
+++ b/src/makefile
@@ -95,7 +95,7 @@ LOEK += test/audio.cpp
 LOEK += test/dummy.cpp
 JARO += test/PhysicsTest.cpp
 
-FMT := $(JARO) #<<< CHANGE THIS TO YOUR NAME FOR STEP 2
+FMT := $(LOEK) #<<< CHANGE THIS TO YOUR NAME FOR STEP 2
 format: FORCE
 	clang-tidy -p build/compile_commands.json --fix-errors $(FMT)
 
-- 
cgit v1.2.3


From dc93b1e9b3e05dfd3e271aaccbee1210180a6906 Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Thu, 7 Nov 2024 21:19:01 +0100
Subject: update clang-format and run `make format` over my (loek)s files

---
 .clang-format                                      |  1 +
 mwe/ecs-homemade/src/Components.cpp                |  4 +-
 mwe/ecs-homemade/src/GameObjectMax.cpp             |  6 ++-
 .../inc/ContiguousContainer.hpp                    |  3 +-
 mwe/ecs-memory-efficient/src/Components.cpp        |  4 +-
 mwe/ecs-memory-efficient/src/GameObjectMax.cpp     |  6 ++-
 mwe/events/include/customTypes.h                   |  4 +-
 mwe/events/include/eventHandler.h                  |  3 +-
 mwe/events/src/event.cpp                           | 31 +++++++++----
 mwe/events/src/main.cpp                            |  4 +-
 mwe/events/src/uiObject.cpp                        | 13 ++++--
 mwe/gameloop/src/gameObject.cpp                    |  7 ++-
 src/crepe/Exception.cpp                            |  5 +-
 src/crepe/Exception.h                              |  3 +-
 src/crepe/ValueBroker.h                            |  7 +--
 src/crepe/ValueBroker.hpp                          | 11 ++---
 src/crepe/api/CircleCollider.h                     |  3 +-
 src/crepe/api/Config.cpp                           |  1 -
 src/crepe/api/Config.h                             |  6 +--
 src/crepe/api/Metadata.cpp                         |  4 +-
 src/crepe/api/ParticleEmitter.cpp                  | 11 +++--
 src/crepe/api/Rigidbody.cpp                        |  3 +-
 src/crepe/api/SaveManager.cpp                      | 53 ++++++++++++++--------
 src/crepe/api/SaveManager.h                        |  7 ++-
 src/crepe/api/Sprite.cpp                           |  5 +-
 src/crepe/api/Transform.cpp                        |  5 +-
 src/crepe/facade/DB.cpp                            | 25 +++++-----
 src/crepe/facade/DB.h                              |  7 ++-
 src/crepe/util/Proxy.h                             |  7 ++-
 src/crepe/util/Proxy.hpp                           |  9 ++--
 src/example/db.cpp                                 |  4 +-
 src/example/proxy.cpp                              | 20 ++++----
 src/example/savemgr.cpp                            | 13 +++---
 src/makefile                                       |  2 -
 34 files changed, 179 insertions(+), 118 deletions(-)

(limited to 'src')

diff --git a/.clang-format b/.clang-format
index 3ae6c28..8ce4033 100644
--- a/.clang-format
+++ b/.clang-format
@@ -23,6 +23,7 @@ ReflowComments: false
 AlignEscapedNewlines: DontAlign
 BreakBeforeBinaryOperators: All
 AlwaysBreakTemplateDeclarations: Yes
+PackConstructorInitializers: CurrentLine
 ...
 
 # vim: ft=yaml
diff --git a/mwe/ecs-homemade/src/Components.cpp b/mwe/ecs-homemade/src/Components.cpp
index de8753e..0d62bd5 100644
--- a/mwe/ecs-homemade/src/Components.cpp
+++ b/mwe/ecs-homemade/src/Components.cpp
@@ -6,7 +6,9 @@ Component::Component() : mActive(true) {}
 Sprite::Sprite(std::string path) : mPath(path) {}
 
 Rigidbody::Rigidbody(int mass, int gravityScale, int bodyType)
-	: mMass(mass), mGravityScale(gravityScale), mBodyType(bodyType) {}
+	: mMass(mass),
+	  mGravityScale(gravityScale),
+	  mBodyType(bodyType) {}
 
 Colider::Colider(int size) : mSize(size) {}
 
diff --git a/mwe/ecs-homemade/src/GameObjectMax.cpp b/mwe/ecs-homemade/src/GameObjectMax.cpp
index b0c5af7..753c8e2 100644
--- a/mwe/ecs-homemade/src/GameObjectMax.cpp
+++ b/mwe/ecs-homemade/src/GameObjectMax.cpp
@@ -4,4 +4,8 @@
 
 GameObject::GameObject(std::uint32_t id, std::string name, std::string tag,
 					   int layer)
-	: mId(id), mName(name), mTag(tag), mActive(true), mLayer(layer) {}
+	: mId(id),
+	  mName(name),
+	  mTag(tag),
+	  mActive(true),
+	  mLayer(layer) {}
diff --git a/mwe/ecs-memory-efficient/inc/ContiguousContainer.hpp b/mwe/ecs-memory-efficient/inc/ContiguousContainer.hpp
index 408d5aa..ff8fde4 100644
--- a/mwe/ecs-memory-efficient/inc/ContiguousContainer.hpp
+++ b/mwe/ecs-memory-efficient/inc/ContiguousContainer.hpp
@@ -1,5 +1,6 @@
 template <typename T>
-ContiguousContainer<T>::ContiguousContainer() : mSize(0), mCapacity(10) {
+ContiguousContainer<T>::ContiguousContainer() : mSize(0),
+												mCapacity(10) {
 	// Allocate memory for 10 objects initially
 	mData = static_cast<T *>(malloc(mCapacity * sizeof(T)));
 	if (!mData) {
diff --git a/mwe/ecs-memory-efficient/src/Components.cpp b/mwe/ecs-memory-efficient/src/Components.cpp
index c8347b3..2ec8609 100644
--- a/mwe/ecs-memory-efficient/src/Components.cpp
+++ b/mwe/ecs-memory-efficient/src/Components.cpp
@@ -6,6 +6,8 @@ Component::Component() : mActive(true) {}
 Sprite::Sprite(std::string path) : mPath(path) {}
 
 Rigidbody::Rigidbody(int mass, int gravityScale, int bodyType)
-	: mMass(mass), mGravityScale(gravityScale), mBodyType(bodyType) {}
+	: mMass(mass),
+	  mGravityScale(gravityScale),
+	  mBodyType(bodyType) {}
 
 Colider::Colider(int size) : mSize(size) {}
diff --git a/mwe/ecs-memory-efficient/src/GameObjectMax.cpp b/mwe/ecs-memory-efficient/src/GameObjectMax.cpp
index b0c5af7..753c8e2 100644
--- a/mwe/ecs-memory-efficient/src/GameObjectMax.cpp
+++ b/mwe/ecs-memory-efficient/src/GameObjectMax.cpp
@@ -4,4 +4,8 @@
 
 GameObject::GameObject(std::uint32_t id, std::string name, std::string tag,
 					   int layer)
-	: mId(id), mName(name), mTag(tag), mActive(true), mLayer(layer) {}
+	: mId(id),
+	  mName(name),
+	  mTag(tag),
+	  mActive(true),
+	  mLayer(layer) {}
diff --git a/mwe/events/include/customTypes.h b/mwe/events/include/customTypes.h
index a5d8dc9..415b989 100644
--- a/mwe/events/include/customTypes.h
+++ b/mwe/events/include/customTypes.h
@@ -33,6 +33,8 @@ struct Collision {
 	// Constructor to initialize a Collision
 	Collision(int idA, int idB, const Vector2 & point, const Vector2 & normal,
 			  float depth)
-		: objectIdA(idA), objectIdB(idB), contactPoint(point),
+		: objectIdA(idA),
+		  objectIdB(idB),
+		  contactPoint(point),
 		  contactNormal(normal) {}
 };
diff --git a/mwe/events/include/eventHandler.h b/mwe/events/include/eventHandler.h
index aa8f63b..3a83b15 100644
--- a/mwe/events/include/eventHandler.h
+++ b/mwe/events/include/eventHandler.h
@@ -24,7 +24,8 @@ class EventHandlerWrapper : public IEventHandlerWrapper {
 public:
 	explicit EventHandlerWrapper(const EventHandler<EventType> & handler,
 								 const bool destroyOnSuccess = false)
-		: m_handler(handler), m_handlerType(m_handler.target_type().name()),
+		: m_handler(handler),
+		  m_handlerType(m_handler.target_type().name()),
 		  m_destroyOnSuccess(destroyOnSuccess) {
 		// std::cout << m_handlerType << std::endl;
 	}
diff --git a/mwe/events/src/event.cpp b/mwe/events/src/event.cpp
index 0c9f3ed..8ffa0b1 100644
--- a/mwe/events/src/event.cpp
+++ b/mwe/events/src/event.cpp
@@ -23,7 +23,9 @@ void Event::markHandled() { isHandled = true; }
 
 // KeyPressedEvent class methods
 KeyPressedEvent::KeyPressedEvent(int keycode)
-	: Event("KeyPressedEvent"), key(keycode), repeatCount(0) {}
+	: Event("KeyPressedEvent"),
+	  key(keycode),
+	  repeatCount(0) {}
 
 Keycode KeyPressedEvent::getKeyCode() const { return key; }
 
@@ -31,13 +33,16 @@ int KeyPressedEvent::getRepeatCount() const { return repeatCount; }
 
 // KeyReleasedEvent class methods
 KeyReleasedEvent::KeyReleasedEvent(int keycode)
-	: Event("KeyReleasedEvent"), key(keycode) {}
+	: Event("KeyReleasedEvent"),
+	  key(keycode) {}
 
 Keycode KeyReleasedEvent::getKeyCode() const { return key; }
 
 // MousePressedEvent class methods
 MousePressedEvent::MousePressedEvent(int mouseX, int mouseY)
-	: Event("MousePressedEvent"), mouseX(mouseX), mouseY(mouseY) {}
+	: Event("MousePressedEvent"),
+	  mouseX(mouseX),
+	  mouseY(mouseY) {}
 
 std::pair<int, int> MousePressedEvent::getMousePosition() const {
 	return {mouseX, mouseY};
@@ -45,26 +50,36 @@ std::pair<int, int> MousePressedEvent::getMousePosition() const {
 
 //Collision event
 CollisionEvent::CollisionEvent(Collision collision)
-	: collisionData(collision), Event("CollisionEvent") {}
+	: collisionData(collision),
+	  Event("CollisionEvent") {}
 
 Collision CollisionEvent::getCollisionData() const {
 	return this->collisionData;
 }
 
 TextSubmitEvent::TextSubmitEvent(std::string text)
-	: text(text), Event("TextSubmitEvent") {}
+	: text(text),
+	  Event("TextSubmitEvent") {}
 
 std::string TextSubmitEvent::getText() const { return this->text; }
 
 MouseReleasedEvent::MouseReleasedEvent(int x, int y, MouseButton button)
-	: mouseX(x), mouseY(y), button(button), Event("MouseReleased") {}
+	: mouseX(x),
+	  mouseY(y),
+	  button(button),
+	  Event("MouseReleased") {}
 std::pair<int, int> MouseReleasedEvent::getMousePosition() const {
 	return {mouseX, mouseY};
 }
 MouseClickEvent::MouseClickEvent(int x, int y, MouseButton button)
-	: mouseX(x), mouseY(y), button(button), Event("MouseClickEvent") {}
+	: mouseX(x),
+	  mouseY(y),
+	  button(button),
+	  Event("MouseClickEvent") {}
 MouseMovedEvent::MouseMovedEvent(int x, int y)
-	: mouseX(x), mouseY(y), Event("MouseMovedEvent") {}
+	: mouseX(x),
+	  mouseY(y),
+	  Event("MouseMovedEvent") {}
 std::pair<int, int> MouseClickEvent::getMousePosition() const {
 	return {mouseX, mouseY};
 }
diff --git a/mwe/events/src/main.cpp b/mwe/events/src/main.cpp
index d49cf74..f4e7390 100644
--- a/mwe/events/src/main.cpp
+++ b/mwe/events/src/main.cpp
@@ -11,7 +11,9 @@
 class PlayerDamagedEvent : public Event {
 public:
 	PlayerDamagedEvent(int damage, int playerID)
-		: Event("PlayerDamaged"), damage(damage), playerID(playerID) {}
+		: Event("PlayerDamaged"),
+		  damage(damage),
+		  playerID(playerID) {}
 
 	REGISTER_EVENT_TYPE(PlayerDamagedEvent);
 
diff --git a/mwe/events/src/uiObject.cpp b/mwe/events/src/uiObject.cpp
index 8405469..947d1a2 100644
--- a/mwe/events/src/uiObject.cpp
+++ b/mwe/events/src/uiObject.cpp
@@ -7,7 +7,9 @@ UIObject::UIObject(int width, int height) : width(width), height(height) {}
 Button::Button(int width, int height) : UIObject(width, height) {}
 
 Text::Text(int width, int height)
-	: UIObject(width, height), size(12), font(nullptr),
+	: UIObject(width, height),
+	  size(12),
+	  font(nullptr),
 	  color{255, 255, 255} { // Default size and color
 	alignment.horizontal = Alignment::Horizontal::CENTER;
 	alignment.vertical = Alignment::Vertical::MIDDLE;
@@ -15,8 +17,13 @@ Text::Text(int width, int height)
 }
 
 TextInput::TextInput(int width, int height)
-	: UIObject(width, height), textBuffer(""), placeholder(""), isActive(false),
-	  textColor{255, 255, 255}, backgroundColor{0, 0, 0}, maxLength(100),
+	: UIObject(width, height),
+	  textBuffer(""),
+	  placeholder(""),
+	  isActive(false),
+	  textColor{255, 255, 255},
+	  backgroundColor{0, 0, 0},
+	  maxLength(100),
 	  font(nullptr) {
 	alignment.horizontal = Alignment::Horizontal::LEFT;
 	alignment.vertical = Alignment::Vertical::TOP;
diff --git a/mwe/gameloop/src/gameObject.cpp b/mwe/gameloop/src/gameObject.cpp
index 78217c4..b33dc78 100644
--- a/mwe/gameloop/src/gameObject.cpp
+++ b/mwe/gameloop/src/gameObject.cpp
@@ -26,5 +26,10 @@ void GameObject::setVelY(float value) { velY = value; }
 
 GameObject::GameObject(std::string name, float x, float y, float width,
 					   float height, float velX, float velY)
-	: name(name), x(x), y(y), width(width), height(height), velX(velX),
+	: name(name),
+	  x(x),
+	  y(y),
+	  width(width),
+	  height(height),
+	  velX(velX),
 	  velY(velY) {}
diff --git a/src/crepe/Exception.cpp b/src/crepe/Exception.cpp
index f27d5a8..dab8f2e 100644
--- a/src/crepe/Exception.cpp
+++ b/src/crepe/Exception.cpp
@@ -6,9 +6,7 @@
 using namespace std;
 using namespace crepe;
 
-const char * Exception::what() {
-	return error.c_str();
-}
+const char * Exception::what() { return error.c_str(); }
 
 Exception::Exception(const char * fmt, ...) {
 	va_list args;
@@ -16,4 +14,3 @@ Exception::Exception(const char * fmt, ...) {
 	this->error = va_stringf(args, fmt);
 	va_end(args);
 }
-
diff --git a/src/crepe/Exception.h b/src/crepe/Exception.h
index e4a7bb8..6473043 100644
--- a/src/crepe/Exception.h
+++ b/src/crepe/Exception.h
@@ -17,7 +17,6 @@ protected:
 	Exception() = default;
 	//! Formatted error message
 	std::string error;
-
 };
 
-}
+} // namespace crepe
diff --git a/src/crepe/ValueBroker.h b/src/crepe/ValueBroker.h
index 88988b4..d844d6a 100644
--- a/src/crepe/ValueBroker.h
+++ b/src/crepe/ValueBroker.h
@@ -23,10 +23,12 @@ public:
 	virtual const T & get();
 
 	typedef std::function<void(const T & target)> setter_t;
-	typedef std::function<const T & ()> getter_t;
+	typedef std::function<const T &()> getter_t;
+
 private:
 	setter_t setter;
 	getter_t getter;
+
 public:
 	/**
 	 * \param setter  Function that sets the variable
@@ -35,7 +37,6 @@ public:
 	ValueBroker(const setter_t & setter, const getter_t & getter);
 };
 
-}
+} // namespace crepe
 
 #include "ValueBroker.hpp"
-
diff --git a/src/crepe/ValueBroker.hpp b/src/crepe/ValueBroker.hpp
index 0d08333..5c3bed9 100644
--- a/src/crepe/ValueBroker.hpp
+++ b/src/crepe/ValueBroker.hpp
@@ -5,11 +5,9 @@
 namespace crepe {
 
 template <typename T>
-ValueBroker<T>::ValueBroker(const setter_t & setter, const getter_t & getter) :
-	setter(setter),
-	getter(getter)
-	{
-}
+ValueBroker<T>::ValueBroker(const setter_t & setter, const getter_t & getter)
+	: setter(setter),
+	  getter(getter) {}
 
 template <typename T>
 const T & ValueBroker<T>::get() {
@@ -21,5 +19,4 @@ void ValueBroker<T>::set(const T & value) {
 	this->setter(value);
 }
 
-}
-
+} // namespace crepe
diff --git a/src/crepe/api/CircleCollider.h b/src/crepe/api/CircleCollider.h
index caa7e43..e77a592 100644
--- a/src/crepe/api/CircleCollider.h
+++ b/src/crepe/api/CircleCollider.h
@@ -6,7 +6,8 @@ namespace crepe {
 class CircleCollider : public Collider {
 public:
 	CircleCollider(game_object_id_t game_object_id, int radius)
-		: Collider(game_object_id), radius(radius) {}
+		: Collider(game_object_id),
+		  radius(radius) {}
 	int radius;
 };
 
diff --git a/src/crepe/api/Config.cpp b/src/crepe/api/Config.cpp
index d6206da..0100bcc 100644
--- a/src/crepe/api/Config.cpp
+++ b/src/crepe/api/Config.cpp
@@ -6,4 +6,3 @@ Config & Config::get_instance() {
 	static Config instance;
 	return instance;
 }
-
diff --git a/src/crepe/api/Config.h b/src/crepe/api/Config.h
index 56e3af5..8c9e643 100644
--- a/src/crepe/api/Config.h
+++ b/src/crepe/api/Config.h
@@ -7,6 +7,7 @@ namespace crepe {
 class Config {
 private:
 	Config() = default;
+
 public:
 	~Config() = default;
 
@@ -16,8 +17,8 @@ public:
 	// singleton
 	Config(const Config &) = delete;
 	Config(Config &&) = delete;
-	Config & operator = (const Config &) = delete;
-	Config & operator = (Config &&) = delete;
+	Config & operator=(const Config &) = delete;
+	Config & operator=(Config &&) = delete;
 
 public:
 	//! Logging-related settings
@@ -60,4 +61,3 @@ public:
 };
 
 } // namespace crepe
-
diff --git a/src/crepe/api/Metadata.cpp b/src/crepe/api/Metadata.cpp
index 76f11d7..d421de5 100644
--- a/src/crepe/api/Metadata.cpp
+++ b/src/crepe/api/Metadata.cpp
@@ -4,4 +4,6 @@ using namespace crepe;
 using namespace std;
 
 Metadata::Metadata(game_object_id_t id, const string & name, const string & tag)
-	: Component(id), name(name), tag(tag) {}
+	: Component(id),
+	  name(name),
+	  tag(tag) {}
diff --git a/src/crepe/api/ParticleEmitter.cpp b/src/crepe/api/ParticleEmitter.cpp
index 3b2e2f2..0bc2197 100644
--- a/src/crepe/api/ParticleEmitter.cpp
+++ b/src/crepe/api/ParticleEmitter.cpp
@@ -11,9 +11,14 @@ ParticleEmitter::ParticleEmitter(game_object_id_t id, uint32_t max_particles,
 								 uint32_t speed_offset, uint32_t angle,
 								 uint32_t angleOffset, float begin_lifespan,
 								 float end_lifespan)
-	: Component(id), max_particles(max_particles), emission_rate(emission_rate),
-	  speed(speed), speed_offset(speed_offset), position{0, 0},
-	  begin_lifespan(begin_lifespan), end_lifespan(end_lifespan) {
+	: Component(id),
+	  max_particles(max_particles),
+	  emission_rate(emission_rate),
+	  speed(speed),
+	  speed_offset(speed_offset),
+	  position{0, 0},
+	  begin_lifespan(begin_lifespan),
+	  end_lifespan(end_lifespan) {
 	std::srand(
 		static_cast<uint32_t>(std::time(nullptr))); // initialize random seed
 	std::cout << "Create emitter" << std::endl;
diff --git a/src/crepe/api/Rigidbody.cpp b/src/crepe/api/Rigidbody.cpp
index cbf1325..3bf1c5b 100644
--- a/src/crepe/api/Rigidbody.cpp
+++ b/src/crepe/api/Rigidbody.cpp
@@ -3,7 +3,8 @@
 using namespace crepe;
 
 crepe::Rigidbody::Rigidbody(uint32_t game_object_id, const Data & data)
-	: Component(game_object_id), data(data) {}
+	: Component(game_object_id),
+	  data(data) {}
 
 void crepe::Rigidbody::add_force_linear(const Vector2 & force) {
 	this->data.linear_velocity += force;
diff --git a/src/crepe/api/SaveManager.cpp b/src/crepe/api/SaveManager.cpp
index 23587e4..43276c5 100644
--- a/src/crepe/api/SaveManager.cpp
+++ b/src/crepe/api/SaveManager.cpp
@@ -2,8 +2,8 @@
 #include "../util/log.h"
 
 #include "Config.h"
-#include "ValueBroker.h"
 #include "SaveManager.h"
+#include "ValueBroker.h"
 
 using namespace std;
 using namespace crepe;
@@ -65,17 +65,33 @@ string SaveManager::deserialize(const string & value) const noexcept {
 	return value;
 }
 
-template <> uint8_t SaveManager::deserialize(const string & value) const noexcept { return deserialize<uint64_t>(value); }
-template <> int8_t SaveManager::deserialize(const string & value) const noexcept { return deserialize<int64_t>(value); }
-template <> uint16_t SaveManager::deserialize(const string & value) const noexcept { return deserialize<uint64_t>(value); }
-template <> int16_t SaveManager::deserialize(const string & value) const noexcept { return deserialize<int64_t>(value); }
-template <> uint32_t SaveManager::deserialize(const string & value) const noexcept { return deserialize<uint64_t>(value); }
-template <> int32_t SaveManager::deserialize(const string & value) const noexcept { return deserialize<int64_t>(value); }
-
-SaveManager::SaveManager() {
-	dbg_trace();
+template <>
+uint8_t SaveManager::deserialize(const string & value) const noexcept {
+	return deserialize<uint64_t>(value);
+}
+template <>
+int8_t SaveManager::deserialize(const string & value) const noexcept {
+	return deserialize<int64_t>(value);
+}
+template <>
+uint16_t SaveManager::deserialize(const string & value) const noexcept {
+	return deserialize<uint64_t>(value);
+}
+template <>
+int16_t SaveManager::deserialize(const string & value) const noexcept {
+	return deserialize<int64_t>(value);
+}
+template <>
+uint32_t SaveManager::deserialize(const string & value) const noexcept {
+	return deserialize<uint64_t>(value);
+}
+template <>
+int32_t SaveManager::deserialize(const string & value) const noexcept {
+	return deserialize<int64_t>(value);
 }
 
+SaveManager::SaveManager() { dbg_trace(); }
+
 SaveManager & SaveManager::get_instance() {
 	dbg_trace();
 	static SaveManager instance;
@@ -118,17 +134,19 @@ template void SaveManager::set(const string &, const double &);
 
 template <typename T>
 ValueBroker<T> SaveManager::get(const string & key, const T & default_value) {
-	if (!this->has(key))
-		this->set<T>(key, default_value);
+	if (!this->has(key)) this->set<T>(key, default_value);
 	return this->get<T>(key);
 }
 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 &);
@@ -138,8 +156,8 @@ template <typename T>
 ValueBroker<T> SaveManager::get(const string & key) {
 	T value;
 	return {
-		[this, key] (const T & target) { this->set<T>(key, target); },
-		[this, key, value] () mutable -> const T & {
+		[this, key](const T & target) { this->set<T>(key, target); },
+		[this, key, value]() mutable -> const T & {
 			value = this->deserialize<T>(this->get_db().get(key));
 			return value;
 		},
@@ -156,4 +174,3 @@ template ValueBroker<int64_t> SaveManager::get(const string &);
 template ValueBroker<float> SaveManager::get(const string &);
 template ValueBroker<double> SaveManager::get(const string &);
 template ValueBroker<string> SaveManager::get(const string &);
-
diff --git a/src/crepe/api/SaveManager.h b/src/crepe/api/SaveManager.h
index 3073656..4be85fb 100644
--- a/src/crepe/api/SaveManager.h
+++ b/src/crepe/api/SaveManager.h
@@ -93,8 +93,8 @@ public:
 	static SaveManager & get_instance();
 	SaveManager(const SaveManager &) = delete;
 	SaveManager(SaveManager &&) = delete;
-	SaveManager & operator = (const SaveManager &) = delete;
-	SaveManager & operator = (SaveManager &&) = delete;
+	SaveManager & operator=(const SaveManager &) = delete;
+	SaveManager & operator=(SaveManager &&) = delete;
 
 private:
 	/**
@@ -110,5 +110,4 @@ private:
 	static DB & get_db();
 };
 
-}
-
+} // namespace crepe
diff --git a/src/crepe/api/Sprite.cpp b/src/crepe/api/Sprite.cpp
index d3465c7..88a442b 100644
--- a/src/crepe/api/Sprite.cpp
+++ b/src/crepe/api/Sprite.cpp
@@ -12,7 +12,10 @@ using namespace crepe;
 
 Sprite::Sprite(game_object_id_t id, shared_ptr<Texture> image,
 			   const Color & color, const FlipSettings & flip)
-	: Component(id), color(color), flip(flip), sprite_image(image) {
+	: Component(id),
+	  color(color),
+	  flip(flip),
+	  sprite_image(image) {
 	dbg_trace();
 }
 
diff --git a/src/crepe/api/Transform.cpp b/src/crepe/api/Transform.cpp
index a244bc5..e401120 100644
--- a/src/crepe/api/Transform.cpp
+++ b/src/crepe/api/Transform.cpp
@@ -6,6 +6,9 @@ using namespace crepe;
 
 Transform::Transform(game_object_id_t id, const Vector2 & point,
 					 double rotation, double scale)
-	: Component(id), position(point), rotation(rotation), scale(scale) {
+	: Component(id),
+	  position(point),
+	  rotation(rotation),
+	  scale(scale) {
 	dbg_trace();
 }
diff --git a/src/crepe/facade/DB.cpp b/src/crepe/facade/DB.cpp
index c885560..405f7c4 100644
--- a/src/crepe/facade/DB.cpp
+++ b/src/crepe/facade/DB.cpp
@@ -1,7 +1,7 @@
 #include <cstring>
 
-#include "util/log.h"
 #include "Exception.h"
+#include "util/log.h"
 
 #include "DB.h"
 
@@ -16,20 +16,20 @@ DB::DB(const string & path) {
 	libdb::DB * db;
 	if ((ret = libdb::db_create(&db, NULL, 0)) != 0)
 		throw Exception("db_create: %s", libdb::db_strerror(ret));
-	this->db = { db, [] (libdb::DB * db) { db->close(db, 0); } };
+	this->db = {db, [](libdb::DB * db) { db->close(db, 0); }};
 
 	// load or create database file
-	if ((ret = this->db->open(this->db.get(), NULL, path.c_str(), NULL, libdb::DB_BTREE, DB_CREATE, 0)) != 0)
-		throw Exception("db->open: %s", libdb::db_strerror(ret));
+	ret = this->db->open(this->db.get(), NULL, path.c_str(), NULL,
+						 libdb::DB_BTREE, DB_CREATE, 0);
+	if (ret != 0) throw Exception("db->open: %s", libdb::db_strerror(ret));
 
 	// create cursor
 	libdb::DBC * cursor;
-	if ((ret = this->db->cursor(this->db.get(), NULL, &cursor, 0)) != 0)
-		throw Exception("db->cursor: %s", libdb::db_strerror(ret));
-	this->cursor = { cursor, [] (libdb::DBC * cursor) { cursor->close(cursor); } };
+	ret = this->db->cursor(this->db.get(), NULL, &cursor, 0);
+	if (ret != 0) throw Exception("db->cursor: %s", libdb::db_strerror(ret));
+	this->cursor = {cursor, [](libdb::DBC * cursor) { cursor->close(cursor); }};
 }
 
-
 libdb::DBT DB::to_thing(const string & thing) const noexcept {
 	libdb::DBT thang;
 	memset(&thang, 0, sizeof(libdb::DBT));
@@ -44,17 +44,15 @@ string DB::get(const string & key) {
 	memset(&db_val, 0, sizeof(libdb::DBT));
 
 	int ret = this->cursor->get(this->cursor.get(), &db_key, &db_val, DB_FIRST);
-	if (ret != 0)
-		throw Exception("cursor->get: %s", libdb::db_strerror(ret));
-	return { static_cast<char *>(db_val.data), db_val.size };
+	if (ret != 0) throw Exception("cursor->get: %s", libdb::db_strerror(ret));
+	return {static_cast<char *>(db_val.data), db_val.size};
 }
 
 void DB::set(const string & key, const string & value) {
 	libdb::DBT db_key = this->to_thing(key);
 	libdb::DBT db_val = this->to_thing(value);
 	int ret = this->db->put(this->db.get(), NULL, &db_key, &db_val, 0);
-	if (ret != 0)
-		throw Exception("cursor->get: %s", libdb::db_strerror(ret));
+	if (ret != 0) throw Exception("cursor->get: %s", libdb::db_strerror(ret));
 }
 
 bool DB::has(const std::string & key) noexcept {
@@ -65,4 +63,3 @@ bool DB::has(const std::string & key) noexcept {
 	}
 	return true;
 }
-
diff --git a/src/crepe/facade/DB.h b/src/crepe/facade/DB.h
index b62a974..7c757a2 100644
--- a/src/crepe/facade/DB.h
+++ b/src/crepe/facade/DB.h
@@ -1,14 +1,14 @@
 #pragma once
 
-#include <string>
 #include <functional>
 #include <memory>
+#include <string>
 
 namespace libdb {
 extern "C" {
 #include <db.h>
 }
-}
+} // namespace libdb
 
 namespace crepe {
 
@@ -71,5 +71,4 @@ private:
 	libdb::DBT to_thing(const std::string & thing) const noexcept;
 };
 
-}
-
+} // namespace crepe
diff --git a/src/crepe/util/Proxy.h b/src/crepe/util/Proxy.h
index fbfed0c..f84e462 100644
--- a/src/crepe/util/Proxy.h
+++ b/src/crepe/util/Proxy.h
@@ -16,9 +16,9 @@ template <typename T>
 class Proxy {
 public:
 	//! Set operator
-	Proxy & operator = (const T &);
+	Proxy & operator=(const T &);
 	//! Get operator
-	operator const T & ();
+	operator const T &();
 
 public:
 	Proxy(ValueBroker<T>);
@@ -27,7 +27,6 @@ private:
 	ValueBroker<T> broker;
 };
 
-}
+} // namespace crepe
 
 #include "Proxy.hpp"
-
diff --git a/src/crepe/util/Proxy.hpp b/src/crepe/util/Proxy.hpp
index 4aec9e9..b9923db 100644
--- a/src/crepe/util/Proxy.hpp
+++ b/src/crepe/util/Proxy.hpp
@@ -5,18 +5,17 @@
 namespace crepe {
 
 template <typename T>
-Proxy<T>::Proxy(ValueBroker<T> broker) : broker(broker) { }
+Proxy<T>::Proxy(ValueBroker<T> broker) : broker(broker) {}
 
 template <typename T>
-Proxy<T> & Proxy<T>::operator = (const T & val) {
+Proxy<T> & Proxy<T>::operator=(const T & val) {
 	this->broker.set(val);
 	return *this;
 }
 
 template <typename T>
-Proxy<T>::operator const T & () {
+Proxy<T>::operator const T &() {
 	return this->broker.get();
 }
 
-}
-
+} // namespace crepe
diff --git a/src/example/db.cpp b/src/example/db.cpp
index c046421..8c06a84 100644
--- a/src/example/db.cpp
+++ b/src/example/db.cpp
@@ -1,12 +1,12 @@
-#include <crepe/facade/DB.h>
 #include <crepe/api/Config.h>
+#include <crepe/facade/DB.h>
 #include <crepe/util/log.h>
 
 using namespace crepe;
 using namespace std;
 
 // run before main
-static auto _ = [] () {
+static auto _ = []() {
 	auto & cfg = Config::get_instance();
 	cfg.log.level = LogLevel::TRACE;
 	return 0;
diff --git a/src/example/proxy.cpp b/src/example/proxy.cpp
index 9f54f96..0afff41 100644
--- a/src/example/proxy.cpp
+++ b/src/example/proxy.cpp
@@ -5,15 +5,15 @@
 
 #include <crepe/ValueBroker.h>
 #include <crepe/api/Config.h>
-#include <crepe/util/log.h>
 #include <crepe/util/Proxy.h>
+#include <crepe/util/log.h>
 
 using namespace std;
 using namespace crepe;
 
-void test_ro_ref(const int & val) { }
-void test_rw_ref(int & val) { }
-void test_ro_val(int val) { }
+void test_ro_ref(const int & val) {}
+void test_rw_ref(int & val) {}
+void test_ro_val(int val) {}
 
 int main() {
 	auto & cfg = Config::get_instance();
@@ -21,18 +21,19 @@ int main() {
 
 	int real_value = 0;
 
-	ValueBroker<int> broker {
-		[&real_value] (const int & target) {
-			dbg_logf("set %s to %s", to_string(real_value).c_str(), to_string(target).c_str());
+	ValueBroker<int> broker{
+		[&real_value](const int & target) {
+			dbg_logf("set %s to %s", to_string(real_value).c_str(),
+					 to_string(target).c_str());
 			real_value = target;
 		},
-		[&real_value] () -> const int & {
+		[&real_value]() -> const int & {
 			dbg_logf("get %s", to_string(real_value).c_str());
 			return real_value;
 		},
 	};
 
-	Proxy<int> proxy { broker };
+	Proxy<int> proxy{broker};
 
 	broker.set(54);
 	proxy = 84;
@@ -43,4 +44,3 @@ int main() {
 
 	return 0;
 }
-
diff --git a/src/example/savemgr.cpp b/src/example/savemgr.cpp
index c8dd2bc..436fb5a 100644
--- a/src/example/savemgr.cpp
+++ b/src/example/savemgr.cpp
@@ -4,21 +4,21 @@
  */
 
 #include <cassert>
-#include <crepe/util/log.h>
-#include <crepe/util/Proxy.h>
-#include <crepe/api/SaveManager.h>
 #include <crepe/api/Config.h>
+#include <crepe/api/SaveManager.h>
+#include <crepe/util/Proxy.h>
+#include <crepe/util/log.h>
 
 using namespace crepe;
 
 // unrelated setup code
-int _ = [] () {
+int _ = []() {
 	// make sure all log messages get printed
 	auto & cfg = Config::get_instance();
 	cfg.log.level = LogLevel::TRACE;
 
 	return 0; // satisfy compiler
-} ();
+}();
 
 int main() {
 	const char * key = "mygame.test";
@@ -27,7 +27,7 @@ int main() {
 
 	dbg_logf("has key = %s", mgr.has(key) ? "true" : "false");
 	ValueBroker<int> prop = mgr.get<int>(key, 0);
-	Proxy<int> val        = mgr.get<int>(key, 0);
+	Proxy<int> val = mgr.get<int>(key, 0);
 
 	dbg_logf("val = %d", mgr.get<int>(key).get());
 	prop.set(1);
@@ -42,4 +42,3 @@ int main() {
 
 	return 0;
 }
-
diff --git a/src/makefile b/src/makefile
index ee189e3..d9c5a57 100644
--- a/src/makefile
+++ b/src/makefile
@@ -32,8 +32,6 @@ TODO += crepe/Position.h
 TODO += crepe/api/AssetManager.cpp
 TODO += crepe/api/AssetManager.h
 TODO += crepe/api/AssetManager.hpp
-LOEK += crepe/api/AudioSource.cpp
-LOEK += crepe/api/AudioSource.h
 LOEK += crepe/api/BehaviorScript.cpp
 LOEK += crepe/api/BehaviorScript.h
 LOEK += crepe/api/BehaviorScript.hpp
-- 
cgit v1.2.3


From 7b63eb310dfd299b6d26169cb0981c9bfaf160b6 Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Thu, 7 Nov 2024 21:21:32 +0100
Subject: update cleanup

---
 src/crepe/api/AudioSource.cpp | 23 ----------------------
 src/crepe/api/AudioSource.h   | 39 ------------------------------------
 src/makefile                  | 46 -------------------------------------------
 3 files changed, 108 deletions(-)
 delete mode 100644 src/crepe/api/AudioSource.cpp
 delete mode 100644 src/crepe/api/AudioSource.h

(limited to 'src')

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/makefile b/src/makefile
index d9c5a57..778e2c9 100644
--- a/src/makefile
+++ b/src/makefile
@@ -15,83 +15,37 @@
 #    pull request. Make sure to ask someone to review the code standards for
 #    each ENTIRE FILE in this pull request.
 
-LOEK += crepe/Asset.cpp
-LOEK += crepe/Asset.h
 TODO += crepe/Collider.cpp
 TODO += crepe/Collider.h
-MAX += crepe/Component.cpp
-MAX += crepe/Component.h
-MAX += crepe/ComponentManager.cpp
-MAX += crepe/ComponentManager.h
-MAX += crepe/ComponentManager.hpp
-MAX += crepe/api/Metadata.cpp
-MAX += crepe/api/Metadata.h
 TODO += crepe/Particle.cpp
 TODO += crepe/Particle.h
 TODO += crepe/Position.h
 TODO += crepe/api/AssetManager.cpp
 TODO += crepe/api/AssetManager.h
 TODO += crepe/api/AssetManager.hpp
-LOEK += crepe/api/BehaviorScript.cpp
-LOEK += crepe/api/BehaviorScript.h
-LOEK += crepe/api/BehaviorScript.hpp
 TODO += crepe/api/CircleCollider.h
 TODO += crepe/api/Color.cpp
 TODO += crepe/api/Color.h
-LOEK += crepe/api/Config.h
-MAX += crepe/api/GameObject.cpp
-MAX += crepe/api/GameObject.h
-MAX += crepe/api/GameObject.hpp
 TODO += crepe/api/ParticleEmitter.cpp
 TODO += crepe/api/ParticleEmitter.h
 TODO += crepe/api/Vector2.h
 TODO += crepe/api/Vector2.cpp
-JARO += crepe/api/Rigidbody.cpp
-JARO += crepe/api/Rigidbody.h
-LOEK += crepe/api/Script.cpp
-LOEK += crepe/api/Script.h
-LOEK += crepe/api/Script.hpp
 TODO += crepe/api/Sprite.cpp
 TODO += crepe/api/Sprite.h
 TODO += crepe/api/Texture.cpp
 TODO += crepe/api/Texture.h
-MAX += crepe/api/Transform.cpp
-MAX += crepe/api/Transform.h
 TODO += crepe/facade/SDLContext.cpp
 TODO += crepe/facade/SDLContext.h
-LOEK += crepe/facade/Sound.cpp
-LOEK += crepe/facade/Sound.h
-LOEK += crepe/facade/SoundContext.cpp
-LOEK += crepe/facade/SoundContext.h
 TODO += crepe/system/CollisionSystem.cpp
 TODO += crepe/system/CollisionSystem.h
 TODO += crepe/system/ParticleSystem.cpp
 TODO += crepe/system/ParticleSystem.h
-JARO += crepe/system/PhysicsSystem.cpp
-JARO += crepe/system/PhysicsSystem.h
 TODO += crepe/system/RenderSystem.cpp
 TODO += crepe/system/RenderSystem.h
-LOEK += crepe/system/ScriptSystem.cpp
-LOEK += crepe/system/ScriptSystem.h
-LOEK += crepe/system/System.h
-LOEK += crepe/util/LogColor.cpp
-LOEK += crepe/util/LogColor.h
-LOEK += crepe/util/fmt.cpp
-LOEK += crepe/util/fmt.h
-LOEK += crepe/util/log.cpp
-LOEK += crepe/util/log.h
 TODO += example/asset_manager.cpp
-LOEK += example/audio_internal.cpp
 TODO += example/components_internal.cpp
-MAX += example/ecs.cpp
-LOEK += example/log.cpp
 TODO += example/particle.cpp
-JARO += example/physics.cpp
 TODO += example/rendering.cpp
-LOEK += example/script.cpp
-LOEK += test/audio.cpp
-LOEK += test/dummy.cpp
-JARO += test/PhysicsTest.cpp
 
 FMT := $(LOEK) #<<< CHANGE THIS TO YOUR NAME FOR STEP 2
 format: FORCE
-- 
cgit v1.2.3


From 067247360d68042ad5466b802399338c14d7dc58 Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Fri, 8 Nov 2024 11:38:16 +0100
Subject: fix code standard issue in Exception

---
 src/crepe/Exception.cpp | 2 +-
 src/crepe/Exception.h   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

(limited to 'src')

diff --git a/src/crepe/Exception.cpp b/src/crepe/Exception.cpp
index dab8f2e..bfdbcdd 100644
--- a/src/crepe/Exception.cpp
+++ b/src/crepe/Exception.cpp
@@ -6,7 +6,7 @@
 using namespace std;
 using namespace crepe;
 
-const char * Exception::what() { return error.c_str(); }
+const char * Exception::what() const noexcept { return error.c_str(); }
 
 Exception::Exception(const char * fmt, ...) {
 	va_list args;
diff --git a/src/crepe/Exception.h b/src/crepe/Exception.h
index 6473043..80af068 100644
--- a/src/crepe/Exception.h
+++ b/src/crepe/Exception.h
@@ -11,7 +11,7 @@ public:
 	//! printf
 	Exception(const char * fmt, ...);
 	//! Get formatted error message
-	const char * what();
+	const char * what() const noexcept;
 
 protected:
 	Exception() = default;
-- 
cgit v1.2.3


From 0e9a4b0e9b4ba92290c106cda7164607c499940c Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Tue, 12 Nov 2024 15:16:39 +0100
Subject: `make format`

---
 src/crepe/Exception.cpp    |  1 -
 src/crepe/ValueBroker.hpp  |  3 ++-
 src/crepe/api/Animator.cpp |  5 ++++-
 src/crepe/api/Camera.cpp   |  3 ++-
 src/crepe/facade/DB.cpp    |  1 -
 src/makefile               | 52 +---------------------------------------------
 6 files changed, 9 insertions(+), 56 deletions(-)

(limited to 'src')

diff --git a/src/crepe/Exception.cpp b/src/crepe/Exception.cpp
index a1fa765..bfdbcdd 100644
--- a/src/crepe/Exception.cpp
+++ b/src/crepe/Exception.cpp
@@ -14,4 +14,3 @@ Exception::Exception(const char * fmt, ...) {
 	this->error = va_stringf(args, fmt);
 	va_end(args);
 }
-
diff --git a/src/crepe/ValueBroker.hpp b/src/crepe/ValueBroker.hpp
index 927142f..5c3bed9 100644
--- a/src/crepe/ValueBroker.hpp
+++ b/src/crepe/ValueBroker.hpp
@@ -6,7 +6,8 @@ namespace crepe {
 
 template <typename T>
 ValueBroker<T>::ValueBroker(const setter_t & setter, const getter_t & getter)
-	: setter(setter), getter(getter) {}
+	: setter(setter),
+	  getter(getter) {}
 
 template <typename T>
 const T & ValueBroker<T>::get() {
diff --git a/src/crepe/api/Animator.cpp b/src/crepe/api/Animator.cpp
index 8b396af..58fee2a 100644
--- a/src/crepe/api/Animator.cpp
+++ b/src/crepe/api/Animator.cpp
@@ -10,7 +10,10 @@
 using namespace crepe;
 
 Animator::Animator(uint32_t id, Sprite & ss, int row, int col, int col_animator)
-	: Component(id), spritesheet(ss), row(row), col(col) {
+	: Component(id),
+	  spritesheet(ss),
+	  row(row),
+	  col(col) {
 	dbg_trace();
 
 	animator_rect = spritesheet.sprite_rect;
diff --git a/src/crepe/api/Camera.cpp b/src/crepe/api/Camera.cpp
index 820a6a8..6355a03 100644
--- a/src/crepe/api/Camera.cpp
+++ b/src/crepe/api/Camera.cpp
@@ -10,7 +10,8 @@
 using namespace crepe;
 
 Camera::Camera(uint32_t id, const Color & bg_color)
-	: Component(id), bg_color(bg_color) {
+	: Component(id),
+	  bg_color(bg_color) {
 	dbg_trace();
 }
 
diff --git a/src/crepe/facade/DB.cpp b/src/crepe/facade/DB.cpp
index 0805a08..405f7c4 100644
--- a/src/crepe/facade/DB.cpp
+++ b/src/crepe/facade/DB.cpp
@@ -63,4 +63,3 @@ bool DB::has(const std::string & key) noexcept {
 	}
 	return true;
 }
-
diff --git a/src/makefile b/src/makefile
index 778e2c9..5f80204 100644
--- a/src/makefile
+++ b/src/makefile
@@ -1,56 +1,6 @@
 .PHONY: FORCE
 
-# STEPS FOR BIG CLEANUP
-#
-# 1. Change TODO to your name (in capitals) for each file in the list below
-#    that is yours (or you are going to fix)
-# 2. Update the name between parentheses below this list (see comment) to your
-#    name
-# 3. Create a git commit at this point (ensure `git status` reports "working
-#    tree clean")
-# 4. Run `make format` in the REPOSITORY ROOT DIRECTORY (NOT HERE), and start
-#    fixing reported errors or miscorrections manually until everything works
-#    again.
-# 5. Once everything is working again, create another git commit, and create a
-#    pull request. Make sure to ask someone to review the code standards for
-#    each ENTIRE FILE in this pull request.
-
-TODO += crepe/Collider.cpp
-TODO += crepe/Collider.h
-TODO += crepe/Particle.cpp
-TODO += crepe/Particle.h
-TODO += crepe/Position.h
-TODO += crepe/api/AssetManager.cpp
-TODO += crepe/api/AssetManager.h
-TODO += crepe/api/AssetManager.hpp
-TODO += crepe/api/CircleCollider.h
-TODO += crepe/api/Color.cpp
-TODO += crepe/api/Color.h
-TODO += crepe/api/ParticleEmitter.cpp
-TODO += crepe/api/ParticleEmitter.h
-TODO += crepe/api/Vector2.h
-TODO += crepe/api/Vector2.cpp
-TODO += crepe/api/Sprite.cpp
-TODO += crepe/api/Sprite.h
-TODO += crepe/api/Texture.cpp
-TODO += crepe/api/Texture.h
-TODO += crepe/facade/SDLContext.cpp
-TODO += crepe/facade/SDLContext.h
-TODO += crepe/system/CollisionSystem.cpp
-TODO += crepe/system/CollisionSystem.h
-TODO += crepe/system/ParticleSystem.cpp
-TODO += crepe/system/ParticleSystem.h
-TODO += crepe/system/RenderSystem.cpp
-TODO += crepe/system/RenderSystem.h
-TODO += example/asset_manager.cpp
-TODO += example/components_internal.cpp
-TODO += example/particle.cpp
-TODO += example/rendering.cpp
-
-FMT := $(LOEK) #<<< CHANGE THIS TO YOUR NAME FOR STEP 2
+FMT := $(shell git ls-files '*.c' '*.cpp' '*.h' '*.hpp')
 format: FORCE
 	clang-tidy -p build/compile_commands.json --fix-errors $(FMT)
 
-# FMT += $(shell git ls-files '*.c' '*.cpp' '*.h' '*.hpp')
-# TODO: re-enable linter after all corrections
-
-- 
cgit v1.2.3


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/CMakeLists.txt                |  1 -
 src/crepe/Asset.cpp               | 18 ++++++----
 src/crepe/Asset.h                 |  2 +-
 src/crepe/Collider.cpp            |  1 -
 src/crepe/Collider.h              |  2 +-
 src/crepe/Component.cpp           |  4 +--
 src/crepe/Component.h             | 21 ++++++-----
 src/crepe/ComponentManager.cpp    | 16 +++++----
 src/crepe/ComponentManager.h      | 27 +++++++--------
 src/crepe/ComponentManager.hpp    |  5 ++-
 src/crepe/Resource.h              | 33 ++++++++++++++++++
 src/crepe/api/Animator.cpp        |  4 +--
 src/crepe/api/Animator.h          |  3 +-
 src/crepe/api/BehaviorScript.cpp  |  4 +++
 src/crepe/api/BehaviorScript.h    | 20 +++++++++--
 src/crepe/api/BehaviorScript.hpp  |  4 +--
 src/crepe/api/CMakeLists.txt      | 10 +++---
 src/crepe/api/Camera.cpp          |  7 ++--
 src/crepe/api/Camera.h            |  2 +-
 src/crepe/api/GameObject.cpp      |  9 ++---
 src/crepe/api/GameObject.h        | 17 ++++++---
 src/crepe/api/GameObject.hpp      |  2 +-
 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/Script.cpp          |  1 +
 src/crepe/api/Script.h            | 15 ++++++--
 src/crepe/api/Script.hpp          |  6 ++--
 src/crepe/api/Sprite.cpp          |  4 +--
 src/crepe/api/Sprite.h            |  2 +-
 src/crepe/api/Transform.cpp       |  4 +--
 src/crepe/api/Transform.h         |  2 +-
 src/crepe/facade/Sound.cpp        | 31 ++++++++---------
 src/crepe/facade/Sound.h          | 14 ++++----
 src/crepe/facade/SoundContext.cpp |  6 +---
 src/crepe/facade/SoundContext.h   | 13 ++++---
 src/crepe/system/CMakeLists.txt   | 19 +++++-----
 src/crepe/system/ScriptSystem.cpp | 23 ++++++++----
 src/crepe/system/ScriptSystem.h   |  5 +--
 src/crepe/system/System.cpp       |  6 ++++
 src/crepe/system/System.h         |  7 +++-
 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 ++++++++
 50 files changed, 338 insertions(+), 161 deletions(-)
 create mode 100644 src/crepe/Resource.h
 create mode 100644 src/crepe/system/System.cpp
 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')

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e4922df..445a8b2 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -38,6 +38,5 @@ install(
 
 target_link_libraries(test_main
 	PRIVATE gtest
-	PRIVATE gtest_main
 	PUBLIC crepe
 )
diff --git a/src/crepe/Asset.cpp b/src/crepe/Asset.cpp
index 8a2a11c..3d4df53 100644
--- a/src/crepe/Asset.cpp
+++ b/src/crepe/Asset.cpp
@@ -1,16 +1,20 @@
 #include <filesystem>
 
 #include "Asset.h"
+#include "Exception.h"
 
 using namespace crepe;
+using namespace std;
 
-Asset::Asset(const std::string & src) {
-	// FIXME: restore this
-	// this->src = std::filesystem::canonical(src);
-	this->src = src;
-	this->file = std::ifstream(this->src, std::ios::in | std::ios::binary);
+Asset::Asset(const string & src) : src(src) {
+	try {
+		this->src = filesystem::canonical(src);
+	} catch (filesystem::filesystem_error & e) {
+		throw Exception("Asset error: %s", e.what());
+	}
+	this->file = ifstream(this->src, ios::in | ios::binary);
 }
 
-const std::istream & Asset::read() { return this->file; }
+const istream & Asset::read() { return this->file; }
 
-const char * Asset::canonical() { return this->src.c_str(); }
+const char * Asset::canonical() const { return this->src.c_str(); }
diff --git a/src/crepe/Asset.h b/src/crepe/Asset.h
index 0cb5834..d4e4ba1 100644
--- a/src/crepe/Asset.h
+++ b/src/crepe/Asset.h
@@ -23,7 +23,7 @@ public:
 	//! Get an input stream to the contents of this resource
 	const std::istream & read();
 	//! Get the canonical path to this resource
-	const char * canonical();
+	const char * canonical() const;
 
 private:
 	std::string src;
diff --git a/src/crepe/Collider.cpp b/src/crepe/Collider.cpp
index bbec488..b408609 100644
--- a/src/crepe/Collider.cpp
+++ b/src/crepe/Collider.cpp
@@ -2,4 +2,3 @@
 
 using namespace crepe;
 
-Collider::Collider(game_object_id_t id) : Component(id) {}
diff --git a/src/crepe/Collider.h b/src/crepe/Collider.h
index 827f83d..a1e9095 100644
--- a/src/crepe/Collider.h
+++ b/src/crepe/Collider.h
@@ -6,7 +6,7 @@ namespace crepe {
 
 class Collider : public Component {
 public:
-	Collider(game_object_id_t id);
+	using Component::Component;
 
 	int size;
 };
diff --git a/src/crepe/Component.cpp b/src/crepe/Component.cpp
index 73c2d07..c133739 100644
--- a/src/crepe/Component.cpp
+++ b/src/crepe/Component.cpp
@@ -1,6 +1,6 @@
 #include "Component.h"
-#include "types.h"
 
 using namespace crepe;
 
-Component::Component(game_object_id_t id) : game_object_id(id) {}
+Component::Component(const Data & data) : data(data) {}
+
diff --git a/src/crepe/Component.h b/src/crepe/Component.h
index 0fe60b2..c6d72df 100644
--- a/src/crepe/Component.h
+++ b/src/crepe/Component.h
@@ -2,8 +2,6 @@
 
 #include "types.h"
 
-#include <cstdint>
-
 namespace crepe {
 
 class ComponentManager;
@@ -15,13 +13,21 @@ class ComponentManager;
  * interface for all components.
  */
 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;
+	};
+
 protected:
-	//! Only the ComponentManager can create components
-	friend class crepe::ComponentManager;
 	/**
-	 * \param id The id of the GameObject this component belongs to
+	 * \param base Data
 	 */
-	Component(game_object_id_t id);
+	Component(const Data & base);
+	//! Only the ComponentManager can create components
+	friend class crepe::ComponentManager;
 
 public:
 	virtual ~Component() = default;
@@ -37,8 +43,7 @@ public:
 	virtual int get_instances_max() const { return -1; }
 
 public:
-	//! The id of the GameObject this component belongs to
-	const game_object_id_t game_object_id;
+	Data data;
 	//! Whether the component is active
 	bool active = true;
 };
diff --git a/src/crepe/ComponentManager.cpp b/src/crepe/ComponentManager.cpp
index 85149c8..f6acc1a 100644
--- a/src/crepe/ComponentManager.cpp
+++ b/src/crepe/ComponentManager.cpp
@@ -1,13 +1,10 @@
+#include "api/GameObject.h"
 #include "util/log.h"
 
 #include "ComponentManager.h"
 
 using namespace crepe;
-
-ComponentManager & ComponentManager::get_instance() {
-	static ComponentManager instance;
-	return instance;
-}
+using namespace std;
 
 void ComponentManager::delete_all_components_of_id(game_object_id_t id) {
 	// Loop through all the types (in the unordered_map<>)
@@ -26,5 +23,12 @@ 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);
+	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 c8c196c..e37bc4a 100644
--- a/src/crepe/ComponentManager.h
+++ b/src/crepe/ComponentManager.h
@@ -1,15 +1,18 @@
 #pragma once
 
-#include <cstdint>
 #include <memory>
 #include <typeindex>
 #include <unordered_map>
 #include <vector>
+#include <forward_list>
 
 #include "Component.h"
+#include "api/Vector2.h"
 
 namespace crepe {
 
+class GameObject;
+
 /**
  * \brief Manages all components
  * 
@@ -18,18 +21,10 @@ namespace crepe {
  */
 class ComponentManager {
 public:
-	/**
-	 * \brief Get the instance of the ComponentManager
-	 * 
-	 * \return The instance of the ComponentManager
-	 */
-	static ComponentManager & get_instance();
-	ComponentManager(const ComponentManager &) = delete;
-	ComponentManager(ComponentManager &&) = delete;
-	ComponentManager & operator=(const ComponentManager &) = delete;
-	ComponentManager & operator=(ComponentManager &&) = delete;
-	~ComponentManager();
+	ComponentManager(); // dbg_trace
+	~ComponentManager(); // dbg_trace
 
+public:
 	/**
 	 * \brief Add a component to the ComponentManager
 	 * 
@@ -100,8 +95,8 @@ public:
 	template <typename T>
 	std::vector<std::reference_wrapper<T>> get_components_by_type() const;
 
-private:
-	ComponentManager();
+	// TODO: doxygen
+	GameObject & new_object(const std::string & name, const std::string & tag = "", const Vector2 & position = { 0, 0 }, double rotation = 0, double scale = 0);
 
 private:
 	/**
@@ -118,6 +113,10 @@ private:
 	std::unordered_map<std::type_index,
 					   std::vector<std::vector<std::unique_ptr<Component>>>>
 		components;
+
+	//! ID of next GameObject
+	game_object_id_t next_id = 0;
+	std::forward_list<std::unique_ptr<GameObject>> objects;
 };
 
 } // namespace crepe
diff --git a/src/crepe/ComponentManager.hpp b/src/crepe/ComponentManager.hpp
index 98efb49..89a8536 100644
--- a/src/crepe/ComponentManager.hpp
+++ b/src/crepe/ComponentManager.hpp
@@ -31,7 +31,10 @@ 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(id, forward<Args>(args)...);
+	T * instance_ptr = new T(Component::Data {
+		.id = id,
+		.component_manager = *this,
+	}, forward<Args>(args)...);
 	if (instance_ptr == nullptr) throw std::bad_alloc();
 
 	T & instance_ref = *instance_ptr;
diff --git a/src/crepe/Resource.h b/src/crepe/Resource.h
new file mode 100644
index 0000000..dcf3dbd
--- /dev/null
+++ b/src/crepe/Resource.h
@@ -0,0 +1,33 @@
+#pragma once
+
+#include <memory>
+
+namespace crepe {
+
+class ResourceManager;
+class Asset;
+
+/**
+ * Resource is an interface class used to represent a (deserialized) game
+ * resource (e.g. textures, sounds).
+ */
+class Resource {
+private:
+	/**
+	 * \brief Prototype pattern clone function.
+	 *
+	 * \param src Source file of new resource (abstraction for file saved on
+	 * disk)
+	 *
+	 * \returns New instance of concrete resource
+	 */
+	virtual std::unique_ptr<Resource> clone(const Asset & src) const = 0;
+	/**
+	 * The resource manager uses \c clone to create new instances of the concrete
+	 * resource class. This may be used to inherit references to classes that
+	 * would otherwise need to be implemented as singletons.
+	 */
+	friend class ResourceManager;
+};
+
+} // namespace crepe
diff --git a/src/crepe/api/Animator.cpp b/src/crepe/api/Animator.cpp
index 58fee2a..ad60981 100644
--- a/src/crepe/api/Animator.cpp
+++ b/src/crepe/api/Animator.cpp
@@ -9,8 +9,8 @@
 
 using namespace crepe;
 
-Animator::Animator(uint32_t id, Sprite & ss, int row, int col, int col_animator)
-	: Component(id),
+Animator::Animator(const Component::Data & data, Sprite & ss, int row, int col, int col_animator)
+	: Component(data),
 	  spritesheet(ss),
 	  row(row),
 	  col(col) {
diff --git a/src/crepe/api/Animator.h b/src/crepe/api/Animator.h
index def0240..f66dc1a 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(const Component::Data & data, 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 e69de29..ce1cfde 100644
--- a/src/crepe/api/BehaviorScript.cpp
+++ b/src/crepe/api/BehaviorScript.cpp
@@ -0,0 +1,4 @@
+#include "BehaviorScript.h"
+
+using namespace crepe;
+
diff --git a/src/crepe/api/BehaviorScript.h b/src/crepe/api/BehaviorScript.h
index 6b1fec7..8d21a72 100644
--- a/src/crepe/api/BehaviorScript.h
+++ b/src/crepe/api/BehaviorScript.h
@@ -12,19 +12,35 @@ class Script;
 
 class BehaviorScript : public Component {
 protected:
-	friend class crepe::ComponentManager;
 	using Component::Component;
+	//! Only ComponentManager is allowed to instantiate BehaviorScript
+	friend class ComponentManager;
 
 public:
 	virtual ~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;
 	std::unique_ptr<Script> script = nullptr;
+
+private:
+	//! Script accesses the component manager directly via its parent
+	// (BehaviorScript) reference
+	friend class Script;
 };
 
 } // namespace crepe
diff --git a/src/crepe/api/BehaviorScript.hpp b/src/crepe/api/BehaviorScript.hpp
index 4751607..bb5d829 100644
--- a/src/crepe/api/BehaviorScript.hpp
+++ b/src/crepe/api/BehaviorScript.hpp
@@ -11,10 +11,10 @@ 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;
 	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..d9cda57 100644
--- a/src/crepe/api/CMakeLists.txt
+++ b/src/crepe/api/CMakeLists.txt
@@ -14,11 +14,11 @@ target_sources(crepe PUBLIC
 	Config.cpp
 	Metadata.cpp
 	Scene.cpp
-	SceneManager.cpp
+	# SceneManager.cpp
 	Vector2.cpp
 	Camera.cpp
 	Animator.cpp
-	LoopManager.cpp
+	# LoopManager.cpp
 	LoopTimer.cpp
 )
 
@@ -40,10 +40,10 @@ 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
+	# LoopManager.h
 	LoopTimer.h
 )
diff --git a/src/crepe/api/Camera.cpp b/src/crepe/api/Camera.cpp
index 6355a03..fece199 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,8 +6,8 @@
 
 using namespace crepe;
 
-Camera::Camera(uint32_t id, const Color & bg_color)
-	: Component(id),
+Camera::Camera(const Component::Data & data, const Color & bg_color)
+	: Component(data),
 	  bg_color(bg_color) {
 	dbg_trace();
 }
diff --git a/src/crepe/api/Camera.h b/src/crepe/api/Camera.h
index ba3a9ef..a52f2f7 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(const Component::Data & data, 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..bba1f26 100644
--- a/src/crepe/api/GameObject.cpp
+++ b/src/crepe/api/GameObject.cpp
@@ -6,18 +6,19 @@
 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..d09938a 100644
--- a/src/crepe/api/GameObject.h
+++ b/src/crepe/api/GameObject.h
@@ -3,10 +3,11 @@
 #include <string>
 
 #include "types.h"
+#include "Vector2.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,11 @@ 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 +62,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/Metadata.cpp b/src/crepe/api/Metadata.cpp
index d421de5..6f0a280 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(game_object_id_t id, const string & name, const string & tag)
-	: Component(id),
+Metadata::Metadata(const Component::Data & data, const string & name, const string & tag)
+	: Component(data),
 	  name(name),
 	  tag(tag) {}
diff --git a/src/crepe/api/Metadata.h b/src/crepe/api/Metadata.h
index c61e006..8c91797 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(game_object_id_t id, const std::string & name,
+	Metadata(const Component::Data & data, 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 0bc2197..ed4fec8 100644
--- a/src/crepe/api/ParticleEmitter.cpp
+++ b/src/crepe/api/ParticleEmitter.cpp
@@ -6,12 +6,12 @@
 
 using namespace crepe;
 
-ParticleEmitter::ParticleEmitter(game_object_id_t id, uint32_t max_particles,
+ParticleEmitter::ParticleEmitter(const Component::Data & data, 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(id),
+	: Component(data),
 	  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 5939723..ba89538 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(game_object_id_t id, uint32_t max_particles,
+	ParticleEmitter(const Component::Data & data, 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 3bf1c5b..be6bb93 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(const Component::Data & component_data, const Data & data)
+	: Component(component_data),
 	  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..99837a6 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(const Component::Data & component_data, const Data & data);
 	//! struct to hold data of rigidbody
 	Data data;
 
diff --git a/src/crepe/api/Script.cpp b/src/crepe/api/Script.cpp
index 390cec7..0423315 100644
--- a/src/crepe/api/Script.cpp
+++ b/src/crepe/api/Script.cpp
@@ -1,3 +1,4 @@
 #include "Script.h"
 
 using namespace crepe;
+
diff --git a/src/crepe/api/Script.h b/src/crepe/api/Script.h
index 49e625f..d543df8 100644
--- a/src/crepe/api/Script.h
+++ b/src/crepe/api/Script.h
@@ -11,6 +11,7 @@ namespace crepe {
 class BehaviorScript;
 
 class Script {
+	//! ScriptSystem calls \c update()
 	friend class crepe::ScriptSystem;
 
 protected:
@@ -22,17 +23,25 @@ protected:
 	// added event.
 
 protected:
+	//! Retrieve component from component manager (utility)
 	template <typename T>
 	T & get_component();
 
+	//! Retrieve components from component manager (utility)
 	template <typename T>
 	std::vector<std::reference_wrapper<T>> get_components();
 
-private:
-	friend class crepe::BehaviorScript;
-	BehaviorScript * parent = nullptr;
+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;
+	BehaviorScript * parent_ref = nullptr;
 };
 
 } // namespace crepe
 
 #include "Script.hpp"
+
diff --git a/src/crepe/api/Script.hpp b/src/crepe/api/Script.hpp
index d96c0e8..68bcc29 100644
--- a/src/crepe/api/Script.hpp
+++ b/src/crepe/api/Script.hpp
@@ -18,8 +18,10 @@ T & Script::get_component() {
 
 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);
+	auto & parent = *this->parent_ref;
+	auto & mgr = parent.data.component_manager;
+
+	return mgr.get_components_by_id<T>(parent.data.id);
 }
 
 } // namespace crepe
diff --git a/src/crepe/api/Sprite.cpp b/src/crepe/api/Sprite.cpp
index 6f0433f..716609f 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(game_object_id_t id, const shared_ptr<Texture> image,
+Sprite::Sprite(const Component::Data & data, const shared_ptr<Texture> image,
 			   const Color & color, const FlipSettings & flip)
-	: Component(id),
+	: Component(data),
 	  color(color),
 	  flip(flip),
 	  sprite_image(image) {
diff --git a/src/crepe/api/Sprite.h b/src/crepe/api/Sprite.h
index deb3f93..171dfeb 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(game_object_id_t id, const std::shared_ptr<Texture> image,
+	Sprite(const Component::Data & data, 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 e401120..9645d03 100644
--- a/src/crepe/api/Transform.cpp
+++ b/src/crepe/api/Transform.cpp
@@ -4,9 +4,9 @@
 
 using namespace crepe;
 
-Transform::Transform(game_object_id_t id, const Vector2 & point,
+Transform::Transform(const Component::Data & data, const Vector2 & point,
 					 double rotation, double scale)
-	: Component(id),
+	: Component(data),
 	  position(point),
 	  rotation(rotation),
 	  scale(scale) {
diff --git a/src/crepe/api/Transform.h b/src/crepe/api/Transform.h
index 756e45b..a7bcd89 100644
--- a/src/crepe/api/Transform.h
+++ b/src/crepe/api/Transform.h
@@ -20,7 +20,7 @@ public:
 	 * \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,
+	Transform(const Component::Data & data, const Vector2 & point, double rotation,
 			  double scale);
 	/**
 	 * \brief Get the maximum number of instances for this component
diff --git a/src/crepe/facade/Sound.cpp b/src/crepe/facade/Sound.cpp
index 648ec81..3a6e1e1 100644
--- a/src/crepe/facade/Sound.cpp
+++ b/src/crepe/facade/Sound.cpp
@@ -1,26 +1,24 @@
+#include <memory>
+
 #include "../util/log.h"
+#include "../Asset.h"
 
 #include "Sound.h"
 #include "SoundContext.h"
 
 using namespace crepe;
+using namespace std;
 
-Sound::Sound(std::unique_ptr<Asset> res) {
-	dbg_trace();
-	this->load(std::move(res));
-}
+Sound::Sound(SoundContext & ctx) : context(ctx) { dbg_trace(); }
 
-Sound::Sound(const char * src) {
-	dbg_trace();
-	this->load(std::make_unique<Asset>(src));
-}
-
-void Sound::load(std::unique_ptr<Asset> res) {
-	this->sample.load(res->canonical());
+unique_ptr<Resource> Sound::clone(const Asset & src) const {
+	auto instance = make_unique<Sound>(*this);
+	instance->sample.load(src.canonical());
+	return instance;
 }
 
 void Sound::play() {
-	SoundContext & ctx = SoundContext::get_instance();
+	SoundContext & ctx = this->context;
 	if (ctx.engine.getPause(this->handle)) {
 		// resume if paused
 		ctx.engine.setPause(this->handle, false);
@@ -32,13 +30,13 @@ void Sound::play() {
 }
 
 void Sound::pause() {
-	SoundContext & ctx = SoundContext::get_instance();
+	SoundContext & ctx = this->context;
 	if (ctx.engine.getPause(this->handle)) return;
 	ctx.engine.setPause(this->handle, true);
 }
 
 void Sound::rewind() {
-	SoundContext & ctx = SoundContext::get_instance();
+	SoundContext & ctx = this->context;
 	if (!ctx.engine.isValidVoiceHandle(this->handle)) return;
 	ctx.engine.seek(this->handle, 0);
 }
@@ -46,7 +44,7 @@ void Sound::rewind() {
 void Sound::set_volume(float volume) {
 	this->volume = volume;
 
-	SoundContext & ctx = SoundContext::get_instance();
+	SoundContext & ctx = this->context;
 	if (!ctx.engine.isValidVoiceHandle(this->handle)) return;
 	ctx.engine.setVolume(this->handle, this->volume);
 }
@@ -54,7 +52,8 @@ void Sound::set_volume(float volume) {
 void Sound::set_looping(bool looping) {
 	this->looping = looping;
 
-	SoundContext & ctx = SoundContext::get_instance();
+	SoundContext & ctx = this->context;
 	if (!ctx.engine.isValidVoiceHandle(this->handle)) return;
 	ctx.engine.setLooping(this->handle, this->looping);
 }
+
diff --git a/src/crepe/facade/Sound.h b/src/crepe/facade/Sound.h
index 183bd7c..e5b2f19 100644
--- a/src/crepe/facade/Sound.h
+++ b/src/crepe/facade/Sound.h
@@ -4,11 +4,13 @@
 #include <soloud/soloud.h>
 #include <soloud/soloud_wav.h>
 
-#include "../Asset.h"
+#include "../Resource.h"
 
 namespace crepe {
 
-class Sound {
+class SoundContext;
+
+class Sound : public Resource {
 public:
 	/**
 	 * \brief Pause this sample
@@ -64,15 +66,13 @@ public:
 	bool get_looping() const { return this->looping; }
 
 public:
-	Sound(const char * src);
-	Sound(std::unique_ptr<Asset> res);
-
-private:
-	void load(std::unique_ptr<Asset> res);
+	Sound(SoundContext & ctx);
+	std::unique_ptr<Resource> clone(const Asset & src) const override;
 
 private:
 	SoLoud::Wav sample;
 	SoLoud::handle handle;
+	SoundContext & context;
 
 	float volume = 1.0f;
 	bool looping = false;
diff --git a/src/crepe/facade/SoundContext.cpp b/src/crepe/facade/SoundContext.cpp
index 5e5a3a9..c89fb03 100644
--- a/src/crepe/facade/SoundContext.cpp
+++ b/src/crepe/facade/SoundContext.cpp
@@ -4,11 +4,6 @@
 
 using namespace crepe;
 
-SoundContext & SoundContext::get_instance() {
-	static SoundContext instance;
-	return instance;
-}
-
 SoundContext::SoundContext() {
 	dbg_trace();
 	engine.init();
@@ -18,3 +13,4 @@ SoundContext::~SoundContext() {
 	dbg_trace();
 	engine.deinit();
 }
+
diff --git a/src/crepe/facade/SoundContext.h b/src/crepe/facade/SoundContext.h
index d3123d2..c360fb8 100644
--- a/src/crepe/facade/SoundContext.h
+++ b/src/crepe/facade/SoundContext.h
@@ -7,19 +7,18 @@
 namespace crepe {
 
 class SoundContext {
-private:
+public:
 	SoundContext();
 	virtual ~SoundContext();
 
-	// singleton
-	static SoundContext & get_instance();
-	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;
+	//! Sound directly calls methods on \c engine
 	friend class Sound;
 };
 
diff --git a/src/crepe/system/CMakeLists.txt b/src/crepe/system/CMakeLists.txt
index 4c18b87..9ee12f6 100644
--- a/src/crepe/system/CMakeLists.txt
+++ b/src/crepe/system/CMakeLists.txt
@@ -1,17 +1,18 @@
 target_sources(crepe PUBLIC
-	ParticleSystem.cpp
+	System.cpp
+	# ParticleSystem.cpp
 	ScriptSystem.cpp
-	PhysicsSystem.cpp
-	CollisionSystem.cpp
-	RenderSystem.cpp
-	AnimatorSystem.cpp
+	# PhysicsSystem.cpp
+	# CollisionSystem.cpp
+	# RenderSystem.cpp
+	# AnimatorSystem.cpp
 )
 
 target_sources(crepe PUBLIC FILE_SET HEADERS FILES
 	System.h
 	ScriptSystem.h
-	PhysicsSystem.h
-	CollisionSystem.h
-	RenderSystem.h
-	AnimatorSystem.h
+	# PhysicsSystem.h
+	# CollisionSystem.h
+	# RenderSystem.h
+	# AnimatorSystem.h
 )
diff --git a/src/crepe/system/ScriptSystem.cpp b/src/crepe/system/ScriptSystem.cpp
index f2673e7..0a87fcc 100644
--- a/src/crepe/system/ScriptSystem.cpp
+++ b/src/crepe/system/ScriptSystem.cpp
@@ -13,16 +13,24 @@ using namespace std;
 using namespace crepe;
 
 void ScriptSystem::update() {
-	using namespace std;
 	dbg_trace();
 
-	forward_list<Script *> scripts = this->get_scripts();
-	for (Script * script : scripts) script->update();
+	forward_list<reference_wrapper<Script>> scripts = this->get_scripts();
+
+	for (auto & script_ref : scripts) {
+		Script & script = script_ref.get();
+		BehaviorScript & component = *script.parent_ref;
+		if (!component.initialized) {
+			script.init();
+			component.initialized = true;
+		}
+		script.update();
+	}
 }
 
-forward_list<Script *> ScriptSystem::get_scripts() {
-	forward_list<Script *> scripts = {};
-	ComponentManager & mgr = ComponentManager::get_instance();
+forward_list<reference_wrapper<Script>> ScriptSystem::get_scripts() {
+	forward_list<reference_wrapper<Script>> scripts = {};
+	ComponentManager & mgr = this->component_manager;
 	vector<reference_wrapper<BehaviorScript>> behavior_scripts
 		= mgr.get_components_by_type<BehaviorScript>();
 
@@ -31,8 +39,9 @@ forward_list<Script *> ScriptSystem::get_scripts() {
 		if (!behavior_script.active) continue;
 		Script * script = behavior_script.script.get();
 		if (script == nullptr) continue;
-		scripts.push_front(script);
+		scripts.push_front(*script);
 	}
 
 	return scripts;
 }
+
diff --git a/src/crepe/system/ScriptSystem.h b/src/crepe/system/ScriptSystem.h
index 4fa6141..b52e825 100644
--- a/src/crepe/system/ScriptSystem.h
+++ b/src/crepe/system/ScriptSystem.h
@@ -7,14 +7,15 @@
 namespace crepe {
 
 class Script;
+class BehaviorScript;
 
 class ScriptSystem : public System {
 public:
+	using System::System;
 	void update();
 
 private:
-	// TODO: to forward_list<reference_wrapper>
-	std::forward_list<Script *> get_scripts();
+	std::forward_list<std::reference_wrapper<Script>> get_scripts();
 };
 
 } // namespace crepe
diff --git a/src/crepe/system/System.cpp b/src/crepe/system/System.cpp
new file mode 100644
index 0000000..296f1ed
--- /dev/null
+++ b/src/crepe/system/System.cpp
@@ -0,0 +1,6 @@
+#include "System.h"
+
+using namespace crepe;
+
+System::System(ComponentManager & mgr) : component_manager(mgr) {}
+
diff --git a/src/crepe/system/System.h b/src/crepe/system/System.h
index 3b81bef..7970e72 100644
--- a/src/crepe/system/System.h
+++ b/src/crepe/system/System.h
@@ -2,13 +2,18 @@
 
 namespace crepe {
 
+class ComponentManager;
+
 class System {
 public:
 	virtual void update() = 0;
 
 public:
-	System() = default;
+	System(ComponentManager &);
 	virtual ~System() = default;
+
+protected:
+	ComponentManager & component_manager;
 };
 
 } // namespace crepe
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')

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 ec3601fbc17a38a44608a04f53d4e36c1bff8c96 Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Wed, 13 Nov 2024 12:12:26 +0100
Subject: re-enable loop manager + remove more singletons

---
 src/crepe/api/CMakeLists.txt         |  4 ++--
 src/crepe/api/LoopManager.cpp        | 24 ++++++++++++++++++++---
 src/crepe/api/LoopManager.h          | 29 +++++++++++++++++----------
 src/crepe/api/LoopManager.hpp        | 38 ++++++++++++++++++++++++++++++++++++
 src/crepe/system/AnimatorSystem.cpp  | 12 +-----------
 src/crepe/system/AnimatorSystem.h    | 17 ++--------------
 src/crepe/system/CMakeLists.txt      | 12 ++++++------
 src/crepe/system/CollisionSystem.cpp |  3 +--
 src/crepe/system/CollisionSystem.h   |  8 +++++---
 src/crepe/system/RenderSystem.cpp    | 14 ++-----------
 src/crepe/system/RenderSystem.h      | 13 ++----------
 src/crepe/system/System.cpp          |  6 +++++-
 12 files changed, 104 insertions(+), 76 deletions(-)
 create mode 100644 src/crepe/api/LoopManager.hpp

(limited to 'src')

diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt
index ee77947..85696c4 100644
--- a/src/crepe/api/CMakeLists.txt
+++ b/src/crepe/api/CMakeLists.txt
@@ -18,7 +18,7 @@ target_sources(crepe PUBLIC
 	Vector2.cpp
 	Camera.cpp
 	Animator.cpp
-	# LoopManager.cpp
+	LoopManager.cpp
 	LoopTimer.cpp
 )
 
@@ -44,6 +44,6 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES
 	SceneManager.hpp
 	Camera.h
 	Animator.h
-	# LoopManager.h
+	LoopManager.h
 	LoopTimer.h
 )
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..ef1c14f 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 "../system/System.h"
+#include "../ComponentManager.h"
+
 namespace crepe {
 
 class LoopManager {
@@ -73,7 +67,22 @@ 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..20e8d1c
--- /dev/null
+++ b/src/crepe/api/LoopManager.hpp
@@ -0,0 +1,38 @@
+#pragma once
+
+#include <cassert>
+#include <memory>
+
+#include "../system/System.h"
+#include "../Exception.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/system/AnimatorSystem.cpp b/src/crepe/system/AnimatorSystem.cpp
index bf45362..9d18873 100644
--- a/src/crepe/system/AnimatorSystem.cpp
+++ b/src/crepe/system/AnimatorSystem.cpp
@@ -1,27 +1,17 @@
-
 #include <cstdint>
 #include <functional>
 #include <vector>
 
 #include "api/Animator.h"
 #include "facade/SDLContext.h"
-#include "util/log.h"
 
 #include "AnimatorSystem.h"
 #include "ComponentManager.h"
 
 using namespace crepe;
 
-AnimatorSystem::AnimatorSystem() { dbg_trace(); }
-AnimatorSystem::~AnimatorSystem() { dbg_trace(); }
-
-AnimatorSystem & AnimatorSystem::get_instance() {
-	static AnimatorSystem instance;
-	return instance;
-}
-
 void AnimatorSystem::update() {
-	ComponentManager & mgr = ComponentManager::get_instance();
+	ComponentManager & mgr = this->component_manager;
 
 	std::vector<std::reference_wrapper<Animator>> animations
 		= mgr.get_components_by_type<Animator>();
diff --git a/src/crepe/system/AnimatorSystem.h b/src/crepe/system/AnimatorSystem.h
index 969e9d1..aa97084 100644
--- a/src/crepe/system/AnimatorSystem.h
+++ b/src/crepe/system/AnimatorSystem.h
@@ -17,16 +17,7 @@ namespace crepe {
 class AnimatorSystem : public System {
 
 public:
-	/**
-	 * \brief Retrieves the singleton instance of the AnimatorSystem.
-	 *
-	 * \return A reference to the single instance of the AnimatorSystem.
-	 *
-	 * This method ensures that there is only one instance of the AnimatorSystem, following the
-	 * singleton design pattern. It can be used to access the system globally.
-	 */
-	static AnimatorSystem & get_instance();
-
+	using System::System;
 	/**
 	 * \brief Updates the Animator components.
 	 *
@@ -34,11 +25,7 @@ public:
 	 * Animator components, moving the animations forward and managing their behavior (e.g., looping).
 	 */
 	void update() override;
-
-private:
-	// private because singleton
-	AnimatorSystem(); // dbg_trace
-	~AnimatorSystem(); // dbg_trace
+	// FIXME: never say "likely" in the documentation lmao
 };
 
 } // namespace crepe
diff --git a/src/crepe/system/CMakeLists.txt b/src/crepe/system/CMakeLists.txt
index 2fb58dc..d658b25 100644
--- a/src/crepe/system/CMakeLists.txt
+++ b/src/crepe/system/CMakeLists.txt
@@ -3,16 +3,16 @@ target_sources(crepe PUBLIC
 	ParticleSystem.cpp
 	ScriptSystem.cpp
 	PhysicsSystem.cpp
-	# CollisionSystem.cpp
-	# RenderSystem.cpp
-	# AnimatorSystem.cpp
+	CollisionSystem.cpp
+	RenderSystem.cpp
+	AnimatorSystem.cpp
 )
 
 target_sources(crepe PUBLIC FILE_SET HEADERS FILES
 	System.h
 	ScriptSystem.h
 	PhysicsSystem.h
-	# CollisionSystem.h
-	# RenderSystem.h
-	# AnimatorSystem.h
+	CollisionSystem.h
+	RenderSystem.h
+	AnimatorSystem.h
 )
diff --git a/src/crepe/system/CollisionSystem.cpp b/src/crepe/system/CollisionSystem.cpp
index 55e0fdc..67f535a 100644
--- a/src/crepe/system/CollisionSystem.cpp
+++ b/src/crepe/system/CollisionSystem.cpp
@@ -2,6 +2,5 @@
 
 using namespace crepe;
 
-CollisionSystem::CollisionSystem() {}
-
 void CollisionSystem::update() {}
+
diff --git a/src/crepe/system/CollisionSystem.h b/src/crepe/system/CollisionSystem.h
index 1e9f1aa..c1a70d8 100644
--- a/src/crepe/system/CollisionSystem.h
+++ b/src/crepe/system/CollisionSystem.h
@@ -1,11 +1,13 @@
 #pragma once
 
+#include "System.h"
+
 namespace crepe {
 
-class CollisionSystem {
+class CollisionSystem : public System {
 public:
-	CollisionSystem();
-	void update();
+	using System::System;
+	void update() override;
 };
 
 } // namespace crepe
diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp
index 10211a3..3e6360c 100644
--- a/src/crepe/system/RenderSystem.cpp
+++ b/src/crepe/system/RenderSystem.cpp
@@ -11,15 +11,6 @@
 
 using namespace crepe;
 
-RenderSystem::RenderSystem() { dbg_trace(); }
-
-RenderSystem::~RenderSystem() { dbg_trace(); }
-
-RenderSystem & RenderSystem::get_instance() {
-	static RenderSystem instance;
-	return instance;
-}
-
 void RenderSystem::clear_screen() const {
 	SDLContext::get_instance().clear_screen();
 }
@@ -28,7 +19,7 @@ void RenderSystem::present_screen() const {
 	SDLContext::get_instance().present_screen();
 }
 void RenderSystem::update_camera() {
-	ComponentManager & mgr = ComponentManager::get_instance();
+	ComponentManager & mgr = this->component_manager;
 
 	std::vector<std::reference_wrapper<Camera>> cameras
 		= mgr.get_components_by_type<Camera>();
@@ -39,8 +30,7 @@ void RenderSystem::update_camera() {
 	}
 }
 void RenderSystem::render_sprites() const {
-
-	ComponentManager & mgr = ComponentManager::get_instance();
+	ComponentManager & mgr = this->component_manager;
 
 	std::vector<std::reference_wrapper<Sprite>> sprites
 		= mgr.get_components_by_type<Sprite>();
diff --git a/src/crepe/system/RenderSystem.h b/src/crepe/system/RenderSystem.h
index 70db21a..da4e910 100644
--- a/src/crepe/system/RenderSystem.h
+++ b/src/crepe/system/RenderSystem.h
@@ -15,14 +15,8 @@ namespace crepe {
  * rendering services for the application.
  */
 class RenderSystem : public System {
-
 public:
-	/**
-	 * \brief Gets the singleton instance of RenderSystem.
-	 * \return Reference to the RenderSystem instance.
-	 */
-	static RenderSystem & get_instance();
-
+	using System::System;
 	/**
 	 * \brief Updates the RenderSystem for the current frame.
 	 * This method is called to perform all rendering operations for the current game frame.
@@ -30,10 +24,6 @@ public:
 	void update() override;
 
 private:
-	// Private constructor to enforce singleton pattern.
-	RenderSystem();
-	~RenderSystem();
-
 	//! Clears the screen in preparation for rendering.
 	void clear_screen() const;
 
@@ -61,4 +51,5 @@ private:
 	Camera * curr_cam = nullptr;
 	// TODO: needs a better solution
 };
+
 } // namespace crepe
diff --git a/src/crepe/system/System.cpp b/src/crepe/system/System.cpp
index 296f1ed..31b1337 100644
--- a/src/crepe/system/System.cpp
+++ b/src/crepe/system/System.cpp
@@ -1,6 +1,10 @@
+#include "../util/log.h"
+
 #include "System.h"
 
 using namespace crepe;
 
-System::System(ComponentManager & mgr) : component_manager(mgr) {}
+System::System(ComponentManager & mgr) : component_manager(mgr) {
+	dbg_trace();
+}
 
-- 
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')

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 9d58e897fb68ab8dd001a5085cde2fae4634c274 Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Wed, 13 Nov 2024 12:33:59 +0100
Subject: move some files from `loek/tests` to `loek/audio`

---
 src/crepe/Resource.h              | 33 ---------------------------------
 src/crepe/facade/Sound.cpp        | 30 ++++++++++++++++--------------
 src/crepe/facade/Sound.h          | 14 +++++++-------
 src/crepe/facade/SoundContext.cpp |  5 +++++
 src/crepe/facade/SoundContext.h   |  5 +++--
 5 files changed, 31 insertions(+), 56 deletions(-)
 delete mode 100644 src/crepe/Resource.h

(limited to 'src')

diff --git a/src/crepe/Resource.h b/src/crepe/Resource.h
deleted file mode 100644
index dcf3dbd..0000000
--- a/src/crepe/Resource.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#pragma once
-
-#include <memory>
-
-namespace crepe {
-
-class ResourceManager;
-class Asset;
-
-/**
- * Resource is an interface class used to represent a (deserialized) game
- * resource (e.g. textures, sounds).
- */
-class Resource {
-private:
-	/**
-	 * \brief Prototype pattern clone function.
-	 *
-	 * \param src Source file of new resource (abstraction for file saved on
-	 * disk)
-	 *
-	 * \returns New instance of concrete resource
-	 */
-	virtual std::unique_ptr<Resource> clone(const Asset & src) const = 0;
-	/**
-	 * The resource manager uses \c clone to create new instances of the concrete
-	 * resource class. This may be used to inherit references to classes that
-	 * would otherwise need to be implemented as singletons.
-	 */
-	friend class ResourceManager;
-};
-
-} // namespace crepe
diff --git a/src/crepe/facade/Sound.cpp b/src/crepe/facade/Sound.cpp
index b8ea71a..648ec81 100644
--- a/src/crepe/facade/Sound.cpp
+++ b/src/crepe/facade/Sound.cpp
@@ -1,24 +1,26 @@
-#include <memory>
-
-#include "../Asset.h"
 #include "../util/log.h"
 
 #include "Sound.h"
 #include "SoundContext.h"
 
 using namespace crepe;
-using namespace std;
 
-Sound::Sound(SoundContext & ctx) : context(ctx) { dbg_trace(); }
+Sound::Sound(std::unique_ptr<Asset> res) {
+	dbg_trace();
+	this->load(std::move(res));
+}
+
+Sound::Sound(const char * src) {
+	dbg_trace();
+	this->load(std::make_unique<Asset>(src));
+}
 
-unique_ptr<Resource> Sound::clone(const Asset & src) const {
-	auto instance = make_unique<Sound>(*this);
-	instance->sample.load(src.canonical());
-	return instance;
+void Sound::load(std::unique_ptr<Asset> res) {
+	this->sample.load(res->canonical());
 }
 
 void Sound::play() {
-	SoundContext & ctx = this->context;
+	SoundContext & ctx = SoundContext::get_instance();
 	if (ctx.engine.getPause(this->handle)) {
 		// resume if paused
 		ctx.engine.setPause(this->handle, false);
@@ -30,13 +32,13 @@ void Sound::play() {
 }
 
 void Sound::pause() {
-	SoundContext & ctx = this->context;
+	SoundContext & ctx = SoundContext::get_instance();
 	if (ctx.engine.getPause(this->handle)) return;
 	ctx.engine.setPause(this->handle, true);
 }
 
 void Sound::rewind() {
-	SoundContext & ctx = this->context;
+	SoundContext & ctx = SoundContext::get_instance();
 	if (!ctx.engine.isValidVoiceHandle(this->handle)) return;
 	ctx.engine.seek(this->handle, 0);
 }
@@ -44,7 +46,7 @@ void Sound::rewind() {
 void Sound::set_volume(float volume) {
 	this->volume = volume;
 
-	SoundContext & ctx = this->context;
+	SoundContext & ctx = SoundContext::get_instance();
 	if (!ctx.engine.isValidVoiceHandle(this->handle)) return;
 	ctx.engine.setVolume(this->handle, this->volume);
 }
@@ -52,7 +54,7 @@ void Sound::set_volume(float volume) {
 void Sound::set_looping(bool looping) {
 	this->looping = looping;
 
-	SoundContext & ctx = this->context;
+	SoundContext & ctx = SoundContext::get_instance();
 	if (!ctx.engine.isValidVoiceHandle(this->handle)) return;
 	ctx.engine.setLooping(this->handle, this->looping);
 }
diff --git a/src/crepe/facade/Sound.h b/src/crepe/facade/Sound.h
index e5b2f19..183bd7c 100644
--- a/src/crepe/facade/Sound.h
+++ b/src/crepe/facade/Sound.h
@@ -4,13 +4,11 @@
 #include <soloud/soloud.h>
 #include <soloud/soloud_wav.h>
 
-#include "../Resource.h"
+#include "../Asset.h"
 
 namespace crepe {
 
-class SoundContext;
-
-class Sound : public Resource {
+class Sound {
 public:
 	/**
 	 * \brief Pause this sample
@@ -66,13 +64,15 @@ public:
 	bool get_looping() const { return this->looping; }
 
 public:
-	Sound(SoundContext & ctx);
-	std::unique_ptr<Resource> clone(const Asset & src) const override;
+	Sound(const char * src);
+	Sound(std::unique_ptr<Asset> res);
+
+private:
+	void load(std::unique_ptr<Asset> res);
 
 private:
 	SoLoud::Wav sample;
 	SoLoud::handle handle;
-	SoundContext & context;
 
 	float volume = 1.0f;
 	bool looping = false;
diff --git a/src/crepe/facade/SoundContext.cpp b/src/crepe/facade/SoundContext.cpp
index b5f3db3..5e5a3a9 100644
--- a/src/crepe/facade/SoundContext.cpp
+++ b/src/crepe/facade/SoundContext.cpp
@@ -4,6 +4,11 @@
 
 using namespace crepe;
 
+SoundContext & SoundContext::get_instance() {
+	static SoundContext instance;
+	return instance;
+}
+
 SoundContext::SoundContext() {
 	dbg_trace();
 	engine.init();
diff --git a/src/crepe/facade/SoundContext.h b/src/crepe/facade/SoundContext.h
index 8d9e396..d3123d2 100644
--- a/src/crepe/facade/SoundContext.h
+++ b/src/crepe/facade/SoundContext.h
@@ -7,10 +7,12 @@
 namespace crepe {
 
 class SoundContext {
-public:
+private:
 	SoundContext();
 	virtual ~SoundContext();
 
+	// singleton
+	static SoundContext & get_instance();
 	SoundContext(const SoundContext &) = delete;
 	SoundContext(SoundContext &&) = delete;
 	SoundContext & operator=(const SoundContext &) = delete;
@@ -18,7 +20,6 @@ public:
 
 private:
 	SoLoud::Soloud engine;
-	//! Sound directly calls methods on \c engine
 	friend class Sound;
 };
 
-- 
cgit v1.2.3


From fac06d488e635583307cd4a916a611500fb64c16 Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Wed, 13 Nov 2024 13:10:25 +0100
Subject: cleanup + fix examples

---
 src/crepe/api/BehaviorScript.cpp    |  7 +++++++
 src/crepe/api/BehaviorScript.h      | 13 +++++++++++++
 src/crepe/api/GameObject.cpp        |  6 ------
 src/crepe/api/GameObject.h          | 13 -------------
 src/crepe/api/Script.h              |  3 ++-
 src/example/components_internal.cpp | 13 ++++---------
 src/example/ecs.cpp                 | 18 ++++++++++++------
 src/example/physics.cpp             |  9 +++++----
 src/example/rendering.cpp           | 10 ++++++----
 src/example/scene_manager.cpp       |  4 ++--
 10 files changed, 51 insertions(+), 45 deletions(-)

(limited to 'src')

diff --git a/src/crepe/api/BehaviorScript.cpp b/src/crepe/api/BehaviorScript.cpp
index c5fecef..7bbace0 100644
--- a/src/crepe/api/BehaviorScript.cpp
+++ b/src/crepe/api/BehaviorScript.cpp
@@ -1,8 +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 f156081..a49fc96 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 {
 
@@ -44,6 +45,18 @@ private:
 	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/GameObject.cpp b/src/crepe/api/GameObject.cpp
index e05cea1..4f3c639 100644
--- a/src/crepe/api/GameObject.cpp
+++ b/src/crepe/api/GameObject.cpp
@@ -33,9 +33,3 @@ 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 e4a2539..73ff0b8 100644
--- a/src/crepe/api/GameObject.h
+++ b/src/crepe/api/GameObject.h
@@ -8,7 +8,6 @@
 namespace crepe {
 
 class ComponentManager;
-class BehaviorScript;
 
 /**
  * \brief Represents a GameObject
@@ -70,18 +69,6 @@ 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/Script.h b/src/crepe/api/Script.h
index 837420f..051ea00 100644
--- a/src/crepe/api/Script.h
+++ b/src/crepe/api/Script.h
@@ -32,7 +32,7 @@ protected:
 	template <typename T>
 	std::vector<std::reference_wrapper<T>> get_components();
 
-private:
+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.
@@ -40,6 +40,7 @@ private:
 	//! Only \c BehaviorScript instantiates Script
 	friend class BehaviorScript;
 
+private:
 	// These references are set by BehaviorScript immediately after calling the
 	// constructor of Script.
 	BehaviorScript * parent_ref = nullptr;
diff --git a/src/example/components_internal.cpp b/src/example/components_internal.cpp
index ea1eaad..dd4c7df 100644
--- a/src/example/components_internal.cpp
+++ b/src/example/components_internal.cpp
@@ -23,17 +23,16 @@ using namespace std;
 int main() {
 	dbg_trace();
 
-	auto & mgr = ComponentManager::get_instance();
+	ComponentManager mgr{};
 
 	auto start_adding = chrono::high_resolution_clock::now();
 
 	GameObject * game_object[OBJ_COUNT];
 
 	for (int i = 0; i < OBJ_COUNT; ++i) {
-		game_object[i] = new GameObject(i, "Name", "Tag", 0);
-
-		game_object[i]->add_component<Sprite>("test");
-		game_object[i]->add_component<Rigidbody>(0, 0, i);
+		GameObject & obj = mgr.new_object("Name", "Tag");
+		obj.add_component<Sprite>("test");
+		obj.add_component<Rigidbody>(0, 0, i);
 	}
 
 	auto stop_adding = chrono::high_resolution_clock::now();
@@ -45,10 +44,6 @@ int main() {
 
 	auto stop_looping = chrono::high_resolution_clock::now();
 
-	for (int i = 0; i < OBJ_COUNT; ++i) {
-		delete game_object[i];
-	}
-
 	auto add_time = chrono::duration_cast<chrono::microseconds>(stop_adding
 																- start_adding);
 	auto loop_time = chrono::duration_cast<chrono::microseconds>(stop_looping
diff --git a/src/example/ecs.cpp b/src/example/ecs.cpp
index e61c398..9a008ea 100644
--- a/src/example/ecs.cpp
+++ b/src/example/ecs.cpp
@@ -9,13 +9,20 @@ using namespace crepe;
 using namespace std;
 
 int main() {
+	ComponentManager mgr{};
+
 	// Create a few GameObjects
 	try {
-		GameObject body(0, "body", "person", Vector2{0, 0}, 0, 1);
-		GameObject right_leg(1, "rightLeg", "person", Vector2{1, 1}, 0, 1);
-		GameObject left_leg(2, "leftLeg", "person", Vector2{1, 1}, 0, 1);
-		GameObject right_foot(3, "rightFoot", "person", Vector2{2, 2}, 0, 1);
-		GameObject left_foot(4, "leftFoot", "person", Vector2{2, 2}, 0, 1);
+		GameObject & body
+			= mgr.new_object("body", "person", Vector2{0, 0}, 0, 1);
+		GameObject & right_leg
+			= mgr.new_object("rightLeg", "person", Vector2{1, 1}, 0, 1);
+		GameObject & left_leg
+			= mgr.new_object("leftLeg", "person", Vector2{1, 1}, 0, 1);
+		GameObject & right_foot
+			= mgr.new_object("rightFoot", "person", Vector2{2, 2}, 0, 1);
+		GameObject & left_foot
+			= mgr.new_object("leftFoot", "person", Vector2{2, 2}, 0, 1);
 
 		// Set the parent of each GameObject
 		right_foot.set_parent(right_leg);
@@ -30,7 +37,6 @@ int main() {
 	}
 
 	// Get the Metadata and Transform components of each GameObject
-	ComponentManager & mgr = ComponentManager::get_instance();
 	vector<reference_wrapper<Metadata>> metadata
 		= mgr.get_components_by_type<Metadata>();
 	vector<reference_wrapper<Transform>> transform
diff --git a/src/example/physics.cpp b/src/example/physics.cpp
index 848f857..2ebf779 100644
--- a/src/example/physics.cpp
+++ b/src/example/physics.cpp
@@ -9,9 +9,11 @@ using namespace crepe;
 using namespace std;
 
 int main(int argc, char * argv[]) {
-	GameObject * game_object;
-	game_object = new GameObject(0, "Name", "Tag", Vector2{0, 0}, 0, 0);
-	game_object->add_component<Rigidbody>(Rigidbody::Data{
+	ComponentManager mgr{};
+
+	GameObject & game_object
+		= mgr.new_object("Name", "Tag", Vector2{0, 0}, 0, 0);
+	game_object.add_component<Rigidbody>(Rigidbody::Data{
 		.mass = 1,
 		.gravity_scale = 1,
 		.body_type = Rigidbody::BodyType::DYNAMIC,
@@ -19,6 +21,5 @@ int main(int argc, char * argv[]) {
 		.use_gravity = true,
 		.bounce = false,
 	});
-	delete game_object;
 	return 0;
 }
diff --git a/src/example/rendering.cpp b/src/example/rendering.cpp
index 493169b..95d5dac 100644
--- a/src/example/rendering.cpp
+++ b/src/example/rendering.cpp
@@ -20,9 +20,12 @@ using namespace crepe;
 int main() {
 	dbg_trace();
 
-	auto obj = GameObject(0, "name", "tag", Vector2{0, 0}, 1, 1);
-	auto obj1 = GameObject(1, "name", "tag", Vector2{500, 0}, 1, 0.1);
-	auto obj2 = GameObject(2, "name", "tag", Vector2{800, 0}, 1, 0.1);
+	ComponentManager mgr{};
+	RenderSystem sys{mgr};
+
+	auto & obj = mgr.new_object("name", "tag", Vector2{0, 0}, 1, 1);
+	auto & obj1 = mgr.new_object("name", "tag", Vector2{500, 0}, 1, 0.1);
+	auto & obj2 = mgr.new_object("name", "tag", Vector2{800, 0}, 1, 0.1);
 
 	// Normal adding components
 	{
@@ -47,7 +50,6 @@ int main() {
 	}
 	*/
 
-	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/scene_manager.cpp b/src/example/scene_manager.cpp
index f46dc36..5cd7336 100644
--- a/src/example/scene_manager.cpp
+++ b/src/example/scene_manager.cpp
@@ -34,7 +34,8 @@ public:
 };
 
 int main() {
-	SceneManager & scene_mgr = SceneManager::get_instance();
+	ComponentManager component_mgr{};
+	SceneManager scene_mgr{component_mgr};
 
 	// Add the scenes to the scene manager
 	scene_mgr.add_scene<ConcreteScene1>("scene1");
@@ -45,7 +46,6 @@ int main() {
 	scene_mgr.load_next_scene();
 
 	// Get the Metadata components of each GameObject of Scene1
-	ComponentManager & component_mgr = ComponentManager::get_instance();
 	vector<reference_wrapper<Metadata>> metadata
 		= component_mgr.get_components_by_type<Metadata>();
 
-- 
cgit v1.2.3


From 9e87a556a5f68c5f9bb04bef9a66880536ccd6e8 Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Wed, 13 Nov 2024 13:12:06 +0100
Subject: move more files from `loek/tests` to `loek/audio`

---
 src/crepe/Asset.cpp | 18 +++++++-----------
 src/crepe/Asset.h   |  2 +-
 2 files changed, 8 insertions(+), 12 deletions(-)

(limited to 'src')

diff --git a/src/crepe/Asset.cpp b/src/crepe/Asset.cpp
index 3d4df53..8a2a11c 100644
--- a/src/crepe/Asset.cpp
+++ b/src/crepe/Asset.cpp
@@ -1,20 +1,16 @@
 #include <filesystem>
 
 #include "Asset.h"
-#include "Exception.h"
 
 using namespace crepe;
-using namespace std;
 
-Asset::Asset(const string & src) : src(src) {
-	try {
-		this->src = filesystem::canonical(src);
-	} catch (filesystem::filesystem_error & e) {
-		throw Exception("Asset error: %s", e.what());
-	}
-	this->file = ifstream(this->src, ios::in | ios::binary);
+Asset::Asset(const std::string & src) {
+	// FIXME: restore this
+	// this->src = std::filesystem::canonical(src);
+	this->src = src;
+	this->file = std::ifstream(this->src, std::ios::in | std::ios::binary);
 }
 
-const istream & Asset::read() { return this->file; }
+const std::istream & Asset::read() { return this->file; }
 
-const char * Asset::canonical() const { return this->src.c_str(); }
+const char * Asset::canonical() { return this->src.c_str(); }
diff --git a/src/crepe/Asset.h b/src/crepe/Asset.h
index d4e4ba1..0cb5834 100644
--- a/src/crepe/Asset.h
+++ b/src/crepe/Asset.h
@@ -23,7 +23,7 @@ public:
 	//! Get an input stream to the contents of this resource
 	const std::istream & read();
 	//! Get the canonical path to this resource
-	const char * canonical() const;
+	const char * canonical();
 
 private:
 	std::string src;
-- 
cgit v1.2.3


From 1df510f4a2dbe0fcb8c9f8a34695abf8d33f9ddc Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Wed, 13 Nov 2024 14:35:27 +0100
Subject: update logging to use C++20 format and classes

---
 src/crepe/CMakeLists.txt            |  1 +
 src/crepe/ComponentManager.cpp      |  2 +-
 src/crepe/Exception.cpp             | 13 ++----
 src/crepe/Exception.h               | 16 ++++++--
 src/crepe/Exception.hpp             | 13 ++++++
 src/crepe/api/Animator.cpp          |  2 +-
 src/crepe/api/AssetManager.cpp      |  2 +-
 src/crepe/api/BehaviorScript.hpp    |  2 +-
 src/crepe/api/Camera.cpp            |  2 +-
 src/crepe/api/Config.h              |  4 +-
 src/crepe/api/LoopTimer.cpp         |  2 +-
 src/crepe/api/SaveManager.cpp       |  2 +-
 src/crepe/api/Script.h              |  5 +--
 src/crepe/api/Sprite.cpp            |  2 +-
 src/crepe/api/Texture.cpp           |  2 +-
 src/crepe/api/Transform.cpp         |  2 +-
 src/crepe/facade/DB.cpp             |  2 +-
 src/crepe/facade/SDLContext.cpp     |  2 +-
 src/crepe/facade/Sound.cpp          |  2 +-
 src/crepe/facade/SoundContext.cpp   |  2 +-
 src/crepe/system/AnimatorSystem.cpp |  2 +-
 src/crepe/system/RenderSystem.cpp   |  2 +-
 src/crepe/system/ScriptSystem.cpp   |  2 +-
 src/crepe/util/CMakeLists.txt       |  7 ++--
 src/crepe/util/Log.cpp              | 39 ++++++++++++++++++
 src/crepe/util/Log.h                | 80 +++++++++++++++++++++++++++++++++++++
 src/crepe/util/Log.hpp              | 18 +++++++++
 src/crepe/util/LogColor.cpp         | 19 +--------
 src/crepe/util/LogColor.h           | 29 +++++++++-----
 src/crepe/util/fmt.cpp              | 35 ----------------
 src/crepe/util/fmt.h                | 10 -----
 src/crepe/util/log.cpp              | 53 ------------------------
 src/crepe/util/log.h                | 39 ------------------
 src/example/log.cpp                 | 13 +++---
 34 files changed, 218 insertions(+), 210 deletions(-)
 create mode 100644 src/crepe/Exception.hpp
 create mode 100644 src/crepe/util/Log.cpp
 create mode 100644 src/crepe/util/Log.h
 create mode 100644 src/crepe/util/Log.hpp
 delete mode 100644 src/crepe/util/fmt.cpp
 delete mode 100644 src/crepe/util/fmt.h
 delete mode 100644 src/crepe/util/log.cpp
 delete mode 100644 src/crepe/util/log.h

(limited to 'src')

diff --git a/src/crepe/CMakeLists.txt b/src/crepe/CMakeLists.txt
index fc95bd3..52a781e 100644
--- a/src/crepe/CMakeLists.txt
+++ b/src/crepe/CMakeLists.txt
@@ -16,6 +16,7 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES
 	ValueBroker.h
 	ValueBroker.hpp
 	Exception.h
+	Exception.hpp
 )
 
 add_subdirectory(api)
diff --git a/src/crepe/ComponentManager.cpp b/src/crepe/ComponentManager.cpp
index 85149c8..7123905 100644
--- a/src/crepe/ComponentManager.cpp
+++ b/src/crepe/ComponentManager.cpp
@@ -1,4 +1,4 @@
-#include "util/log.h"
+#include "util/Log.h"
 
 #include "ComponentManager.h"
 
diff --git a/src/crepe/Exception.cpp b/src/crepe/Exception.cpp
index bfdbcdd..3217169 100644
--- a/src/crepe/Exception.cpp
+++ b/src/crepe/Exception.cpp
@@ -1,16 +1,11 @@
-#include <cstdarg>
-
 #include "Exception.h"
-#include "util/fmt.h"
 
-using namespace std;
 using namespace crepe;
+using namespace std;
 
 const char * Exception::what() const noexcept { return error.c_str(); }
 
-Exception::Exception(const char * fmt, ...) {
-	va_list args;
-	va_start(args, fmt);
-	this->error = va_stringf(args, fmt);
-	va_end(args);
+Exception::Exception(const string & msg) {
+	this->error = msg;
 }
+
diff --git a/src/crepe/Exception.h b/src/crepe/Exception.h
index 80af068..ed3ab15 100644
--- a/src/crepe/Exception.h
+++ b/src/crepe/Exception.h
@@ -2,21 +2,31 @@
 
 #include <exception>
 #include <string>
+#include <format>
 
 namespace crepe {
 
-//! Exception class with printf-style constructor
+//! Exception class
 class Exception : public std::exception {
 public:
-	//! printf
-	Exception(const char * fmt, ...);
+	//! Exception with plain message
+	Exception(const std::string & msg);
+
+	//! Exception with \c std::format message
+	template<class... Args>
+	Exception(std::format_string<Args...> fmt, Args&&... args);
+
 	//! Get formatted error message
 	const char * what() const noexcept;
 
 protected:
 	Exception() = default;
+
 	//! Formatted error message
 	std::string error;
 };
 
 } // namespace crepe
+
+#include "Exception.hpp"
+
diff --git a/src/crepe/Exception.hpp b/src/crepe/Exception.hpp
new file mode 100644
index 0000000..d813879
--- /dev/null
+++ b/src/crepe/Exception.hpp
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "Exception.h"
+
+namespace crepe {
+
+template<class... Args>
+Exception::Exception(std::format_string<Args...> fmt, Args&&... args) {
+	this->error = std::format(fmt, std::forward<Args>(args)...);
+}
+
+}
+
diff --git a/src/crepe/api/Animator.cpp b/src/crepe/api/Animator.cpp
index 58fee2a..863dce6 100644
--- a/src/crepe/api/Animator.cpp
+++ b/src/crepe/api/Animator.cpp
@@ -1,7 +1,7 @@
 
 #include <cstdint>
 
-#include "util/log.h"
+#include "util/Log.h"
 
 #include "Animator.h"
 #include "Component.h"
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/BehaviorScript.hpp b/src/crepe/api/BehaviorScript.hpp
index 4751607..bc157fd 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"
diff --git a/src/crepe/api/Camera.cpp b/src/crepe/api/Camera.cpp
index 6355a03..6f0deb1 100644
--- a/src/crepe/api/Camera.cpp
+++ b/src/crepe/api/Camera.cpp
@@ -1,7 +1,7 @@
 
 #include <cstdint>
 
-#include "util/log.h"
+#include "util/Log.h"
 
 #include "Camera.h"
 #include "Color.h"
diff --git a/src/crepe/api/Config.h b/src/crepe/api/Config.h
index 8c9e643..8fd381e 100644
--- a/src/crepe/api/Config.h
+++ b/src/crepe/api/Config.h
@@ -1,6 +1,6 @@
 #pragma once
 
-#include "../util/log.h"
+#include "../util/Log.h"
 
 namespace crepe {
 
@@ -29,7 +29,7 @@ public:
 		 * 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
 		 *
diff --git a/src/crepe/api/LoopTimer.cpp b/src/crepe/api/LoopTimer.cpp
index 8f09e41..b3aec22 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"
 
diff --git a/src/crepe/api/SaveManager.cpp b/src/crepe/api/SaveManager.cpp
index 43276c5..2974b91 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"
diff --git a/src/crepe/api/Script.h b/src/crepe/api/Script.h
index 49e625f..ed247ad 100644
--- a/src/crepe/api/Script.h
+++ b/src/crepe/api/Script.h
@@ -2,12 +2,9 @@
 
 #include <vector>
 
-namespace crepe {
-class ScriptSystem;
-}
-
 namespace crepe {
 
+class ScriptSystem;
 class BehaviorScript;
 
 class Script {
diff --git a/src/crepe/api/Sprite.cpp b/src/crepe/api/Sprite.cpp
index 6f0433f..ac0079e 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"
diff --git a/src/crepe/api/Texture.cpp b/src/crepe/api/Texture.cpp
index 5ebd23d..8ddeac5 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"
diff --git a/src/crepe/api/Transform.cpp b/src/crepe/api/Transform.cpp
index e401120..e9108c4 100644
--- a/src/crepe/api/Transform.cpp
+++ b/src/crepe/api/Transform.cpp
@@ -1,4 +1,4 @@
-#include "util/log.h"
+#include "../util/Log.h"
 
 #include "Transform.h"
 
diff --git a/src/crepe/facade/DB.cpp b/src/crepe/facade/DB.cpp
index 405f7c4..ec6191b 100644
--- a/src/crepe/facade/DB.cpp
+++ b/src/crepe/facade/DB.cpp
@@ -1,7 +1,7 @@
 #include <cstring>
 
 #include "Exception.h"
-#include "util/log.h"
+#include "util/Log.h"
 
 #include "DB.h"
 
diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp
index 39d0d4d..a28f7bd 100644
--- a/src/crepe/facade/SDLContext.cpp
+++ b/src/crepe/facade/SDLContext.cpp
@@ -15,7 +15,7 @@
 #include "../api/Sprite.h"
 #include "../api/Texture.h"
 #include "../api/Transform.h"
-#include "../util/log.h"
+#include "../util/Log.h"
 #include "Exception.h"
 
 #include "SDLContext.h"
diff --git a/src/crepe/facade/Sound.cpp b/src/crepe/facade/Sound.cpp
index 648ec81..49fb8dc 100644
--- a/src/crepe/facade/Sound.cpp
+++ b/src/crepe/facade/Sound.cpp
@@ -1,4 +1,4 @@
-#include "../util/log.h"
+#include "../util/Log.h"
 
 #include "Sound.h"
 #include "SoundContext.h"
diff --git a/src/crepe/facade/SoundContext.cpp b/src/crepe/facade/SoundContext.cpp
index 5e5a3a9..deb2b62 100644
--- a/src/crepe/facade/SoundContext.cpp
+++ b/src/crepe/facade/SoundContext.cpp
@@ -1,4 +1,4 @@
-#include "../util/log.h"
+#include "../util/Log.h"
 
 #include "SoundContext.h"
 
diff --git a/src/crepe/system/AnimatorSystem.cpp b/src/crepe/system/AnimatorSystem.cpp
index bf45362..1c101fa 100644
--- a/src/crepe/system/AnimatorSystem.cpp
+++ b/src/crepe/system/AnimatorSystem.cpp
@@ -5,7 +5,7 @@
 
 #include "api/Animator.h"
 #include "facade/SDLContext.h"
-#include "util/log.h"
+#include "util/Log.h"
 
 #include "AnimatorSystem.h"
 #include "ComponentManager.h"
diff --git a/src/crepe/system/RenderSystem.cpp b/src/crepe/system/RenderSystem.cpp
index 10211a3..3ff5b4f 100644
--- a/src/crepe/system/RenderSystem.cpp
+++ b/src/crepe/system/RenderSystem.cpp
@@ -5,7 +5,7 @@
 #include "../api/Sprite.h"
 #include "../api/Transform.h"
 #include "../facade/SDLContext.h"
-#include "../util/log.h"
+#include "../util/Log.h"
 
 #include "RenderSystem.h"
 
diff --git a/src/crepe/system/ScriptSystem.cpp b/src/crepe/system/ScriptSystem.cpp
index f2673e7..aceb218 100644
--- a/src/crepe/system/ScriptSystem.cpp
+++ b/src/crepe/system/ScriptSystem.cpp
@@ -5,7 +5,7 @@
 #include "../ComponentManager.h"
 #include "../api/BehaviorScript.h"
 #include "../api/Script.h"
-#include "../util/log.h"
+#include "../util/Log.h"
 
 #include "ScriptSystem.h"
 
diff --git a/src/crepe/util/CMakeLists.txt b/src/crepe/util/CMakeLists.txt
index 0fa4343..4be738a 100644
--- a/src/crepe/util/CMakeLists.txt
+++ b/src/crepe/util/CMakeLists.txt
@@ -1,13 +1,12 @@
 target_sources(crepe PUBLIC
 	LogColor.cpp
-	log.cpp
-	fmt.cpp
+	Log.cpp
 )
 
 target_sources(crepe PUBLIC FILE_SET HEADERS FILES
 	LogColor.h
-	log.h
-	fmt.h
+	Log.h
+	Log.hpp
 	Proxy.h
 	Proxy.hpp
 )
diff --git a/src/crepe/util/Log.cpp b/src/crepe/util/Log.cpp
new file mode 100644
index 0000000..346e08e
--- /dev/null
+++ b/src/crepe/util/Log.cpp
@@ -0,0 +1,39 @@
+#include <cstdarg>
+#include <cstdio>
+#include <cstdlib>
+#include <string>
+
+#include "../api/Config.h"
+#include "Log.h"
+
+using namespace crepe;
+using namespace std;
+
+string Log::prefix(const Level & level) {
+	switch (level) {
+		case Level::TRACE:
+			return LogColor().fg_white().str("[TRACE]") + " ";
+		case Level::DEBUG:
+			return LogColor().fg_magenta().str("[DEBUG]") + " ";
+		case Level::INFO:
+			return LogColor().fg_blue().str("[INFO]") + " ";
+		case Level::WARNING:
+			return LogColor().fg_yellow().str("[WARN]") + " ";
+		case Level::ERROR:
+			return LogColor().fg_red().str("[ERROR]") + " ";
+	}
+	return "";
+}
+
+void Log::log(const Level & level, const string & msg) {
+	auto & cfg = Config::get_instance();
+	if (level < cfg.log.level) return;
+
+	string out = Log::prefix(level) + msg;
+	if (!out.ends_with("\n")) out += "\n";
+
+	// TODO: also log to file or smth
+	fwrite(out.c_str(), 1, out.size(), stdout);
+	fflush(stdout);
+}
+
diff --git a/src/crepe/util/Log.h b/src/crepe/util/Log.h
new file mode 100644
index 0000000..4e32e9d
--- /dev/null
+++ b/src/crepe/util/Log.h
@@ -0,0 +1,80 @@
+#pragma once
+
+#include <format>
+
+// allow user to disable debug macros
+#ifndef CREPE_DISABLE_MACROS
+
+#include "LogColor.h"
+
+// utility macros
+#define _crepe_logf_here(level, fmt, ...) crepe::Log::logf(level, "{}" fmt, crepe::LogColor().fg_white(false).str(std::format("{} ({}:{})", __PRETTY_FUNCTION__, __FILE_NAME__, __LINE__)), __VA_ARGS__)
+
+// very illegal global function-style macros
+// NOLINTBEGIN
+#define dbg_logf(fmt, ...) \
+	_crepe_logf_here(crepe::Log::Level::DEBUG, ": " fmt, __VA_ARGS__)
+#define dbg_log(str) _crepe_logf_here(crepe::Log::Level::DEBUG, ": {}", str)
+#define dbg_trace() _crepe_logf_here(crepe::Log::Level::TRACE, "", "")
+// NOLINTEND
+
+#endif
+
+namespace crepe {
+
+/**
+ * \brief Logging utility
+ *
+ * This class is used to output log messages to the console and/or log files.
+ */
+class Log {
+public:
+	//! Log message severity
+	enum Level {
+		TRACE, //< Include (internal) function calls
+		DEBUG, //< Include dbg_logf output
+		INFO, //< General-purpose messages
+		WARNING, //< Non-fatal errors
+		ERROR, //< Fatal errors
+	};
+
+	/**
+	 * \brief Log a formatted message
+	 *
+	 * \param level Message severity
+	 * \param msg Formatted message
+	 */
+	static void log(const Level & level, const std::string & msg);
+
+	/**
+	 * \brief Format a message and log it
+	 *
+	 * \param level Message severity
+	 * \param fmt Message format
+	 * \param args Format arguments
+	 */
+	template<class... Args>
+	static void logf(const Level & level, std::format_string<Args...> fmt, Args&&... args);
+
+	/**
+	 * \brief Format a message and log it (with default severity \c INFO)
+	 *
+	 * \param fmt Message format
+	 * \param args Format arguments
+	 */
+	template<class... Args>
+	static void logf(std::format_string<Args...> fmt, Args&&... args);
+
+private:
+	/**
+	 * \brief Output a message prefix depending on the log level
+	 *
+	 * \param level Message severity
+	 */
+	static std::string prefix(const Level & level);
+};
+
+} // namespace crepe
+
+#include "Log.hpp"
+
diff --git a/src/crepe/util/Log.hpp b/src/crepe/util/Log.hpp
new file mode 100644
index 0000000..58ba475
--- /dev/null
+++ b/src/crepe/util/Log.hpp
@@ -0,0 +1,18 @@
+#pragma once
+
+#include "Log.h"
+
+namespace crepe {
+
+template<class... Args>
+void Log::logf(std::format_string<Args...> fmt, Args&&... args) {
+	Log::logf(Level::INFO, fmt, std::forward<Args>(args)...);
+}
+
+template<class... Args>
+void Log::logf(const Level & level, std::format_string<Args...> fmt, Args&&... args) {
+	Log::log(level, std::format(fmt, std::forward<Args>(args)...));
+}
+
+}
+
diff --git a/src/crepe/util/LogColor.cpp b/src/crepe/util/LogColor.cpp
index b5fe3ea..ae44d72 100644
--- a/src/crepe/util/LogColor.cpp
+++ b/src/crepe/util/LogColor.cpp
@@ -3,14 +3,12 @@
 #include "../api/Config.h"
 #include "LogColor.h"
 
-#include "fmt.h"
-
 using namespace crepe;
 using namespace std;
 
 static constexpr const char * RESET_CODE = "\e[0m";
 
-const string LogColor::str(const string & content) {
+const string LogColor::str(const string & content) const {
 	auto & cfg = Config::get_instance();
 	string out = content;
 	if (cfg.log.color) out = this->code + out;
@@ -19,21 +17,8 @@ const string LogColor::str(const string & content) {
 	return out;
 }
 
-const char * LogColor::c_str(const char * content) {
-	this->final = this->str(content == NULL ? "" : content);
-	return this->final.c_str();
-}
-
-const char * LogColor::fmt(const char * fmt, ...) {
-	va_list args;
-	va_start(args, fmt);
-	string content = va_stringf(args, fmt);
-	va_end(args);
-	return this->c_str(content.c_str());
-}
-
 LogColor & LogColor::add_code(unsigned int code) {
-	this->code += stringf("\e[%dm", code);
+	this->code += format("\e[{}m", code);
 	return *this;
 }
 
diff --git a/src/crepe/util/LogColor.h b/src/crepe/util/LogColor.h
index c1170cb..4b65127 100644
--- a/src/crepe/util/LogColor.h
+++ b/src/crepe/util/LogColor.h
@@ -4,20 +4,19 @@
 
 namespace crepe {
 
+/**
+ * \brief Utility class for coloring text using ANSI escape codes
+ *
+ * \note Most methods in this class return a reference to \c this, which may be
+ * used to chain multiple display attributes.
+ */
 class LogColor {
 public:
-	LogColor() = default;
+	//! Get color code as stl string (or color content string)
+	const std::string str(const std::string & content = "") const;
 
 public:
-	//! get color code as c-style string (or color content string)
-	const char * c_str(const char * content = NULL);
-	//! color printf-style format string
-	const char * fmt(const char * fmt, ...);
-	//! get color code as stl string (or color content string)
-	const std::string str(const std::string & content = "");
-
-public:
-	//! reset color to default foreground and background color
+	//! Reset color to default foreground and background color
 	LogColor & reset();
 
 public:
@@ -41,11 +40,19 @@ public:
 	LogColor & bg_white(bool bright = false);
 
 private:
+	/**
+	 * \brief Append SGR escape sequence to \c this->code
+	 *
+	 * \param code SGR attribute number
+	 *
+	 * See <https://en.wikipedia.org/wiki/ANSI_escape_code> for magic number
+	 * reference.
+	 */
 	LogColor & add_code(unsigned int code);
 
 private:
+	//! Color escape sequence
 	std::string code = "";
-	std::string final = "";
 };
 
 } // namespace crepe
diff --git a/src/crepe/util/fmt.cpp b/src/crepe/util/fmt.cpp
deleted file mode 100644
index 4b50da8..0000000
--- a/src/crepe/util/fmt.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-#include <cstdarg>
-#include <cstdio>
-#include <string>
-
-#include "fmt.h"
-
-using namespace std;
-
-string crepe::va_stringf(va_list args, const char * fmt) {
-	string out;
-
-	va_list args_copy;
-	va_copy(args_copy, args);
-	size_t length = vsnprintf(NULL, 0, fmt, args_copy);
-	// resize to include terminating null byte
-	out.resize(length + 1);
-	va_end(args_copy);
-
-	// vsnprintf adds terminating null byte
-	vsnprintf(out.data(), out.size(), fmt, args);
-	// resize to actual length
-	out.resize(length);
-
-	va_end(args);
-
-	return out;
-}
-
-string crepe::stringf(const char * fmt, ...) {
-	va_list args;
-	va_start(args, fmt);
-	string out = va_stringf(args, fmt);
-	va_end(args);
-	return out;
-}
diff --git a/src/crepe/util/fmt.h b/src/crepe/util/fmt.h
deleted file mode 100644
index e319e6e..0000000
--- a/src/crepe/util/fmt.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#pragma once
-
-#include <string>
-
-namespace crepe {
-
-std::string va_stringf(va_list args, const char * fmt);
-std::string stringf(const char * fmt, ...);
-
-} // namespace crepe
diff --git a/src/crepe/util/log.cpp b/src/crepe/util/log.cpp
deleted file mode 100644
index 4a8f8e8..0000000
--- a/src/crepe/util/log.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-#include <cstdarg>
-#include <cstdio>
-#include <cstdlib>
-#include <string>
-
-#include "../api/Config.h"
-#include "fmt.h"
-#include "log.h"
-
-using namespace crepe;
-using namespace std;
-
-string log_prefix(LogLevel level) {
-	switch (level) {
-		case LogLevel::TRACE:
-			return LogColor().fg_white().str("[TRACE]") + " ";
-		case LogLevel::DEBUG:
-			return LogColor().fg_magenta().str("[DEBUG]") + " ";
-		case LogLevel::INFO:
-			return LogColor().fg_blue().str("[INFO]") + " ";
-		case LogLevel::WARNING:
-			return LogColor().fg_yellow().str("[WARN]") + " ";
-		case LogLevel::ERROR:
-			return LogColor().fg_red().str("[ERROR]") + " ";
-	}
-	return "";
-}
-
-static void log(LogLevel level, const string msg) {
-	auto & cfg = Config::get_instance();
-	if (level < cfg.log.level) return;
-
-	string out = log_prefix(level) + msg;
-	if (!out.ends_with("\n")) out += "\n";
-
-	// TODO: also log to file or smth
-	fwrite(out.c_str(), 1, out.size(), stdout);
-	fflush(stdout);
-}
-
-void crepe::logf(const char * fmt, ...) {
-	va_list args;
-	va_start(args, fmt);
-	log(LogLevel::DEBUG, va_stringf(args, fmt));
-	va_end(args);
-}
-
-void crepe::logf(LogLevel level, const char * fmt, ...) {
-	va_list args;
-	va_start(args, fmt);
-	log(level, va_stringf(args, fmt));
-	va_end(args);
-}
diff --git a/src/crepe/util/log.h b/src/crepe/util/log.h
deleted file mode 100644
index 5a1cf00..0000000
--- a/src/crepe/util/log.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#pragma once
-
-// allow user to disable debug macros
-#ifndef CREPE_DISABLE_MACROS
-
-#include "LogColor.h"
-
-// utility macros
-#define _crepe_logf_here(level, format, ...) \
-	crepe::logf( \
-		level, "%s" format, \
-		crepe::LogColor().fg_white(false).fmt( \
-			"%s (%s:%d)", __PRETTY_FUNCTION__, __FILE_NAME__, __LINE__), \
-		__VA_ARGS__)
-
-// very illegal global function-style macros
-// NOLINTBEGIN
-#define dbg_logf(fmt, ...) \
-	_crepe_logf_here(crepe::LogLevel::DEBUG, ": " fmt, __VA_ARGS__)
-#define dbg_log(str) _crepe_logf_here(crepe::LogLevel::DEBUG, "%s: " str, "")
-#define dbg_trace() _crepe_logf_here(crepe::LogLevel::TRACE, "%s", "")
-// NOLINTEND
-
-#endif
-
-namespace crepe {
-
-enum LogLevel {
-	TRACE,
-	DEBUG,
-	INFO,
-	WARNING,
-	ERROR,
-};
-
-void logf(const char * fmt, ...);
-void logf(enum LogLevel level, const char * fmt, ...);
-
-} // namespace crepe
diff --git a/src/example/log.cpp b/src/example/log.cpp
index db8aa48..13d592b 100644
--- a/src/example/log.cpp
+++ b/src/example/log.cpp
@@ -4,7 +4,7 @@
  */
 
 #include <crepe/api/Config.h>
-#include <crepe/util/log.h>
+#include <crepe/util/Log.h>
 
 using namespace crepe;
 
@@ -12,17 +12,18 @@ using namespace crepe;
 int _ = []() {
 	// make sure all log messages get printed
 	auto & cfg = Config::get_instance();
-	cfg.log.level = LogLevel::TRACE;
+	cfg.log.level = Log::Level::TRACE;
 
 	return 0; // satisfy compiler
 }();
 
 int main() {
 	dbg_trace();
-	dbg_logf("test printf parameters: %d", 3);
-	logf(LogLevel::INFO, "info message");
-	logf(LogLevel::WARNING, "warning");
-	logf(LogLevel::ERROR, "error");
+	dbg_log("debug message");
+	Log::logf("info message with variable: {}", 3);
+	Log::logf(Log::Level::WARNING, "warning");
+	Log::logf(Log::Level::ERROR, "error");
+	
 
 	return 0;
 }
-- 
cgit v1.2.3


From 202725f481e64c4d95e370102ab93d4f8cf4af93 Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Wed, 13 Nov 2024 14:51:02 +0100
Subject: incorporate feedback on #26

---
 src/crepe/Asset.cpp               | 13 +++++++------
 src/crepe/Asset.h                 | 18 +++++++++++++-----
 src/crepe/api/BehaviorScript.h    |  2 +-
 src/crepe/system/ScriptSystem.cpp |  2 +-
 src/crepe/system/ScriptSystem.h   |  2 +-
 5 files changed, 23 insertions(+), 14 deletions(-)

(limited to 'src')

diff --git a/src/crepe/Asset.cpp b/src/crepe/Asset.cpp
index 8a2a11c..4affd58 100644
--- a/src/crepe/Asset.cpp
+++ b/src/crepe/Asset.cpp
@@ -3,14 +3,15 @@
 #include "Asset.h"
 
 using namespace crepe;
+using namespace std;
 
-Asset::Asset(const std::string & src) {
-	// FIXME: restore this
-	// this->src = std::filesystem::canonical(src);
-	this->src = src;
+// FIXME: restore this
+// src(std::filesystem::canonical(src))
+Asset::Asset(const std::string & src) : src(src) {
 	this->file = std::ifstream(this->src, std::ios::in | std::ios::binary);
 }
 
-const std::istream & Asset::read() { return this->file; }
+istream & Asset::get_stream() { return this->file; }
+
+const string & Asset::get_canonical() const { return this->src; }
 
-const char * Asset::canonical() { return this->src.c_str(); }
diff --git a/src/crepe/Asset.h b/src/crepe/Asset.h
index 0cb5834..cb413f4 100644
--- a/src/crepe/Asset.h
+++ b/src/crepe/Asset.h
@@ -20,13 +20,21 @@ public:
 	Asset(const std::string & src);
 
 public:
-	//! Get an input stream to the contents of this resource
-	const std::istream & read();
-	//! Get the canonical path to this resource
-	const char * canonical();
+	/**
+	 * \brief Get an input stream to the contents of this asset
+	 * \return Input stream with file contents
+	 */
+	std::istream & get_stream();
+	/**
+	 * \brief Get the canonical path to this asset
+	 * \return Canonical path to this asset
+	 */
+	const std::string & get_canonical() const;
 
 private:
-	std::string src;
+	//! Canonical path to asset
+	const std::string src;
+	//! File handle (stream)
 	std::ifstream file;
 };
 
diff --git a/src/crepe/api/BehaviorScript.h b/src/crepe/api/BehaviorScript.h
index 6b1fec7..c20842d 100644
--- a/src/crepe/api/BehaviorScript.h
+++ b/src/crepe/api/BehaviorScript.h
@@ -16,7 +16,7 @@ protected:
 	using Component::Component;
 
 public:
-	virtual ~BehaviorScript() = default;
+	~BehaviorScript() = default;
 
 public:
 	template <class T>
diff --git a/src/crepe/system/ScriptSystem.cpp b/src/crepe/system/ScriptSystem.cpp
index aceb218..807ad7f 100644
--- a/src/crepe/system/ScriptSystem.cpp
+++ b/src/crepe/system/ScriptSystem.cpp
@@ -20,7 +20,7 @@ void ScriptSystem::update() {
 	for (Script * script : scripts) script->update();
 }
 
-forward_list<Script *> ScriptSystem::get_scripts() {
+forward_list<Script *> ScriptSystem::get_scripts() const {
 	forward_list<Script *> scripts = {};
 	ComponentManager & mgr = ComponentManager::get_instance();
 	vector<reference_wrapper<BehaviorScript>> behavior_scripts
diff --git a/src/crepe/system/ScriptSystem.h b/src/crepe/system/ScriptSystem.h
index 4fa6141..f3d26d4 100644
--- a/src/crepe/system/ScriptSystem.h
+++ b/src/crepe/system/ScriptSystem.h
@@ -14,7 +14,7 @@ public:
 
 private:
 	// TODO: to forward_list<reference_wrapper>
-	std::forward_list<Script *> get_scripts();
+	std::forward_list<Script *> get_scripts() const;
 };
 
 } // namespace crepe
-- 
cgit v1.2.3


From 7ec392eda3345606f0de75a432954b221cee82ce Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Wed, 13 Nov 2024 15:40:01 +0100
Subject: add doxygen + check const correctness

---
 src/crepe/api/BehaviorScript.h      |  8 ++++++++
 src/crepe/api/Config.h              |  3 +--
 src/crepe/api/Script.h              | 40 +++++++++++++++++++++++++++++++++++--
 src/crepe/api/Script.hpp            |  8 +++++---
 src/crepe/api/Texture.cpp           |  2 +-
 src/crepe/facade/Sound.cpp          |  9 +++++----
 src/crepe/facade/Sound.h            |  6 ++++++
 src/crepe/facade/SoundContext.h     | 11 +++++++---
 src/crepe/system/PhysicsSystem.h    |  1 +
 src/crepe/system/ScriptSystem.h     | 19 ++++++++++++++++++
 src/crepe/system/System.h           | 10 ++++++++++
 src/example/audio_internal.cpp      |  4 ++--
 src/example/components_internal.cpp |  2 +-
 src/example/db.cpp                  |  8 ++++----
 src/example/proxy.cpp               |  9 ++++-----
 src/example/rendering.cpp           |  2 +-
 src/example/savemgr.cpp             | 16 +++++++--------
 src/example/script.cpp              |  6 +++---
 18 files changed, 125 insertions(+), 39 deletions(-)

(limited to 'src')

diff --git a/src/crepe/api/BehaviorScript.h b/src/crepe/api/BehaviorScript.h
index c20842d..4160a72 100644
--- a/src/crepe/api/BehaviorScript.h
+++ b/src/crepe/api/BehaviorScript.h
@@ -10,6 +10,13 @@ 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;
@@ -24,6 +31,7 @@ public:
 
 protected:
 	friend class crepe::ScriptSystem;
+	//! Script instance
 	std::unique_ptr<Script> script = nullptr;
 };
 
diff --git a/src/crepe/api/Config.h b/src/crepe/api/Config.h
index 8fd381e..dad7e08 100644
--- a/src/crepe/api/Config.h
+++ b/src/crepe/api/Config.h
@@ -7,7 +7,6 @@ namespace crepe {
 class Config {
 private:
 	Config() = default;
-
 public:
 	~Config() = default;
 
@@ -26,7 +25,7 @@ public:
 		/**
 		 * \brief Log level
 		 *
-		 * Only messages with equal or higher priority than this value will be
+		 * Only messages with equal or higher severity than this value will be
 		 * logged.
 		 */
 		Log::Level level = Log::Level::INFO;
diff --git a/src/crepe/api/Script.h b/src/crepe/api/Script.h
index ed247ad..e6fbb5c 100644
--- a/src/crepe/api/Script.h
+++ b/src/crepe/api/Script.h
@@ -7,11 +7,30 @@ namespace crepe {
 class ScriptSystem;
 class BehaviorScript;
 
+/**
+ * \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.
+ */
 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
@@ -19,11 +38,28 @@ protected:
 	// added event.
 
 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;
 
+	/**
+	 * \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;
 
 private:
 	friend class crepe::BehaviorScript;
diff --git a/src/crepe/api/Script.hpp b/src/crepe/api/Script.hpp
index d96c0e8..afe653f 100644
--- a/src/crepe/api/Script.hpp
+++ b/src/crepe/api/Script.hpp
@@ -1,6 +1,7 @@
 #pragma once
 
 #include "../ComponentManager.h"
+#include "../Exception.h"
 
 #include "BehaviorScript.h"
 #include "Script.h"
@@ -8,16 +9,17 @@
 namespace crepe {
 
 template <typename T>
-T & Script::get_component() {
+T & Script::get_component() const {
 	std::vector<std::reference_wrapper<T>> all_components
 		= this->get_components<T>();
-	if (all_components.size() < 1) throw nullptr; // TODO
+	if (all_components.size() < 1)
+		throw Exception("Script: no component found with type = %s", typeid(T).name());
 
 	return all_components.back().get();
 }
 
 template <typename T>
-std::vector<std::reference_wrapper<T>> Script::get_components() {
+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);
 }
diff --git a/src/crepe/api/Texture.cpp b/src/crepe/api/Texture.cpp
index 8ddeac5..de0d0ea 100644
--- a/src/crepe/api/Texture.cpp
+++ b/src/crepe/api/Texture.cpp
@@ -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/facade/Sound.cpp b/src/crepe/facade/Sound.cpp
index 49fb8dc..a65b052 100644
--- a/src/crepe/facade/Sound.cpp
+++ b/src/crepe/facade/Sound.cpp
@@ -4,19 +4,20 @@
 #include "SoundContext.h"
 
 using namespace crepe;
+using namespace std;
 
-Sound::Sound(std::unique_ptr<Asset> res) {
+Sound::Sound(unique_ptr<Asset> res) {
 	dbg_trace();
 	this->load(std::move(res));
 }
 
 Sound::Sound(const char * src) {
 	dbg_trace();
-	this->load(std::make_unique<Asset>(src));
+	this->load(make_unique<Asset>(src));
 }
 
-void Sound::load(std::unique_ptr<Asset> res) {
-	this->sample.load(res->canonical());
+void Sound::load(unique_ptr<Asset> res) {
+	this->sample.load(res->get_canonical().c_str());
 }
 
 void Sound::play() {
diff --git a/src/crepe/facade/Sound.h b/src/crepe/facade/Sound.h
index 183bd7c..402482f 100644
--- a/src/crepe/facade/Sound.h
+++ b/src/crepe/facade/Sound.h
@@ -8,6 +8,12 @@
 
 namespace crepe {
 
+/**
+ * \brief Sound resource facade
+ *
+ * This class is a wrapper around a \c SoLoud::Wav instance, which holds a
+ * single sample. It is part of the sound facade.
+ */
 class Sound {
 public:
 	/**
diff --git a/src/crepe/facade/SoundContext.h b/src/crepe/facade/SoundContext.h
index d3123d2..d703c16 100644
--- a/src/crepe/facade/SoundContext.h
+++ b/src/crepe/facade/SoundContext.h
@@ -6,19 +6,24 @@
 
 namespace crepe {
 
+/**
+ * \brief Sound engine facade
+ *
+ * This class is a wrapper around a \c SoLoud::Soloud instance, which provides
+ * the methods for playing \c Sound instances. It is part of the sound facade.
+ */
 class SoundContext {
 private:
+	// singleton
 	SoundContext();
 	virtual ~SoundContext();
-
-	// singleton
-	static SoundContext & get_instance();
 	SoundContext(const SoundContext &) = delete;
 	SoundContext(SoundContext &&) = delete;
 	SoundContext & operator=(const SoundContext &) = delete;
 	SoundContext & operator=(SoundContext &&) = delete;
 
 private:
+	static SoundContext & get_instance();
 	SoLoud::Soloud engine;
 	friend class Sound;
 };
diff --git a/src/crepe/system/PhysicsSystem.h b/src/crepe/system/PhysicsSystem.h
index cc13b70..cb6160e 100644
--- a/src/crepe/system/PhysicsSystem.h
+++ b/src/crepe/system/PhysicsSystem.h
@@ -1,6 +1,7 @@
 #pragma once
 
 namespace crepe {
+
 /**
  * \brief System that controls all physics
  * 
diff --git a/src/crepe/system/ScriptSystem.h b/src/crepe/system/ScriptSystem.h
index f3d26d4..9d57640 100644
--- a/src/crepe/system/ScriptSystem.h
+++ b/src/crepe/system/ScriptSystem.h
@@ -8,12 +8,31 @@ namespace crepe {
 
 class Script;
 
+/**
+ * \brief Script system
+ * 
+ * The script system is responsible for all \c BehaviorScript components, and
+ * calls the methods on classes derived from \c Script.
+ */
 class ScriptSystem : public System {
 public:
+	/**
+	 * \brief Call Script::update() on all active \c BehaviorScript instances
+	 *
+	 * This routine updates all scripts sequentially using the Script::update()
+	 * method. It also calls Script::init() if this has not been done before on
+	 * the \c BehaviorScript instance.
+	 */
 	void update();
 
 private:
 	// TODO: to forward_list<reference_wrapper>
+	/**
+	 * \brief Aggregate all active \c BehaviorScript components and return a list
+	 * of references to their \c Script instances (utility)
+	 *
+	 * \returns List of active \c Script instances
+	 */
 	std::forward_list<Script *> get_scripts() const;
 };
 
diff --git a/src/crepe/system/System.h b/src/crepe/system/System.h
index 3b81bef..ec4507f 100644
--- a/src/crepe/system/System.h
+++ b/src/crepe/system/System.h
@@ -2,8 +2,18 @@
 
 namespace crepe {
 
+/**
+ * \brief Base ECS system class
+ *
+ * This class is used as the base for all system classes. Classes derived from
+ * System must implement the System::update() method and copy Script::Script
+ * with the `using`-syntax.
+ */
 class System {
 public:
+	/**
+	 * \brief Process all components this system is responsible for.
+	 */
 	virtual void update() = 0;
 
 public:
diff --git a/src/example/audio_internal.cpp b/src/example/audio_internal.cpp
index 1ea839d..ff55a59 100644
--- a/src/example/audio_internal.cpp
+++ b/src/example/audio_internal.cpp
@@ -5,7 +5,7 @@
 
 #include <crepe/api/Config.h>
 #include <crepe/facade/Sound.h>
-#include <crepe/util/log.h>
+#include <crepe/util/Log.h>
 
 #include <thread>
 
@@ -18,7 +18,7 @@ using std::make_unique;
 int _ = []() {
 	// Show dbg_trace() output
 	auto & cfg = Config::get_instance();
-	cfg.log.level = LogLevel::TRACE;
+	cfg.log.level = Log::Level::TRACE;
 
 	return 0; // satisfy compiler
 }();
diff --git a/src/example/components_internal.cpp b/src/example/components_internal.cpp
index ea1eaad..f7e395b 100644
--- a/src/example/components_internal.cpp
+++ b/src/example/components_internal.cpp
@@ -13,7 +13,7 @@
 #include <crepe/api/Rigidbody.h>
 #include <crepe/api/Sprite.h>
 
-#include <crepe/util/log.h>
+#include <crepe/util/Log.h>
 
 using namespace crepe;
 using namespace std;
diff --git a/src/example/db.cpp b/src/example/db.cpp
index 8c06a84..ee4e8fc 100644
--- a/src/example/db.cpp
+++ b/src/example/db.cpp
@@ -1,6 +1,6 @@
 #include <crepe/api/Config.h>
 #include <crepe/facade/DB.h>
-#include <crepe/util/log.h>
+#include <crepe/util/Log.h>
 
 using namespace crepe;
 using namespace std;
@@ -8,7 +8,7 @@ using namespace std;
 // run before main
 static auto _ = []() {
 	auto & cfg = Config::get_instance();
-	cfg.log.level = LogLevel::TRACE;
+	cfg.log.level = Log::Level::TRACE;
 	return 0;
 }();
 
@@ -20,11 +20,11 @@ int main() {
 	const char * test_key = "test-key";
 	string test_data = "Hello world!";
 
-	dbg_logf("DB has key = %d", db.has(test_key));
+	dbg_logf("DB has key = {}", db.has(test_key));
 
 	db.set(test_key, test_data);
 
-	dbg_logf("key = \"%s\"", db.get(test_key).c_str());
+	dbg_logf("key = \"{}\"", db.get(test_key));
 
 	return 0;
 }
diff --git a/src/example/proxy.cpp b/src/example/proxy.cpp
index 0afff41..ca68d9a 100644
--- a/src/example/proxy.cpp
+++ b/src/example/proxy.cpp
@@ -6,7 +6,7 @@
 #include <crepe/ValueBroker.h>
 #include <crepe/api/Config.h>
 #include <crepe/util/Proxy.h>
-#include <crepe/util/log.h>
+#include <crepe/util/Log.h>
 
 using namespace std;
 using namespace crepe;
@@ -17,18 +17,17 @@ void test_ro_val(int val) {}
 
 int main() {
 	auto & cfg = Config::get_instance();
-	cfg.log.level = LogLevel::DEBUG;
+	cfg.log.level = Log::Level::DEBUG;
 
 	int real_value = 0;
 
 	ValueBroker<int> broker{
 		[&real_value](const int & target) {
-			dbg_logf("set %s to %s", to_string(real_value).c_str(),
-					 to_string(target).c_str());
+			dbg_logf("set {} to {}", real_value, target);
 			real_value = target;
 		},
 		[&real_value]() -> const int & {
-			dbg_logf("get %s", to_string(real_value).c_str());
+			dbg_logf("get {}", real_value);
 			return real_value;
 		},
 	};
diff --git a/src/example/rendering.cpp b/src/example/rendering.cpp
index d554a8a..cbd7de7 100644
--- a/src/example/rendering.cpp
+++ b/src/example/rendering.cpp
@@ -1,7 +1,7 @@
 #include <crepe/ComponentManager.h>
 #include <crepe/api/GameObject.h>
 #include <crepe/system/RenderSystem.h>
-#include <crepe/util/log.h>
+#include <crepe/util/Log.h>
 
 #include <crepe/api/AssetManager.h>
 #include <crepe/api/Color.h>
diff --git a/src/example/savemgr.cpp b/src/example/savemgr.cpp
index 436fb5a..5a415b7 100644
--- a/src/example/savemgr.cpp
+++ b/src/example/savemgr.cpp
@@ -7,7 +7,7 @@
 #include <crepe/api/Config.h>
 #include <crepe/api/SaveManager.h>
 #include <crepe/util/Proxy.h>
-#include <crepe/util/log.h>
+#include <crepe/util/Log.h>
 
 using namespace crepe;
 
@@ -15,7 +15,7 @@ using namespace crepe;
 int _ = []() {
 	// make sure all log messages get printed
 	auto & cfg = Config::get_instance();
-	cfg.log.level = LogLevel::TRACE;
+	cfg.log.level = Log::Level::TRACE;
 
 	return 0; // satisfy compiler
 }();
@@ -25,19 +25,19 @@ int main() {
 
 	SaveManager & mgr = SaveManager::get_instance();
 
-	dbg_logf("has key = %s", mgr.has(key) ? "true" : "false");
+	dbg_logf("has key = {}", mgr.has(key));
 	ValueBroker<int> prop = mgr.get<int>(key, 0);
 	Proxy<int> val = mgr.get<int>(key, 0);
 
-	dbg_logf("val = %d", mgr.get<int>(key).get());
+	dbg_logf("val = {}", mgr.get<int>(key).get());
 	prop.set(1);
-	dbg_logf("val = %d", mgr.get<int>(key).get());
+	dbg_logf("val = {}", mgr.get<int>(key).get());
 	val = 2;
-	dbg_logf("val = %d", mgr.get<int>(key).get());
+	dbg_logf("val = {}", mgr.get<int>(key).get());
 	mgr.set<int>(key, 3);
-	dbg_logf("val = %d", mgr.get<int>(key).get());
+	dbg_logf("val = {}", mgr.get<int>(key).get());
 
-	dbg_logf("has key = %s", mgr.has(key) ? "true" : "false");
+	dbg_logf("has key = {}", mgr.has(key));
 	assert(true == mgr.has(key));
 
 	return 0;
diff --git a/src/example/script.cpp b/src/example/script.cpp
index 9e8b147..d1388b5 100644
--- a/src/example/script.cpp
+++ b/src/example/script.cpp
@@ -5,7 +5,7 @@
 
 #include <crepe/ComponentManager.h>
 #include <crepe/system/ScriptSystem.h>
-#include <crepe/util/log.h>
+#include <crepe/util/Log.h>
 
 #include <crepe/api/BehaviorScript.h>
 #include <crepe/api/Config.h>
@@ -20,7 +20,7 @@ using namespace std;
 int _ = []() {
 	// Show dbg_trace() output
 	auto & cfg = Config::get_instance();
-	cfg.log.level = LogLevel::TRACE;
+	cfg.log.level = Log::Level::TRACE;
 
 	return 0; // satisfy compiler
 }();
@@ -30,7 +30,7 @@ class MyScript : public Script {
 	void update() {
 		// Retrieve component from the same GameObject this script is on
 		Transform & test = get_component<Transform>();
-		dbg_logf("Transform(%.2f, %.2f)", test.position.x, test.position.y);
+		dbg_logf("Transform({:.2f}, {:.2f})", test.position.x, test.position.y);
 	}
 };
 
-- 
cgit v1.2.3


From 5e59c22f77073fdf49bf98697da6a68819eb5776 Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Wed, 13 Nov 2024 15:50:13 +0100
Subject: `make format`

---
 src/crepe/Asset.cpp      |  1 -
 src/crepe/Exception.cpp  |  5 +----
 src/crepe/Exception.h    |  7 +++----
 src/crepe/Exception.hpp  |  7 +++----
 src/crepe/api/Config.h   |  1 +
 src/crepe/api/Script.hpp |  3 ++-
 src/crepe/util/Log.cpp   |  1 -
 src/crepe/util/Log.h     | 17 +++++++++++------
 src/crepe/util/Log.hpp   | 12 ++++++------
 src/example/log.cpp      |  1 -
 src/example/proxy.cpp    |  2 +-
 src/example/savemgr.cpp  |  2 +-
 12 files changed, 29 insertions(+), 30 deletions(-)

(limited to 'src')

diff --git a/src/crepe/Asset.cpp b/src/crepe/Asset.cpp
index 4affd58..9c41ecb 100644
--- a/src/crepe/Asset.cpp
+++ b/src/crepe/Asset.cpp
@@ -14,4 +14,3 @@ Asset::Asset(const std::string & src) : src(src) {
 istream & Asset::get_stream() { return this->file; }
 
 const string & Asset::get_canonical() const { return this->src; }
-
diff --git a/src/crepe/Exception.cpp b/src/crepe/Exception.cpp
index 3217169..5a24e7e 100644
--- a/src/crepe/Exception.cpp
+++ b/src/crepe/Exception.cpp
@@ -5,7 +5,4 @@ using namespace std;
 
 const char * Exception::what() const noexcept { return error.c_str(); }
 
-Exception::Exception(const string & msg) {
-	this->error = msg;
-}
-
+Exception::Exception(const string & msg) { this->error = msg; }
diff --git a/src/crepe/Exception.h b/src/crepe/Exception.h
index ed3ab15..580fc16 100644
--- a/src/crepe/Exception.h
+++ b/src/crepe/Exception.h
@@ -1,8 +1,8 @@
 #pragma once
 
 #include <exception>
-#include <string>
 #include <format>
+#include <string>
 
 namespace crepe {
 
@@ -13,8 +13,8 @@ public:
 	Exception(const std::string & msg);
 
 	//! Exception with \c std::format message
-	template<class... Args>
-	Exception(std::format_string<Args...> fmt, Args&&... args);
+	template <class... Args>
+	Exception(std::format_string<Args...> fmt, Args &&... args);
 
 	//! Get formatted error message
 	const char * what() const noexcept;
@@ -29,4 +29,3 @@ protected:
 } // namespace crepe
 
 #include "Exception.hpp"
-
diff --git a/src/crepe/Exception.hpp b/src/crepe/Exception.hpp
index d813879..7c462a3 100644
--- a/src/crepe/Exception.hpp
+++ b/src/crepe/Exception.hpp
@@ -4,10 +4,9 @@
 
 namespace crepe {
 
-template<class... Args>
-Exception::Exception(std::format_string<Args...> fmt, Args&&... args) {
+template <class... Args>
+Exception::Exception(std::format_string<Args...> fmt, Args &&... args) {
 	this->error = std::format(fmt, std::forward<Args>(args)...);
 }
 
-}
-
+} // namespace crepe
diff --git a/src/crepe/api/Config.h b/src/crepe/api/Config.h
index dad7e08..e3f86bf 100644
--- a/src/crepe/api/Config.h
+++ b/src/crepe/api/Config.h
@@ -7,6 +7,7 @@ namespace crepe {
 class Config {
 private:
 	Config() = default;
+
 public:
 	~Config() = default;
 
diff --git a/src/crepe/api/Script.hpp b/src/crepe/api/Script.hpp
index afe653f..d755fda 100644
--- a/src/crepe/api/Script.hpp
+++ b/src/crepe/api/Script.hpp
@@ -13,7 +13,8 @@ T & Script::get_component() const {
 	std::vector<std::reference_wrapper<T>> all_components
 		= this->get_components<T>();
 	if (all_components.size() < 1)
-		throw Exception("Script: no component found with type = %s", typeid(T).name());
+		throw Exception("Script: no component found with type = %s",
+						typeid(T).name());
 
 	return all_components.back().get();
 }
diff --git a/src/crepe/util/Log.cpp b/src/crepe/util/Log.cpp
index 346e08e..e583734 100644
--- a/src/crepe/util/Log.cpp
+++ b/src/crepe/util/Log.cpp
@@ -36,4 +36,3 @@ void Log::log(const Level & level, const string & msg) {
 	fwrite(out.c_str(), 1, out.size(), stdout);
 	fflush(stdout);
 }
-
diff --git a/src/crepe/util/Log.h b/src/crepe/util/Log.h
index 4e32e9d..01452b2 100644
--- a/src/crepe/util/Log.h
+++ b/src/crepe/util/Log.h
@@ -8,7 +8,12 @@
 #include "LogColor.h"
 
 // utility macros
-#define _crepe_logf_here(level, fmt, ...) crepe::Log::logf(level, "{}" fmt, crepe::LogColor().fg_white(false).str(std::format("{} ({}:{})", __PRETTY_FUNCTION__, __FILE_NAME__, __LINE__)), __VA_ARGS__)
+#define _crepe_logf_here(level, fmt, ...) \
+	crepe::Log::logf( \
+		level, "{}" fmt, \
+		crepe::LogColor().fg_white(false).str(std::format( \
+			"{} ({}:{})", __PRETTY_FUNCTION__, __FILE_NAME__, __LINE__)), \
+		__VA_ARGS__)
 
 // very illegal global function-style macros
 // NOLINTBEGIN
@@ -53,8 +58,9 @@ public:
 	 * \param fmt Message format
 	 * \param args Format arguments
 	 */
-	template<class... Args>
-	static void logf(const Level & level, std::format_string<Args...> fmt, Args&&... args);
+	template <class... Args>
+	static void logf(const Level & level, std::format_string<Args...> fmt,
+					 Args &&... args);
 
 	/**
 	 * \brief Format a message and log it (with default severity \c INFO)
@@ -62,8 +68,8 @@ public:
 	 * \param fmt Message format
 	 * \param args Format arguments
 	 */
-	template<class... Args>
-	static void logf(std::format_string<Args...> fmt, Args&&... args);
+	template <class... Args>
+	static void logf(std::format_string<Args...> fmt, Args &&... args);
 
 private:
 	/**
@@ -77,4 +83,3 @@ private:
 } // namespace crepe
 
 #include "Log.hpp"
-
diff --git a/src/crepe/util/Log.hpp b/src/crepe/util/Log.hpp
index 58ba475..651f076 100644
--- a/src/crepe/util/Log.hpp
+++ b/src/crepe/util/Log.hpp
@@ -4,15 +4,15 @@
 
 namespace crepe {
 
-template<class... Args>
-void Log::logf(std::format_string<Args...> fmt, Args&&... args) {
+template <class... Args>
+void Log::logf(std::format_string<Args...> fmt, Args &&... args) {
 	Log::logf(Level::INFO, fmt, std::forward<Args>(args)...);
 }
 
-template<class... Args>
-void Log::logf(const Level & level, std::format_string<Args...> fmt, Args&&... args) {
+template <class... Args>
+void Log::logf(const Level & level, std::format_string<Args...> fmt,
+			   Args &&... args) {
 	Log::log(level, std::format(fmt, std::forward<Args>(args)...));
 }
 
-}
-
+} // namespace crepe
diff --git a/src/example/log.cpp b/src/example/log.cpp
index 13d592b..5baa021 100644
--- a/src/example/log.cpp
+++ b/src/example/log.cpp
@@ -23,7 +23,6 @@ int main() {
 	Log::logf("info message with variable: {}", 3);
 	Log::logf(Log::Level::WARNING, "warning");
 	Log::logf(Log::Level::ERROR, "error");
-	
 
 	return 0;
 }
diff --git a/src/example/proxy.cpp b/src/example/proxy.cpp
index ca68d9a..69451f8 100644
--- a/src/example/proxy.cpp
+++ b/src/example/proxy.cpp
@@ -5,8 +5,8 @@
 
 #include <crepe/ValueBroker.h>
 #include <crepe/api/Config.h>
-#include <crepe/util/Proxy.h>
 #include <crepe/util/Log.h>
+#include <crepe/util/Proxy.h>
 
 using namespace std;
 using namespace crepe;
diff --git a/src/example/savemgr.cpp b/src/example/savemgr.cpp
index 5a415b7..65c4a34 100644
--- a/src/example/savemgr.cpp
+++ b/src/example/savemgr.cpp
@@ -6,8 +6,8 @@
 #include <cassert>
 #include <crepe/api/Config.h>
 #include <crepe/api/SaveManager.h>
-#include <crepe/util/Proxy.h>
 #include <crepe/util/Log.h>
+#include <crepe/util/Proxy.h>
 
 using namespace crepe;
 
-- 
cgit v1.2.3


From 78c370bd6cb37c156d06e098fe4e555a9da9dcee Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Wed, 13 Nov 2024 15:52:57 +0100
Subject: fix format strings w/o printf

---
 src/crepe/api/Script.hpp        |  2 +-
 src/crepe/facade/DB.cpp         | 10 +++++-----
 src/crepe/facade/SDLContext.cpp |  4 ++--
 3 files changed, 8 insertions(+), 8 deletions(-)

(limited to 'src')

diff --git a/src/crepe/api/Script.hpp b/src/crepe/api/Script.hpp
index d755fda..7ec3ebe 100644
--- a/src/crepe/api/Script.hpp
+++ b/src/crepe/api/Script.hpp
@@ -13,7 +13,7 @@ T & Script::get_component() const {
 	std::vector<std::reference_wrapper<T>> all_components
 		= this->get_components<T>();
 	if (all_components.size() < 1)
-		throw Exception("Script: no component found with type = %s",
+		throw Exception("Script: no component found with type = {}",
 						typeid(T).name());
 
 	return all_components.back().get();
diff --git a/src/crepe/facade/DB.cpp b/src/crepe/facade/DB.cpp
index ec6191b..80047a6 100644
--- a/src/crepe/facade/DB.cpp
+++ b/src/crepe/facade/DB.cpp
@@ -15,18 +15,18 @@ DB::DB(const string & path) {
 	// init database struct
 	libdb::DB * db;
 	if ((ret = libdb::db_create(&db, NULL, 0)) != 0)
-		throw Exception("db_create: %s", libdb::db_strerror(ret));
+		throw Exception("db_create: {}", libdb::db_strerror(ret));
 	this->db = {db, [](libdb::DB * db) { db->close(db, 0); }};
 
 	// load or create database file
 	ret = this->db->open(this->db.get(), NULL, path.c_str(), NULL,
 						 libdb::DB_BTREE, DB_CREATE, 0);
-	if (ret != 0) throw Exception("db->open: %s", libdb::db_strerror(ret));
+	if (ret != 0) throw Exception("db->open: {}", libdb::db_strerror(ret));
 
 	// create cursor
 	libdb::DBC * cursor;
 	ret = this->db->cursor(this->db.get(), NULL, &cursor, 0);
-	if (ret != 0) throw Exception("db->cursor: %s", libdb::db_strerror(ret));
+	if (ret != 0) throw Exception("db->cursor: {}", libdb::db_strerror(ret));
 	this->cursor = {cursor, [](libdb::DBC * cursor) { cursor->close(cursor); }};
 }
 
@@ -44,7 +44,7 @@ string DB::get(const string & key) {
 	memset(&db_val, 0, sizeof(libdb::DBT));
 
 	int ret = this->cursor->get(this->cursor.get(), &db_key, &db_val, DB_FIRST);
-	if (ret != 0) throw Exception("cursor->get: %s", libdb::db_strerror(ret));
+	if (ret != 0) throw Exception("cursor->get: {}", libdb::db_strerror(ret));
 	return {static_cast<char *>(db_val.data), db_val.size};
 }
 
@@ -52,7 +52,7 @@ void DB::set(const string & key, const string & value) {
 	libdb::DBT db_key = this->to_thing(key);
 	libdb::DBT db_val = this->to_thing(value);
 	int ret = this->db->put(this->db.get(), NULL, &db_key, &db_val, 0);
-	if (ret != 0) throw Exception("cursor->get: %s", libdb::db_strerror(ret));
+	if (ret != 0) throw Exception("cursor->get: {}", libdb::db_strerror(ret));
 }
 
 bool DB::has(const std::string & key) noexcept {
diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp
index a28f7bd..1cb2936 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) {
-		throw Exception("surface cannot be load from %s", path.c_str());
+		throw Exception("surface cannot be load from {}", path);
 	}
 
 	std::unique_ptr<SDL_Surface, std::function<void(SDL_Surface *)>>
@@ -171,7 +171,7 @@ SDLContext::texture_from_path(const std::string & path) {
 		this->game_renderer.get(), img_surface.get());
 
 	if (tmp_texture == nullptr) {
-		throw Exception("Texture cannot be load from %s", path.c_str());
+		throw Exception("Texture cannot be load from {}", path);
 	}
 
 	std::unique_ptr<SDL_Texture, std::function<void(SDL_Texture *)>>
-- 
cgit v1.2.3


From bc2a31190b5afe7754b04e9c61fcda30e577d7d8 Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Wed, 13 Nov 2024 16:27:03 +0100
Subject: `make format`

---
 src/crepe/system/ScriptSystem.cpp | 1 -
 1 file changed, 1 deletion(-)

(limited to 'src')

diff --git a/src/crepe/system/ScriptSystem.cpp b/src/crepe/system/ScriptSystem.cpp
index 7b22533..f4a826b 100644
--- a/src/crepe/system/ScriptSystem.cpp
+++ b/src/crepe/system/ScriptSystem.cpp
@@ -43,4 +43,3 @@ forward_list<reference_wrapper<Script>> ScriptSystem::get_scripts() const {
 
 	return scripts;
 }
-
-- 
cgit v1.2.3


From 0aa97807cb9b7f1d1850449dd5a5e45b961445ce Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Wed, 13 Nov 2024 18:46:06 +0100
Subject: fix scene_manager example

---
 src/crepe/ComponentManager.cpp      |  8 +++-----
 src/crepe/ComponentManager.h        |  2 +-
 src/crepe/api/Scene.cpp             |  2 +-
 src/crepe/api/Scene.h               | 10 ++++++++--
 src/crepe/api/SceneManager.hpp      |  9 ++++++---
 src/example/components_internal.cpp |  2 +-
 src/example/ecs.cpp                 | 15 +++++----------
 src/example/physics.cpp             |  3 +--
 src/example/rendering.cpp           |  6 +++---
 src/example/scene_manager.cpp       | 25 +++++++++++++++----------
 src/example/script.cpp              |  2 +-
 11 files changed, 45 insertions(+), 39 deletions(-)

(limited to 'src')

diff --git a/src/crepe/ComponentManager.cpp b/src/crepe/ComponentManager.cpp
index c6b658c..1e23609 100644
--- a/src/crepe/ComponentManager.cpp
+++ b/src/crepe/ComponentManager.cpp
@@ -25,13 +25,11 @@ void ComponentManager::delete_all_components() {
 ComponentManager::ComponentManager() { dbg_trace(); }
 ComponentManager::~ComponentManager() { dbg_trace(); }
 
-GameObject & ComponentManager::new_object(const string & name,
+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));
+	GameObject object{*this, this->next_id, name, tag, position, rotation, scale};
 	this->next_id++;
-	return *object;
+	return object;
 }
diff --git a/src/crepe/ComponentManager.h b/src/crepe/ComponentManager.h
index 75606e0..31a8bfa 100644
--- a/src/crepe/ComponentManager.h
+++ b/src/crepe/ComponentManager.h
@@ -101,7 +101,7 @@ public:
 	std::vector<std::reference_wrapper<T>> get_components_by_type() const;
 
 	// TODO: doxygen
-	GameObject & new_object(const std::string & name,
+	GameObject new_object(const std::string & name,
 							const std::string & tag = "",
 							const Vector2 & position = {0, 0},
 							double rotation = 0, double scale = 0);
diff --git a/src/crepe/api/Scene.cpp b/src/crepe/api/Scene.cpp
index 933edf4..008d689 100644
--- a/src/crepe/api/Scene.cpp
+++ b/src/crepe/api/Scene.cpp
@@ -2,4 +2,4 @@
 
 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..334f306 100644
--- a/src/crepe/api/Scene.h
+++ b/src/crepe/api/Scene.h
@@ -4,14 +4,20 @@
 
 namespace crepe {
 
+class ComponentManager;
+
 class Scene {
 public:
-	Scene(const std::string & name);
+	Scene(ComponentManager & mgr, const std::string & name);
 	virtual ~Scene() = default;
+
 	virtual void load_scene() = 0;
 
 public:
-	std::string name;
+	const std::string name;
+
+protected:
+	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/example/components_internal.cpp b/src/example/components_internal.cpp
index 7a8a08a..eeecdc0 100644
--- a/src/example/components_internal.cpp
+++ b/src/example/components_internal.cpp
@@ -30,7 +30,7 @@ int main() {
 	GameObject * game_object[OBJ_COUNT];
 
 	for (int i = 0; i < OBJ_COUNT; ++i) {
-		GameObject & obj = mgr.new_object("Name", "Tag");
+		GameObject obj = mgr.new_object("Name", "Tag");
 		obj.add_component<Sprite>("test");
 		obj.add_component<Rigidbody>(0, 0, i);
 	}
diff --git a/src/example/ecs.cpp b/src/example/ecs.cpp
index 9a008ea..06fc563 100644
--- a/src/example/ecs.cpp
+++ b/src/example/ecs.cpp
@@ -13,16 +13,11 @@ int main() {
 
 	// Create a few GameObjects
 	try {
-		GameObject & body
-			= mgr.new_object("body", "person", Vector2{0, 0}, 0, 1);
-		GameObject & right_leg
-			= mgr.new_object("rightLeg", "person", Vector2{1, 1}, 0, 1);
-		GameObject & left_leg
-			= mgr.new_object("leftLeg", "person", Vector2{1, 1}, 0, 1);
-		GameObject & right_foot
-			= mgr.new_object("rightFoot", "person", Vector2{2, 2}, 0, 1);
-		GameObject & left_foot
-			= mgr.new_object("leftFoot", "person", Vector2{2, 2}, 0, 1);
+		GameObject body = mgr.new_object("body", "person", Vector2{0, 0}, 0, 1);
+		GameObject right_leg = mgr.new_object("rightLeg", "person", Vector2{1, 1}, 0, 1);
+		GameObject left_leg = mgr.new_object("leftLeg", "person", Vector2{1, 1}, 0, 1);
+		GameObject right_foot = mgr.new_object("rightFoot", "person", Vector2{2, 2}, 0, 1);
+		GameObject left_foot = mgr.new_object("leftFoot", "person", Vector2{2, 2}, 0, 1);
 
 		// Set the parent of each GameObject
 		right_foot.set_parent(right_leg);
diff --git a/src/example/physics.cpp b/src/example/physics.cpp
index 2ebf779..ad663a0 100644
--- a/src/example/physics.cpp
+++ b/src/example/physics.cpp
@@ -11,8 +11,7 @@ using namespace std;
 int main(int argc, char * argv[]) {
 	ComponentManager mgr{};
 
-	GameObject & game_object
-		= mgr.new_object("Name", "Tag", Vector2{0, 0}, 0, 0);
+	GameObject game_object = mgr.new_object("Name", "Tag", Vector2{0, 0}, 0, 0);
 	game_object.add_component<Rigidbody>(Rigidbody::Data{
 		.mass = 1,
 		.gravity_scale = 1,
diff --git a/src/example/rendering.cpp b/src/example/rendering.cpp
index 74c00e2..abd11b1 100644
--- a/src/example/rendering.cpp
+++ b/src/example/rendering.cpp
@@ -23,9 +23,9 @@ int main() {
 	ComponentManager mgr{};
 	RenderSystem sys{mgr};
 
-	auto & obj = mgr.new_object("name", "tag", Vector2{0, 0}, 1, 1);
-	auto & obj1 = mgr.new_object("name", "tag", Vector2{500, 0}, 1, 0.1);
-	auto & obj2 = mgr.new_object("name", "tag", Vector2{800, 0}, 1, 0.1);
+	GameObject obj = mgr.new_object("name", "tag", Vector2{0, 0}, 1, 1);
+	GameObject obj1 = mgr.new_object("name", "tag", Vector2{500, 0}, 1, 0.1);
+	GameObject obj2 = mgr.new_object("name", "tag", Vector2{800, 0}, 1, 0.1);
 
 	// Normal adding components
 	{
diff --git a/src/example/scene_manager.cpp b/src/example/scene_manager.cpp
index 5cd7336..1c982aa 100644
--- a/src/example/scene_manager.cpp
+++ b/src/example/scene_manager.cpp
@@ -12,24 +12,26 @@ using namespace std;
 
 class ConcreteScene1 : public Scene {
 public:
-	ConcreteScene1(string name) : Scene(name) {}
+	using Scene::Scene;
 
 	void load_scene() {
-		GameObject object1(0, "scene_1", "tag_scene_1", Vector2{0, 0}, 0, 1);
-		GameObject object2(1, "scene_1", "tag_scene_1", Vector2{1, 0}, 0, 1);
-		GameObject object3(2, "scene_1", "tag_scene_1", Vector2{2, 0}, 0, 1);
+		auto & mgr = this->component_manager;
+		GameObject object1 = mgr.new_object("scene_1", "tag_scene_1", Vector2{0, 0}, 0, 1);
+		GameObject object2 = mgr.new_object("scene_1", "tag_scene_1", Vector2{1, 0}, 0, 1);
+		GameObject object3 = mgr.new_object("scene_1", "tag_scene_1", Vector2{2, 0}, 0, 1);
 	}
 };
 
 class ConcreteScene2 : public Scene {
 public:
-	ConcreteScene2(string name) : Scene(name) {}
+	using Scene::Scene;
 
 	void load_scene() {
-		GameObject object1(0, "scene_2", "tag_scene_2", Vector2{0, 0}, 0, 1);
-		GameObject object2(1, "scene_2", "tag_scene_2", Vector2{0, 1}, 0, 1);
-		GameObject object3(2, "scene_2", "tag_scene_2", Vector2{0, 2}, 0, 1);
-		GameObject object4(3, "scene_2", "tag_scene_2", Vector2{0, 3}, 0, 1);
+		auto & mgr = this->component_manager;
+		GameObject object1 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 0}, 0, 1);
+		GameObject object2 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 1}, 0, 1);
+		GameObject object3 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 2}, 0, 1);
+		GameObject object4 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 3}, 0, 1);
 	}
 };
 
@@ -41,7 +43,9 @@ int main() {
 	scene_mgr.add_scene<ConcreteScene1>("scene1");
 	scene_mgr.add_scene<ConcreteScene2>("scene2");
 
-	// There is no need to call set_next_scene() at the beginnen, because the first scene will be automatically set as the next scene
+	// There is no need to call set_next_scene() at the beginning because the
+	// first scene will be automatically set as the next scene
+
 	// Load scene1 (the first scene added)
 	scene_mgr.load_next_scene();
 
@@ -73,3 +77,4 @@ int main() {
 
 	return 0;
 }
+
diff --git a/src/example/script.cpp b/src/example/script.cpp
index c82764c..a23295b 100644
--- a/src/example/script.cpp
+++ b/src/example/script.cpp
@@ -39,7 +39,7 @@ int main() {
 	ScriptSystem system{component_manager};
 
 	// Create game object with Transform and BehaviorScript components
-	auto & obj = component_manager.new_object("name");
+	GameObject obj = component_manager.new_object("name");
 	obj.add_component<BehaviorScript>().set_script<MyScript>();
 
 	// Update all scripts. This should result in MyScript::update being called
-- 
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')

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


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

---
 src/crepe/ComponentManager.cpp | 10 +++++-----
 src/crepe/ComponentManager.h   |  6 +++---
 src/crepe/api/Scene.cpp        |  4 +++-
 src/example/ecs.cpp            | 12 ++++++++----
 src/example/scene_manager.cpp  | 22 ++++++++++++++--------
 5 files changed, 33 insertions(+), 21 deletions(-)

(limited to 'src')

diff --git a/src/crepe/ComponentManager.cpp b/src/crepe/ComponentManager.cpp
index 1e23609..7af0380 100644
--- a/src/crepe/ComponentManager.cpp
+++ b/src/crepe/ComponentManager.cpp
@@ -25,11 +25,11 @@ 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{*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{*this,	this->next_id, name, tag,
+					  position, rotation,	   scale};
 	this->next_id++;
 	return object;
 }
diff --git a/src/crepe/ComponentManager.h b/src/crepe/ComponentManager.h
index 31a8bfa..51c84a4 100644
--- a/src/crepe/ComponentManager.h
+++ b/src/crepe/ComponentManager.h
@@ -102,9 +102,9 @@ public:
 
 	// TODO: doxygen
 	GameObject new_object(const std::string & name,
-							const std::string & tag = "",
-							const Vector2 & position = {0, 0},
-							double rotation = 0, double scale = 0);
+						  const std::string & tag = "",
+						  const Vector2 & position = {0, 0},
+						  double rotation = 0, double scale = 0);
 
 private:
 	/**
diff --git a/src/crepe/api/Scene.cpp b/src/crepe/api/Scene.cpp
index 008d689..88aa82d 100644
--- a/src/crepe/api/Scene.cpp
+++ b/src/crepe/api/Scene.cpp
@@ -2,4 +2,6 @@
 
 using namespace crepe;
 
-Scene::Scene(ComponentManager & mgr, const std::string & name) : component_manager(mgr), name(name) {}
+Scene::Scene(ComponentManager & mgr, const std::string & name)
+	: component_manager(mgr),
+	  name(name) {}
diff --git a/src/example/ecs.cpp b/src/example/ecs.cpp
index 06fc563..5f83da1 100644
--- a/src/example/ecs.cpp
+++ b/src/example/ecs.cpp
@@ -14,10 +14,14 @@ int main() {
 	// Create a few GameObjects
 	try {
 		GameObject body = mgr.new_object("body", "person", Vector2{0, 0}, 0, 1);
-		GameObject right_leg = mgr.new_object("rightLeg", "person", Vector2{1, 1}, 0, 1);
-		GameObject left_leg = mgr.new_object("leftLeg", "person", Vector2{1, 1}, 0, 1);
-		GameObject right_foot = mgr.new_object("rightFoot", "person", Vector2{2, 2}, 0, 1);
-		GameObject left_foot = mgr.new_object("leftFoot", "person", Vector2{2, 2}, 0, 1);
+		GameObject right_leg
+			= mgr.new_object("rightLeg", "person", Vector2{1, 1}, 0, 1);
+		GameObject left_leg
+			= mgr.new_object("leftLeg", "person", Vector2{1, 1}, 0, 1);
+		GameObject right_foot
+			= mgr.new_object("rightFoot", "person", Vector2{2, 2}, 0, 1);
+		GameObject left_foot
+			= mgr.new_object("leftFoot", "person", Vector2{2, 2}, 0, 1);
 
 		// Set the parent of each GameObject
 		right_foot.set_parent(right_leg);
diff --git a/src/example/scene_manager.cpp b/src/example/scene_manager.cpp
index 1c982aa..24ab72e 100644
--- a/src/example/scene_manager.cpp
+++ b/src/example/scene_manager.cpp
@@ -16,9 +16,12 @@ public:
 
 	void load_scene() {
 		auto & mgr = this->component_manager;
-		GameObject object1 = mgr.new_object("scene_1", "tag_scene_1", Vector2{0, 0}, 0, 1);
-		GameObject object2 = mgr.new_object("scene_1", "tag_scene_1", Vector2{1, 0}, 0, 1);
-		GameObject object3 = mgr.new_object("scene_1", "tag_scene_1", Vector2{2, 0}, 0, 1);
+		GameObject object1
+			= mgr.new_object("scene_1", "tag_scene_1", Vector2{0, 0}, 0, 1);
+		GameObject object2
+			= mgr.new_object("scene_1", "tag_scene_1", Vector2{1, 0}, 0, 1);
+		GameObject object3
+			= mgr.new_object("scene_1", "tag_scene_1", Vector2{2, 0}, 0, 1);
 	}
 };
 
@@ -28,10 +31,14 @@ public:
 
 	void load_scene() {
 		auto & mgr = this->component_manager;
-		GameObject object1 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 0}, 0, 1);
-		GameObject object2 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 1}, 0, 1);
-		GameObject object3 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 2}, 0, 1);
-		GameObject object4 = mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 3}, 0, 1);
+		GameObject object1
+			= mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 0}, 0, 1);
+		GameObject object2
+			= mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 1}, 0, 1);
+		GameObject object3
+			= mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 2}, 0, 1);
+		GameObject object4
+			= mgr.new_object("scene_2", "tag_scene_2", Vector2{0, 3}, 0, 1);
 	}
 };
 
@@ -77,4 +84,3 @@ int main() {
 
 	return 0;
 }
-
-- 
cgit v1.2.3