From 918392ec503a66e369fffa3a5a49c8afccf96a62 Mon Sep 17 00:00:00 2001 From: Max-001 <80035972+Max-001@users.noreply.github.com> Date: Wed, 25 Sep 2024 13:32:07 +0200 Subject: Setup CMake --- mwe/ecs-homemade/CMakeLists.txt | 10 ++++++++++ mwe/ecs-homemade/src/main.cpp | 5 +++++ 2 files changed, 15 insertions(+) create mode 100644 mwe/ecs-homemade/CMakeLists.txt create mode 100644 mwe/ecs-homemade/src/main.cpp (limited to 'mwe') diff --git a/mwe/ecs-homemade/CMakeLists.txt b/mwe/ecs-homemade/CMakeLists.txt new file mode 100644 index 0000000..26bf600 --- /dev/null +++ b/mwe/ecs-homemade/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.5) +project(ecs-homemake) + +# Set the C++ standard (optional, but good practice) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +add_executable(ecs-homemake + src/main.cpp +) diff --git a/mwe/ecs-homemade/src/main.cpp b/mwe/ecs-homemade/src/main.cpp new file mode 100644 index 0000000..f8b829c --- /dev/null +++ b/mwe/ecs-homemade/src/main.cpp @@ -0,0 +1,5 @@ +#include + +int main() { + std::cout << "Hello, world!" << std::endl; +} -- cgit v1.2.3 From 5458abaca5f01a4d34bb55b1b44dc4fb4e9890be Mon Sep 17 00:00:00 2001 From: Max-001 <80035972+Max-001@users.noreply.github.com> Date: Wed, 25 Sep 2024 21:08:54 +0200 Subject: Made a homemade ECS --- mwe/ecs-homemade/CMakeLists.txt | 6 +++- mwe/ecs-homemade/inc/ComponentManager.h | 37 ++++++++++++++++++++ mwe/ecs-homemade/inc/ComponentManager.hpp | 58 +++++++++++++++++++++++++++++++ mwe/ecs-homemade/inc/Components.h | 22 ++++++++++++ mwe/ecs-homemade/inc/GameObjectMax.h | 20 +++++++++++ mwe/ecs-homemade/inc/GameObjectMax.hpp | 6 ++++ mwe/ecs-homemade/src/ComponentManager.cpp | 9 +++++ mwe/ecs-homemade/src/Components.cpp | 10 ++++++ mwe/ecs-homemade/src/GameObjectMax.cpp | 5 +++ mwe/ecs-homemade/src/main.cpp | 36 ++++++++++++++++++- 10 files changed, 207 insertions(+), 2 deletions(-) create mode 100644 mwe/ecs-homemade/inc/ComponentManager.h create mode 100644 mwe/ecs-homemade/inc/ComponentManager.hpp create mode 100644 mwe/ecs-homemade/inc/Components.h create mode 100644 mwe/ecs-homemade/inc/GameObjectMax.h create mode 100644 mwe/ecs-homemade/inc/GameObjectMax.hpp create mode 100644 mwe/ecs-homemade/src/ComponentManager.cpp create mode 100644 mwe/ecs-homemade/src/Components.cpp create mode 100644 mwe/ecs-homemade/src/GameObjectMax.cpp (limited to 'mwe') diff --git a/mwe/ecs-homemade/CMakeLists.txt b/mwe/ecs-homemade/CMakeLists.txt index 26bf600..5960181 100644 --- a/mwe/ecs-homemade/CMakeLists.txt +++ b/mwe/ecs-homemade/CMakeLists.txt @@ -2,9 +2,13 @@ cmake_minimum_required(VERSION 3.5) project(ecs-homemake) # Set the C++ standard (optional, but good practice) -set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED True) add_executable(ecs-homemake src/main.cpp + src/ComponentManager.cpp + src/Components.cpp + src/GameObjectMax.cpp ) +target_include_directories(ecs-homemake PRIVATE "${CMAKE_SOURCE_DIR}/inc") diff --git a/mwe/ecs-homemade/inc/ComponentManager.h b/mwe/ecs-homemade/inc/ComponentManager.h new file mode 100644 index 0000000..cfc5f20 --- /dev/null +++ b/mwe/ecs-homemade/inc/ComponentManager.h @@ -0,0 +1,37 @@ +#pragma once + +#include "Components.h" +#include +#include +#include +#include +#include +#include + +class ComponentManager { +public: + static ComponentManager& GetInstance(); + + ComponentManager(const ComponentManager&) = delete; + ComponentManager(ComponentManager&&) = delete; + ComponentManager& operator=(const ComponentManager&) = delete; + ComponentManager& operator=(ComponentManager&&) = delete; + + template + void AddComponent(T* component, std::uint32_t id); + template + T* GetComponent(std::uint32_t id); + template + std::vector GetAllComponentIDs(); + template + std::vector GetAllComponentPointer(); + +private: + static ComponentManager mInstance; + + ComponentManager(); + + std::unordered_map> mComponents; //TODO: Make this not only work with Component* OR add extra checks at templated methodes!!! +}; + +#include "ComponentManager.hpp" diff --git a/mwe/ecs-homemade/inc/ComponentManager.hpp b/mwe/ecs-homemade/inc/ComponentManager.hpp new file mode 100644 index 0000000..df8ea32 --- /dev/null +++ b/mwe/ecs-homemade/inc/ComponentManager.hpp @@ -0,0 +1,58 @@ +// AddComponent implementation +template +void ComponentManager::AddComponent(T* component, std::uint32_t id) { + std::type_index type = typeid(T); + if (mComponents.find(type) == mComponents.end()) { + mComponents[type] = std::vector(); + } + // Resize the vector if the id is greater than current size + if (id >= mComponents[type].size()) { + mComponents[type].resize(id + 1, nullptr); // Initialize new slots to nullptr + } + mComponents[type][id] = component; // Store the raw pointer +} + +// GetComponent implementation +template +T* ComponentManager::GetComponent(std::uint32_t id) { + std::type_index type = typeid(T); + if (mComponents.find(type) != mComponents.end()) { + auto& componentArray = mComponents[type]; + if (id < componentArray.size()) { + return static_cast(componentArray[id]); // Cast to the correct type + } + } + return nullptr; // Return nullptr if not found +} + +// GetAllComponentIDs implementation +template +std::vector ComponentManager::GetAllComponentIDs() { + std::type_index type = typeid(T); + std::vector ids; + if (mComponents.find(type) != mComponents.end()) { + const auto& componentArray = mComponents[type]; + for (std::uint32_t id = 0; id < componentArray.size(); ++id) { + if (componentArray[id] != nullptr) { + ids.push_back(id); // Collect IDs of non-null components + } + } + } + return ids; +} + +// GetAllComponentPointer implementation +template +std::vector ComponentManager::GetAllComponentPointer() { + std::type_index type = typeid(T); + std::vector pointers; + if (mComponents.find(type) != mComponents.end()) { + const auto& componentArray = mComponents[type]; + for (const auto& component : componentArray) { + if (component != nullptr) { + pointers.push_back(static_cast(component)); // Cast to the correct type + } + } + } + return pointers; +} diff --git a/mwe/ecs-homemade/inc/Components.h b/mwe/ecs-homemade/inc/Components.h new file mode 100644 index 0000000..1ea8428 --- /dev/null +++ b/mwe/ecs-homemade/inc/Components.h @@ -0,0 +1,22 @@ +#pragma once + +class Component { +public: + Component(); + + bool mActive; +}; + +class Sprite : public Component { +public: + void Render(); +}; + +class Rigidbody : public Component { +public: + Rigidbody(int mass, int gravityScale, int bodyType); + + int mMass; + int mGravityScale; + int mBodyType; +}; diff --git a/mwe/ecs-homemade/inc/GameObjectMax.h b/mwe/ecs-homemade/inc/GameObjectMax.h new file mode 100644 index 0000000..dbfe981 --- /dev/null +++ b/mwe/ecs-homemade/inc/GameObjectMax.h @@ -0,0 +1,20 @@ +#pragma once + +#include +#include + +class GameObject { +public: + GameObject(std::uint32_t id, std::string name, std::string tag, int layer); + + template + void AddComponent(T* component); + + std::uint32_t mId; + std::string mName; + std::string mTag; + bool mActive; + int mLayer; +}; + +#include "GameObjectMax.hpp" diff --git a/mwe/ecs-homemade/inc/GameObjectMax.hpp b/mwe/ecs-homemade/inc/GameObjectMax.hpp new file mode 100644 index 0000000..e1a49be --- /dev/null +++ b/mwe/ecs-homemade/inc/GameObjectMax.hpp @@ -0,0 +1,6 @@ +#include "ComponentManager.h" + +template +void GameObject::AddComponent(T* component) { + ComponentManager::GetInstance().AddComponent(component, mId); +} diff --git a/mwe/ecs-homemade/src/ComponentManager.cpp b/mwe/ecs-homemade/src/ComponentManager.cpp new file mode 100644 index 0000000..287da38 --- /dev/null +++ b/mwe/ecs-homemade/src/ComponentManager.cpp @@ -0,0 +1,9 @@ +#include "ComponentManager.h" + +ComponentManager ComponentManager::mInstance; + +ComponentManager& ComponentManager::GetInstance() { + return mInstance; +} + +ComponentManager::ComponentManager() {} diff --git a/mwe/ecs-homemade/src/Components.cpp b/mwe/ecs-homemade/src/Components.cpp new file mode 100644 index 0000000..3aece4b --- /dev/null +++ b/mwe/ecs-homemade/src/Components.cpp @@ -0,0 +1,10 @@ +#include "Components.h" +#include + +Component::Component() : mActive(true) {} + +void Sprite::Render() { + std::cout << "Rendering sprite" << std::endl; +} + +Rigidbody::Rigidbody(int mass, int gravityScale, int bodyType) : mMass(mass), mGravityScale(gravityScale), mBodyType(bodyType) {} diff --git a/mwe/ecs-homemade/src/GameObjectMax.cpp b/mwe/ecs-homemade/src/GameObjectMax.cpp new file mode 100644 index 0000000..62c41de --- /dev/null +++ b/mwe/ecs-homemade/src/GameObjectMax.cpp @@ -0,0 +1,5 @@ +#include "GameObjectMax.h" + +#include "ComponentManager.h" + +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/mwe/ecs-homemade/src/main.cpp b/mwe/ecs-homemade/src/main.cpp index f8b829c..3dd082f 100644 --- a/mwe/ecs-homemade/src/main.cpp +++ b/mwe/ecs-homemade/src/main.cpp @@ -1,5 +1,39 @@ #include +#include +#include + +#include "ComponentManager.h" +#include "GameObjectMax.h" +#include "Components.h" int main() { - std::cout << "Hello, world!" << std::endl; + GameObject gameObect0(0, "Name: 0", "Tag: 0", 0); //Entity 0 + GameObject gameObect1(1, "Name: 1", "Tag: 1", 1); //Entity 1 + + Sprite sprite0; + Rigidbody rigidbody0(1, 2, 3); + gameObect0.AddComponent(&sprite0); //Add a sprite to entity0 + gameObect0.AddComponent(&rigidbody0); //Also add a rigidbody to entity0 + + Rigidbody rigidbody1(4, 5, 6); + gameObect1.AddComponent(&rigidbody1); //Only add a rigidbody to entity1 + + //The entities are now initialized + //Now I will demonstrate some ways of retreiving/getting components + + Rigidbody* rigidbodyOfEntity0 = ComponentManager::GetInstance().GetComponent(gameObect0.mId); //Get the pointer to the Rigidbody component of entity 0 + std::cout << "rigidbodyOfEntity0: " << rigidbodyOfEntity0->mMass << " " << rigidbodyOfEntity0->mGravityScale << " " << rigidbodyOfEntity0->mBodyType << std::endl; + std::cout << std::endl; + + std::vector rigidbodyIDs = ComponentManager::GetInstance().GetAllComponentIDs(); //Get all the IDs that have a Rigidbody component + for(std::uint32_t ID : rigidbodyIDs) { + std::cout << "Rigidbody ID: " << ID << std::endl; + } + std::cout << std::endl; + + std::vector rigidbodyComponents = ComponentManager::GetInstance().GetAllComponentPointer(); //Get all the pointers to the Rigidbody component(s) + for(Rigidbody* rigidbody : rigidbodyComponents) { + std::cout << "rigidbody: " << rigidbody->mMass << " " << rigidbody->mGravityScale << " " << rigidbody->mBodyType << std::endl; + } + std::cout << std::endl; } -- cgit v1.2.3 From aedbb8b82f13d8b390419e59cea098ea73295df5 Mon Sep 17 00:00:00 2001 From: Max-001 <80035972+Max-001@users.noreply.github.com> Date: Wed, 2 Oct 2024 12:33:42 +0200 Subject: Little fix in CMakeLists.txt and forced output to type debug --- mwe/ecs-homemade/CMakeLists.txt | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'mwe') diff --git a/mwe/ecs-homemade/CMakeLists.txt b/mwe/ecs-homemade/CMakeLists.txt index 5960181..2819727 100644 --- a/mwe/ecs-homemade/CMakeLists.txt +++ b/mwe/ecs-homemade/CMakeLists.txt @@ -1,14 +1,17 @@ cmake_minimum_required(VERSION 3.5) -project(ecs-homemake) +project(ecs-homemade) # Set the C++ standard (optional, but good practice) set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED True) -add_executable(ecs-homemake +# Use the debug mode (otherwise breakpoints are not compiled) +set(CMAKE_BUILD_TYPE Debug) + +add_executable(ecs-homemade src/main.cpp src/ComponentManager.cpp src/Components.cpp src/GameObjectMax.cpp ) -target_include_directories(ecs-homemake PRIVATE "${CMAKE_SOURCE_DIR}/inc") +target_include_directories(ecs-homemade PRIVATE "${CMAKE_SOURCE_DIR}/inc") -- cgit v1.2.3 From e409986d9a21ca96ee0b491826eb0008ff6ab8e0 Mon Sep 17 00:00:00 2001 From: Max-001 <80035972+Max-001@users.noreply.github.com> Date: Wed, 2 Oct 2024 12:35:01 +0200 Subject: Changed componentsManager to allow mutliple componts of the same type for one entity (id) --- mwe/ecs-homemade/inc/ComponentManager.h | 12 ++++---- mwe/ecs-homemade/inc/ComponentManager.hpp | 47 ++++++++++++++++++++----------- mwe/ecs-homemade/inc/GameObjectMax.h | 4 +-- mwe/ecs-homemade/inc/GameObjectMax.hpp | 6 ++-- mwe/ecs-homemade/src/main.cpp | 20 ++++++------- 5 files changed, 51 insertions(+), 38 deletions(-) (limited to 'mwe') diff --git a/mwe/ecs-homemade/inc/ComponentManager.h b/mwe/ecs-homemade/inc/ComponentManager.h index cfc5f20..5b0629f 100644 --- a/mwe/ecs-homemade/inc/ComponentManager.h +++ b/mwe/ecs-homemade/inc/ComponentManager.h @@ -17,21 +17,21 @@ public: ComponentManager& operator=(const ComponentManager&) = delete; ComponentManager& operator=(ComponentManager&&) = delete; + template + void AddComponent(std::uint32_t id, Args&&... args); template - void AddComponent(T* component, std::uint32_t id); - template - T* GetComponent(std::uint32_t id); - template + std::vector> GetComponentsOfID(std::uint32_t id); + /*template std::vector GetAllComponentIDs(); template - std::vector GetAllComponentPointer(); + std::vector GetAllComponentPointer();*/ private: static ComponentManager mInstance; ComponentManager(); - std::unordered_map> mComponents; //TODO: Make this not only work with Component* OR add extra checks at templated methodes!!! + std::unordered_map>>> mComponents; }; #include "ComponentManager.hpp" diff --git a/mwe/ecs-homemade/inc/ComponentManager.hpp b/mwe/ecs-homemade/inc/ComponentManager.hpp index df8ea32..a7fc30f 100644 --- a/mwe/ecs-homemade/inc/ComponentManager.hpp +++ b/mwe/ecs-homemade/inc/ComponentManager.hpp @@ -1,31 +1,44 @@ -// AddComponent implementation -template -void ComponentManager::AddComponent(T* component, std::uint32_t id) { - std::type_index type = typeid(T); - if (mComponents.find(type) == mComponents.end()) { - mComponents[type] = std::vector(); + +template +void ComponentManager::AddComponent(std::uint32_t id, Args&&... args) { + std::type_index type = typeid(T); //Determine the type of T (this is used as the key of the unordered_map<>) + + if (mComponents.find(type) == mComponents.end()) { //Check if this component type is already in the unordered_map<> + mComponents[type] = std::vector>>(); //If not, create a new (empty) vector<> of unique_ptr } - // Resize the vector if the id is greater than current size - if (id >= mComponents[type].size()) { - mComponents[type].resize(id + 1, nullptr); // Initialize new slots to nullptr + + if (id >= mComponents[type].size()) { //Resize the vector<> if the id is greater than the current size + mComponents[type].resize(id + 1); //Initialize new slots to nullptr (resize does this automatically) } - mComponents[type][id] = component; // Store the raw pointer + + mComponents[type][id].push_back(std::make_unique(std::forward(args)...)); //Create a new component of type T using perfect forwarding and store its unique_ptr in the correct vector } -// GetComponent implementation template -T* ComponentManager::GetComponent(std::uint32_t id) { +std::vector> ComponentManager::GetComponentsOfID(std::uint32_t id) { std::type_index type = typeid(T); + + std::vector> componentVector; + if (mComponents.find(type) != mComponents.end()) { - auto& componentArray = mComponents[type]; + + const auto& componentArray = mComponents[type]; + if (id < componentArray.size()) { - return static_cast(componentArray[id]); // Cast to the correct type + for (const auto& componentPtr : componentArray[id]) { + // Use static_cast instead of dynamic_cast + T* castedComponent = static_cast(componentPtr.get()); + if (castedComponent) { // Ensure cast was successful + componentVector.push_back(*castedComponent); // Add the raw pointer to the vector + } + } } } - return nullptr; // Return nullptr if not found + + return componentVector; // Return empty vector if not found } -// GetAllComponentIDs implementation +/*// GetAllComponentIDs implementation template std::vector ComponentManager::GetAllComponentIDs() { std::type_index type = typeid(T); @@ -55,4 +68,4 @@ std::vector ComponentManager::GetAllComponentPointer() { } } return pointers; -} +}*/ diff --git a/mwe/ecs-homemade/inc/GameObjectMax.h b/mwe/ecs-homemade/inc/GameObjectMax.h index dbfe981..f0bcec9 100644 --- a/mwe/ecs-homemade/inc/GameObjectMax.h +++ b/mwe/ecs-homemade/inc/GameObjectMax.h @@ -7,8 +7,8 @@ class GameObject { public: GameObject(std::uint32_t id, std::string name, std::string tag, int layer); - template - void AddComponent(T* component); + template + void AddComponent(Args&&... args); std::uint32_t mId; std::string mName; diff --git a/mwe/ecs-homemade/inc/GameObjectMax.hpp b/mwe/ecs-homemade/inc/GameObjectMax.hpp index e1a49be..1e952ba 100644 --- a/mwe/ecs-homemade/inc/GameObjectMax.hpp +++ b/mwe/ecs-homemade/inc/GameObjectMax.hpp @@ -1,6 +1,6 @@ #include "ComponentManager.h" -template -void GameObject::AddComponent(T* component) { - ComponentManager::GetInstance().AddComponent(component, mId); +template +void GameObject::AddComponent(Args&&... args) { + ComponentManager::GetInstance().AddComponent(mId, std::forward(args)...); } diff --git a/mwe/ecs-homemade/src/main.cpp b/mwe/ecs-homemade/src/main.cpp index 3dd082f..73f710b 100644 --- a/mwe/ecs-homemade/src/main.cpp +++ b/mwe/ecs-homemade/src/main.cpp @@ -10,22 +10,22 @@ int main() { GameObject gameObect0(0, "Name: 0", "Tag: 0", 0); //Entity 0 GameObject gameObect1(1, "Name: 1", "Tag: 1", 1); //Entity 1 - Sprite sprite0; - Rigidbody rigidbody0(1, 2, 3); - gameObect0.AddComponent(&sprite0); //Add a sprite to entity0 - gameObect0.AddComponent(&rigidbody0); //Also add a rigidbody to entity0 + //Sprite sprite0; + //Rigidbody rigidbody0(1, 2, 3); + gameObect0.AddComponent(); //Add a sprite to entity0 + gameObect0.AddComponent(1, 2, 3); //Also add a rigidbody to entity0 - Rigidbody rigidbody1(4, 5, 6); - gameObect1.AddComponent(&rigidbody1); //Only add a rigidbody to entity1 + //Rigidbody rigidbody1(4, 5, 6); + gameObect1.AddComponent(4, 5, 6); //Only add a rigidbody to entity1 //The entities are now initialized //Now I will demonstrate some ways of retreiving/getting components - Rigidbody* rigidbodyOfEntity0 = ComponentManager::GetInstance().GetComponent(gameObect0.mId); //Get the pointer to the Rigidbody component of entity 0 - std::cout << "rigidbodyOfEntity0: " << rigidbodyOfEntity0->mMass << " " << rigidbodyOfEntity0->mGravityScale << " " << rigidbodyOfEntity0->mBodyType << std::endl; + std::vector> rigidbodyOfEntity0 = ComponentManager::GetInstance().GetComponentsOfID(gameObect0.mId); //Get the pointer to the Rigidbody component of entity 0 + std::cout << "rigidbodyOfEntity0: " << rigidbodyOfEntity0[0].get().mMass << " " << rigidbodyOfEntity0[0].get().mGravityScale << " " << rigidbodyOfEntity0[0].get().mBodyType << std::endl; std::cout << std::endl; - std::vector rigidbodyIDs = ComponentManager::GetInstance().GetAllComponentIDs(); //Get all the IDs that have a Rigidbody component + /*std::vector rigidbodyIDs = ComponentManager::GetInstance().GetAllComponentIDs(); //Get all the IDs that have a Rigidbody component for(std::uint32_t ID : rigidbodyIDs) { std::cout << "Rigidbody ID: " << ID << std::endl; } @@ -35,5 +35,5 @@ int main() { for(Rigidbody* rigidbody : rigidbodyComponents) { std::cout << "rigidbody: " << rigidbody->mMass << " " << rigidbody->mGravityScale << " " << rigidbody->mBodyType << std::endl; } - std::cout << std::endl; + std::cout << std::endl;*/ } -- cgit v1.2.3 From 2bd37e7d98728d72ba44da18eefea91547a7885a Mon Sep 17 00:00:00 2001 From: Max-001 <80035972+Max-001@users.noreply.github.com> Date: Wed, 2 Oct 2024 15:26:24 +0200 Subject: Refactored componentManager (it now uses smart pointer, does not return raw pointers (it only returns references) and it is now possible to store multiple components of the same type for the same entity) --- mwe/ecs-homemade/CMakeLists.txt | 2 +- mwe/ecs-homemade/inc/ComponentManager.h | 33 +++++++------ mwe/ecs-homemade/inc/ComponentManager.hpp | 77 +++++++++++++++---------------- mwe/ecs-homemade/src/main.cpp | 20 ++++---- 4 files changed, 65 insertions(+), 67 deletions(-) (limited to 'mwe') diff --git a/mwe/ecs-homemade/CMakeLists.txt b/mwe/ecs-homemade/CMakeLists.txt index 2819727..6267c1a 100644 --- a/mwe/ecs-homemade/CMakeLists.txt +++ b/mwe/ecs-homemade/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.5) project(ecs-homemade) # Set the C++ standard (optional, but good practice) -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED True) # Use the debug mode (otherwise breakpoints are not compiled) diff --git a/mwe/ecs-homemade/inc/ComponentManager.h b/mwe/ecs-homemade/inc/ComponentManager.h index 5b0629f..763c28e 100644 --- a/mwe/ecs-homemade/inc/ComponentManager.h +++ b/mwe/ecs-homemade/inc/ComponentManager.h @@ -6,31 +6,38 @@ #include #include #include -#include +#include class ComponentManager { public: - static ComponentManager& GetInstance(); + static ComponentManager& GetInstance(); //Singleton - ComponentManager(const ComponentManager&) = delete; - ComponentManager(ComponentManager&&) = delete; - ComponentManager& operator=(const ComponentManager&) = delete; - ComponentManager& operator=(ComponentManager&&) = delete; + ComponentManager(const ComponentManager&) = delete; //Singleton + ComponentManager(ComponentManager&&) = delete; //Singleton + ComponentManager& operator=(const ComponentManager&) = delete; //Singleton + ComponentManager& operator=(ComponentManager&&) = delete; //Singleton template - void AddComponent(std::uint32_t id, Args&&... args); + void AddComponent(std::uint32_t id, Args&&... args); //Add a component + //TODO: void DeleteAllComponentsOfId(std::uint32_t id); //Deletes all components of a specific id + //TODO: void DeleteAllComponents(); //Deletes all components + template - std::vector> GetComponentsOfID(std::uint32_t id); - /*template - std::vector GetAllComponentIDs(); + std::vector> GetComponentsByID(std::uint32_t id) const; //Get a vector<> of all components at specific id template - std::vector GetAllComponentPointer();*/ + std::vector, std::uint32_t>> GetComponentsByType() const; //Get a vector<> of all components of a specific type private: - static ComponentManager mInstance; + static ComponentManager mInstance; //Singleton - ComponentManager(); + ComponentManager(); //Singleton + /* + * The std::unordered_map>>> 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>>> mComponents; }; diff --git a/mwe/ecs-homemade/inc/ComponentManager.hpp b/mwe/ecs-homemade/inc/ComponentManager.hpp index a7fc30f..03135a8 100644 --- a/mwe/ecs-homemade/inc/ComponentManager.hpp +++ b/mwe/ecs-homemade/inc/ComponentManager.hpp @@ -4,68 +4,63 @@ void ComponentManager::AddComponent(std::uint32_t id, Args&&... args) { std::type_index type = typeid(T); //Determine the type of T (this is used as the key of the unordered_map<>) if (mComponents.find(type) == mComponents.end()) { //Check if this component type is already in the unordered_map<> - mComponents[type] = std::vector>>(); //If not, create a new (empty) vector<> of unique_ptr + mComponents[type] = std::vector>>(); //If not, create a new (empty) vector<> of vector> } if (id >= mComponents[type].size()) { //Resize the vector<> if the id is greater than the current size - mComponents[type].resize(id + 1); //Initialize new slots to nullptr (resize does this automatically) + mComponents[type].resize(id + 1); //Initialize new slots to nullptr (resize does automatically init to nullptr) } - mComponents[type][id].push_back(std::make_unique(std::forward(args)...)); //Create a new component of type T using perfect forwarding and store its unique_ptr in the correct vector + mComponents[type][id].push_back(std::make_unique(std::forward(args)...)); //Create a new component of type T using perfect forwarding and store its unique_ptr in the vector<> } template -std::vector> ComponentManager::GetComponentsOfID(std::uint32_t id) { - std::type_index type = typeid(T); +std::vector> ComponentManager::GetComponentsByID(std::uint32_t id) const { + std::type_index type = typeid(T); //Determine the type of T (this is used as the key of the unordered_map<>) + + std::vector> componentVector; //Create an empty vector<> - std::vector> componentVector; + if (mComponents.find(type) != mComponents.end()) { //Find the type (in the unordered_list<>) - if (mComponents.find(type) != mComponents.end()) { + const std::vector>>& componentArray = mComponents.at(type); //Get the correct vector<> - const auto& componentArray = mComponents[type]; + if (id < componentArray.size()) { //Make sure that the id (that we are looking for) is within the boundaries of the vector<> + for (const std::unique_ptr& componentPtr : componentArray[id]) { //Loop trough the whole vector<> + T* castedComponent = static_cast(componentPtr.get()); //Cast the unique_ptr to a raw pointer - if (id < componentArray.size()) { - for (const auto& componentPtr : componentArray[id]) { - // Use static_cast instead of dynamic_cast - T* castedComponent = static_cast(componentPtr.get()); - if (castedComponent) { // Ensure cast was successful - componentVector.push_back(*castedComponent); // Add the raw pointer to the vector + if (castedComponent) { //Ensure that the cast was successful + componentVector.push_back(*castedComponent); //Add the dereferenced raw pointer to the vector<> } } } } - return componentVector; // Return empty vector if not found + return componentVector; //Return the vector<> } -/*// GetAllComponentIDs implementation template -std::vector ComponentManager::GetAllComponentIDs() { - std::type_index type = typeid(T); - std::vector ids; - if (mComponents.find(type) != mComponents.end()) { - const auto& componentArray = mComponents[type]; - for (std::uint32_t id = 0; id < componentArray.size(); ++id) { - if (componentArray[id] != nullptr) { - ids.push_back(id); // Collect IDs of non-null components - } - } - } - return ids; -} +std::vector, std::uint32_t>> ComponentManager::GetComponentsByType() const { + std::type_index type = typeid(T); //Determine the type of T (this is used as the key of the unordered_map<>) -// GetAllComponentPointer implementation -template -std::vector ComponentManager::GetAllComponentPointer() { - std::type_index type = typeid(T); - std::vector pointers; - if (mComponents.find(type) != mComponents.end()) { - const auto& componentArray = mComponents[type]; - for (const auto& component : componentArray) { - if (component != nullptr) { - pointers.push_back(static_cast(component)); // Cast to the correct type + std::vector, std::uint32_t>> componentVector; //Create an empty vector<> + std::uint32_t id = 0; //Set the id to 0 (the id will also be stored in the returned vector<>) + + if (mComponents.find(type) != mComponents.end()) { //Find the type (in the unordered_list<>) + + const std::vector>>& componentArray = mComponents.at(type); //Get the correct vector<> + + for (const std::vector>& component : componentArray) { //Loop through the whole vector<> + for (const std::unique_ptr& componentPtr : component) { //Loop trough the whole vector<> + T* castedComponent = static_cast(componentPtr.get()); //Cast the unique_ptr to a raw pointer + + if (castedComponent) { //Ensure that the cast was successful + componentVector.push_back(std::make_pair(std::ref(*castedComponent), id)); //Pair the dereferenced raw pointer and the id and add it to the vector<> + } } + + ++id; //Increase the id (the id will also be stored in the returned vector<>) } } - return pointers; -}*/ + + return componentVector; +} diff --git a/mwe/ecs-homemade/src/main.cpp b/mwe/ecs-homemade/src/main.cpp index 73f710b..f72a044 100644 --- a/mwe/ecs-homemade/src/main.cpp +++ b/mwe/ecs-homemade/src/main.cpp @@ -14,6 +14,7 @@ int main() { //Rigidbody rigidbody0(1, 2, 3); gameObect0.AddComponent(); //Add a sprite to entity0 gameObect0.AddComponent(1, 2, 3); //Also add a rigidbody to entity0 + gameObect0.AddComponent(3, 2, 1); //Add a second rigidbody to entity0 //Rigidbody rigidbody1(4, 5, 6); gameObect1.AddComponent(4, 5, 6); //Only add a rigidbody to entity1 @@ -21,19 +22,14 @@ int main() { //The entities are now initialized //Now I will demonstrate some ways of retreiving/getting components - std::vector> rigidbodyOfEntity0 = ComponentManager::GetInstance().GetComponentsOfID(gameObect0.mId); //Get the pointer to the Rigidbody component of entity 0 - std::cout << "rigidbodyOfEntity0: " << rigidbodyOfEntity0[0].get().mMass << " " << rigidbodyOfEntity0[0].get().mGravityScale << " " << rigidbodyOfEntity0[0].get().mBodyType << std::endl; - std::cout << std::endl; - - /*std::vector rigidbodyIDs = ComponentManager::GetInstance().GetAllComponentIDs(); //Get all the IDs that have a Rigidbody component - for(std::uint32_t ID : rigidbodyIDs) { - std::cout << "Rigidbody ID: " << ID << std::endl; + std::vector> rigidbodyOfEntity0 = ComponentManager::GetInstance().GetComponentsByID(gameObect0.mId); //Get the pointer to the Rigidbody component of entity 0 + for(Rigidbody& rigidbodyEntity0 : rigidbodyOfEntity0) { + std::cout << "rigidbodyOfEntity0: " << rigidbodyEntity0.mMass << " " << rigidbodyEntity0.mGravityScale << " " << rigidbodyEntity0.mBodyType << std::endl; + std::cout << std::endl; } - std::cout << std::endl; - std::vector rigidbodyComponents = ComponentManager::GetInstance().GetAllComponentPointer(); //Get all the pointers to the Rigidbody component(s) - for(Rigidbody* rigidbody : rigidbodyComponents) { - std::cout << "rigidbody: " << rigidbody->mMass << " " << rigidbody->mGravityScale << " " << rigidbody->mBodyType << std::endl; + std::vector, std::uint32_t>> rigidBodies = ComponentManager::GetInstance().GetComponentsByType(); + for(auto& [rigidbody, id] : rigidBodies) { + std::cout << "Rigidbody of id: " << id << ": " << rigidbody.get().mMass << " " << rigidbody.get().mGravityScale << " " << rigidbody.get().mBodyType << std::endl; } - std::cout << std::endl;*/ } -- cgit v1.2.3 From 9ef08417da5d3aada6306b70a056355071b8c3ca Mon Sep 17 00:00:00 2001 From: Max-001 <80035972+Max-001@users.noreply.github.com> Date: Wed, 2 Oct 2024 15:54:36 +0200 Subject: Improved tests --- mwe/ecs-homemade/inc/Components.h | 7 ++++ mwe/ecs-homemade/src/Components.cpp | 2 + mwe/ecs-homemade/src/main.cpp | 84 ++++++++++++++++++++++++++++++++++--- 3 files changed, 87 insertions(+), 6 deletions(-) (limited to 'mwe') diff --git a/mwe/ecs-homemade/inc/Components.h b/mwe/ecs-homemade/inc/Components.h index 1ea8428..2645a45 100644 --- a/mwe/ecs-homemade/inc/Components.h +++ b/mwe/ecs-homemade/inc/Components.h @@ -20,3 +20,10 @@ public: int mGravityScale; int mBodyType; }; + +class Colider : public Component { +public: + Colider(int size); + + int mSize; +}; diff --git a/mwe/ecs-homemade/src/Components.cpp b/mwe/ecs-homemade/src/Components.cpp index 3aece4b..5f10bc5 100644 --- a/mwe/ecs-homemade/src/Components.cpp +++ b/mwe/ecs-homemade/src/Components.cpp @@ -8,3 +8,5 @@ void Sprite::Render() { } Rigidbody::Rigidbody(int mass, int gravityScale, int bodyType) : mMass(mass), mGravityScale(gravityScale), mBodyType(bodyType) {} + +Colider::Colider(int size) : mSize(size) {} diff --git a/mwe/ecs-homemade/src/main.cpp b/mwe/ecs-homemade/src/main.cpp index f72a044..6ab0adc 100644 --- a/mwe/ecs-homemade/src/main.cpp +++ b/mwe/ecs-homemade/src/main.cpp @@ -9,27 +9,99 @@ int main() { GameObject gameObect0(0, "Name: 0", "Tag: 0", 0); //Entity 0 GameObject gameObect1(1, "Name: 1", "Tag: 1", 1); //Entity 1 + GameObject gameObect2(2, "Name: 2", "Tag: 2", 2); //Entity 2 + GameObject gameObect3(3, "Name: 3", "Tag: 3", 3); //Entity 3 + GameObject gameObect4(4, "Name: 4", "Tag: 4", 4); //Entity 4 + GameObject gameObect5(5, "Name: 5", "Tag: 5", 5); //Entity 5 + GameObject gameObect6(6, "Name: 6", "Tag: 6", 6); //Entity 6 + GameObject gameObect7(7, "Name: 7", "Tag: 7", 7); //Entity 7 - //Sprite sprite0; - //Rigidbody rigidbody0(1, 2, 3); gameObect0.AddComponent(); //Add a sprite to entity0 gameObect0.AddComponent(1, 2, 3); //Also add a rigidbody to entity0 gameObect0.AddComponent(3, 2, 1); //Add a second rigidbody to entity0 - //Rigidbody rigidbody1(4, 5, 6); gameObect1.AddComponent(4, 5, 6); //Only add a rigidbody to entity1 + gameObect2.AddComponent(); //Add four sprites to entity2 + gameObect2.AddComponent(); + gameObect2.AddComponent(); + gameObect2.AddComponent(); + gameObect2.AddComponent(10, 100, 500); //Add four rigidbodies to entity2 + gameObect2.AddComponent(10, 100, 501); + gameObect2.AddComponent(10, 100, 502); + gameObect2.AddComponent(10, 100, 500); + + //Add non components to entity3, entity4, entity5 and entity6 + + gameObect7.AddComponent(); //Add only a sprite to entity 7 + //The entities are now initialized //Now I will demonstrate some ways of retreiving/getting components - std::vector> rigidbodyOfEntity0 = ComponentManager::GetInstance().GetComponentsByID(gameObect0.mId); //Get the pointer to the Rigidbody component of entity 0 + std::cout << "Finding all sprites of entity 0" << std::endl; + std::vector> spriteOfEntity0 = ComponentManager::GetInstance().GetComponentsByID(gameObect0.mId); + for(Sprite& spriteEntity0 : spriteOfEntity0) { + std::cout << "Sprite of entity 0: " << spriteEntity0.mActive << std::endl; + } + std::cout << std::endl; + + std::cout << "Finding all rigidbodies of entity 0" << std::endl; + std::vector> rigidbodyOfEntity0 = ComponentManager::GetInstance().GetComponentsByID(gameObect0.mId); for(Rigidbody& rigidbodyEntity0 : rigidbodyOfEntity0) { - std::cout << "rigidbodyOfEntity0: " << rigidbodyEntity0.mMass << " " << rigidbodyEntity0.mGravityScale << " " << rigidbodyEntity0.mBodyType << std::endl; - std::cout << std::endl; + std::cout << "Rigidbody of entity 0: " << rigidbodyEntity0.mMass << " " << rigidbodyEntity0.mGravityScale << " " << rigidbodyEntity0.mBodyType << std::endl; + + rigidbodyEntity0.mMass = 15; + } + std::cout << std::endl; + + std::cout << "Finding all coliders of entity 0" << std::endl; + std::vector> coliderOfEntity0 = ComponentManager::GetInstance().GetComponentsByID(gameObect0.mId); + for(Colider& coliderEntity0 : coliderOfEntity0) { + std::cout << "Colider of entity 0: " << coliderEntity0.mSize << std::endl; + } + std::cout << std::endl; + + std::cout << "Finding all sprites of entity 3" << std::endl; + std::vector> spriteOfEntity3 = ComponentManager::GetInstance().GetComponentsByID(gameObect3.mId); + for(Sprite& spriteEntity3 : spriteOfEntity3) { + std::cout << "Sprite of entity 3: " << spriteEntity3.mActive << std::endl; } + std::cout << std::endl; + std::cout << "Finding all rigidbodies of entity 3" << std::endl; + std::vector> rigidbodyOfEntity3 = ComponentManager::GetInstance().GetComponentsByID(gameObect3.mId); + for(Rigidbody& rigidbodyEntity3 : rigidbodyOfEntity3) { + std::cout << "Rigidbody of entity 3: " << rigidbodyEntity3.mMass << " " << rigidbodyEntity3.mGravityScale << " " << rigidbodyEntity3.mBodyType << std::endl; + } + std::cout << std::endl; + + std::cout << "Finding all sprites of all entities" << std::endl; + std::vector, std::uint32_t>> sprites = ComponentManager::GetInstance().GetComponentsByType(); + for(auto& [sprite, id] : sprites) { + std::cout << "Sprite of id: " << id << ": " << sprite.get().mActive << std::endl; + } + std::cout << std::endl; + + std::cout << "Finding all coliders of all entities" << std::endl; + std::vector, std::uint32_t>> coliders = ComponentManager::GetInstance().GetComponentsByType(); + for(auto& [colider, id] : coliders) { + std::cout << "Colder of id: " << id << ": " << colider.get().mSize << std::endl; + } + std::cout << std::endl; + + std::cout << "Finding all rigidbodies of all entities" << std::endl; std::vector, std::uint32_t>> rigidBodies = ComponentManager::GetInstance().GetComponentsByType(); for(auto& [rigidbody, id] : rigidBodies) { std::cout << "Rigidbody of id: " << id << ": " << rigidbody.get().mMass << " " << rigidbody.get().mGravityScale << " " << rigidbody.get().mBodyType << std::endl; + + rigidbody.get().mMass = -1; + } + std::cout << std::endl; + + std::cout << "Finding all rigidbodies of all entities for the second time (after changing mMass to -1)" << std::endl; + std::vector, std::uint32_t>> rigidBodies2 = ComponentManager::GetInstance().GetComponentsByType(); + for(auto& [rigidbody2, id2] : rigidBodies2) { + std::cout << "Rigidbody of id: " << id2 << ": " << rigidbody2.get().mMass << " " << rigidbody2.get().mGravityScale << " " << rigidbody2.get().mBodyType << std::endl; } + std::cout << std::endl; } -- cgit v1.2.3 From 7fc607bc74e0be80b1668032348459399c311898 Mon Sep 17 00:00:00 2001 From: Max-001 <80035972+Max-001@users.noreply.github.com> Date: Wed, 2 Oct 2024 16:03:19 +0200 Subject: Added Colider component --- mwe/ecs-homemade/src/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'mwe') diff --git a/mwe/ecs-homemade/src/main.cpp b/mwe/ecs-homemade/src/main.cpp index 6ab0adc..9e230e5 100644 --- a/mwe/ecs-homemade/src/main.cpp +++ b/mwe/ecs-homemade/src/main.cpp @@ -33,7 +33,8 @@ int main() { //Add non components to entity3, entity4, entity5 and entity6 - gameObect7.AddComponent(); //Add only a sprite to entity 7 + gameObect7.AddComponent(); //Add a sprite to entity 7 + gameObect7.AddComponent(30); //Add a colder to entity 7 //The entities are now initialized //Now I will demonstrate some ways of retreiving/getting components -- cgit v1.2.3 From 3e99a6fe36e63a1e14ba62f2a6e5a3827484e4e6 Mon Sep 17 00:00:00 2001 From: Max-001 <80035972+Max-001@users.noreply.github.com> Date: Wed, 2 Oct 2024 16:21:01 +0200 Subject: DeleteAllComponents created --- mwe/ecs-homemade/inc/ComponentManager.h | 12 ++++++++---- mwe/ecs-homemade/inc/ComponentManager.hpp | 12 +++++++++++- mwe/ecs-homemade/src/ComponentManager.cpp | 8 ++++++++ mwe/ecs-homemade/src/main.cpp | 2 ++ 4 files changed, 29 insertions(+), 5 deletions(-) (limited to 'mwe') diff --git a/mwe/ecs-homemade/inc/ComponentManager.h b/mwe/ecs-homemade/inc/ComponentManager.h index 763c28e..893aa56 100644 --- a/mwe/ecs-homemade/inc/ComponentManager.h +++ b/mwe/ecs-homemade/inc/ComponentManager.h @@ -18,12 +18,16 @@ public: ComponentManager& operator=(ComponentManager&&) = delete; //Singleton template - void AddComponent(std::uint32_t id, Args&&... args); //Add a component - //TODO: void DeleteAllComponentsOfId(std::uint32_t id); //Deletes all components of a specific id - //TODO: void DeleteAllComponents(); //Deletes all components + void AddComponent(std::uint32_t id, Args&&... args); //Add a component of a specific type + template + void DeleteComponentsById(std::uint32_t id); //Deletes all components of a specific type and id + template + void DeleteComponents(); //Deletes all components of a specific type + void DeleteAllComponentsOfId(std::uint32_t id); //Deletes all components of a specific id + void DeleteAllComponents(); //Deletes all components template - std::vector> GetComponentsByID(std::uint32_t id) const; //Get a vector<> of all components at specific id + std::vector> GetComponentsByID(std::uint32_t id) const; //Get a vector<> of all components at specific type and id template std::vector, std::uint32_t>> GetComponentsByType() const; //Get a vector<> of all components of a specific type diff --git a/mwe/ecs-homemade/inc/ComponentManager.hpp b/mwe/ecs-homemade/inc/ComponentManager.hpp index 03135a8..18bd548 100644 --- a/mwe/ecs-homemade/inc/ComponentManager.hpp +++ b/mwe/ecs-homemade/inc/ComponentManager.hpp @@ -14,6 +14,16 @@ void ComponentManager::AddComponent(std::uint32_t id, Args&&... args) { mComponents[type][id].push_back(std::make_unique(std::forward(args)...)); //Create a new component of type T using perfect forwarding and store its unique_ptr in the vector<> } +template +void ComponentManager::DeleteComponentsById(std::uint32_t id) { + +} + +template +void ComponentManager::DeleteComponents() { + +} + template std::vector> ComponentManager::GetComponentsByID(std::uint32_t id) const { std::type_index type = typeid(T); //Determine the type of T (this is used as the key of the unordered_map<>) @@ -62,5 +72,5 @@ std::vector, std::uint32_t>> ComponentManage } } - return componentVector; + return componentVector; //Return the vector<> } diff --git a/mwe/ecs-homemade/src/ComponentManager.cpp b/mwe/ecs-homemade/src/ComponentManager.cpp index 287da38..cca84bc 100644 --- a/mwe/ecs-homemade/src/ComponentManager.cpp +++ b/mwe/ecs-homemade/src/ComponentManager.cpp @@ -7,3 +7,11 @@ ComponentManager& ComponentManager::GetInstance() { } ComponentManager::ComponentManager() {} + +void ComponentManager::DeleteAllComponentsOfId(std::uint32_t id) { + +} + +void ComponentManager::DeleteAllComponents() { + mComponents.clear(); +} diff --git a/mwe/ecs-homemade/src/main.cpp b/mwe/ecs-homemade/src/main.cpp index 9e230e5..df229a2 100644 --- a/mwe/ecs-homemade/src/main.cpp +++ b/mwe/ecs-homemade/src/main.cpp @@ -99,6 +99,8 @@ int main() { } std::cout << std::endl; + ComponentManager::GetInstance().DeleteAllComponents(); + std::cout << "Finding all rigidbodies of all entities for the second time (after changing mMass to -1)" << std::endl; std::vector, std::uint32_t>> rigidBodies2 = ComponentManager::GetInstance().GetComponentsByType(); for(auto& [rigidbody2, id2] : rigidBodies2) { -- cgit v1.2.3 From b242f28862ac8e9c1137c3f8e3640011a1ddddfa Mon Sep 17 00:00:00 2001 From: Max-001 <80035972+Max-001@users.noreply.github.com> Date: Wed, 2 Oct 2024 16:29:17 +0200 Subject: DeleteComponents<> method created --- mwe/ecs-homemade/inc/ComponentManager.hpp | 10 ++++++++-- mwe/ecs-homemade/src/ComponentManager.cpp | 2 +- mwe/ecs-homemade/src/main.cpp | 5 +++-- 3 files changed, 12 insertions(+), 5 deletions(-) (limited to 'mwe') diff --git a/mwe/ecs-homemade/inc/ComponentManager.hpp b/mwe/ecs-homemade/inc/ComponentManager.hpp index 18bd548..e6523ca 100644 --- a/mwe/ecs-homemade/inc/ComponentManager.hpp +++ b/mwe/ecs-homemade/inc/ComponentManager.hpp @@ -16,12 +16,18 @@ void ComponentManager::AddComponent(std::uint32_t id, Args&&... args) { template void ComponentManager::DeleteComponentsById(std::uint32_t id) { + std::type_index type = typeid(T); //Determine the type of T (this is used as the key of the unordered_map<>) + } template void ComponentManager::DeleteComponents() { + std::type_index type = typeid(T); //Determine the type of T (this is used as the key of the unordered_map<>) + if (mComponents.find(type) != mComponents.end()) { //Find the type (in the unordered_map<>) + mComponents[type].clear(); //Clear the whole vector<> of this specific type + } } template @@ -30,7 +36,7 @@ std::vector> ComponentManager::GetComponentsByID(std:: std::vector> componentVector; //Create an empty vector<> - if (mComponents.find(type) != mComponents.end()) { //Find the type (in the unordered_list<>) + if (mComponents.find(type) != mComponents.end()) { //Find the type (in the unordered_map<>) const std::vector>>& componentArray = mComponents.at(type); //Get the correct vector<> @@ -55,7 +61,7 @@ std::vector, std::uint32_t>> ComponentManage std::vector, std::uint32_t>> componentVector; //Create an empty vector<> std::uint32_t id = 0; //Set the id to 0 (the id will also be stored in the returned vector<>) - if (mComponents.find(type) != mComponents.end()) { //Find the type (in the unordered_list<>) + if (mComponents.find(type) != mComponents.end()) { //Find the type (in the unordered_map<>) const std::vector>>& componentArray = mComponents.at(type); //Get the correct vector<> diff --git a/mwe/ecs-homemade/src/ComponentManager.cpp b/mwe/ecs-homemade/src/ComponentManager.cpp index cca84bc..def50be 100644 --- a/mwe/ecs-homemade/src/ComponentManager.cpp +++ b/mwe/ecs-homemade/src/ComponentManager.cpp @@ -13,5 +13,5 @@ void ComponentManager::DeleteAllComponentsOfId(std::uint32_t id) { } void ComponentManager::DeleteAllComponents() { - mComponents.clear(); + mComponents.clear(); //Clear the whole unordered_map<> } diff --git a/mwe/ecs-homemade/src/main.cpp b/mwe/ecs-homemade/src/main.cpp index df229a2..e1ca9e9 100644 --- a/mwe/ecs-homemade/src/main.cpp +++ b/mwe/ecs-homemade/src/main.cpp @@ -69,6 +69,9 @@ int main() { } std::cout << std::endl; + ComponentManager::GetInstance().DeleteComponents(); + gameObect5.AddComponent(); + std::cout << "Finding all rigidbodies of entity 3" << std::endl; std::vector> rigidbodyOfEntity3 = ComponentManager::GetInstance().GetComponentsByID(gameObect3.mId); for(Rigidbody& rigidbodyEntity3 : rigidbodyOfEntity3) { @@ -99,8 +102,6 @@ int main() { } std::cout << std::endl; - ComponentManager::GetInstance().DeleteAllComponents(); - std::cout << "Finding all rigidbodies of all entities for the second time (after changing mMass to -1)" << std::endl; std::vector, std::uint32_t>> rigidBodies2 = ComponentManager::GetInstance().GetComponentsByType(); for(auto& [rigidbody2, id2] : rigidBodies2) { -- cgit v1.2.3 From 0b6a5731401348ab5931a80e07e134ae460d9955 Mon Sep 17 00:00:00 2001 From: Max-001 <80035972+Max-001@users.noreply.github.com> Date: Wed, 2 Oct 2024 16:37:47 +0200 Subject: Added DeleteComponentsById<> method --- mwe/ecs-homemade/inc/ComponentManager.hpp | 8 +++++++- mwe/ecs-homemade/src/main.cpp | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'mwe') diff --git a/mwe/ecs-homemade/inc/ComponentManager.hpp b/mwe/ecs-homemade/inc/ComponentManager.hpp index e6523ca..75b2ab1 100644 --- a/mwe/ecs-homemade/inc/ComponentManager.hpp +++ b/mwe/ecs-homemade/inc/ComponentManager.hpp @@ -18,7 +18,13 @@ template void ComponentManager::DeleteComponentsById(std::uint32_t id) { std::type_index type = typeid(T); //Determine the type of T (this is used as the key of the unordered_map<>) - + if (mComponents.find(type) != mComponents.end()) { //Find the type (in the unordered_map<>) + std::vector>>& componentArray = mComponents[type]; //Get the correct vector<> + + if (id < componentArray.size()) { //Make sure that the id (that we are looking for) is within the boundaries of the vector<> + componentArray[id].clear(); //Clear the whole vector<> of this specific type and id + } + } } template diff --git a/mwe/ecs-homemade/src/main.cpp b/mwe/ecs-homemade/src/main.cpp index e1ca9e9..f0b94f0 100644 --- a/mwe/ecs-homemade/src/main.cpp +++ b/mwe/ecs-homemade/src/main.cpp @@ -69,8 +69,8 @@ int main() { } std::cout << std::endl; - ComponentManager::GetInstance().DeleteComponents(); - gameObect5.AddComponent(); + ComponentManager::GetInstance().DeleteComponentsById(gameObect2.mId); + gameObect2.AddComponent(); std::cout << "Finding all rigidbodies of entity 3" << std::endl; std::vector> rigidbodyOfEntity3 = ComponentManager::GetInstance().GetComponentsByID(gameObect3.mId); -- cgit v1.2.3 From 8b69b8cb28f0ef43d1039b7616ca893344e236cd Mon Sep 17 00:00:00 2001 From: Max-001 <80035972+Max-001@users.noreply.github.com> Date: Wed, 2 Oct 2024 17:01:47 +0200 Subject: Added DeleteAllComponentsOfId methode --- mwe/ecs-homemade/src/ComponentManager.cpp | 6 +++++- mwe/ecs-homemade/src/main.cpp | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'mwe') diff --git a/mwe/ecs-homemade/src/ComponentManager.cpp b/mwe/ecs-homemade/src/ComponentManager.cpp index def50be..16cc2b6 100644 --- a/mwe/ecs-homemade/src/ComponentManager.cpp +++ b/mwe/ecs-homemade/src/ComponentManager.cpp @@ -9,7 +9,11 @@ ComponentManager& ComponentManager::GetInstance() { ComponentManager::ComponentManager() {} void ComponentManager::DeleteAllComponentsOfId(std::uint32_t id) { - + for(auto& [type, componentArray] : mComponents) { //Loop through all the types (in the unordered_map<>) + if (id < componentArray.size()) { //Make sure that the id (that we are looking for) is within the boundaries of the vector<> + componentArray[id].clear(); //Clear the components at this specific id + } + } } void ComponentManager::DeleteAllComponents() { diff --git a/mwe/ecs-homemade/src/main.cpp b/mwe/ecs-homemade/src/main.cpp index f0b94f0..2ee6edd 100644 --- a/mwe/ecs-homemade/src/main.cpp +++ b/mwe/ecs-homemade/src/main.cpp @@ -69,8 +69,8 @@ int main() { } std::cout << std::endl; - ComponentManager::GetInstance().DeleteComponentsById(gameObect2.mId); - gameObect2.AddComponent(); + ComponentManager::GetInstance().DeleteAllComponentsOfId(gameObect0.mId); + gameObect0.AddComponent(-10, -120, -564); std::cout << "Finding all rigidbodies of entity 3" << std::endl; std::vector> rigidbodyOfEntity3 = ComponentManager::GetInstance().GetComponentsByID(gameObect3.mId); -- cgit v1.2.3 From 23ce7028e76cbbce6c104f3f3e58758d46f6a500 Mon Sep 17 00:00:00 2001 From: Max-001 <80035972+Max-001@users.noreply.github.com> Date: Wed, 2 Oct 2024 17:06:42 +0200 Subject: Modified test --- mwe/ecs-homemade/src/main.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'mwe') diff --git a/mwe/ecs-homemade/src/main.cpp b/mwe/ecs-homemade/src/main.cpp index 2ee6edd..9e230e5 100644 --- a/mwe/ecs-homemade/src/main.cpp +++ b/mwe/ecs-homemade/src/main.cpp @@ -69,9 +69,6 @@ int main() { } std::cout << std::endl; - ComponentManager::GetInstance().DeleteAllComponentsOfId(gameObect0.mId); - gameObect0.AddComponent(-10, -120, -564); - std::cout << "Finding all rigidbodies of entity 3" << std::endl; std::vector> rigidbodyOfEntity3 = ComponentManager::GetInstance().GetComponentsByID(gameObect3.mId); for(Rigidbody& rigidbodyEntity3 : rigidbodyOfEntity3) { -- cgit v1.2.3 From 03b25facdf35117eb9f56c7a2edbec5b34b90203 Mon Sep 17 00:00:00 2001 From: Max-001 <80035972+Max-001@users.noreply.github.com> Date: Thu, 3 Oct 2024 15:22:38 +0200 Subject: Replace push_back with emplace_back --- mwe/ecs-homemade/inc/ComponentManager.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'mwe') diff --git a/mwe/ecs-homemade/inc/ComponentManager.hpp b/mwe/ecs-homemade/inc/ComponentManager.hpp index 75b2ab1..53dfddd 100644 --- a/mwe/ecs-homemade/inc/ComponentManager.hpp +++ b/mwe/ecs-homemade/inc/ComponentManager.hpp @@ -76,7 +76,7 @@ std::vector, std::uint32_t>> ComponentManage T* castedComponent = static_cast(componentPtr.get()); //Cast the unique_ptr to a raw pointer if (castedComponent) { //Ensure that the cast was successful - componentVector.push_back(std::make_pair(std::ref(*castedComponent), id)); //Pair the dereferenced raw pointer and the id and add it to the vector<> + componentVector.emplace_back(std::ref(*castedComponent), id); //Pair the dereferenced raw pointer and the id and add it to the vector<> } } -- cgit v1.2.3 From 4ec01101ddc04f4f30d0aa0b4f3f71fa74e0e6f3 Mon Sep 17 00:00:00 2001 From: Max-001 <80035972+Max-001@users.noreply.github.com> Date: Sat, 5 Oct 2024 12:25:10 +0200 Subject: Added some time testing for comparison --- .vscode/settings.json | 6 ++- mwe/ecs-homemade/inc/Components.h | 6 ++- mwe/ecs-homemade/src/Components.cpp | 4 +- mwe/ecs-homemade/src/main.cpp | 104 +++++++++--------------------------- 4 files changed, 36 insertions(+), 84 deletions(-) (limited to 'mwe') diff --git a/.vscode/settings.json b/.vscode/settings.json index 52c6107..27ae565 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -54,6 +54,10 @@ "cinttypes": "cpp", "typeindex": "cpp", "typeinfo": "cpp", - "variant": "cpp" + "variant": "cpp", + "chrono": "cpp", + "ratio": "cpp", + "iomanip": "cpp", + "sstream": "cpp" } } diff --git a/mwe/ecs-homemade/inc/Components.h b/mwe/ecs-homemade/inc/Components.h index 2645a45..98c5fe7 100644 --- a/mwe/ecs-homemade/inc/Components.h +++ b/mwe/ecs-homemade/inc/Components.h @@ -1,5 +1,7 @@ #pragma once +#include + class Component { public: Component(); @@ -9,7 +11,9 @@ public: class Sprite : public Component { public: - void Render(); + Sprite(std::string path); + + std::string mPath; }; class Rigidbody : public Component { diff --git a/mwe/ecs-homemade/src/Components.cpp b/mwe/ecs-homemade/src/Components.cpp index 5f10bc5..69b5eaa 100644 --- a/mwe/ecs-homemade/src/Components.cpp +++ b/mwe/ecs-homemade/src/Components.cpp @@ -3,9 +3,7 @@ Component::Component() : mActive(true) {} -void Sprite::Render() { - std::cout << "Rendering sprite" << std::endl; -} +Sprite::Sprite(std::string path) : mPath(path) {} Rigidbody::Rigidbody(int mass, int gravityScale, int bodyType) : mMass(mass), mGravityScale(gravityScale), mBodyType(bodyType) {} diff --git a/mwe/ecs-homemade/src/main.cpp b/mwe/ecs-homemade/src/main.cpp index 9e230e5..122311a 100644 --- a/mwe/ecs-homemade/src/main.cpp +++ b/mwe/ecs-homemade/src/main.cpp @@ -1,108 +1,54 @@ #include #include #include +#include #include "ComponentManager.h" #include "GameObjectMax.h" #include "Components.h" int main() { - GameObject gameObect0(0, "Name: 0", "Tag: 0", 0); //Entity 0 - GameObject gameObect1(1, "Name: 1", "Tag: 1", 1); //Entity 1 - GameObject gameObect2(2, "Name: 2", "Tag: 2", 2); //Entity 2 - GameObject gameObect3(3, "Name: 3", "Tag: 3", 3); //Entity 3 - GameObject gameObect4(4, "Name: 4", "Tag: 4", 4); //Entity 4 - GameObject gameObect5(5, "Name: 5", "Tag: 5", 5); //Entity 5 - GameObject gameObect6(6, "Name: 6", "Tag: 6", 6); //Entity 6 - GameObject gameObect7(7, "Name: 7", "Tag: 7", 7); //Entity 7 + auto startAdding = std::chrono::high_resolution_clock::now(); - gameObect0.AddComponent(); //Add a sprite to entity0 - gameObect0.AddComponent(1, 2, 3); //Also add a rigidbody to entity0 - gameObect0.AddComponent(3, 2, 1); //Add a second rigidbody to entity0 + GameObject* gameObject[100000]; - gameObect1.AddComponent(4, 5, 6); //Only add a rigidbody to entity1 + for(int i = 0; i < 100000; ++i) { + gameObject[i] = new GameObject(i, "Name", "Tag", 0); - gameObect2.AddComponent(); //Add four sprites to entity2 - gameObect2.AddComponent(); - gameObect2.AddComponent(); - gameObect2.AddComponent(); - gameObect2.AddComponent(10, 100, 500); //Add four rigidbodies to entity2 - gameObect2.AddComponent(10, 100, 501); - gameObect2.AddComponent(10, 100, 502); - gameObect2.AddComponent(10, 100, 500); - - //Add non components to entity3, entity4, entity5 and entity6 - - gameObect7.AddComponent(); //Add a sprite to entity 7 - gameObect7.AddComponent(30); //Add a colder to entity 7 - - //The entities are now initialized - //Now I will demonstrate some ways of retreiving/getting components - - std::cout << "Finding all sprites of entity 0" << std::endl; - std::vector> spriteOfEntity0 = ComponentManager::GetInstance().GetComponentsByID(gameObect0.mId); - for(Sprite& spriteEntity0 : spriteOfEntity0) { - std::cout << "Sprite of entity 0: " << spriteEntity0.mActive << std::endl; - } - std::cout << std::endl; - - std::cout << "Finding all rigidbodies of entity 0" << std::endl; - std::vector> rigidbodyOfEntity0 = ComponentManager::GetInstance().GetComponentsByID(gameObect0.mId); - for(Rigidbody& rigidbodyEntity0 : rigidbodyOfEntity0) { - std::cout << "Rigidbody of entity 0: " << rigidbodyEntity0.mMass << " " << rigidbodyEntity0.mGravityScale << " " << rigidbodyEntity0.mBodyType << std::endl; - - rigidbodyEntity0.mMass = 15; - } - std::cout << std::endl; - - std::cout << "Finding all coliders of entity 0" << std::endl; - std::vector> coliderOfEntity0 = ComponentManager::GetInstance().GetComponentsByID(gameObect0.mId); - for(Colider& coliderEntity0 : coliderOfEntity0) { - std::cout << "Colider of entity 0: " << coliderEntity0.mSize << std::endl; - } - std::cout << std::endl; - - std::cout << "Finding all sprites of entity 3" << std::endl; - std::vector> spriteOfEntity3 = ComponentManager::GetInstance().GetComponentsByID(gameObect3.mId); - for(Sprite& spriteEntity3 : spriteOfEntity3) { - std::cout << "Sprite of entity 3: " << spriteEntity3.mActive << std::endl; + gameObject[i]->AddComponent("C:/Test"); + gameObject[i]->AddComponent(0, 0, i); + gameObject[i]->AddComponent(i); } - std::cout << std::endl; + + auto stopAdding = std::chrono::high_resolution_clock::now(); - std::cout << "Finding all rigidbodies of entity 3" << std::endl; - std::vector> rigidbodyOfEntity3 = ComponentManager::GetInstance().GetComponentsByID(gameObect3.mId); - for(Rigidbody& rigidbodyEntity3 : rigidbodyOfEntity3) { - std::cout << "Rigidbody of entity 3: " << rigidbodyEntity3.mMass << " " << rigidbodyEntity3.mGravityScale << " " << rigidbodyEntity3.mBodyType << std::endl; - } - std::cout << std::endl; + //This is what systems would do: - std::cout << "Finding all sprites of all entities" << std::endl; std::vector, std::uint32_t>> sprites = ComponentManager::GetInstance().GetComponentsByType(); for(auto& [sprite, id] : sprites) { - std::cout << "Sprite of id: " << id << ": " << sprite.get().mActive << std::endl; + std::cout << sprite.get().mPath << std::endl; } std::cout << std::endl; - std::cout << "Finding all coliders of all entities" << std::endl; + std::vector, std::uint32_t>> rigidBodies = ComponentManager::GetInstance().GetComponentsByType(); + for(auto& [rigidbody, id] : rigidBodies) { + std::cout << rigidbody.get().mMass << " " << rigidbody.get().mGravityScale << " " << rigidbody.get().mBodyType << std::endl; + } + std::vector, std::uint32_t>> coliders = ComponentManager::GetInstance().GetComponentsByType(); for(auto& [colider, id] : coliders) { - std::cout << "Colder of id: " << id << ": " << colider.get().mSize << std::endl; + std::cout << colider.get().mSize << std::endl; } std::cout << std::endl; - std::cout << "Finding all rigidbodies of all entities" << std::endl; - std::vector, std::uint32_t>> rigidBodies = ComponentManager::GetInstance().GetComponentsByType(); - for(auto& [rigidbody, id] : rigidBodies) { - std::cout << "Rigidbody of id: " << id << ": " << rigidbody.get().mMass << " " << rigidbody.get().mGravityScale << " " << rigidbody.get().mBodyType << std::endl; + auto stopLooping = std::chrono::high_resolution_clock::now(); - rigidbody.get().mMass = -1; + for (int i = 0; i < 100000; ++i) { + delete gameObject[i]; } - std::cout << std::endl; - std::cout << "Finding all rigidbodies of all entities for the second time (after changing mMass to -1)" << std::endl; - std::vector, std::uint32_t>> rigidBodies2 = ComponentManager::GetInstance().GetComponentsByType(); - for(auto& [rigidbody2, id2] : rigidBodies2) { - std::cout << "Rigidbody of id: " << id2 << ": " << rigidbody2.get().mMass << " " << rigidbody2.get().mGravityScale << " " << rigidbody2.get().mBodyType << std::endl; - } - std::cout << std::endl; + auto Addtime = std::chrono::duration_cast(stopAdding - startAdding); + auto LoopTime = std::chrono::duration_cast(stopLooping - stopAdding); + std::cout << "AddTime: " << Addtime.count() << " us" << std::endl; + std::cout << "LoopTime: " << LoopTime.count() << " us" << std::endl; } -- cgit v1.2.3 From a5fa49f39473a8d2dc535145cb34866967ec10ab Mon Sep 17 00:00:00 2001 From: Max-001 <80035972+Max-001@users.noreply.github.com> Date: Sat, 5 Oct 2024 12:31:50 +0200 Subject: Improved test --- mwe/ecs-homemade/src/main.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'mwe') diff --git a/mwe/ecs-homemade/src/main.cpp b/mwe/ecs-homemade/src/main.cpp index 122311a..c78e085 100644 --- a/mwe/ecs-homemade/src/main.cpp +++ b/mwe/ecs-homemade/src/main.cpp @@ -26,20 +26,20 @@ int main() { std::vector, std::uint32_t>> sprites = ComponentManager::GetInstance().GetComponentsByType(); for(auto& [sprite, id] : sprites) { - std::cout << sprite.get().mPath << std::endl; + //std::cout << sprite.get().mPath << std::endl; } - std::cout << std::endl; + //std::cout << std::endl; std::vector, std::uint32_t>> rigidBodies = ComponentManager::GetInstance().GetComponentsByType(); for(auto& [rigidbody, id] : rigidBodies) { - std::cout << rigidbody.get().mMass << " " << rigidbody.get().mGravityScale << " " << rigidbody.get().mBodyType << std::endl; + //std::cout << rigidbody.get().mMass << " " << rigidbody.get().mGravityScale << " " << rigidbody.get().mBodyType << std::endl; } - + //std::cout << std::endl; + std::vector, std::uint32_t>> coliders = ComponentManager::GetInstance().GetComponentsByType(); for(auto& [colider, id] : coliders) { - std::cout << colider.get().mSize << std::endl; + //std::cout << colider.get().mSize << std::endl; } - std::cout << std::endl; auto stopLooping = std::chrono::high_resolution_clock::now(); -- cgit v1.2.3 From 765550bce8a81c6f0c79c0083b14ef68e0c900b2 Mon Sep 17 00:00:00 2001 From: Max-001 <80035972+Max-001@users.noreply.github.com> Date: Sat, 5 Oct 2024 12:36:26 +0200 Subject: Removed the std::pair to improve test --- mwe/ecs-homemade/inc/ComponentManager.h | 2 +- mwe/ecs-homemade/inc/ComponentManager.hpp | 10 +++++----- mwe/ecs-homemade/src/main.cpp | 14 +++++++------- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'mwe') diff --git a/mwe/ecs-homemade/inc/ComponentManager.h b/mwe/ecs-homemade/inc/ComponentManager.h index 893aa56..1a58b01 100644 --- a/mwe/ecs-homemade/inc/ComponentManager.h +++ b/mwe/ecs-homemade/inc/ComponentManager.h @@ -29,7 +29,7 @@ public: template std::vector> GetComponentsByID(std::uint32_t id) const; //Get a vector<> of all components at specific type and id template - std::vector, std::uint32_t>> GetComponentsByType() const; //Get a vector<> of all components of a specific type + std::vector> GetComponentsByType() const; //Get a vector<> of all components of a specific type private: static ComponentManager mInstance; //Singleton diff --git a/mwe/ecs-homemade/inc/ComponentManager.hpp b/mwe/ecs-homemade/inc/ComponentManager.hpp index 53dfddd..720ee79 100644 --- a/mwe/ecs-homemade/inc/ComponentManager.hpp +++ b/mwe/ecs-homemade/inc/ComponentManager.hpp @@ -61,11 +61,11 @@ std::vector> ComponentManager::GetComponentsByID(std:: } template -std::vector, std::uint32_t>> ComponentManager::GetComponentsByType() const { +std::vector> ComponentManager::GetComponentsByType() const { std::type_index type = typeid(T); //Determine the type of T (this is used as the key of the unordered_map<>) - std::vector, std::uint32_t>> componentVector; //Create an empty vector<> - std::uint32_t id = 0; //Set the id to 0 (the id will also be stored in the returned vector<>) + std::vector> componentVector; //Create an empty vector<> + //std::uint32_t id = 0; //Set the id to 0 (the id will also be stored in the returned vector<>) if (mComponents.find(type) != mComponents.end()) { //Find the type (in the unordered_map<>) @@ -76,11 +76,11 @@ std::vector, std::uint32_t>> ComponentManage T* castedComponent = static_cast(componentPtr.get()); //Cast the unique_ptr to a raw pointer if (castedComponent) { //Ensure that the cast was successful - componentVector.emplace_back(std::ref(*castedComponent), id); //Pair the dereferenced raw pointer and the id and add it to the vector<> + componentVector.emplace_back(std::ref(*castedComponent)); //Pair the dereferenced raw pointer and the id and add it to the vector<> } } - ++id; //Increase the id (the id will also be stored in the returned vector<>) + //++id; //Increase the id (the id will also be stored in the returned vector<>) } } diff --git a/mwe/ecs-homemade/src/main.cpp b/mwe/ecs-homemade/src/main.cpp index c78e085..41f7d6d 100644 --- a/mwe/ecs-homemade/src/main.cpp +++ b/mwe/ecs-homemade/src/main.cpp @@ -24,20 +24,20 @@ int main() { //This is what systems would do: - std::vector, std::uint32_t>> sprites = ComponentManager::GetInstance().GetComponentsByType(); - for(auto& [sprite, id] : sprites) { + std::vector> sprites = ComponentManager::GetInstance().GetComponentsByType(); + for(Sprite& sprite : sprites) { //std::cout << sprite.get().mPath << std::endl; } //std::cout << std::endl; - std::vector, std::uint32_t>> rigidBodies = ComponentManager::GetInstance().GetComponentsByType(); - for(auto& [rigidbody, id] : rigidBodies) { + std::vector> rigidBodies = ComponentManager::GetInstance().GetComponentsByType(); + for(Rigidbody& rigidbody : rigidBodies) { //std::cout << rigidbody.get().mMass << " " << rigidbody.get().mGravityScale << " " << rigidbody.get().mBodyType << std::endl; } //std::cout << std::endl; - - std::vector, std::uint32_t>> coliders = ComponentManager::GetInstance().GetComponentsByType(); - for(auto& [colider, id] : coliders) { + + std::vector> coliders = ComponentManager::GetInstance().GetComponentsByType(); + for(Colider& colider : coliders) { //std::cout << colider.get().mSize << std::endl; } -- cgit v1.2.3 From 7c9d3452c99fcb89ea6df55755e90f741b23cf10 Mon Sep 17 00:00:00 2001 From: Loek Le Blansch Date: Sun, 6 Oct 2024 13:22:10 +0200 Subject: copy homemade ECS to crepe + correct code style --- .clang-format | 1 + contributing.md | 5 + mwe/ecs-homemade/inc/ComponentManager.h | 43 +++++---- mwe/ecs-homemade/inc/ComponentManager.hpp | 154 +++++++++++++++++++----------- mwe/ecs-homemade/inc/GameObjectMax.h | 3 +- mwe/ecs-homemade/inc/GameObjectMax.hpp | 5 +- mwe/ecs-homemade/src/ComponentManager.cpp | 20 ++-- mwe/ecs-homemade/src/Components.cpp | 3 +- mwe/ecs-homemade/src/GameObjectMax.cpp | 4 +- mwe/ecs-homemade/src/main.cpp | 35 ++++--- 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 +++ 19 files changed, 487 insertions(+), 106 deletions(-) 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 'mwe') diff --git a/.clang-format b/.clang-format index 5d233eb..d2918db 100644 --- a/.clang-format +++ b/.clang-format @@ -22,6 +22,7 @@ AlignTrailingComments: ReflowComments: false AlignEscapedNewlines: DontAlign BreakBeforeBinaryOperators: All +BreakTemplateDeclarations: Yes ... # vim: ft=yaml diff --git a/contributing.md b/contributing.md index 2ff411a..933f1bf 100644 --- a/contributing.md +++ b/contributing.md @@ -17,6 +17,11 @@ # Code style - ASCII only +- 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 +- Explanatory comments in headers may be used to clarify implementation design + decisions - Formatting nitty-gritty is handled by clang-format/clang-tidy (run `make format` in the root folder of this repository to format all sources files) - When using libraries of which the header include order is important, make diff --git a/mwe/ecs-homemade/inc/ComponentManager.h b/mwe/ecs-homemade/inc/ComponentManager.h index 1a58b01..d368516 100644 --- a/mwe/ecs-homemade/inc/ComponentManager.h +++ b/mwe/ecs-homemade/inc/ComponentManager.h @@ -2,39 +2,44 @@ #include "Components.h" #include -#include -#include -#include #include +#include +#include #include +#include class ComponentManager { public: - static ComponentManager& GetInstance(); //Singleton + static ComponentManager & GetInstance(); //Singleton - ComponentManager(const ComponentManager&) = delete; //Singleton - ComponentManager(ComponentManager&&) = delete; //Singleton - ComponentManager& operator=(const ComponentManager&) = delete; //Singleton - ComponentManager& operator=(ComponentManager&&) = delete; //Singleton + ComponentManager(const ComponentManager &) = delete; //Singleton + ComponentManager(ComponentManager &&) = delete; //Singleton + ComponentManager & operator=(const ComponentManager &) = delete; //Singleton + ComponentManager & operator=(ComponentManager &&) = delete; //Singleton template - void AddComponent(std::uint32_t id, Args&&... args); //Add a component of a specific type + void AddComponent(std::uint32_t id, + Args &&... args); //Add a component of a specific type template - void DeleteComponentsById(std::uint32_t id); //Deletes all components of a specific type and id + void DeleteComponentsById( + std::uint32_t id); //Deletes all components of a specific type and id template - void DeleteComponents(); //Deletes all components of a specific type - void DeleteAllComponentsOfId(std::uint32_t id); //Deletes all components of a specific id - void DeleteAllComponents(); //Deletes all components + void DeleteComponents(); //Deletes all components of a specific type + void DeleteAllComponentsOfId( + std::uint32_t id); //Deletes all components of a specific id + void DeleteAllComponents(); //Deletes all components template - std::vector> GetComponentsByID(std::uint32_t id) const; //Get a vector<> of all components at specific type and id + std::vector> GetComponentsByID(std::uint32_t id) + const; //Get a vector<> of all components at specific type and id template - std::vector> GetComponentsByType() const; //Get a vector<> of all components of a specific type + std::vector> GetComponentsByType() + const; //Get a vector<> of all components of a specific type private: - static ComponentManager mInstance; //Singleton + static ComponentManager mInstance; //Singleton - ComponentManager(); //Singleton + ComponentManager(); //Singleton /* * The std::unordered_map>>> below might seem a bit strange, let me explain this structure: @@ -42,7 +47,9 @@ 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>>> mComponents; + std::unordered_map>>> + mComponents; }; #include "ComponentManager.hpp" diff --git a/mwe/ecs-homemade/inc/ComponentManager.hpp b/mwe/ecs-homemade/inc/ComponentManager.hpp index 720ee79..161ce71 100644 --- a/mwe/ecs-homemade/inc/ComponentManager.hpp +++ b/mwe/ecs-homemade/inc/ComponentManager.hpp @@ -1,88 +1,126 @@ template -void ComponentManager::AddComponent(std::uint32_t id, Args&&... args) { - std::type_index type = typeid(T); //Determine the type of T (this is used as the key of the unordered_map<>) - - if (mComponents.find(type) == mComponents.end()) { //Check if this component type is already in the unordered_map<> - mComponents[type] = std::vector>>(); //If not, create a new (empty) vector<> of vector> - } +void ComponentManager::AddComponent(std::uint32_t id, Args &&... args) { + std::type_index type = typeid( + T); //Determine the type of T (this is used as the key of the unordered_map<>) + + if (mComponents.find(type) + == mComponents + .end()) { //Check if this component type is already in the unordered_map<> + mComponents[type] = std::vector>>(); //If not, create a new (empty) vector<> of vector> + } - if (id >= mComponents[type].size()) { //Resize the vector<> if the id is greater than the current size - mComponents[type].resize(id + 1); //Initialize new slots to nullptr (resize does automatically init to nullptr) - } + if (id + >= mComponents[type] + .size()) { //Resize the vector<> if the id is greater than the current size + mComponents[type].resize( + id + + 1); //Initialize new slots to nullptr (resize does automatically init to nullptr) + } - mComponents[type][id].push_back(std::make_unique(std::forward(args)...)); //Create a new component of type T using perfect forwarding and store its unique_ptr in the vector<> + mComponents[type][id].push_back(std::make_unique(std::forward( + args)...)); //Create a new component of type T using perfect forwarding and store its unique_ptr in the vector<> } template void ComponentManager::DeleteComponentsById(std::uint32_t id) { - std::type_index type = typeid(T); //Determine the type of T (this is used as the key of the unordered_map<>) - - if (mComponents.find(type) != mComponents.end()) { //Find the type (in the unordered_map<>) - std::vector>>& componentArray = mComponents[type]; //Get the correct vector<> - - if (id < componentArray.size()) { //Make sure that the id (that we are looking for) is within the boundaries of the vector<> - componentArray[id].clear(); //Clear the whole vector<> of this specific type and id - } + std::type_index type = typeid( + T); //Determine the type of T (this is used as the key of the unordered_map<>) + + if (mComponents.find(type) + != mComponents.end()) { //Find the type (in the unordered_map<>) + std::vector>> & componentArray + = mComponents[type]; //Get the correct vector<> + + if (id + < componentArray + .size()) { //Make sure that the id (that we are looking for) is within the boundaries of the vector<> + componentArray[id] + .clear(); //Clear the whole vector<> of this specific type and id + } } } -template -void ComponentManager::DeleteComponents() { - std::type_index type = typeid(T); //Determine the type of T (this is used as the key of the unordered_map<>) +template void ComponentManager::DeleteComponents() { + std::type_index type = typeid( + T); //Determine the type of T (this is used as the key of the unordered_map<>) - if (mComponents.find(type) != mComponents.end()) { //Find the type (in the unordered_map<>) - mComponents[type].clear(); //Clear the whole vector<> of this specific type + if (mComponents.find(type) + != mComponents.end()) { //Find the type (in the unordered_map<>) + mComponents[type] + .clear(); //Clear the whole vector<> of this specific type } } template -std::vector> ComponentManager::GetComponentsByID(std::uint32_t id) const { - std::type_index type = typeid(T); //Determine the type of T (this is used as the key of the unordered_map<>) - - std::vector> componentVector; //Create an empty vector<> - - if (mComponents.find(type) != mComponents.end()) { //Find the type (in the unordered_map<>) - - const std::vector>>& componentArray = mComponents.at(type); //Get the correct vector<> - - if (id < componentArray.size()) { //Make sure that the id (that we are looking for) is within the boundaries of the vector<> - for (const std::unique_ptr& componentPtr : componentArray[id]) { //Loop trough the whole vector<> - T* castedComponent = static_cast(componentPtr.get()); //Cast the unique_ptr to a raw pointer - - if (castedComponent) { //Ensure that the cast was successful - componentVector.push_back(*castedComponent); //Add the dereferenced raw pointer to the vector<> - } - } - } - } +std::vector> +ComponentManager::GetComponentsByID(std::uint32_t id) const { + std::type_index type = typeid( + T); //Determine the type of T (this is used as the key of the unordered_map<>) + + std::vector> + componentVector; //Create an empty vector<> + + if (mComponents.find(type) + != mComponents.end()) { //Find the type (in the unordered_map<>) + + const std::vector>> & + componentArray + = mComponents.at(type); //Get the correct vector<> + + if (id + < componentArray + .size()) { //Make sure that the id (that we are looking for) is within the boundaries of the vector<> + for (const std::unique_ptr & componentPtr : + componentArray[id]) { //Loop trough the whole vector<> + T * castedComponent = static_cast( + componentPtr.get()); //Cast the unique_ptr to a raw pointer + + if (castedComponent) { //Ensure that the cast was successful + componentVector.push_back( + *castedComponent); //Add the dereferenced raw pointer to the vector<> + } + } + } + } - return componentVector; //Return the vector<> + return componentVector; //Return the vector<> } template -std::vector> ComponentManager::GetComponentsByType() const { - std::type_index type = typeid(T); //Determine the type of T (this is used as the key of the unordered_map<>) +std::vector> +ComponentManager::GetComponentsByType() const { + std::type_index type = typeid( + T); //Determine the type of T (this is used as the key of the unordered_map<>) - std::vector> componentVector; //Create an empty vector<> + std::vector> + componentVector; //Create an empty vector<> //std::uint32_t id = 0; //Set the id to 0 (the id will also be stored in the returned vector<>) - if (mComponents.find(type) != mComponents.end()) { //Find the type (in the unordered_map<>) + if (mComponents.find(type) + != mComponents.end()) { //Find the type (in the unordered_map<>) - const std::vector>>& componentArray = mComponents.at(type); //Get the correct vector<> + const std::vector>> & + componentArray + = mComponents.at(type); //Get the correct vector<> - for (const std::vector>& component : componentArray) { //Loop through the whole vector<> - for (const std::unique_ptr& componentPtr : component) { //Loop trough the whole vector<> - T* castedComponent = static_cast(componentPtr.get()); //Cast the unique_ptr to a raw pointer + for (const std::vector> & component : + componentArray) { //Loop through the whole vector<> + for (const std::unique_ptr & componentPtr : + component) { //Loop trough the whole vector<> + T * castedComponent = static_cast( + componentPtr.get()); //Cast the unique_ptr to a raw pointer - if (castedComponent) { //Ensure that the cast was successful - componentVector.emplace_back(std::ref(*castedComponent)); //Pair the dereferenced raw pointer and the id and add it to the vector<> - } - } + if (castedComponent) { //Ensure that the cast was successful + componentVector.emplace_back(std::ref( + *castedComponent)); //Pair the dereferenced raw pointer and the id and add it to the vector<> + } + } //++id; //Increase the id (the id will also be stored in the returned vector<>) - } - } + } + } - return componentVector; //Return the vector<> + return componentVector; //Return the vector<> } diff --git a/mwe/ecs-homemade/inc/GameObjectMax.h b/mwe/ecs-homemade/inc/GameObjectMax.h index f0bcec9..c88a834 100644 --- a/mwe/ecs-homemade/inc/GameObjectMax.h +++ b/mwe/ecs-homemade/inc/GameObjectMax.h @@ -7,8 +7,7 @@ class GameObject { public: GameObject(std::uint32_t id, std::string name, std::string tag, int layer); - template - void AddComponent(Args&&... args); + template void AddComponent(Args &&... args); std::uint32_t mId; std::string mName; diff --git a/mwe/ecs-homemade/inc/GameObjectMax.hpp b/mwe/ecs-homemade/inc/GameObjectMax.hpp index 1e952ba..91d51ea 100644 --- a/mwe/ecs-homemade/inc/GameObjectMax.hpp +++ b/mwe/ecs-homemade/inc/GameObjectMax.hpp @@ -1,6 +1,7 @@ #include "ComponentManager.h" template -void GameObject::AddComponent(Args&&... args) { - ComponentManager::GetInstance().AddComponent(mId, std::forward(args)...); +void GameObject::AddComponent(Args &&... args) { + ComponentManager::GetInstance().AddComponent( + mId, std::forward(args)...); } diff --git a/mwe/ecs-homemade/src/ComponentManager.cpp b/mwe/ecs-homemade/src/ComponentManager.cpp index 16cc2b6..536c152 100644 --- a/mwe/ecs-homemade/src/ComponentManager.cpp +++ b/mwe/ecs-homemade/src/ComponentManager.cpp @@ -2,20 +2,22 @@ ComponentManager ComponentManager::mInstance; -ComponentManager& ComponentManager::GetInstance() { - return mInstance; -} +ComponentManager & ComponentManager::GetInstance() { return mInstance; } ComponentManager::ComponentManager() {} void ComponentManager::DeleteAllComponentsOfId(std::uint32_t id) { - for(auto& [type, componentArray] : mComponents) { //Loop through all the types (in the unordered_map<>) - if (id < componentArray.size()) { //Make sure that the id (that we are looking for) is within the boundaries of the vector<> - componentArray[id].clear(); //Clear the components at this specific id - } - } + for (auto & [type, componentArray] : + mComponents) { //Loop through all the types (in the unordered_map<>) + if (id + < componentArray + .size()) { //Make sure that the id (that we are looking for) is within the boundaries of the vector<> + componentArray[id] + .clear(); //Clear the components at this specific id + } + } } void ComponentManager::DeleteAllComponents() { - mComponents.clear(); //Clear the whole unordered_map<> + mComponents.clear(); //Clear the whole unordered_map<> } diff --git a/mwe/ecs-homemade/src/Components.cpp b/mwe/ecs-homemade/src/Components.cpp index 69b5eaa..c8347b3 100644 --- a/mwe/ecs-homemade/src/Components.cpp +++ b/mwe/ecs-homemade/src/Components.cpp @@ -5,6 +5,7 @@ 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) {} +Rigidbody::Rigidbody(int mass, int gravityScale, int 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 62c41de..b0c5af7 100644 --- a/mwe/ecs-homemade/src/GameObjectMax.cpp +++ b/mwe/ecs-homemade/src/GameObjectMax.cpp @@ -2,4 +2,6 @@ #include "ComponentManager.h" -GameObject::GameObject(std::uint32_t id, std::string name, std::string tag, int layer) : mId(id), mName(name), mTag(tag), mActive(true), mLayer(layer) {} +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/mwe/ecs-homemade/src/main.cpp b/mwe/ecs-homemade/src/main.cpp index 41f7d6d..330e154 100644 --- a/mwe/ecs-homemade/src/main.cpp +++ b/mwe/ecs-homemade/src/main.cpp @@ -1,54 +1,59 @@ +#include +#include #include #include -#include -#include #include "ComponentManager.h" -#include "GameObjectMax.h" #include "Components.h" +#include "GameObjectMax.h" int main() { auto startAdding = std::chrono::high_resolution_clock::now(); - GameObject* gameObject[100000]; + GameObject * gameObject[100000]; - for(int i = 0; i < 100000; ++i) { + for (int i = 0; i < 100000; ++i) { gameObject[i] = new GameObject(i, "Name", "Tag", 0); gameObject[i]->AddComponent("C:/Test"); gameObject[i]->AddComponent(0, 0, i); gameObject[i]->AddComponent(i); } - + auto stopAdding = std::chrono::high_resolution_clock::now(); //This is what systems would do: - std::vector> sprites = ComponentManager::GetInstance().GetComponentsByType(); - for(Sprite& sprite : sprites) { + std::vector> sprites + = ComponentManager::GetInstance().GetComponentsByType(); + for (Sprite & sprite : sprites) { //std::cout << sprite.get().mPath << std::endl; } //std::cout << std::endl; - std::vector> rigidBodies = ComponentManager::GetInstance().GetComponentsByType(); - for(Rigidbody& rigidbody : rigidBodies) { + std::vector> rigidBodies + = ComponentManager::GetInstance().GetComponentsByType(); + for (Rigidbody & rigidbody : rigidBodies) { //std::cout << rigidbody.get().mMass << " " << rigidbody.get().mGravityScale << " " << rigidbody.get().mBodyType << std::endl; } //std::cout << std::endl; - std::vector> coliders = ComponentManager::GetInstance().GetComponentsByType(); - for(Colider& colider : coliders) { + std::vector> coliders + = ComponentManager::GetInstance().GetComponentsByType(); + for (Colider & colider : coliders) { //std::cout << colider.get().mSize << std::endl; } auto stopLooping = std::chrono::high_resolution_clock::now(); for (int i = 0; i < 100000; ++i) { - delete gameObject[i]; + delete gameObject[i]; } - auto Addtime = std::chrono::duration_cast(stopAdding - startAdding); - auto LoopTime = std::chrono::duration_cast(stopLooping - stopAdding); + auto Addtime = std::chrono::duration_cast( + stopAdding - startAdding); + auto LoopTime = std::chrono::duration_cast( + stopLooping - stopAdding); std::cout << "AddTime: " << Addtime.count() << " us" << std::endl; std::cout << "LoopTime: " << LoopTime.count() << " us" << std::endl; } 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 +#include +#include +#include +#include +#include + +#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 void AddComponent(std::uint32_t id, Args &&... args); + //! Deletes all components of a specific type and id + template void DeleteComponentsById(std::uint32_t id); + //! Deletes all components of a specific type + template 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 std::vector> GetComponentsByID(std::uint32_t id) const; + //! Get a vector<> of all components of a specific type + template std::vector> GetComponentsByType() const; + +private: + ComponentManager() = default; + + /* + * The std::unordered_map>>> 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>>> 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 +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> + components[type] = std::vector>>(); + } + + // 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(std::forward(args)...)); +} + +template +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>> & 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 +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 +std::vector> +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> componentVector; + + // Find the type (in the unordered_map<>) + if (components.find(type) != components.end()) { + // Get the correct vector<> + const std::vector>> & 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 & componentPtr : componentArray[id]) { + // Cast the unique_ptr to a raw pointer + T * castedComponent = static_cast(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 +std::vector> +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> 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>> & componentArray = components.at(type); + + // Loop through the whole vector<> + for (const std::vector> & component : componentArray) { + // Loop trough the whole vector<> + for (const std::unique_ptr & componentPtr : component) { + // Cast the unique_ptr to a raw pointer + T * castedComponent = static_cast(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 + +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 + +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 +#include + +namespace crepe { + +class GameObject { +public: + GameObject(std::uint32_t id, std::string name, std::string tag, int layer); + + template 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 +void GameObject::AddComponent(Args &&... args) { + ComponentManager::get_instance().AddComponent(mId, std::forward(args)...); +} + +} + -- cgit v1.2.3 From 509fb6ebdd27bc75375c1c51024ea906e25032c0 Mon Sep 17 00:00:00 2001 From: Loek Le Blansch 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 'mwe') 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 void ComponentManager::DeleteComponents() { +template +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 void AddComponent(Args &&... args); + template + 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 void AddComponent(std::uint32_t id, Args &&... args); + template + void add_component(std::uint32_t id, Args &&... args); //! Deletes all components of a specific type and id - template void DeleteComponentsById(std::uint32_t id); + template + void delete_components_by_id(std::uint32_t id); //! Deletes all components of a specific type - template void DeleteComponents(); + template + 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 std::vector> GetComponentsByID(std::uint32_t id) const; + template + std::vector> + get_components_by_id(std::uint32_t id) const; //! Get a vector<> of all components of a specific type - template std::vector> GetComponentsByType() const; + template + std::vector> 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>>> components; + std::unordered_map>>> + 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 -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> - components[type] = std::vector>>(); + components[type] + = std::vector>>(); } // 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(std::forward(args)...)); + components[type][id].push_back( + std::make_unique(std::forward(args)...)); } template -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>> & componentArray = components[type]; + std::vector>> & 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 -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 std::vector> -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>> & componentArray = components.at(type); + const std::vector>> & + 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 & componentPtr : componentArray[id]) { + for (const std::unique_ptr & componentPtr : + componentArray[id]) { // Cast the unique_ptr to a raw pointer T * castedComponent = static_cast(componentPtr.get()); @@ -92,7 +98,7 @@ ComponentManager::GetComponentsByID(std::uint32_t id) const { template std::vector> -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>> & componentArray = components.at(type); + const std::vector>> & + componentArray + = components.at(type); // Loop through the whole vector<> - for (const std::vector> & component : componentArray) { + for (const std::vector> & component : + componentArray) { // Loop trough the whole vector<> for (const std::unique_ptr & 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 void AddComponent(Args &&... args); + template + 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 void GameObject::AddComponent(Args &&... args) { - ComponentManager::get_instance().AddComponent(mId, std::forward(args)...); -} - + ComponentManager::get_instance().AddComponent( + mId, std::forward(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 _sound; + std::unique_ptr sound; }; } // namespace crepe::api -- cgit v1.2.3