aboutsummaryrefslogtreecommitdiff
path: root/mwe/ecs-homemade/inc
diff options
context:
space:
mode:
authorMax-001 <80035972+Max-001@users.noreply.github.com>2024-10-02 15:26:24 +0200
committerMax-001 <80035972+Max-001@users.noreply.github.com>2024-10-02 15:26:24 +0200
commit2bd37e7d98728d72ba44da18eefea91547a7885a (patch)
tree63ebde9c853c5f683e50ffc4dd8950b08dc48efa /mwe/ecs-homemade/inc
parente409986d9a21ca96ee0b491826eb0008ff6ab8e0 (diff)
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)
Diffstat (limited to 'mwe/ecs-homemade/inc')
-rw-r--r--mwe/ecs-homemade/inc/ComponentManager.h33
-rw-r--r--mwe/ecs-homemade/inc/ComponentManager.hpp77
2 files changed, 56 insertions, 54 deletions
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 <vector>
#include <typeindex>
#include <memory>
-#include <any>
+#include <utility>
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 <typename T, typename... Args>
- 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 <typename T>
- std::vector<std::reference_wrapper<T>> GetComponentsOfID(std::uint32_t id);
- /*template <typename T>
- std::vector<std::uint32_t> GetAllComponentIDs();
+ std::vector<std::reference_wrapper<T>> GetComponentsByID(std::uint32_t id) const; //Get a vector<> of all components at specific id
template <typename T>
- std::vector<T*> GetAllComponentPointer();*/
+ std::vector<std::pair<std::reference_wrapper<T>, 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<std::type_index, std::vector<std::vector<std::unique_ptr<Component>>>> below might seem a bit strange, let me explain this structure:
+ * The std::unordered_map<> has a key and value. The key is a std::type_index and the value is a std::vector. So, a new std::vector will be created for each new std::type_index.
+ * The first std::vector<> stores another vector<>. This first vector<> is to bind the entity's id to a component.
+ * The second std::vector<> stores unique_ptrs. Each component can be gathered via an unique_ptr. This second vector<> allows multiple components of the same std::type_index for one entity (id).
+ */
std::unordered_map<std::type_index, std::vector<std::vector<std::unique_ptr<Component>>>> 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<std::vector<std::unique_ptr<Component>>>(); //If not, create a new (empty) vector<> of unique_ptr<Component>
+ mComponents[type] = std::vector<std::vector<std::unique_ptr<Component>>>(); //If not, create a new (empty) vector<> of vector<unique_ptr<Component>>
}
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<T>(std::forward<Args>(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<T>(std::forward<Args>(args)...)); //Create a new component of type T using perfect forwarding and store its unique_ptr in the vector<>
}
template <typename T>
-std::vector<std::reference_wrapper<T>> ComponentManager::GetComponentsOfID(std::uint32_t id) {
- std::type_index type = typeid(T);
+std::vector<std::reference_wrapper<T>> 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<std::reference_wrapper<T>> componentVector; //Create an empty vector<>
- std::vector<std::reference_wrapper<T>> componentVector;
+ if (mComponents.find(type) != mComponents.end()) { //Find the type (in the unordered_list<>)
- if (mComponents.find(type) != mComponents.end()) {
+ const std::vector<std::vector<std::unique_ptr<Component>>>& 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<Component>& componentPtr : componentArray[id]) { //Loop trough the whole vector<>
+ T* castedComponent = static_cast<T*>(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<T*>(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 <typename T>
-std::vector<std::uint32_t> ComponentManager::GetAllComponentIDs() {
- std::type_index type = typeid(T);
- std::vector<std::uint32_t> 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::pair<std::reference_wrapper<T>, 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 <typename T>
-std::vector<T*> ComponentManager::GetAllComponentPointer() {
- std::type_index type = typeid(T);
- std::vector<T*> 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<T*>(component)); // Cast to the correct type
+ std::vector<std::pair<std::reference_wrapper<T>, 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<std::vector<std::unique_ptr<Component>>>& componentArray = mComponents.at(type); //Get the correct vector<>
+
+ for (const std::vector<std::unique_ptr<Component>>& component : componentArray) { //Loop through the whole vector<>
+ for (const std::unique_ptr<Component>& componentPtr : component) { //Loop trough the whole vector<>
+ T* castedComponent = static_cast<T*>(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;
+}