From 7c9d3452c99fcb89ea6df55755e90f741b23cf10 Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Sun, 6 Oct 2024 13:22:10 +0200
Subject: copy homemade ECS to crepe + correct code style

---
 src/crepe/CMakeLists.txt       |   8 +++
 src/crepe/ComponentManager.cpp |  25 ++++++++
 src/crepe/ComponentManager.h   |  55 +++++++++++++++++
 src/crepe/ComponentManager.hpp | 134 +++++++++++++++++++++++++++++++++++++++++
 src/crepe/Components.cpp       |  13 ++++
 src/crepe/Components.h         |  39 ++++++++++++
 src/crepe/GameObject.cpp       |   9 +++
 src/crepe/GameObject.h         |  22 +++++++
 src/crepe/GameObject.hpp       |  15 +++++
 9 files changed, 320 insertions(+)
 create mode 100644 src/crepe/ComponentManager.cpp
 create mode 100644 src/crepe/ComponentManager.h
 create mode 100644 src/crepe/ComponentManager.hpp
 create mode 100644 src/crepe/Components.cpp
 create mode 100644 src/crepe/Components.h
 create mode 100644 src/crepe/GameObject.cpp
 create mode 100644 src/crepe/GameObject.h
 create mode 100644 src/crepe/GameObject.hpp

(limited to 'src/crepe')

diff --git a/src/crepe/CMakeLists.txt b/src/crepe/CMakeLists.txt
index 208ba1f..5840208 100644
--- a/src/crepe/CMakeLists.txt
+++ b/src/crepe/CMakeLists.txt
@@ -2,12 +2,20 @@ target_sources(crepe PUBLIC
 	Asset.cpp
 	Sound.cpp
 	SoundContext.cpp
+	ComponentManager.cpp
+	Components.cpp
+	GameObject.cpp
 )
 
 target_sources(crepe PUBLIC FILE_SET HEADERS FILES
 	Asset.h
 	Sound.h
 	SoundContext.h
+	ComponentManager.h
+	ComponentManager.hpp
+	Components.h
+	GameObject.h
+	GameObject.hpp
 )
 
 add_subdirectory(api)
diff --git a/src/crepe/ComponentManager.cpp b/src/crepe/ComponentManager.cpp
new file mode 100644
index 0000000..b7a1bea
--- /dev/null
+++ b/src/crepe/ComponentManager.cpp
@@ -0,0 +1,25 @@
+#include "ComponentManager.h"
+
+using namespace crepe;
+
+ComponentManager & ComponentManager::get_instance() {
+	static ComponentManager instance;
+	return instance;
+}
+
+void ComponentManager::DeleteAllComponentsOfId(std::uint32_t id) {
+	// Loop through all the types (in the unordered_map<>)
+	for (auto & [type, componentArray] : components) {
+		// Make sure that the id (that we are looking for) is within the boundaries of the vector<>
+		if (id < componentArray.size()) {
+			// Clear the components at this specific id
+			componentArray[id].clear();
+		}
+	}
+}
+
+void ComponentManager::DeleteAllComponents() {
+	// Clear the whole unordered_map<>
+	components.clear();
+}
+
diff --git a/src/crepe/ComponentManager.h b/src/crepe/ComponentManager.h
new file mode 100644
index 0000000..003cd0b
--- /dev/null
+++ b/src/crepe/ComponentManager.h
@@ -0,0 +1,55 @@
+#pragma once
+
+#include <cstdint>
+#include <memory>
+#include <typeindex>
+#include <unordered_map>
+#include <utility>
+#include <vector>
+
+#include "Components.h"
+
+namespace crepe {
+
+class ComponentManager {
+public:
+	// Singleton
+	static ComponentManager & get_instance();
+	ComponentManager(const ComponentManager &) = delete;
+	ComponentManager(ComponentManager &&) = delete;
+	ComponentManager & operator=(const ComponentManager &) = delete;
+	ComponentManager & operator=(ComponentManager &&) = delete;
+
+public:
+	//! Add a component of a specific type
+	template <typename T, typename... Args> void AddComponent(std::uint32_t id, Args &&... args);
+	//! Deletes all components of a specific type and id
+	template <typename T> void DeleteComponentsById(std::uint32_t id);
+	//! Deletes all components of a specific type
+	template <typename T> void DeleteComponents();
+	//! Deletes all components of a specific id
+	void DeleteAllComponentsOfId(std::uint32_t id);
+	//! Deletes all components
+	void DeleteAllComponents();
+
+	//! Get a vector<> of all components at specific type and id
+	template <typename T> std::vector<std::reference_wrapper<T>> GetComponentsByID(std::uint32_t id) const;
+	//! Get a vector<> of all components of a specific type
+	template <typename T> std::vector<std::reference_wrapper<T>> GetComponentsByType() const;
+
+private:
+	ComponentManager() = default;
+
+	/*
+	 * The std::unordered_map<std::type_index, std::vector<std::vector<std::unique_ptr<Component>>>> below might seem a bit strange, let me explain this structure:
+	 * The std::unordered_map<> has a key and value. The key is a std::type_index and the value is a std::vector. So, a new std::vector will be created for each new std::type_index.
+	 * The first std::vector<> stores another vector<>. This first vector<> is to bind the entity's id to a component.
+	 * The second std::vector<> stores unique_ptrs. Each component can be gathered via an unique_ptr. This second vector<> allows multiple components of the same std::type_index for one entity (id).
+	 */
+	std::unordered_map<std::type_index, std::vector<std::vector<std::unique_ptr<Component>>>> components;
+};
+
+}
+
+// #include "ComponentManager.hpp"
+
diff --git a/src/crepe/ComponentManager.hpp b/src/crepe/ComponentManager.hpp
new file mode 100644
index 0000000..602490e
--- /dev/null
+++ b/src/crepe/ComponentManager.hpp
@@ -0,0 +1,134 @@
+#pragma once
+
+#include "ComponentManager.h"
+
+namespace crepe {
+
+template <typename T, typename... Args>
+void ComponentManager::AddComponent(std::uint32_t id, Args &&... args) {
+	// Determine the type of T (this is used as the key of the unordered_map<>)
+	std::type_index type = typeid(T);
+
+	// Check if this component type is already in the unordered_map<>
+	if (components.find(type) == components.end()) {
+		//If not, create a new (empty) vector<> of vector<unique_ptr<Component>>
+		components[type] = std::vector<std::vector<std::unique_ptr<Component>>>();
+	}
+
+	// Resize the vector<> if the id is greater than the current size
+	if (id >= components[type].size()) {
+		// Initialize new slots to nullptr (resize does automatically init to nullptr)
+		components[type].resize(id + 1);
+	}
+
+	// Create a new component of type T using perfect forwarding and store its
+	// unique_ptr in the vector<>
+	components[type][id].push_back(std::make_unique<T>(std::forward<Args>(args)...));
+}
+
+template <typename T>
+void ComponentManager::DeleteComponentsById(std::uint32_t id) {
+	// Determine the type of T (this is used as the key of the unordered_map<>)
+	std::type_index type = typeid(T);
+
+	// Find the type (in the unordered_map<>)
+	if (components.find(type) != components.end()) {
+		// Get the correct vector<>
+		std::vector<std::vector<std::unique_ptr<Component>>> & componentArray = components[type];
+
+		// Make sure that the id (that we are looking for) is within the boundaries of the vector<>
+		if (id < componentArray.size()) {
+			// Clear the whole vector<> of this specific type and id
+			componentArray[id].clear();
+		}
+	}
+}
+
+template <typename T>
+void ComponentManager::DeleteComponents() {
+	// Determine the type of T (this is used as the key of the unordered_map<>)
+	std::type_index type = typeid(T);
+
+	// Find the type (in the unordered_map<>)
+	if (components.find(type) != components.end()) {
+		// Clear the whole vector<> of this specific type
+		components[type].clear();
+	}
+}
+
+template <typename T>
+std::vector<std::reference_wrapper<T>>
+ComponentManager::GetComponentsByID(std::uint32_t id) const {
+	// Determine the type of T (this is used as the key of the unordered_map<>)
+	std::type_index type = typeid(T);
+
+	// Create an empty vector<>
+	std::vector<std::reference_wrapper<T>> componentVector;
+
+	// Find the type (in the unordered_map<>)
+	if (components.find(type) != components.end()) {
+		// Get the correct vector<>
+		const std::vector<std::vector<std::unique_ptr<Component>>> & componentArray = components.at(type);
+
+		// Make sure that the id (that we are looking for) is within the boundaries of the vector<>
+		if (id < componentArray .size()) {
+			// Loop trough the whole vector<>
+			for (const std::unique_ptr<Component> & componentPtr : componentArray[id]) {
+				// Cast the unique_ptr to a raw pointer
+				T * castedComponent = static_cast<T *>(componentPtr.get());
+
+				// Ensure that the cast was successful
+				if (castedComponent) {
+					// Add the dereferenced raw pointer to the vector<>
+					componentVector.push_back(*castedComponent);
+				}
+			}
+		}
+	}
+
+	// Return the vector<>
+	return componentVector;
+}
+
+template <typename T>
+std::vector<std::reference_wrapper<T>>
+ComponentManager::GetComponentsByType() const {
+	// Determine the type of T (this is used as the key of the unordered_map<>)
+	std::type_index type = typeid(T);
+
+	// Create an empty vector<>
+	std::vector<std::reference_wrapper<T>> componentVector;
+	// Set the id to 0 (the id will also be stored in the returned vector<>)
+	// std::uint32_t id = 0;
+
+	// Find the type (in the unordered_map<>)
+	if (components.find(type) != components.end()) {
+
+		// Get the correct vector<>
+		const std::vector<std::vector<std::unique_ptr<Component>>> & componentArray = components.at(type);
+
+		// Loop through the whole vector<>
+		for (const std::vector<std::unique_ptr<Component>> & component : componentArray) {
+			// Loop trough the whole vector<>
+			for (const std::unique_ptr<Component> & componentPtr : component) {
+				// Cast the unique_ptr to a raw pointer
+				T * castedComponent = static_cast<T *>(componentPtr.get());
+
+				// Ensure that the cast was successful
+				if (castedComponent) {
+					// Pair the dereferenced raw pointer and the id and add it to the vector<>
+					componentVector.emplace_back(std::ref(*castedComponent));
+				}
+			}
+
+			// Increase the id (the id will also be stored in the returned vector<>)
+			//++id;
+		}
+	}
+
+	// Return the vector<>
+	return componentVector;
+}
+
+}
+
diff --git a/src/crepe/Components.cpp b/src/crepe/Components.cpp
new file mode 100644
index 0000000..9760daa
--- /dev/null
+++ b/src/crepe/Components.cpp
@@ -0,0 +1,13 @@
+#include "Components.h"
+#include <iostream>
+
+using namespace crepe;
+
+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) {}
+
+Colider::Colider(int size) : mSize(size) {}
diff --git a/src/crepe/Components.h b/src/crepe/Components.h
new file mode 100644
index 0000000..7cb6fbb
--- /dev/null
+++ b/src/crepe/Components.h
@@ -0,0 +1,39 @@
+#pragma once
+
+#include <string>
+
+namespace crepe {
+
+class Component {
+public:
+	Component();
+
+	bool mActive;
+};
+
+// TODO: these should be in separate files
+
+class Sprite : public Component {
+public:
+	Sprite(std::string path);
+
+	std::string mPath;
+};
+
+class Rigidbody : public Component {
+public:
+	Rigidbody(int mass, int gravityScale, int bodyType);
+
+	int mMass;
+	int mGravityScale;
+	int mBodyType;
+};
+
+class Colider : public Component {
+public:
+	Colider(int size);
+
+	int mSize;
+};
+
+}
diff --git a/src/crepe/GameObject.cpp b/src/crepe/GameObject.cpp
new file mode 100644
index 0000000..5ac9d7a
--- /dev/null
+++ b/src/crepe/GameObject.cpp
@@ -0,0 +1,9 @@
+#include "GameObject.h"
+
+#include "ComponentManager.h"
+
+using namespace crepe;
+
+GameObject::GameObject(std::uint32_t id, std::string name, std::string tag,
+					   int layer)
+	: mId(id), mName(name), mTag(tag), mActive(true), mLayer(layer) {}
diff --git a/src/crepe/GameObject.h b/src/crepe/GameObject.h
new file mode 100644
index 0000000..71ef60d
--- /dev/null
+++ b/src/crepe/GameObject.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include <cstdint>
+#include <string>
+
+namespace crepe {
+
+class GameObject {
+public:
+	GameObject(std::uint32_t id, std::string name, std::string tag, int layer);
+
+	template <typename T, typename... Args> void AddComponent(Args &&... args);
+
+	std::uint32_t mId;
+	std::string mName;
+	std::string mTag;
+	bool mActive;
+	int mLayer;
+};
+
+}
+
diff --git a/src/crepe/GameObject.hpp b/src/crepe/GameObject.hpp
new file mode 100644
index 0000000..5a672cf
--- /dev/null
+++ b/src/crepe/GameObject.hpp
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "GameObject.h"
+
+#include "ComponentManager.h"
+
+namespace crepe {
+
+template <typename T, typename... Args>
+void GameObject::AddComponent(Args &&... args) {
+	ComponentManager::get_instance().AddComponent<T>(mId, std::forward<Args>(args)...);
+}
+
+}
+
-- 
cgit v1.2.3


From 509fb6ebdd27bc75375c1c51024ea906e25032c0 Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Sun, 6 Oct 2024 13:45:05 +0200
Subject: WIP more code style enforcements

---
 .clang-format                             |  2 +-
 .clang-tidy                               | 43 +++++++++++++++++++++----------
 .editorconfig                             |  2 +-
 mwe/ecs-homemade/inc/ComponentManager.hpp |  3 ++-
 mwe/ecs-homemade/inc/GameObjectMax.h      |  3 ++-
 src/crepe/ComponentManager.cpp            |  5 ++--
 src/crepe/ComponentManager.h              | 27 ++++++++++++-------
 src/crepe/ComponentManager.hpp            | 38 ++++++++++++++++-----------
 src/crepe/Components.cpp                  |  9 ++++---
 src/crepe/Components.h                    | 18 ++++++-------
 src/crepe/GameObject.cpp                  |  2 +-
 src/crepe/GameObject.h                    | 16 ++++++------
 src/crepe/GameObject.hpp                  |  6 ++---
 src/crepe/api/AudioSource.h               |  2 +-
 14 files changed, 104 insertions(+), 72 deletions(-)

(limited to 'src/crepe')

diff --git a/.clang-format b/.clang-format
index d2918db..3ae6c28 100644
--- a/.clang-format
+++ b/.clang-format
@@ -22,7 +22,7 @@ AlignTrailingComments:
 ReflowComments: false
 AlignEscapedNewlines: DontAlign
 BreakBeforeBinaryOperators: All
-BreakTemplateDeclarations: Yes
+AlwaysBreakTemplateDeclarations: Yes
 ...
 
 # vim: ft=yaml
diff --git a/.clang-tidy b/.clang-tidy
index b242e3f..0ec997d 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -1,18 +1,33 @@
 Checks: '-*,readability-identifier-naming'
 CheckOptions:
-	- { key: readability-identifier-naming.EnumCase, value: lower_case }
-	- { key: readability-identifier-naming.GlobalFunctionCase, value: lower_case }
-	- { key: readability-identifier-naming.ClassCase, value: CamelCase }
-	- { key: readability-identifier-naming.ClassMethodCase, value: lower_case }
-	- { key: readability-identifier-naming.ClassMethodPrefix, value: '' }
-	- { key: readability-identifier-naming.ClassMemberCase, value: lower_case }
-	- { key: readability-identifier-naming.ClassMemberPrefix, value: '' }
-	- { key: readability-identifier-naming.GlobalConstantCase, value: UPPER_CASE }
-	- { key: readability-identifier-naming.GlobalConstantIgnoredRegexp, value: _.* }
-	- { key: readability-identifier-naming.GlobalVariableCase, value: lower_case }
-	- { key: readability-identifier-naming.GlobalVariableIgnoredRegexp, value: _.* }
-	- { key: readability-identifier-naming.MacroDefinitionCase, value: UPPER_CASE }
-	- { key: readability-identifier-naming.MacroDefinitionIgnoredRegexp, value: _.* }
-	- { key: readability-identifier-naming.StructCase, value: lower_case }
+  - key: 'readability-identifier-naming.EnumCase'
+    value: 'lower_case'
+  - key: 'readability-identifier-naming.GlobalFunctionCase'
+    value: 'lower_case'
+  - key: 'readability-identifier-naming.ClassCase'
+    value: 'CamelCase'
+  - key: 'readability-identifier-naming.MethodCase'
+    value: 'lower_case'
+  - key: 'readability-identifier-naming.MethodPrefix'
+    value: ''
+  - key: 'readability-identifier-naming.MemberCase'
+    value: 'lower_case'
+  - key: 'readability-identifier-naming.MemberPrefix'
+    value: ''
+  - key: 'readability-identifier-naming.GlobalConstantCase'
+    value: 'UPPER_CASE'
+  - key: 'readability-identifier-naming.GlobalConstantIgnoredRegexp'
+    value: '_.*'
+  - key: 'readability-identifier-naming.GlobalVariableCase'
+    value: 'lower_case'
+  - key: 'readability-identifier-naming.GlobalVariableIgnoredRegexp'
+    value: '_.*'
+  - key: 'readability-identifier-naming.MacroDefinitionCase'
+    value: 'UPPER_CASE'
+  - key: 'readability-identifier-naming.MacroDefinitionIgnoredRegexp'
+    value: '_.*'
+  - key: 'readability-identifier-naming.StructCase'
+    value: 'lower_case'
 
 # vim: ft=yaml
+
diff --git a/.editorconfig b/.editorconfig
index 1bd7da9..df2cf5e 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -5,7 +5,7 @@ indent_style = tab
 end_of_line = lf
 insert_final_newline = true
 
-[*.{md,yml}]
+[{*.{md,yml},.clang-*}]
 indent_style = space
 indent_size = 2
 
diff --git a/mwe/ecs-homemade/inc/ComponentManager.hpp b/mwe/ecs-homemade/inc/ComponentManager.hpp
index 161ce71..d6da8e8 100644
--- a/mwe/ecs-homemade/inc/ComponentManager.hpp
+++ b/mwe/ecs-homemade/inc/ComponentManager.hpp
@@ -42,7 +42,8 @@ void ComponentManager::DeleteComponentsById(std::uint32_t id) {
 	}
 }
 
-template <typename T> void ComponentManager::DeleteComponents() {
+template <typename T>
+void ComponentManager::DeleteComponents() {
 	std::type_index type = typeid(
 		T); //Determine the type of T (this is used as the key of the unordered_map<>)
 
diff --git a/mwe/ecs-homemade/inc/GameObjectMax.h b/mwe/ecs-homemade/inc/GameObjectMax.h
index c88a834..3029053 100644
--- a/mwe/ecs-homemade/inc/GameObjectMax.h
+++ b/mwe/ecs-homemade/inc/GameObjectMax.h
@@ -7,7 +7,8 @@ class GameObject {
 public:
 	GameObject(std::uint32_t id, std::string name, std::string tag, int layer);
 
-	template <typename T, typename... Args> void AddComponent(Args &&... args);
+	template <typename T, typename... Args>
+	void AddComponent(Args &&... args);
 
 	std::uint32_t mId;
 	std::string mName;
diff --git a/src/crepe/ComponentManager.cpp b/src/crepe/ComponentManager.cpp
index b7a1bea..b080c9d 100644
--- a/src/crepe/ComponentManager.cpp
+++ b/src/crepe/ComponentManager.cpp
@@ -7,7 +7,7 @@ ComponentManager & ComponentManager::get_instance() {
 	return instance;
 }
 
-void ComponentManager::DeleteAllComponentsOfId(std::uint32_t id) {
+void ComponentManager::delete_all_components_of_id(std::uint32_t id) {
 	// Loop through all the types (in the unordered_map<>)
 	for (auto & [type, componentArray] : components) {
 		// Make sure that the id (that we are looking for) is within the boundaries of the vector<>
@@ -18,8 +18,7 @@ void ComponentManager::DeleteAllComponentsOfId(std::uint32_t id) {
 	}
 }
 
-void ComponentManager::DeleteAllComponents() {
+void ComponentManager::delete_all_components() {
 	// Clear the whole unordered_map<>
 	components.clear();
 }
-
diff --git a/src/crepe/ComponentManager.h b/src/crepe/ComponentManager.h
index 003cd0b..b88ad27 100644
--- a/src/crepe/ComponentManager.h
+++ b/src/crepe/ComponentManager.h
@@ -22,20 +22,26 @@ public:
 
 public:
 	//! Add a component of a specific type
-	template <typename T, typename... Args> void AddComponent(std::uint32_t id, Args &&... args);
+	template <typename T, typename... Args>
+	void add_component(std::uint32_t id, Args &&... args);
 	//! Deletes all components of a specific type and id
-	template <typename T> void DeleteComponentsById(std::uint32_t id);
+	template <typename T>
+	void delete_components_by_id(std::uint32_t id);
 	//! Deletes all components of a specific type
-	template <typename T> void DeleteComponents();
+	template <typename T>
+	void delete_components();
 	//! Deletes all components of a specific id
-	void DeleteAllComponentsOfId(std::uint32_t id);
+	void delete_all_components_of_id(std::uint32_t id);
 	//! Deletes all components
-	void DeleteAllComponents();
+	void delete_all_components();
 
 	//! Get a vector<> of all components at specific type and id
-	template <typename T> std::vector<std::reference_wrapper<T>> GetComponentsByID(std::uint32_t id) const;
+	template <typename T>
+	std::vector<std::reference_wrapper<T>>
+	get_components_by_id(std::uint32_t id) const;
 	//! Get a vector<> of all components of a specific type
-	template <typename T> std::vector<std::reference_wrapper<T>> GetComponentsByType() const;
+	template <typename T>
+	std::vector<std::reference_wrapper<T>> get_components_by_type() const;
 
 private:
 	ComponentManager() = default;
@@ -46,10 +52,11 @@ private:
 	 * The first std::vector<> stores another vector<>. This first vector<> is to bind the entity's id to a component.
 	 * The second std::vector<> stores unique_ptrs. Each component can be gathered via an unique_ptr. This second vector<> allows multiple components of the same std::type_index for one entity (id).
 	 */
-	std::unordered_map<std::type_index, std::vector<std::vector<std::unique_ptr<Component>>>> components;
+	std::unordered_map<std::type_index,
+					   std::vector<std::vector<std::unique_ptr<Component>>>>
+		components;
 };
 
-}
+} // namespace crepe
 
 // #include "ComponentManager.hpp"
-
diff --git a/src/crepe/ComponentManager.hpp b/src/crepe/ComponentManager.hpp
index 602490e..30b0e38 100644
--- a/src/crepe/ComponentManager.hpp
+++ b/src/crepe/ComponentManager.hpp
@@ -5,14 +5,15 @@
 namespace crepe {
 
 template <typename T, typename... Args>
-void ComponentManager::AddComponent(std::uint32_t id, Args &&... args) {
+void ComponentManager::add_component(std::uint32_t id, Args &&... args) {
 	// Determine the type of T (this is used as the key of the unordered_map<>)
 	std::type_index type = typeid(T);
 
 	// Check if this component type is already in the unordered_map<>
 	if (components.find(type) == components.end()) {
 		//If not, create a new (empty) vector<> of vector<unique_ptr<Component>>
-		components[type] = std::vector<std::vector<std::unique_ptr<Component>>>();
+		components[type]
+			= std::vector<std::vector<std::unique_ptr<Component>>>();
 	}
 
 	// Resize the vector<> if the id is greater than the current size
@@ -23,18 +24,20 @@ void ComponentManager::AddComponent(std::uint32_t id, Args &&... args) {
 
 	// Create a new component of type T using perfect forwarding and store its
 	// unique_ptr in the vector<>
-	components[type][id].push_back(std::make_unique<T>(std::forward<Args>(args)...));
+	components[type][id].push_back(
+		std::make_unique<T>(std::forward<Args>(args)...));
 }
 
 template <typename T>
-void ComponentManager::DeleteComponentsById(std::uint32_t id) {
+void ComponentManager::delete_components_by_id(std::uint32_t id) {
 	// Determine the type of T (this is used as the key of the unordered_map<>)
 	std::type_index type = typeid(T);
 
 	// Find the type (in the unordered_map<>)
 	if (components.find(type) != components.end()) {
 		// Get the correct vector<>
-		std::vector<std::vector<std::unique_ptr<Component>>> & componentArray = components[type];
+		std::vector<std::vector<std::unique_ptr<Component>>> & componentArray
+			= components[type];
 
 		// Make sure that the id (that we are looking for) is within the boundaries of the vector<>
 		if (id < componentArray.size()) {
@@ -45,7 +48,7 @@ void ComponentManager::DeleteComponentsById(std::uint32_t id) {
 }
 
 template <typename T>
-void ComponentManager::DeleteComponents() {
+void ComponentManager::delete_components() {
 	// Determine the type of T (this is used as the key of the unordered_map<>)
 	std::type_index type = typeid(T);
 
@@ -58,7 +61,7 @@ void ComponentManager::DeleteComponents() {
 
 template <typename T>
 std::vector<std::reference_wrapper<T>>
-ComponentManager::GetComponentsByID(std::uint32_t id) const {
+ComponentManager::get_components_by_id(std::uint32_t id) const {
 	// Determine the type of T (this is used as the key of the unordered_map<>)
 	std::type_index type = typeid(T);
 
@@ -68,12 +71,15 @@ ComponentManager::GetComponentsByID(std::uint32_t id) const {
 	// Find the type (in the unordered_map<>)
 	if (components.find(type) != components.end()) {
 		// Get the correct vector<>
-		const std::vector<std::vector<std::unique_ptr<Component>>> & componentArray = components.at(type);
+		const std::vector<std::vector<std::unique_ptr<Component>>> &
+			componentArray
+			= components.at(type);
 
 		// Make sure that the id (that we are looking for) is within the boundaries of the vector<>
-		if (id < componentArray .size()) {
+		if (id < componentArray.size()) {
 			// Loop trough the whole vector<>
-			for (const std::unique_ptr<Component> & componentPtr : componentArray[id]) {
+			for (const std::unique_ptr<Component> & componentPtr :
+				 componentArray[id]) {
 				// Cast the unique_ptr to a raw pointer
 				T * castedComponent = static_cast<T *>(componentPtr.get());
 
@@ -92,7 +98,7 @@ ComponentManager::GetComponentsByID(std::uint32_t id) const {
 
 template <typename T>
 std::vector<std::reference_wrapper<T>>
-ComponentManager::GetComponentsByType() const {
+ComponentManager::get_components_by_type() const {
 	// Determine the type of T (this is used as the key of the unordered_map<>)
 	std::type_index type = typeid(T);
 
@@ -105,10 +111,13 @@ ComponentManager::GetComponentsByType() const {
 	if (components.find(type) != components.end()) {
 
 		// Get the correct vector<>
-		const std::vector<std::vector<std::unique_ptr<Component>>> & componentArray = components.at(type);
+		const std::vector<std::vector<std::unique_ptr<Component>>> &
+			componentArray
+			= components.at(type);
 
 		// Loop through the whole vector<>
-		for (const std::vector<std::unique_ptr<Component>> & component : componentArray) {
+		for (const std::vector<std::unique_ptr<Component>> & component :
+			 componentArray) {
 			// Loop trough the whole vector<>
 			for (const std::unique_ptr<Component> & componentPtr : component) {
 				// Cast the unique_ptr to a raw pointer
@@ -130,5 +139,4 @@ ComponentManager::GetComponentsByType() const {
 	return componentVector;
 }
 
-}
-
+} // namespace crepe
diff --git a/src/crepe/Components.cpp b/src/crepe/Components.cpp
index 9760daa..4a43692 100644
--- a/src/crepe/Components.cpp
+++ b/src/crepe/Components.cpp
@@ -3,11 +3,12 @@
 
 using namespace crepe;
 
-Component::Component() : mActive(true) {}
+Component::Component() : m_active(true) {}
 
-Sprite::Sprite(std::string path) : mPath(path) {}
+Sprite::Sprite(std::string path) : m_path(path) {}
 
 Rigidbody::Rigidbody(int mass, int gravityScale, int bodyType)
-	: mMass(mass), mGravityScale(gravityScale), mBodyType(bodyType) {}
+	: m_mass(mass), m_gravity_scale(gravityScale), m_body_type(bodyType) {}
+
+Collider::Collider(int size) : m_size(size) {}
 
-Colider::Colider(int size) : mSize(size) {}
diff --git a/src/crepe/Components.h b/src/crepe/Components.h
index 7cb6fbb..1ad9ef2 100644
--- a/src/crepe/Components.h
+++ b/src/crepe/Components.h
@@ -8,7 +8,7 @@ class Component {
 public:
 	Component();
 
-	bool mActive;
+	bool m_active;
 };
 
 // TODO: these should be in separate files
@@ -17,23 +17,23 @@ class Sprite : public Component {
 public:
 	Sprite(std::string path);
 
-	std::string mPath;
+	std::string m_path;
 };
 
 class Rigidbody : public Component {
 public:
 	Rigidbody(int mass, int gravityScale, int bodyType);
 
-	int mMass;
-	int mGravityScale;
-	int mBodyType;
+	int m_mass;
+	int m_gravity_scale;
+	int m_body_type;
 };
 
-class Colider : public Component {
+class Collider : public Component {
 public:
-	Colider(int size);
+	Collider(int size);
 
-	int mSize;
+	int m_size;
 };
 
-}
+} // namespace crepe
diff --git a/src/crepe/GameObject.cpp b/src/crepe/GameObject.cpp
index 5ac9d7a..16dc62f 100644
--- a/src/crepe/GameObject.cpp
+++ b/src/crepe/GameObject.cpp
@@ -6,4 +6,4 @@ using namespace crepe;
 
 GameObject::GameObject(std::uint32_t id, std::string name, std::string tag,
 					   int layer)
-	: mId(id), mName(name), mTag(tag), mActive(true), mLayer(layer) {}
+	: m_id(id), m_name(name), m_tag(tag), m_active(true), m_layer(layer) {}
diff --git a/src/crepe/GameObject.h b/src/crepe/GameObject.h
index 71ef60d..f0f5ea0 100644
--- a/src/crepe/GameObject.h
+++ b/src/crepe/GameObject.h
@@ -9,14 +9,14 @@ class GameObject {
 public:
 	GameObject(std::uint32_t id, std::string name, std::string tag, int layer);
 
-	template <typename T, typename... Args> void AddComponent(Args &&... args);
+	template <typename T, typename... Args>
+	void add_component(Args &&... args);
 
-	std::uint32_t mId;
-	std::string mName;
-	std::string mTag;
-	bool mActive;
-	int mLayer;
+	std::uint32_t m_id;
+	std::string m_name;
+	std::string m_tag;
+	bool m_active;
+	int m_layer;
 };
 
-}
-
+} // namespace crepe
diff --git a/src/crepe/GameObject.hpp b/src/crepe/GameObject.hpp
index 5a672cf..1152ddf 100644
--- a/src/crepe/GameObject.hpp
+++ b/src/crepe/GameObject.hpp
@@ -8,8 +8,8 @@ namespace crepe {
 
 template <typename T, typename... Args>
 void GameObject::AddComponent(Args &&... args) {
-	ComponentManager::get_instance().AddComponent<T>(mId, std::forward<Args>(args)...);
-}
-
+	ComponentManager::get_instance().AddComponent<T>(
+		mId, std::forward<Args>(args)...);
 }
 
+} // namespace crepe
diff --git a/src/crepe/api/AudioSource.h b/src/crepe/api/AudioSource.h
index 2002d1a..2d26cda 100644
--- a/src/crepe/api/AudioSource.h
+++ b/src/crepe/api/AudioSource.h
@@ -35,7 +35,7 @@ public:
 	float volume;
 
 private:
-	std::unique_ptr<crepe::Sound> _sound;
+	std::unique_ptr<crepe::Sound> sound;
 };
 
 } // namespace crepe::api
-- 
cgit v1.2.3


From f8bc2a06a90c0ee172054db7ae2e1fdae09d14a3 Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Sun, 6 Oct 2024 14:10:52 +0200
Subject: code standard v3

---
 .clang-tidy                    | 10 +++---
 src/CMakeLists.txt             |  3 --
 src/crepe/ComponentManager.h   |  2 --
 src/crepe/ComponentManager.hpp | 74 ++++++++++++++++++++++--------------------
 src/crepe/Components.cpp       | 11 +++----
 src/crepe/Components.h         | 12 +++----
 src/crepe/GameObject.cpp       |  4 +--
 src/crepe/GameObject.h         | 12 +++----
 src/crepe/GameObject.hpp       |  6 ++--
 src/crepe/api/AudioSource.cpp  | 10 +++---
 src/crepe/util/log.cpp         | 10 +++---
 src/crepe/util/log.h           | 10 +++---
 12 files changed, 81 insertions(+), 83 deletions(-)

(limited to 'src/crepe')

diff --git a/.clang-tidy b/.clang-tidy
index 0ec997d..214a5ab 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -14,13 +14,15 @@ CheckOptions:
     value: 'lower_case'
   - key: 'readability-identifier-naming.MemberPrefix'
     value: ''
-  - key: 'readability-identifier-naming.GlobalConstantCase'
+  - key: 'readability-identifier-naming.ConstantCase'
     value: 'UPPER_CASE'
-  - key: 'readability-identifier-naming.GlobalConstantIgnoredRegexp'
+  - key: 'readability-identifier-naming.ConstantIgnoredRegexp'
     value: '_.*'
-  - key: 'readability-identifier-naming.GlobalVariableCase'
+  - key: 'readability-identifier-naming.ConstantParameterCase'
     value: 'lower_case'
-  - key: 'readability-identifier-naming.GlobalVariableIgnoredRegexp'
+  - key: 'readability-identifier-naming.VariableCase'
+    value: 'lower_case'
+  - key: 'readability-identifier-naming.VariableIgnoredRegexp'
     value: '_.*'
   - key: 'readability-identifier-naming.MacroDefinitionCase'
     value: 'UPPER_CASE'
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 62ca9a0..49d65a6 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -3,10 +3,7 @@ cmake_minimum_required(VERSION 3.28)
 set(CMAKE_C_STANDARD 11)
 set(CMAKE_CXX_STANDARD 20)
 set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
-
-# enable debug features
 set(CMAKE_BUILD_TYPE Debug)
-add_compile_definitions(DEBUG)
 
 add_subdirectory(../lib/soloud soloud)
 add_subdirectory(../lib/googletest googletest)
diff --git a/src/crepe/ComponentManager.h b/src/crepe/ComponentManager.h
index b88ad27..cf6edad 100644
--- a/src/crepe/ComponentManager.h
+++ b/src/crepe/ComponentManager.h
@@ -58,5 +58,3 @@ private:
 };
 
 } // namespace crepe
-
-// #include "ComponentManager.hpp"
diff --git a/src/crepe/ComponentManager.hpp b/src/crepe/ComponentManager.hpp
index 30b0e38..999cdcf 100644
--- a/src/crepe/ComponentManager.hpp
+++ b/src/crepe/ComponentManager.hpp
@@ -5,15 +5,16 @@
 namespace crepe {
 
 template <typename T, typename... Args>
-void ComponentManager::add_component(std::uint32_t id, Args &&... args) {
+void ComponentManager::add_component(uint32_t id, Args &&... args) {
+	using namespace std;
+
 	// Determine the type of T (this is used as the key of the unordered_map<>)
-	std::type_index type = typeid(T);
+	type_index type = typeid(T);
 
 	// Check if this component type is already in the unordered_map<>
 	if (components.find(type) == components.end()) {
 		//If not, create a new (empty) vector<> of vector<unique_ptr<Component>>
-		components[type]
-			= std::vector<std::vector<std::unique_ptr<Component>>>();
+		components[type] = vector<vector<unique_ptr<Component>>>();
 	}
 
 	// Resize the vector<> if the id is greater than the current size
@@ -24,25 +25,26 @@ void ComponentManager::add_component(std::uint32_t id, Args &&... args) {
 
 	// Create a new component of type T using perfect forwarding and store its
 	// unique_ptr in the vector<>
-	components[type][id].push_back(
-		std::make_unique<T>(std::forward<Args>(args)...));
+	components[type][id].push_back(make_unique<T>(forward<Args>(args)...));
 }
 
 template <typename T>
-void ComponentManager::delete_components_by_id(std::uint32_t id) {
+void ComponentManager::delete_components_by_id(uint32_t id) {
+	using namespace std;
+
 	// Determine the type of T (this is used as the key of the unordered_map<>)
-	std::type_index type = typeid(T);
+	type_index type = typeid(T);
 
 	// Find the type (in the unordered_map<>)
 	if (components.find(type) != components.end()) {
 		// Get the correct vector<>
-		std::vector<std::vector<std::unique_ptr<Component>>> & componentArray
+		vector<vector<unique_ptr<Component>>> & component_array
 			= components[type];
 
 		// Make sure that the id (that we are looking for) is within the boundaries of the vector<>
-		if (id < componentArray.size()) {
+		if (id < component_array.size()) {
 			// Clear the whole vector<> of this specific type and id
-			componentArray[id].clear();
+			component_array[id].clear();
 		}
 	}
 }
@@ -61,72 +63,74 @@ void ComponentManager::delete_components() {
 
 template <typename T>
 std::vector<std::reference_wrapper<T>>
-ComponentManager::get_components_by_id(std::uint32_t id) const {
+ComponentManager::get_components_by_id(uint32_t id) const {
+	using namespace std;
+
 	// Determine the type of T (this is used as the key of the unordered_map<>)
-	std::type_index type = typeid(T);
+	type_index type = typeid(T);
 
 	// Create an empty vector<>
-	std::vector<std::reference_wrapper<T>> componentVector;
+	vector<reference_wrapper<T>> component_vector;
 
 	// Find the type (in the unordered_map<>)
 	if (components.find(type) != components.end()) {
 		// Get the correct vector<>
-		const std::vector<std::vector<std::unique_ptr<Component>>> &
-			componentArray
+		const vector<vector<unique_ptr<Component>>> & component_array
 			= components.at(type);
 
 		// Make sure that the id (that we are looking for) is within the boundaries of the vector<>
-		if (id < componentArray.size()) {
+		if (id < component_array.size()) {
 			// Loop trough the whole vector<>
-			for (const std::unique_ptr<Component> & componentPtr :
-				 componentArray[id]) {
+			for (const unique_ptr<Component> & component_ptr :
+				 component_array[id]) {
 				// Cast the unique_ptr to a raw pointer
-				T * castedComponent = static_cast<T *>(componentPtr.get());
+				T * casted_component = static_cast<T *>(component_ptr.get());
 
 				// Ensure that the cast was successful
-				if (castedComponent) {
+				if (casted_component) {
 					// Add the dereferenced raw pointer to the vector<>
-					componentVector.push_back(*castedComponent);
+					component_vector.push_back(*casted_component);
 				}
 			}
 		}
 	}
 
 	// Return the vector<>
-	return componentVector;
+	return component_vector;
 }
 
 template <typename T>
 std::vector<std::reference_wrapper<T>>
 ComponentManager::get_components_by_type() const {
+	using namespace std;
+
 	// Determine the type of T (this is used as the key of the unordered_map<>)
-	std::type_index type = typeid(T);
+	type_index type = typeid(T);
 
 	// Create an empty vector<>
-	std::vector<std::reference_wrapper<T>> componentVector;
+	vector<reference_wrapper<T>> component_vector;
 	// Set the id to 0 (the id will also be stored in the returned vector<>)
-	// std::uint32_t id = 0;
+	// uint32_t id = 0;
 
 	// Find the type (in the unordered_map<>)
 	if (components.find(type) != components.end()) {
 
 		// Get the correct vector<>
-		const std::vector<std::vector<std::unique_ptr<Component>>> &
-			componentArray
+		const vector<vector<unique_ptr<Component>>> & component_array
 			= components.at(type);
 
 		// Loop through the whole vector<>
-		for (const std::vector<std::unique_ptr<Component>> & component :
-			 componentArray) {
+		for (const vector<unique_ptr<Component>> & component :
+			 component_array) {
 			// Loop trough the whole vector<>
-			for (const std::unique_ptr<Component> & componentPtr : component) {
+			for (const unique_ptr<Component> & component_ptr : component) {
 				// Cast the unique_ptr to a raw pointer
-				T * castedComponent = static_cast<T *>(componentPtr.get());
+				T * casted_component = static_cast<T *>(component_ptr.get());
 
 				// Ensure that the cast was successful
-				if (castedComponent) {
+				if (casted_component) {
 					// Pair the dereferenced raw pointer and the id and add it to the vector<>
-					componentVector.emplace_back(std::ref(*castedComponent));
+					component_vector.emplace_back(ref(*casted_component));
 				}
 			}
 
@@ -136,7 +140,7 @@ ComponentManager::get_components_by_type() const {
 	}
 
 	// Return the vector<>
-	return componentVector;
+	return component_vector;
 }
 
 } // namespace crepe
diff --git a/src/crepe/Components.cpp b/src/crepe/Components.cpp
index 4a43692..f27c7a4 100644
--- a/src/crepe/Components.cpp
+++ b/src/crepe/Components.cpp
@@ -1,14 +1,13 @@
 #include "Components.h"
-#include <iostream>
 
 using namespace crepe;
+using namespace std;
 
-Component::Component() : m_active(true) {}
+Component::Component() : active(true) {}
 
-Sprite::Sprite(std::string path) : m_path(path) {}
+Sprite::Sprite(string path) : path(path) {}
 
 Rigidbody::Rigidbody(int mass, int gravityScale, int bodyType)
-	: m_mass(mass), m_gravity_scale(gravityScale), m_body_type(bodyType) {}
-
-Collider::Collider(int size) : m_size(size) {}
+	: mass(mass), gravity_scale(gravityScale), body_type(bodyType) {}
 
+Collider::Collider(int size) : size(size) {}
diff --git a/src/crepe/Components.h b/src/crepe/Components.h
index 1ad9ef2..139599c 100644
--- a/src/crepe/Components.h
+++ b/src/crepe/Components.h
@@ -8,7 +8,7 @@ class Component {
 public:
 	Component();
 
-	bool m_active;
+	bool active;
 };
 
 // TODO: these should be in separate files
@@ -17,23 +17,23 @@ class Sprite : public Component {
 public:
 	Sprite(std::string path);
 
-	std::string m_path;
+	std::string path;
 };
 
 class Rigidbody : public Component {
 public:
 	Rigidbody(int mass, int gravityScale, int bodyType);
 
-	int m_mass;
-	int m_gravity_scale;
-	int m_body_type;
+	int mass;
+	int gravity_scale;
+	int body_type;
 };
 
 class Collider : public Component {
 public:
 	Collider(int size);
 
-	int m_size;
+	int size;
 };
 
 } // namespace crepe
diff --git a/src/crepe/GameObject.cpp b/src/crepe/GameObject.cpp
index 16dc62f..304f75a 100644
--- a/src/crepe/GameObject.cpp
+++ b/src/crepe/GameObject.cpp
@@ -1,9 +1,7 @@
 #include "GameObject.h"
 
-#include "ComponentManager.h"
-
 using namespace crepe;
 
 GameObject::GameObject(std::uint32_t id, std::string name, std::string tag,
 					   int layer)
-	: m_id(id), m_name(name), m_tag(tag), m_active(true), m_layer(layer) {}
+	: id(id), name(name), tag(tag), active(true), layer(layer) {}
diff --git a/src/crepe/GameObject.h b/src/crepe/GameObject.h
index f0f5ea0..114990c 100644
--- a/src/crepe/GameObject.h
+++ b/src/crepe/GameObject.h
@@ -7,16 +7,16 @@ namespace crepe {
 
 class GameObject {
 public:
-	GameObject(std::uint32_t id, std::string name, std::string tag, int layer);
+	GameObject(uint32_t id, std::string name, std::string tag, int layer);
 
 	template <typename T, typename... Args>
 	void add_component(Args &&... args);
 
-	std::uint32_t m_id;
-	std::string m_name;
-	std::string m_tag;
-	bool m_active;
-	int m_layer;
+	uint32_t id;
+	std::string name;
+	std::string tag;
+	bool active;
+	int layer;
 };
 
 } // namespace crepe
diff --git a/src/crepe/GameObject.hpp b/src/crepe/GameObject.hpp
index 1152ddf..5966fbf 100644
--- a/src/crepe/GameObject.hpp
+++ b/src/crepe/GameObject.hpp
@@ -7,9 +7,9 @@
 namespace crepe {
 
 template <typename T, typename... Args>
-void GameObject::AddComponent(Args &&... args) {
-	ComponentManager::get_instance().AddComponent<T>(
-		mId, std::forward<Args>(args)...);
+void GameObject::add_component(Args &&... args) {
+	auto & mgr = ComponentManager::get_instance();
+	mgr.add_component<T>(id, std::forward<Args>(args)...);
 }
 
 } // namespace crepe
diff --git a/src/crepe/api/AudioSource.cpp b/src/crepe/api/AudioSource.cpp
index 656fc46..b512d27 100644
--- a/src/crepe/api/AudioSource.cpp
+++ b/src/crepe/api/AudioSource.cpp
@@ -6,17 +6,17 @@
 using namespace crepe::api;
 
 AudioSource::AudioSource(std::unique_ptr<Asset> audio_clip) {
-	this->_sound = std::make_unique<crepe::Sound>(std::move(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();
+	this->sound->set_looping(looping);
+	this->sound->play();
 }
 
 void AudioSource::stop() {
-	this->_sound->pause();
-	this->_sound->rewind();
+	this->sound->pause();
+	this->sound->rewind();
 }
diff --git a/src/crepe/util/log.cpp b/src/crepe/util/log.cpp
index 6829ec3..f91d52c 100644
--- a/src/crepe/util/log.cpp
+++ b/src/crepe/util/log.cpp
@@ -8,10 +8,10 @@
 using namespace crepe::util;
 
 static const char * const LOG_PREFIX[] = {
-	[log_level::debug] = "[DBG] ",
-	[log_level::info] = "[INFO] ",
-	[log_level::warning] = "[WARN] ",
-	[log_level::error] = "[ERR] ",
+	[log_level::DEBUG] = "[DBG] ",
+	[log_level::INFO] = "[INFO] ",
+	[log_level::WARNING] = "[WARN] ",
+	[log_level::ERROR] = "[ERR] ",
 };
 
 static void va_logf(enum log_level level, va_list args, const std::string fmt) {
@@ -38,7 +38,7 @@ static void va_logf(enum log_level level, va_list args, const std::string fmt) {
 void crepe::util::logf(const char * fmt, ...) {
 	va_list args;
 	va_start(args, fmt);
-	va_logf(crepe::util::log_level::debug, args, fmt);
+	va_logf(crepe::util::log_level::DEBUG, args, fmt);
 	va_end(args);
 }
 
diff --git a/src/crepe/util/log.h b/src/crepe/util/log.h
index bfe7291..2b0fbe1 100644
--- a/src/crepe/util/log.h
+++ b/src/crepe/util/log.h
@@ -7,7 +7,7 @@
 
 // utility macros
 #define _crepe_logf_here(fmt, ...) \
-	crepe::util::logf(util::log_level::debug, "%s%s (%s:%d)" fmt "\n", \
+	crepe::util::logf(util::log_level::DEBUG, "%s%s (%s:%d)" fmt "\n", \
 					  crepe::util::color::FG_WHITE, __PRETTY_FUNCTION__, \
 					  __FILE_NAME__, __LINE__, crepe::util::color::RESET, \
 					  __VA_ARGS__)
@@ -24,10 +24,10 @@
 namespace crepe::util {
 
 enum log_level {
-	debug,
-	info,
-	warning,
-	error,
+	DEBUG,
+	INFO,
+	WARNING,
+	ERROR,
 };
 
 void logf(const char * fmt, ...);
-- 
cgit v1.2.3


From 39815f58e3842bb28e644e83111a619bd1374855 Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Sun, 6 Oct 2024 15:12:01 +0200
Subject: add components_internal example

---
 src/crepe/ComponentManager.cpp      |  2 +-
 src/crepe/ComponentManager.h        | 11 +++++---
 src/crepe/GameObject.cpp            |  2 +-
 src/crepe/GameObject.h              |  3 ++
 src/example/CMakeLists.txt          | 18 ++++++++++--
 src/example/components_internal.cpp | 56 +++++++++++++++++++++++++++++++++++++
 6 files changed, 84 insertions(+), 8 deletions(-)
 create mode 100644 src/example/components_internal.cpp

(limited to 'src/crepe')

diff --git a/src/crepe/ComponentManager.cpp b/src/crepe/ComponentManager.cpp
index b080c9d..9a3fec7 100644
--- a/src/crepe/ComponentManager.cpp
+++ b/src/crepe/ComponentManager.cpp
@@ -7,7 +7,7 @@ ComponentManager & ComponentManager::get_instance() {
 	return instance;
 }
 
-void ComponentManager::delete_all_components_of_id(std::uint32_t id) {
+void ComponentManager::delete_all_components_of_id(uint32_t id) {
 	// Loop through all the types (in the unordered_map<>)
 	for (auto & [type, componentArray] : components) {
 		// Make sure that the id (that we are looking for) is within the boundaries of the vector<>
diff --git a/src/crepe/ComponentManager.h b/src/crepe/ComponentManager.h
index cf6edad..9e559dd 100644
--- a/src/crepe/ComponentManager.h
+++ b/src/crepe/ComponentManager.h
@@ -23,22 +23,22 @@ public:
 public:
 	//! Add a component of a specific type
 	template <typename T, typename... Args>
-	void add_component(std::uint32_t id, Args &&... args);
+	void add_component(uint32_t id, Args &&... args);
 	//! Deletes all components of a specific type and id
 	template <typename T>
-	void delete_components_by_id(std::uint32_t id);
+	void delete_components_by_id(uint32_t id);
 	//! Deletes all components of a specific type
 	template <typename T>
 	void delete_components();
 	//! Deletes all components of a specific id
-	void delete_all_components_of_id(std::uint32_t id);
+	void delete_all_components_of_id(uint32_t id);
 	//! Deletes all components
 	void delete_all_components();
 
 	//! Get a vector<> of all components at specific type and id
 	template <typename T>
 	std::vector<std::reference_wrapper<T>>
-	get_components_by_id(std::uint32_t id) const;
+	get_components_by_id(uint32_t id) const;
 	//! Get a vector<> of all components of a specific type
 	template <typename T>
 	std::vector<std::reference_wrapper<T>> get_components_by_type() const;
@@ -58,3 +58,6 @@ private:
 };
 
 } // namespace crepe
+
+#include "ComponentManager.hpp"
+
diff --git a/src/crepe/GameObject.cpp b/src/crepe/GameObject.cpp
index 304f75a..de3beb6 100644
--- a/src/crepe/GameObject.cpp
+++ b/src/crepe/GameObject.cpp
@@ -2,6 +2,6 @@
 
 using namespace crepe;
 
-GameObject::GameObject(std::uint32_t id, std::string name, std::string tag,
+GameObject::GameObject(uint32_t id, std::string name, std::string tag,
 					   int layer)
 	: id(id), name(name), tag(tag), active(true), layer(layer) {}
diff --git a/src/crepe/GameObject.h b/src/crepe/GameObject.h
index 114990c..d5a7c36 100644
--- a/src/crepe/GameObject.h
+++ b/src/crepe/GameObject.h
@@ -20,3 +20,6 @@ public:
 };
 
 } // namespace crepe
+
+#include "GameObject.hpp"
+
diff --git a/src/example/CMakeLists.txt b/src/example/CMakeLists.txt
index bcc9271..eef38fd 100644
--- a/src/example/CMakeLists.txt
+++ b/src/example/CMakeLists.txt
@@ -1,3 +1,17 @@
-add_executable(audio_internal EXCLUDE_FROM_ALL audio_internal.cpp)
-target_link_libraries(audio_internal PUBLIC crepe)
+# add_example(target_name [SOURCES...])
+function(add_example target_name)
+	# if SOURCES is not specified
+	if(NOT ARGV1)
+		# A .cpp file with target_name exists, and should be used
+		set(sources ${target_name}.cpp)
+	else()
+		set(sources ${ARGV})
+	endif()
+
+	add_executable(${target_name} EXCLUDE_FROM_ALL ${sources})
+	target_link_libraries(${target_name} PUBLIC crepe)
+endfunction()
+
+add_example(audio_internal)
+add_example(components_internal)
 
diff --git a/src/example/components_internal.cpp b/src/example/components_internal.cpp
new file mode 100644
index 0000000..821a7de
--- /dev/null
+++ b/src/example/components_internal.cpp
@@ -0,0 +1,56 @@
+/** \file
+ * 
+ * Standalone example for usage of the internal ECS
+ */
+
+#include <cassert>
+#include <chrono>
+
+#include <crepe/util/log.h>
+#include <crepe/ComponentManager.h>
+#include <crepe/GameObject.h>
+#include <crepe/Components.h>
+
+using namespace crepe;
+using namespace std;
+
+#define OBJ_COUNT 100000
+
+int main() {
+	dbg_trace();
+
+	auto & mgr = ComponentManager::get_instance();
+
+  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);
+    game_object[i]->add_component<Collider>(i);
+  }
+
+  auto stop_adding = chrono::high_resolution_clock::now();
+
+  auto sprites = mgr.get_components_by_type<Sprite>();
+  for (auto sprite : sprites) {
+		assert(sprite.get().path == "test");
+  }
+
+  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 - stop_adding);
+	printf("add time:  %ldus\n", add_time.count());
+	printf("loop time: %ldus\n", loop_time.count());
+
+	return 0;
+}
+
-- 
cgit v1.2.3


From aa8755148cbca29b584f7a146636b506070717f9 Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Sun, 6 Oct 2024 15:28:12 +0200
Subject: move components to separate files

---
 contributing.md                     |  1 +
 src/crepe/CMakeLists.txt            | 10 ++++++++--
 src/crepe/Collider.cpp              |  6 ++++++
 src/crepe/Collider.h                | 15 ++++++++++++++
 src/crepe/Component.cpp             |  6 ++++++
 src/crepe/Component.h               | 15 ++++++++++++++
 src/crepe/ComponentManager.h        |  2 +-
 src/crepe/Components.cpp            | 13 -------------
 src/crepe/Components.h              | 39 -------------------------------------
 src/crepe/Rigidbody.cpp             |  7 +++++++
 src/crepe/Rigidbody.h               | 16 +++++++++++++++
 src/crepe/Sprite.cpp                |  9 +++++++++
 src/crepe/Sprite.h                  | 17 ++++++++++++++++
 src/example/components_internal.cpp |  5 ++++-
 14 files changed, 105 insertions(+), 56 deletions(-)
 create mode 100644 src/crepe/Collider.cpp
 create mode 100644 src/crepe/Collider.h
 create mode 100644 src/crepe/Component.cpp
 create mode 100644 src/crepe/Component.h
 delete mode 100644 src/crepe/Components.cpp
 delete mode 100644 src/crepe/Components.h
 create mode 100644 src/crepe/Rigidbody.cpp
 create mode 100644 src/crepe/Rigidbody.h
 create mode 100644 src/crepe/Sprite.cpp
 create mode 100644 src/crepe/Sprite.h

(limited to 'src/crepe')

diff --git a/contributing.md b/contributing.md
index 933f1bf..b79f7a7 100644
--- a/contributing.md
+++ b/contributing.md
@@ -17,6 +17,7 @@
 # Code style
 
 - ASCII only
+- Class names are always singular
 - Explanatory comments are placed above the line(s) they are explaining
 - Source files should only contain comments that plainly state what the code is
   supposed to do
diff --git a/src/crepe/CMakeLists.txt b/src/crepe/CMakeLists.txt
index 5840208..d7d563e 100644
--- a/src/crepe/CMakeLists.txt
+++ b/src/crepe/CMakeLists.txt
@@ -3,8 +3,11 @@ target_sources(crepe PUBLIC
 	Sound.cpp
 	SoundContext.cpp
 	ComponentManager.cpp
-	Components.cpp
+	Component.cpp
 	GameObject.cpp
+	Collider.cpp
+	Rigidbody.cpp
+	Sprite.cpp
 )
 
 target_sources(crepe PUBLIC FILE_SET HEADERS FILES
@@ -13,9 +16,12 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES
 	SoundContext.h
 	ComponentManager.h
 	ComponentManager.hpp
-	Components.h
+	Component.h
 	GameObject.h
 	GameObject.hpp
+	Collider.h
+	Rigidbody.h
+	Sprite.h
 )
 
 add_subdirectory(api)
diff --git a/src/crepe/Collider.cpp b/src/crepe/Collider.cpp
new file mode 100644
index 0000000..b7040eb
--- /dev/null
+++ b/src/crepe/Collider.cpp
@@ -0,0 +1,6 @@
+#include "Collider.h"
+
+using namespace crepe;
+
+Collider::Collider(int size) : size(size) {}
+
diff --git a/src/crepe/Collider.h b/src/crepe/Collider.h
new file mode 100644
index 0000000..666386d
--- /dev/null
+++ b/src/crepe/Collider.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "Component.h"
+
+namespace crepe {
+
+class Collider : public Component {
+public:
+	Collider(int size);
+
+	int size;
+};
+
+}
+
diff --git a/src/crepe/Component.cpp b/src/crepe/Component.cpp
new file mode 100644
index 0000000..9a7731a
--- /dev/null
+++ b/src/crepe/Component.cpp
@@ -0,0 +1,6 @@
+#include "Component.h"
+
+using namespace crepe;
+
+Component::Component() : active(true) {}
+
diff --git a/src/crepe/Component.h b/src/crepe/Component.h
new file mode 100644
index 0000000..6e23d93
--- /dev/null
+++ b/src/crepe/Component.h
@@ -0,0 +1,15 @@
+#pragma once
+
+namespace crepe {
+
+class Component {
+public:
+	Component();
+	// TODO: shouldn't this constructor be deleted because this class will never
+	// directly be instantiated?
+
+	bool active;
+};
+
+} // namespace crepe
+
diff --git a/src/crepe/ComponentManager.h b/src/crepe/ComponentManager.h
index 9e559dd..9463558 100644
--- a/src/crepe/ComponentManager.h
+++ b/src/crepe/ComponentManager.h
@@ -7,7 +7,7 @@
 #include <utility>
 #include <vector>
 
-#include "Components.h"
+#include "Component.h"
 
 namespace crepe {
 
diff --git a/src/crepe/Components.cpp b/src/crepe/Components.cpp
deleted file mode 100644
index f27c7a4..0000000
--- a/src/crepe/Components.cpp
+++ /dev/null
@@ -1,13 +0,0 @@
-#include "Components.h"
-
-using namespace crepe;
-using namespace std;
-
-Component::Component() : active(true) {}
-
-Sprite::Sprite(string path) : path(path) {}
-
-Rigidbody::Rigidbody(int mass, int gravityScale, int bodyType)
-	: mass(mass), gravity_scale(gravityScale), body_type(bodyType) {}
-
-Collider::Collider(int size) : size(size) {}
diff --git a/src/crepe/Components.h b/src/crepe/Components.h
deleted file mode 100644
index 139599c..0000000
--- a/src/crepe/Components.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#pragma once
-
-#include <string>
-
-namespace crepe {
-
-class Component {
-public:
-	Component();
-
-	bool active;
-};
-
-// TODO: these should be in separate files
-
-class Sprite : public Component {
-public:
-	Sprite(std::string path);
-
-	std::string path;
-};
-
-class Rigidbody : public Component {
-public:
-	Rigidbody(int mass, int gravityScale, int bodyType);
-
-	int mass;
-	int gravity_scale;
-	int body_type;
-};
-
-class Collider : public Component {
-public:
-	Collider(int size);
-
-	int size;
-};
-
-} // namespace crepe
diff --git a/src/crepe/Rigidbody.cpp b/src/crepe/Rigidbody.cpp
new file mode 100644
index 0000000..1518d28
--- /dev/null
+++ b/src/crepe/Rigidbody.cpp
@@ -0,0 +1,7 @@
+#include "Rigidbody.h"
+
+using namespace crepe;
+
+Rigidbody::Rigidbody(int mass, int gravityScale, int bodyType)
+	: mass(mass), gravity_scale(gravityScale), body_type(bodyType) {}
+
diff --git a/src/crepe/Rigidbody.h b/src/crepe/Rigidbody.h
new file mode 100644
index 0000000..67edb03
--- /dev/null
+++ b/src/crepe/Rigidbody.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "Component.h"
+
+namespace crepe {
+
+class Rigidbody : public Component {
+public:
+	Rigidbody(int mass, int gravityScale, int bodyType);
+
+	int mass;
+	int gravity_scale;
+	int body_type;
+};
+
+}
diff --git a/src/crepe/Sprite.cpp b/src/crepe/Sprite.cpp
new file mode 100644
index 0000000..c835d83
--- /dev/null
+++ b/src/crepe/Sprite.cpp
@@ -0,0 +1,9 @@
+#include <string>
+
+#include "Sprite.h"
+
+using namespace crepe;
+using namespace std;
+
+Sprite::Sprite(string path) : path(path) {}
+
diff --git a/src/crepe/Sprite.h b/src/crepe/Sprite.h
new file mode 100644
index 0000000..029064b
--- /dev/null
+++ b/src/crepe/Sprite.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#include <string>
+
+#include "Component.h"
+
+namespace crepe {
+
+class Sprite : public Component {
+public:
+	Sprite(std::string path);
+
+	std::string path;
+};
+
+}
+
diff --git a/src/example/components_internal.cpp b/src/example/components_internal.cpp
index 821a7de..4246dd7 100644
--- a/src/example/components_internal.cpp
+++ b/src/example/components_internal.cpp
@@ -9,7 +9,10 @@
 #include <crepe/util/log.h>
 #include <crepe/ComponentManager.h>
 #include <crepe/GameObject.h>
-#include <crepe/Components.h>
+#include <crepe/Component.h>
+#include <crepe/Sprite.h>
+#include <crepe/Rigidbody.h>
+#include <crepe/Collider.h>
 
 using namespace crepe;
 using namespace std;
-- 
cgit v1.2.3


From 8a509ad4c5e15fbf7eaade1c8bf4834f0d0069c5 Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Sun, 6 Oct 2024 15:29:39 +0200
Subject: `make format`

---
 src/crepe/Collider.cpp              |  1 -
 src/crepe/Collider.h                |  3 +--
 src/crepe/Component.cpp             |  1 -
 src/crepe/Component.h               |  1 -
 src/crepe/ComponentManager.h        |  1 -
 src/crepe/GameObject.h              |  1 -
 src/crepe/Rigidbody.cpp             |  1 -
 src/crepe/Rigidbody.h               |  2 +-
 src/crepe/Sprite.cpp                |  1 -
 src/crepe/Sprite.h                  |  3 +--
 src/example/components_internal.cpp | 47 +++++++++++++++++++------------------
 11 files changed, 27 insertions(+), 35 deletions(-)

(limited to 'src/crepe')

diff --git a/src/crepe/Collider.cpp b/src/crepe/Collider.cpp
index b7040eb..3f12afd 100644
--- a/src/crepe/Collider.cpp
+++ b/src/crepe/Collider.cpp
@@ -3,4 +3,3 @@
 using namespace crepe;
 
 Collider::Collider(int size) : size(size) {}
-
diff --git a/src/crepe/Collider.h b/src/crepe/Collider.h
index 666386d..120da05 100644
--- a/src/crepe/Collider.h
+++ b/src/crepe/Collider.h
@@ -11,5 +11,4 @@ public:
 	int size;
 };
 
-}
-
+} // namespace crepe
diff --git a/src/crepe/Component.cpp b/src/crepe/Component.cpp
index 9a7731a..d14159c 100644
--- a/src/crepe/Component.cpp
+++ b/src/crepe/Component.cpp
@@ -3,4 +3,3 @@
 using namespace crepe;
 
 Component::Component() : active(true) {}
-
diff --git a/src/crepe/Component.h b/src/crepe/Component.h
index 6e23d93..16a4ce5 100644
--- a/src/crepe/Component.h
+++ b/src/crepe/Component.h
@@ -12,4 +12,3 @@ public:
 };
 
 } // namespace crepe
-
diff --git a/src/crepe/ComponentManager.h b/src/crepe/ComponentManager.h
index 9463558..2ab9dc8 100644
--- a/src/crepe/ComponentManager.h
+++ b/src/crepe/ComponentManager.h
@@ -60,4 +60,3 @@ private:
 } // namespace crepe
 
 #include "ComponentManager.hpp"
-
diff --git a/src/crepe/GameObject.h b/src/crepe/GameObject.h
index d5a7c36..3588d9a 100644
--- a/src/crepe/GameObject.h
+++ b/src/crepe/GameObject.h
@@ -22,4 +22,3 @@ public:
 } // namespace crepe
 
 #include "GameObject.hpp"
-
diff --git a/src/crepe/Rigidbody.cpp b/src/crepe/Rigidbody.cpp
index 1518d28..495d908 100644
--- a/src/crepe/Rigidbody.cpp
+++ b/src/crepe/Rigidbody.cpp
@@ -4,4 +4,3 @@ using namespace crepe;
 
 Rigidbody::Rigidbody(int mass, int gravityScale, int bodyType)
 	: mass(mass), gravity_scale(gravityScale), body_type(bodyType) {}
-
diff --git a/src/crepe/Rigidbody.h b/src/crepe/Rigidbody.h
index 67edb03..63a8877 100644
--- a/src/crepe/Rigidbody.h
+++ b/src/crepe/Rigidbody.h
@@ -13,4 +13,4 @@ public:
 	int body_type;
 };
 
-}
+} // namespace crepe
diff --git a/src/crepe/Sprite.cpp b/src/crepe/Sprite.cpp
index c835d83..a5a5e68 100644
--- a/src/crepe/Sprite.cpp
+++ b/src/crepe/Sprite.cpp
@@ -6,4 +6,3 @@ using namespace crepe;
 using namespace std;
 
 Sprite::Sprite(string path) : path(path) {}
-
diff --git a/src/crepe/Sprite.h b/src/crepe/Sprite.h
index 029064b..143e702 100644
--- a/src/crepe/Sprite.h
+++ b/src/crepe/Sprite.h
@@ -13,5 +13,4 @@ public:
 	std::string path;
 };
 
-}
-
+} // namespace crepe
diff --git a/src/example/components_internal.cpp b/src/example/components_internal.cpp
index 4246dd7..54ce295 100644
--- a/src/example/components_internal.cpp
+++ b/src/example/components_internal.cpp
@@ -6,13 +6,13 @@
 #include <cassert>
 #include <chrono>
 
-#include <crepe/util/log.h>
+#include <crepe/Collider.h>
+#include <crepe/Component.h>
 #include <crepe/ComponentManager.h>
 #include <crepe/GameObject.h>
-#include <crepe/Component.h>
-#include <crepe/Sprite.h>
 #include <crepe/Rigidbody.h>
-#include <crepe/Collider.h>
+#include <crepe/Sprite.h>
+#include <crepe/util/log.h>
 
 using namespace crepe;
 using namespace std;
@@ -24,36 +24,37 @@ int main() {
 
 	auto & mgr = ComponentManager::get_instance();
 
-  auto start_adding = chrono::high_resolution_clock::now();
+	auto start_adding = chrono::high_resolution_clock::now();
 
-  GameObject * game_object[OBJ_COUNT];
+	GameObject * game_object[OBJ_COUNT];
 
-  for (int i = 0; i < OBJ_COUNT; ++i) {
-    game_object[i] = new GameObject(i, "Name", "Tag", 0);
+	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);
-    game_object[i]->add_component<Collider>(i);
-  }
+		game_object[i]->add_component<Sprite>("test");
+		game_object[i]->add_component<Rigidbody>(0, 0, i);
+		game_object[i]->add_component<Collider>(i);
+	}
 
-  auto stop_adding = chrono::high_resolution_clock::now();
+	auto stop_adding = chrono::high_resolution_clock::now();
 
-  auto sprites = mgr.get_components_by_type<Sprite>();
-  for (auto sprite : sprites) {
+	auto sprites = mgr.get_components_by_type<Sprite>();
+	for (auto sprite : sprites) {
 		assert(sprite.get().path == "test");
-  }
+	}
 
-  auto stop_looping = chrono::high_resolution_clock::now();
+	auto stop_looping = chrono::high_resolution_clock::now();
 
-  for (int i = 0; i < OBJ_COUNT; ++i) {
-    delete game_object[i];
-  }
+	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 - stop_adding);
+	auto add_time = chrono::duration_cast<chrono::microseconds>(stop_adding
+																- start_adding);
+	auto loop_time = chrono::duration_cast<chrono::microseconds>(stop_looping
+																 - stop_adding);
 	printf("add time:  %ldus\n", add_time.count());
 	printf("loop time: %ldus\n", loop_time.count());
 
 	return 0;
 }
-
-- 
cgit v1.2.3


From 2969fe8c0fca4826ca129fe12d2e125bb7955c78 Mon Sep 17 00:00:00 2001
From: Loek Le Blansch <loek@pipeframe.xyz>
Date: Sun, 6 Oct 2024 17:39:15 +0200
Subject: WIP ScriptSystem

---
 src/crepe/CMakeLists.txt         |  4 ++++
 src/crepe/ComponentManager.hpp   | 14 ++++++++++----
 src/crepe/Script.cpp             |  7 +++++++
 src/crepe/Script.h               | 16 ++++++++++++++++
 src/crepe/ScriptSystem.cpp       | 22 ++++++++++++++++++++++
 src/crepe/ScriptSystem.h         | 18 ++++++++++++++++++
 src/crepe/System.h               | 23 +++++++++++++++++++++++
 src/crepe/api/BehaviorScript.cpp | 10 ++++++++++
 src/crepe/api/BehaviorScript.h   | 17 +++++++++++++++++
 src/crepe/api/CMakeLists.txt     |  5 +++--
 src/crepe/api/Component.h        | 10 ----------
 src/example/CMakeLists.txt       |  1 +
 src/example/script.cpp           | 33 +++++++++++++++++++++++++++++++++
 13 files changed, 164 insertions(+), 16 deletions(-)
 create mode 100644 src/crepe/Script.cpp
 create mode 100644 src/crepe/Script.h
 create mode 100644 src/crepe/ScriptSystem.cpp
 create mode 100644 src/crepe/ScriptSystem.h
 create mode 100644 src/crepe/System.h
 create mode 100644 src/crepe/api/BehaviorScript.cpp
 create mode 100644 src/crepe/api/BehaviorScript.h
 delete mode 100644 src/crepe/api/Component.h
 create mode 100644 src/example/script.cpp

(limited to 'src/crepe')

diff --git a/src/crepe/CMakeLists.txt b/src/crepe/CMakeLists.txt
index d7d563e..d85aef0 100644
--- a/src/crepe/CMakeLists.txt
+++ b/src/crepe/CMakeLists.txt
@@ -8,6 +8,8 @@ target_sources(crepe PUBLIC
 	Collider.cpp
 	Rigidbody.cpp
 	Sprite.cpp
+	ScriptSystem.cpp
+	Script.cpp
 )
 
 target_sources(crepe PUBLIC FILE_SET HEADERS FILES
@@ -22,6 +24,8 @@ target_sources(crepe PUBLIC FILE_SET HEADERS FILES
 	Collider.h
 	Rigidbody.h
 	Sprite.h
+	System.h
+	ScriptSystem.h
 )
 
 add_subdirectory(api)
diff --git a/src/crepe/ComponentManager.hpp b/src/crepe/ComponentManager.hpp
index 999cdcf..084cd33 100644
--- a/src/crepe/ComponentManager.hpp
+++ b/src/crepe/ComponentManager.hpp
@@ -1,13 +1,17 @@
 #pragma once
 
+#include <type_traits>
+
 #include "ComponentManager.h"
 
 namespace crepe {
 
-template <typename T, typename... Args>
+template <class T, typename... Args>
 void ComponentManager::add_component(uint32_t id, Args &&... args) {
 	using namespace std;
 
+	static_assert(is_base_of<Component, T>::value, "add_component must recieve a derivative class of Component");
+
 	// Determine the type of T (this is used as the key of the unordered_map<>)
 	type_index type = typeid(T);
 
@@ -23,9 +27,11 @@ void ComponentManager::add_component(uint32_t id, Args &&... args) {
 		components[type].resize(id + 1);
 	}
 
-	// Create a new component of type T using perfect forwarding and store its
-	// unique_ptr in the vector<>
-	components[type][id].push_back(make_unique<T>(forward<Args>(args)...));
+	// Create a new component of type T (arguments directly forwarded). The
+	// constructor must be called by ComponentManager.
+	T * instance = new T(forward<Args>(args)...);
+	// store its unique_ptr in the vector<>
+	components[type][id].push_back(unique_ptr<T>(instance));
 }
 
 template <typename T>
diff --git a/src/crepe/Script.cpp b/src/crepe/Script.cpp
new file mode 100644
index 0000000..42e3666
--- /dev/null
+++ b/src/crepe/Script.cpp
@@ -0,0 +1,7 @@
+#include "Script.h"
+
+using namespace crepe;
+
+void Script::init() { }
+void Script::update() { }
+
diff --git a/src/crepe/Script.h b/src/crepe/Script.h
new file mode 100644
index 0000000..ba4073a
--- /dev/null
+++ b/src/crepe/Script.h
@@ -0,0 +1,16 @@
+#pragma once
+
+namespace crepe {
+
+class Script {
+protected:
+	virtual void init();
+	virtual void update();
+	// NOTE: additional *events* (like unity's OnDisable and OnEnable) should be
+	// implemented as member methods in derivative user script classes and
+	// registered in init(), otherwise this class will balloon in size with each
+	// added event.
+};
+
+}
+
diff --git a/src/crepe/ScriptSystem.cpp b/src/crepe/ScriptSystem.cpp
new file mode 100644
index 0000000..e301c71
--- /dev/null
+++ b/src/crepe/ScriptSystem.cpp
@@ -0,0 +1,22 @@
+#include "util/log.h"
+
+#include "ScriptSystem.h"
+
+using namespace crepe;
+
+ScriptSystem::ScriptSystem() {
+	dbg_trace();
+}
+ScriptSystem::~ScriptSystem() {
+	dbg_trace();
+}
+
+ScriptSystem & ScriptSystem::get_instance() {
+	static ScriptSystem instance;
+	return instance;
+}
+
+void ScriptSystem::update() {
+	dbg_trace();
+}
+
diff --git a/src/crepe/ScriptSystem.h b/src/crepe/ScriptSystem.h
new file mode 100644
index 0000000..e1ed290
--- /dev/null
+++ b/src/crepe/ScriptSystem.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include "System.h"
+
+namespace crepe {
+
+class ScriptSystem : public System {
+public:
+	static ScriptSystem & get_instance();
+	virtual void update();
+
+private:
+	ScriptSystem();
+	~ScriptSystem();
+};
+
+}
+
diff --git a/src/crepe/System.h b/src/crepe/System.h
new file mode 100644
index 0000000..3fe3d66
--- /dev/null
+++ b/src/crepe/System.h
@@ -0,0 +1,23 @@
+#pragma once
+
+namespace crepe {
+
+class System {
+public:
+	static System & get_instance();
+	virtual void update() = 0;
+
+protected:
+	System() { };
+	virtual ~System() { };
+
+private:
+	// singleton
+	System(const System &) = delete;
+	System(System &&) = delete;
+	System & operator=(const System &) = delete;
+	System & operator=(System &&) = delete;
+};
+
+}
+
diff --git a/src/crepe/api/BehaviorScript.cpp b/src/crepe/api/BehaviorScript.cpp
new file mode 100644
index 0000000..2dd933e
--- /dev/null
+++ b/src/crepe/api/BehaviorScript.cpp
@@ -0,0 +1,10 @@
+#include "../util/log.h"
+
+#include "BehaviorScript.h"
+
+using namespace crepe::api;
+
+BehaviorScript::BehaviorScript() {
+	dbg_trace();
+}
+
diff --git a/src/crepe/api/BehaviorScript.h b/src/crepe/api/BehaviorScript.h
new file mode 100644
index 0000000..e9542c1
--- /dev/null
+++ b/src/crepe/api/BehaviorScript.h
@@ -0,0 +1,17 @@
+#pragma once
+
+#include "../Script.h"
+#include "../Component.h"
+
+namespace crepe::api {
+
+class BehaviorScript : public Script, public Component {
+	// only allow ComponentManager to instantiate scripts
+	friend class ComponentManager;
+
+protected:
+	BehaviorScript();
+};
+
+}
+
diff --git a/src/crepe/api/CMakeLists.txt b/src/crepe/api/CMakeLists.txt
index 9548594..86623de 100644
--- a/src/crepe/api/CMakeLists.txt
+++ b/src/crepe/api/CMakeLists.txt
@@ -1,9 +1,10 @@
 target_sources(crepe PUBLIC
 	# AudioSource.cpp
+	BehaviorScript.cpp
 )
 
 target_sources(crepe PUBLIC FILE_SET HEADERS FILES
-	AudioSource.h
-	Component.h
+	# AudioSource.h
+	BehaviorScript.h
 )
 
diff --git a/src/crepe/api/Component.h b/src/crepe/api/Component.h
deleted file mode 100644
index d5e0499..0000000
--- a/src/crepe/api/Component.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#pragma once
-
-namespace crepe::api {
-
-class Component {
-public:
-	bool active;
-};
-
-} // namespace crepe::api
diff --git a/src/example/CMakeLists.txt b/src/example/CMakeLists.txt
index eef38fd..6df4ce7 100644
--- a/src/example/CMakeLists.txt
+++ b/src/example/CMakeLists.txt
@@ -14,4 +14,5 @@ endfunction()
 
 add_example(audio_internal)
 add_example(components_internal)
+add_example(script)
 
diff --git a/src/example/script.cpp b/src/example/script.cpp
new file mode 100644
index 0000000..28605c7
--- /dev/null
+++ b/src/example/script.cpp
@@ -0,0 +1,33 @@
+/** \file
+ * 
+ * Standalone example for usage of the script component and system
+ */
+
+#include <crepe/util/log.h>
+#include <crepe/ScriptSystem.h>
+#include <crepe/ComponentManager.h>
+#include <crepe/GameObject.h>
+
+#include <crepe/api/BehaviorScript.h>
+
+using namespace crepe;
+using namespace std;
+
+class MyScript : public api::BehaviorScript {
+	void update() {
+		dbg_trace();
+	}
+};
+
+int main() {
+	dbg_trace();
+
+	auto obj = GameObject(0, "name", "tag", 0);
+	obj.add_component<MyScript>();
+
+	auto & sys = ScriptSystem::get_instance();
+	sys.update(); // -> MyScript::update
+
+	return 0;
+}
+
-- 
cgit v1.2.3