diff options
Diffstat (limited to 'mwe/ecs-homemade')
| -rw-r--r-- | mwe/ecs-homemade/inc/ComponentManager.h | 27 | ||||
| -rw-r--r-- | mwe/ecs-homemade/inc/ComponentManager.hpp | 144 | ||||
| -rw-r--r-- | mwe/ecs-homemade/inc/Components.h | 33 | ||||
| -rw-r--r-- | mwe/ecs-homemade/inc/Components.hpp | 20 | ||||
| -rw-r--r-- | mwe/ecs-homemade/inc/GameObjectMax.h | 2 | ||||
| -rw-r--r-- | mwe/ecs-homemade/inc/GameObjectMax.hpp | 4 | ||||
| -rw-r--r-- | mwe/ecs-homemade/src/Components.cpp | 12 | ||||
| -rw-r--r-- | mwe/ecs-homemade/src/main.cpp | 16 | 
8 files changed, 175 insertions, 83 deletions
| diff --git a/mwe/ecs-homemade/inc/ComponentManager.h b/mwe/ecs-homemade/inc/ComponentManager.h index d368516..0ba358e 100644 --- a/mwe/ecs-homemade/inc/ComponentManager.h +++ b/mwe/ecs-homemade/inc/ComponentManager.h @@ -17,24 +17,27 @@ public:  	ComponentManager & operator=(const ComponentManager &) = delete; //Singleton  	ComponentManager & operator=(ComponentManager &&) = delete; //Singleton +	//Add a component of a specific type  	template <typename T, typename... Args> -	void AddComponent(std::uint32_t id, -					  Args &&... args); //Add a component of a specific type +	T & AddComponent(std::uint32_t id, Args &&... args); +	//Deletes all components of a specific type and id  	template <typename T> -	void DeleteComponentsById( -		std::uint32_t id); //Deletes all components of a specific type and id +	void DeleteComponentsById(std::uint32_t id); +	//Deletes all components of a specific type  	template <typename T> -	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 id +	void DeleteAllComponentsOfId(std::uint32_t id); +	//Deletes all components +	void DeleteAllComponents(); +	//Get a vector<> of all components at specific type and id  	template <typename T> -	std::vector<std::reference_wrapper<T>> GetComponentsByID(std::uint32_t id) -		const; //Get a vector<> of all components at specific type and id +	std::vector<std::reference_wrapper<T>> +	GetComponentsByID(std::uint32_t id) const; +	//Get a vector<> of all components of a specific type  	template <typename T> -	std::vector<std::reference_wrapper<T>> GetComponentsByType() -		const; //Get a vector<> of all components of a specific type +	std::vector<std::reference_wrapper<T>> GetComponentsByType() const;  private:  	static ComponentManager mInstance; //Singleton diff --git a/mwe/ecs-homemade/inc/ComponentManager.hpp b/mwe/ecs-homemade/inc/ComponentManager.hpp index d6da8e8..92db1d4 100644 --- a/mwe/ecs-homemade/inc/ComponentManager.hpp +++ b/mwe/ecs-homemade/inc/ComponentManager.hpp @@ -1,121 +1,128 @@  template <typename T, typename... Args> -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 vector<unique_ptr<Component>> +T & 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 (mComponents.find(type) == mComponents.end()) { +		//If not, create a new (empty) vector<> of vector<unique_ptr<Component>> +		mComponents[type] +			= std::vector<std::vector<std::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 automatically init to nullptr) +	//Resize the vector<> if the id is greater than the current size +	if (id >= mComponents[type].size()) { +		//Initialize new slots to nullptr (resize does automatically init to nullptr) +		mComponents[type].resize(id + 1);  	} -	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<> +	//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<T>(std::forward<Args>(args)...)); + +	return static_cast<T &>(*mComponents[type][id].back().get());  }  template <typename T>  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<>) +	//Determine the type of T (this is used as the key of the unordered_map<>) +	std::type_index type = typeid(T); -	if (mComponents.find(type) -		!= mComponents.end()) { //Find the type (in the unordered_map<>) +	//Find the type (in the unordered_map<>) +	if (mComponents.find(type) != mComponents.end()) { +		//Get the correct vector<>  		std::vector<std::vector<std::unique_ptr<Component>>> & componentArray -			= mComponents[type]; //Get the correct vector<> +			= mComponents[type]; -		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 +		//Make sure that the id (that we are looking for) is within the boundaries of the vector<> +		if (id < componentArray.size()) { +			//Clear the whole vector<> of this specific type and id +			componentArray[id].clear();  		}  	}  }  template <typename T>  void ComponentManager::DeleteComponents() { -	std::type_index type = typeid( -		T); //Determine the type of T (this is used as the key of the unordered_map<>) +	//Determine the type of T (this is used as the key of the unordered_map<>) +	std::type_index type = typeid(T); -	if (mComponents.find(type) -		!= mComponents.end()) { //Find the type (in the unordered_map<>) -		mComponents[type] -			.clear(); //Clear the whole vector<> of this specific type +	//Find the type (in the unordered_map<>) +	if (mComponents.find(type) != mComponents.end()) { +		//Clear the whole vector<> of this specific type +		mComponents[type].clear();  	}  }  template <typename 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<>) +	//Determine the type of T (this is used as the key of the unordered_map<>) +	std::type_index type = typeid(T); -	std::vector<std::reference_wrapper<T>> -		componentVector; //Create an empty vector<> +	//Create an empty vector<> +	std::vector<std::reference_wrapper<T>> componentVector; -	if (mComponents.find(type) -		!= mComponents.end()) { //Find the type (in the unordered_map<>) +	//Find the type (in the unordered_map<>) +	if (mComponents.find(type) != mComponents.end()) { +		//Get the correct vector<>  		const std::vector<std::vector<std::unique_ptr<Component>>> &  			componentArray -			= mComponents.at(type); //Get the correct vector<> +			= mComponents.at(type); -		if (id -			< componentArray -				  .size()) { //Make sure that the id (that we are looking for) is within the boundaries of the vector<> +		//Make sure that the id (that we are looking for) is within the boundaries of the vector<> +		if (id < componentArray.size()) { +			//Loop trough the whole vector<>  			for (const std::unique_ptr<Component> & componentPtr : -				 componentArray[id]) { //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( -						*castedComponent); //Add the dereferenced raw pointer to the vector<> +				 componentArray[id]) { +				//Cast the unique_ptr to a raw pointer +				T * castedComponent = static_cast<T *>(componentPtr.get()); + +				//Ensure that the cast was successful +				if (castedComponent) { +					//Add the dereferenced raw pointer to the vector<> +					componentVector.push_back(*castedComponent);  				}  			}  		}  	} -	return componentVector; //Return the vector<> +	//Return the vector<> +	return componentVector;  }  template <typename T>  std::vector<std::reference_wrapper<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<>) +	//Determine the type of T (this is used as the key of the unordered_map<>) +	std::type_index type = typeid(T); -	std::vector<std::reference_wrapper<T>> -		componentVector; //Create an empty vector<> +	//Create an empty vector<> +	std::vector<std::reference_wrapper<T>> componentVector;  	//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<>) +	//Find the type (in the unordered_map<>) +	if (mComponents.find(type) != mComponents.end()) { +		//Get the correct vector<>  		const std::vector<std::vector<std::unique_ptr<Component>>> &  			componentArray -			= mComponents.at(type); //Get the correct vector<> +			= mComponents.at(type); +		//Loop through the whole 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.emplace_back(std::ref( -						*castedComponent)); //Pair the dereferenced raw pointer and the id and add it to the vector<> +			 componentArray) { +			//Loop trough the whole vector<> +			for (const std::unique_ptr<Component> & componentPtr : component) { +				//Cast the unique_ptr to a raw pointer +				T * castedComponent = static_cast<T *>(componentPtr.get()); + +				//Ensure that the cast was successful +				if (castedComponent) { +					//Pair the dereferenced raw pointer and the id and add it to the vector<> +					componentVector.emplace_back(std::ref(*castedComponent));  				}  			} @@ -123,5 +130,6 @@ ComponentManager::GetComponentsByType() const {  		}  	} -	return componentVector; //Return the vector<> +	//Return the vector<> +	return componentVector;  } diff --git a/mwe/ecs-homemade/inc/Components.h b/mwe/ecs-homemade/inc/Components.h index 98c5fe7..ad491e7 100644 --- a/mwe/ecs-homemade/inc/Components.h +++ b/mwe/ecs-homemade/inc/Components.h @@ -1,5 +1,6 @@  #pragma once +#include <memory>  #include <string>  class Component { @@ -31,3 +32,35 @@ public:  	int mSize;  }; + +class IBehaviour { +public: +	virtual ~IBehaviour() = default; +	virtual void onStart() = 0; +	virtual void onUpdate() = 0; +}; + +template <typename T> +class BehaviourWrapper : public IBehaviour { +public: +	BehaviourWrapper(); +	void onStart() override; +	void onUpdate() override; + +private: +	T instance; +}; + +class BehaviourScript : public Component { +public: +	template <typename T> +	void addScript(); + +	void onStart(); +	void onUpdate(); + +private: +	std::unique_ptr<IBehaviour> behaviour; +}; + +#include "Components.hpp" diff --git a/mwe/ecs-homemade/inc/Components.hpp b/mwe/ecs-homemade/inc/Components.hpp new file mode 100644 index 0000000..436a28c --- /dev/null +++ b/mwe/ecs-homemade/inc/Components.hpp @@ -0,0 +1,20 @@ +#include "Components.h" +#include <iostream> + +template <typename T> +BehaviourWrapper<T>::BehaviourWrapper() : instance() {} + +template <typename T> +void BehaviourWrapper<T>::onStart() { +	instance.onStart(); +} + +template <typename T> +void BehaviourWrapper<T>::onUpdate() { +	instance.onUpdate(); +} + +template <typename T> +void BehaviourScript::addScript() { +	behaviour = std::make_unique<BehaviourWrapper<T>>(); +} diff --git a/mwe/ecs-homemade/inc/GameObjectMax.h b/mwe/ecs-homemade/inc/GameObjectMax.h index 3029053..5fab44a 100644 --- a/mwe/ecs-homemade/inc/GameObjectMax.h +++ b/mwe/ecs-homemade/inc/GameObjectMax.h @@ -8,7 +8,7 @@ public:  	GameObject(std::uint32_t id, std::string name, std::string tag, int layer);  	template <typename T, typename... Args> -	void AddComponent(Args &&... args); +	T & 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 91d51ea..2f433bb 100644 --- a/mwe/ecs-homemade/inc/GameObjectMax.hpp +++ b/mwe/ecs-homemade/inc/GameObjectMax.hpp @@ -1,7 +1,7 @@  #include "ComponentManager.h"  template <typename T, typename... Args> -void GameObject::AddComponent(Args &&... args) { -	ComponentManager::GetInstance().AddComponent<T>( +T & GameObject::AddComponent(Args &&... args) { +	return ComponentManager::GetInstance().AddComponent<T>(  		mId, std::forward<Args>(args)...);  } diff --git a/mwe/ecs-homemade/src/Components.cpp b/mwe/ecs-homemade/src/Components.cpp index c8347b3..de8753e 100644 --- a/mwe/ecs-homemade/src/Components.cpp +++ b/mwe/ecs-homemade/src/Components.cpp @@ -9,3 +9,15 @@ Rigidbody::Rigidbody(int mass, int gravityScale, int bodyType)  	: mMass(mass), mGravityScale(gravityScale), mBodyType(bodyType) {}  Colider::Colider(int size) : mSize(size) {} + +void BehaviourScript::onStart() { +	if (behaviour) { +		behaviour->onStart(); +	} +} + +void BehaviourScript::onUpdate() { +	if (behaviour) { +		behaviour->onUpdate(); +	} +} diff --git a/mwe/ecs-homemade/src/main.cpp b/mwe/ecs-homemade/src/main.cpp index 330e154..70c5d2c 100644 --- a/mwe/ecs-homemade/src/main.cpp +++ b/mwe/ecs-homemade/src/main.cpp @@ -7,6 +7,13 @@  #include "Components.h"  #include "GameObjectMax.h" +class myScript { +public: +	void onStart() { std::cout << "In onStart" << std::endl; } + +	void onUpdate() { std::cout << "In onUpdate" << std::endl; } +}; +  int main() {  	auto startAdding = std::chrono::high_resolution_clock::now(); @@ -18,6 +25,7 @@ int main() {  		gameObject[i]->AddComponent<Sprite>("C:/Test");  		gameObject[i]->AddComponent<Rigidbody>(0, 0, i);  		gameObject[i]->AddComponent<Colider>(i); +		gameObject[i]->AddComponent<BehaviourScript>().addScript<myScript>();  	}  	auto stopAdding = std::chrono::high_resolution_clock::now(); @@ -44,6 +52,14 @@ int main() {  		//std::cout << colider.get().mSize << std::endl;  	} +	std::vector<std::reference_wrapper<BehaviourScript>> scripts +		= ComponentManager::GetInstance() +			  .GetComponentsByType<BehaviourScript>(); +	for (BehaviourScript & script : scripts) { +		//script.onStart(); +		//script.onUpdate(); +	} +  	auto stopLooping = std::chrono::high_resolution_clock::now();  	for (int i = 0; i < 100000; ++i) { |