aboutsummaryrefslogtreecommitdiff
path: root/mwe/ecs-homemade
diff options
context:
space:
mode:
Diffstat (limited to 'mwe/ecs-homemade')
-rw-r--r--mwe/ecs-homemade/inc/ComponentManager.h29
-rw-r--r--mwe/ecs-homemade/inc/ComponentManager.hpp159
-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.hpp5
-rw-r--r--mwe/ecs-homemade/src/ComponentManager.cpp3
-rw-r--r--mwe/ecs-homemade/src/Components.cpp16
-rw-r--r--mwe/ecs-homemade/src/GameObjectMax.cpp9
-rw-r--r--mwe/ecs-homemade/src/main.cpp23
10 files changed, 192 insertions, 107 deletions
diff --git a/mwe/ecs-homemade/inc/ComponentManager.h b/mwe/ecs-homemade/inc/ComponentManager.h
index d368516..99c108f 100644
--- a/mwe/ecs-homemade/inc/ComponentManager.h
+++ b/mwe/ecs-homemade/inc/ComponentManager.h
@@ -17,24 +17,26 @@ 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
@@ -47,8 +49,7 @@ private:
* 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>>>>
+ 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 d6da8e8..af9c3a1 100644
--- a/mwe/ecs-homemade/inc/ComponentManager.hpp
+++ b/mwe/ecs-homemade/inc/ComponentManager.hpp
@@ -1,121 +1,121 @@
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<>)
-
- std::vector<std::reference_wrapper<T>>
- componentVector; //Create an empty vector<>
-
- if (mComponents.find(type)
- != mComponents.end()) { //Find the type (in the unordered_map<>)
-
- const std::vector<std::vector<std::unique_ptr<Component>>> &
- componentArray
- = mComponents.at(type); //Get the correct vector<>
-
- 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 (castedComponent) { //Ensure that the cast was successful
- componentVector.push_back(
- *castedComponent); //Add the dereferenced raw pointer to the vector<>
+ //Determine the type of T (this is used as the key of the unordered_map<>)
+ std::type_index type = typeid(T);
+
+ //Create an empty vector<>
+ std::vector<std::reference_wrapper<T>> componentVector;
+
+ //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);
+
+ //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]) {
+ //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<>)
+std::vector<std::reference_wrapper<T>> ComponentManager::GetComponentsByType() const {
+ //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()) {
- const std::vector<std::vector<std::unique_ptr<Component>>> &
- componentArray
- = mComponents.at(type); //Get the correct vector<>
+ //Get the correct vector<>
+ const std::vector<std::vector<std::unique_ptr<Component>>> & componentArray
+ = mComponents.at(type);
- 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
+ //Loop through the whole vector<>
+ for (const std::vector<std::unique_ptr<Component>> & component : 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());
- 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<>
+ //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 +123,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..92375bb 100644
--- a/mwe/ecs-homemade/inc/GameObjectMax.hpp
+++ b/mwe/ecs-homemade/inc/GameObjectMax.hpp
@@ -1,7 +1,6 @@
#include "ComponentManager.h"
template <typename T, typename... Args>
-void GameObject::AddComponent(Args &&... args) {
- ComponentManager::GetInstance().AddComponent<T>(
- mId, std::forward<Args>(args)...);
+T & GameObject::AddComponent(Args &&... args) {
+ return ComponentManager::GetInstance().AddComponent<T>(mId, std::forward<Args>(args)...);
}
diff --git a/mwe/ecs-homemade/src/ComponentManager.cpp b/mwe/ecs-homemade/src/ComponentManager.cpp
index 536c152..33ba12e 100644
--- a/mwe/ecs-homemade/src/ComponentManager.cpp
+++ b/mwe/ecs-homemade/src/ComponentManager.cpp
@@ -12,8 +12,7 @@ void ComponentManager::DeleteAllComponentsOfId(std::uint32_t id) {
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 components at this specific id
+ componentArray[id].clear(); //Clear the components at this specific id
}
}
}
diff --git a/mwe/ecs-homemade/src/Components.cpp b/mwe/ecs-homemade/src/Components.cpp
index c8347b3..0d62bd5 100644
--- a/mwe/ecs-homemade/src/Components.cpp
+++ b/mwe/ecs-homemade/src/Components.cpp
@@ -6,6 +6,20 @@ Component::Component() : mActive(true) {}
Sprite::Sprite(std::string path) : mPath(path) {}
Rigidbody::Rigidbody(int mass, int gravityScale, int bodyType)
- : mMass(mass), mGravityScale(gravityScale), mBodyType(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/GameObjectMax.cpp b/mwe/ecs-homemade/src/GameObjectMax.cpp
index b0c5af7..0516f68 100644
--- a/mwe/ecs-homemade/src/GameObjectMax.cpp
+++ b/mwe/ecs-homemade/src/GameObjectMax.cpp
@@ -2,6 +2,9 @@
#include "ComponentManager.h"
-GameObject::GameObject(std::uint32_t id, std::string name, std::string tag,
- int layer)
- : mId(id), mName(name), mTag(tag), mActive(true), mLayer(layer) {}
+GameObject::GameObject(std::uint32_t id, std::string name, std::string tag, int layer)
+ : mId(id),
+ mName(name),
+ mTag(tag),
+ mActive(true),
+ mLayer(layer) {}
diff --git a/mwe/ecs-homemade/src/main.cpp b/mwe/ecs-homemade/src/main.cpp
index 330e154..85ab1f1 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,16 +52,23 @@ 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) {
delete gameObject[i];
}
- auto Addtime = std::chrono::duration_cast<std::chrono::microseconds>(
- stopAdding - startAdding);
- auto LoopTime = std::chrono::duration_cast<std::chrono::microseconds>(
- stopLooping - stopAdding);
+ auto Addtime
+ = std::chrono::duration_cast<std::chrono::microseconds>(stopAdding - startAdding);
+ auto LoopTime
+ = std::chrono::duration_cast<std::chrono::microseconds>(stopLooping - stopAdding);
std::cout << "AddTime: " << Addtime.count() << " us" << std::endl;
std::cout << "LoopTime: " << LoopTime.count() << " us" << std::endl;
}