aboutsummaryrefslogtreecommitdiff
path: root/mwe/ecs-homemade
diff options
context:
space:
mode:
authorLoek Le Blansch <loek@pipeframe.xyz>2024-10-18 14:56:05 +0200
committerLoek Le Blansch <loek@pipeframe.xyz>2024-10-18 14:56:05 +0200
commit0fdebc7d7a143ad2b9b5ed6a596bf4bb1f0f7d7f (patch)
tree7400cea54bc40b01f64cf91c26a4ae20980a64cc /mwe/ecs-homemade
parenta2c719948ff8af9abe267c4d1c9b16cd1e2fb317 (diff)
parent77555730e3ddb811b9ce8470659663e3f1573de2 (diff)
merge master into loek/scripts
Diffstat (limited to 'mwe/ecs-homemade')
-rw-r--r--mwe/ecs-homemade/inc/ComponentManager.h27
-rw-r--r--mwe/ecs-homemade/inc/ComponentManager.hpp144
-rw-r--r--mwe/ecs-homemade/inc/Components.h33
-rw-r--r--mwe/ecs-homemade/inc/Components.hpp20
-rw-r--r--mwe/ecs-homemade/inc/GameObjectMax.h2
-rw-r--r--mwe/ecs-homemade/inc/GameObjectMax.hpp4
-rw-r--r--mwe/ecs-homemade/src/Components.cpp12
-rw-r--r--mwe/ecs-homemade/src/main.cpp16
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) {