#pragma once #include #include #include #include #include #include "Component.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 T & add_component(uint32_t id, Args &&... args); //! Deletes all components of a specific type and id template void delete_components_by_id(uint32_t id); //! Deletes all components of a specific type template void delete_components(); //! Deletes all components of a specific id void delete_all_components_of_id(uint32_t id); //! Deletes all components void delete_all_components(); //! Get a vector<> of all components at specific type and id template std::vector> get_components_by_id(uint32_t id) const; //! Get a vector<> of all components of a specific type template std::vector> get_components_by_type() const; private: ComponentManager(); virtual ~ComponentManager(); /* * 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; }; } // namespace crepe #include "ComponentManager.hpp"