aboutsummaryrefslogtreecommitdiff
path: root/src/crepe/ComponentManager.hpp
diff options
context:
space:
mode:
authormax-001 <maxsmits21@kpnmail.nl>2024-10-16 13:09:28 +0200
committermax-001 <maxsmits21@kpnmail.nl>2024-10-16 13:09:28 +0200
commit85514636cbf9ae34afc8d6c863e9760f291e6478 (patch)
tree4e745d504a0c55386aa20f079dfdaa0d32ac31aa /src/crepe/ComponentManager.hpp
parent809db83cd515c6c2b1d404811354208cf97a5c07 (diff)
parent579824011d5e8776e2079d6624a39535517760ff (diff)
Merge remote-tracking branch 'origin/master' into max/POC-ECS-memory-efficient
Diffstat (limited to 'src/crepe/ComponentManager.hpp')
-rw-r--r--src/crepe/ComponentManager.hpp152
1 files changed, 152 insertions, 0 deletions
diff --git a/src/crepe/ComponentManager.hpp b/src/crepe/ComponentManager.hpp
new file mode 100644
index 0000000..084cd33
--- /dev/null
+++ b/src/crepe/ComponentManager.hpp
@@ -0,0 +1,152 @@
+#pragma once
+
+#include <type_traits>
+
+#include "ComponentManager.h"
+
+namespace crepe {
+
+template <class T, typename... Args>
+void ComponentManager::add_component(uint32_t id, Args &&... args) {
+ using namespace std;
+
+ static_assert(is_base_of<Component, T>::value, "add_component must recieve a derivative class of Component");
+
+ // Determine the type of T (this is used as the key of the unordered_map<>)
+ type_index type = typeid(T);
+
+ // Check if this component type is already in the unordered_map<>
+ if (components.find(type) == components.end()) {
+ //If not, create a new (empty) vector<> of vector<unique_ptr<Component>>
+ components[type] = vector<vector<unique_ptr<Component>>>();
+ }
+
+ // Resize the vector<> if the id is greater than the current size
+ if (id >= components[type].size()) {
+ // Initialize new slots to nullptr (resize does automatically init to nullptr)
+ components[type].resize(id + 1);
+ }
+
+ // Create a new component of type T (arguments directly forwarded). The
+ // constructor must be called by ComponentManager.
+ T * instance = new T(forward<Args>(args)...);
+ // store its unique_ptr in the vector<>
+ components[type][id].push_back(unique_ptr<T>(instance));
+}
+
+template <typename T>
+void ComponentManager::delete_components_by_id(uint32_t id) {
+ using namespace std;
+
+ // Determine the type of T (this is used as the key of the unordered_map<>)
+ type_index type = typeid(T);
+
+ // Find the type (in the unordered_map<>)
+ if (components.find(type) != components.end()) {
+ // Get the correct vector<>
+ vector<vector<unique_ptr<Component>>> & component_array
+ = components[type];
+
+ // Make sure that the id (that we are looking for) is within the boundaries of the vector<>
+ if (id < component_array.size()) {
+ // Clear the whole vector<> of this specific type and id
+ component_array[id].clear();
+ }
+ }
+}
+
+template <typename T>
+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);
+
+ // Find the type (in the unordered_map<>)
+ if (components.find(type) != components.end()) {
+ // Clear the whole vector<> of this specific type
+ components[type].clear();
+ }
+}
+
+template <typename T>
+std::vector<std::reference_wrapper<T>>
+ComponentManager::get_components_by_id(uint32_t id) const {
+ using namespace std;
+
+ // Determine the type of T (this is used as the key of the unordered_map<>)
+ type_index type = typeid(T);
+
+ // Create an empty vector<>
+ vector<reference_wrapper<T>> component_vector;
+
+ // Find the type (in the unordered_map<>)
+ if (components.find(type) != components.end()) {
+ // Get the correct vector<>
+ const vector<vector<unique_ptr<Component>>> & component_array
+ = components.at(type);
+
+ // Make sure that the id (that we are looking for) is within the boundaries of the vector<>
+ if (id < component_array.size()) {
+ // Loop trough the whole vector<>
+ for (const unique_ptr<Component> & component_ptr :
+ component_array[id]) {
+ // Cast the unique_ptr to a raw pointer
+ T * casted_component = static_cast<T *>(component_ptr.get());
+
+ // Ensure that the cast was successful
+ if (casted_component) {
+ // Add the dereferenced raw pointer to the vector<>
+ component_vector.push_back(*casted_component);
+ }
+ }
+ }
+ }
+
+ // Return the vector<>
+ return component_vector;
+}
+
+template <typename T>
+std::vector<std::reference_wrapper<T>>
+ComponentManager::get_components_by_type() const {
+ using namespace std;
+
+ // Determine the type of T (this is used as the key of the unordered_map<>)
+ type_index type = typeid(T);
+
+ // Create an empty vector<>
+ vector<reference_wrapper<T>> component_vector;
+ // Set the id to 0 (the id will also be stored in the returned vector<>)
+ // uint32_t id = 0;
+
+ // Find the type (in the unordered_map<>)
+ if (components.find(type) != components.end()) {
+
+ // Get the correct vector<>
+ const vector<vector<unique_ptr<Component>>> & component_array
+ = components.at(type);
+
+ // Loop through the whole vector<>
+ for (const vector<unique_ptr<Component>> & component :
+ component_array) {
+ // Loop trough the whole vector<>
+ for (const unique_ptr<Component> & component_ptr : component) {
+ // Cast the unique_ptr to a raw pointer
+ T * casted_component = static_cast<T *>(component_ptr.get());
+
+ // Ensure that the cast was successful
+ if (casted_component) {
+ // Pair the dereferenced raw pointer and the id and add it to the vector<>
+ component_vector.emplace_back(ref(*casted_component));
+ }
+ }
+
+ // Increase the id (the id will also be stored in the returned vector<>)
+ //++id;
+ }
+ }
+
+ // Return the vector<>
+ return component_vector;
+}
+
+} // namespace crepe