From eedee9dd9f7a2048598f95937d7688972911e3e4 Mon Sep 17 00:00:00 2001 From: sebastian Date: Wed, 29 Jul 2026 19:03:48 +0200 Subject: [PATCH] ADD: ECS-System --- CMakeLists.txt | 6 +++ engine/src/ecs/ComponentPool.cpp | 5 +++ engine/src/ecs/ComponentPool.h | 45 ++++++++++++++++++++ engine/src/ecs/Entity.cpp | 5 +++ engine/src/ecs/Entity.h | 39 +++++++++++++++++ engine/src/ecs/EntityRegistry.cpp | 5 +++ engine/src/ecs/EntityRegistry.h | 70 +++++++++++++++++++++++++++++++ 7 files changed, 175 insertions(+) create mode 100644 engine/src/ecs/ComponentPool.cpp create mode 100644 engine/src/ecs/ComponentPool.h create mode 100644 engine/src/ecs/Entity.cpp create mode 100644 engine/src/ecs/Entity.h create mode 100644 engine/src/ecs/EntityRegistry.cpp create mode 100644 engine/src/ecs/EntityRegistry.h diff --git a/CMakeLists.txt b/CMakeLists.txt index f49df64..3510575 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -118,6 +118,12 @@ add_executable(ColorRace engine/src/renderer/shader/StaticShader.h engine/src/renderer/entities/Camera.cpp engine/src/renderer/entities/Camera.h + engine/src/ecs/EntityRegistry.cpp + engine/src/ecs/EntityRegistry.h + engine/src/ecs/Entity.cpp + engine/src/ecs/Entity.h + engine/src/ecs/ComponentPool.cpp + engine/src/ecs/ComponentPool.h ) diff --git a/engine/src/ecs/ComponentPool.cpp b/engine/src/ecs/ComponentPool.cpp new file mode 100644 index 0000000..4a0e664 --- /dev/null +++ b/engine/src/ecs/ComponentPool.cpp @@ -0,0 +1,5 @@ +// +// Created by sebastian on 29.07.26. +// + +#include "ComponentPool.h" diff --git a/engine/src/ecs/ComponentPool.h b/engine/src/ecs/ComponentPool.h new file mode 100644 index 0000000..6bfd6bb --- /dev/null +++ b/engine/src/ecs/ComponentPool.h @@ -0,0 +1,45 @@ +// +// Created by sebastian on 29.07.26. +// + +#ifndef COLORRACE_COMPONENTPOOL_H +#define COLORRACE_COMPONENTPOOL_H +#include "Entity.h" + + +namespace engine { + class IComponentPool { + public: + virtual ~IComponentPool() = default; + virtual void remove(Entity entity) = 0; + }; + + template + class ComponentPool : public IComponentPool { + public: + void remove(Entity entity) override { + m_components.erase(entity); + } + + void insert(Entity entity, T component) { + m_components[entity] = std::move(component); + } + + [[nodiscard]] bool has(Entity entity) const { + return m_components.contains(entity); + } + + T& get(Entity entity) { + return m_components.at(entity); + } + + // Für Iteration in Systemen + auto begin() { return m_components.begin(); } + auto end() { return m_components.end(); } + + private: + std::unordered_map m_components; + }; +} + +#endif //COLORRACE_COMPONENTPOOL_H diff --git a/engine/src/ecs/Entity.cpp b/engine/src/ecs/Entity.cpp new file mode 100644 index 0000000..338fdff --- /dev/null +++ b/engine/src/ecs/Entity.cpp @@ -0,0 +1,5 @@ +// +// Created by sebastian on 29.07.26. +// + +#include "Entity.h" diff --git a/engine/src/ecs/Entity.h b/engine/src/ecs/Entity.h new file mode 100644 index 0000000..082a81e --- /dev/null +++ b/engine/src/ecs/Entity.h @@ -0,0 +1,39 @@ +// +// Created by sebastian on 29.07.26. +// + +#ifndef COLORRACE_ENTITY_H +#define COLORRACE_ENTITY_H +#include +#include +#include // <- das hier fehlt vermutlich + +namespace engine { + class Entity { + public: + constexpr Entity() noexcept = default; + constexpr explicit Entity(std::uint32_t id) noexcept : m_id(id) {} + + [[nodiscard]] constexpr std::uint32_t value() const noexcept { return m_id; } + + constexpr bool operator==(const Entity&) const = default; + + static constexpr Entity null() noexcept { + return Entity{std::numeric_limits::max()}; + } + + private: + std::uint32_t m_id = std::numeric_limits::max(); + }; +} + +// Damit Entity in unordered_map als Key funktioniert +template<> +struct std::hash { + std::size_t operator()(const engine::Entity& e) const noexcept { + return std::hash{}(e.value()); + } +}; + + +#endif //COLORRACE_ENTITY_H diff --git a/engine/src/ecs/EntityRegistry.cpp b/engine/src/ecs/EntityRegistry.cpp new file mode 100644 index 0000000..aaf1162 --- /dev/null +++ b/engine/src/ecs/EntityRegistry.cpp @@ -0,0 +1,5 @@ +// +// Created by sebastian on 29.07.26. +// + +#include "EntityRegistry.h" diff --git a/engine/src/ecs/EntityRegistry.h b/engine/src/ecs/EntityRegistry.h new file mode 100644 index 0000000..d7fe834 --- /dev/null +++ b/engine/src/ecs/EntityRegistry.h @@ -0,0 +1,70 @@ +// +// Created by sebastian on 29.07.26. +// + +#ifndef COLORRACE_ENTITYREGISTRY_H +#define COLORRACE_ENTITYREGISTRY_H +#include +#include +#include +#include + +#include "ComponentPool.h" + + +namespace engine { + class EntityRegistry { + public: + Entity createEntity() { + return Entity{m_nextId++}; + } + + void destroyEntity(Entity entity) { + for (auto& [type, pool] : m_pools) { + pool->remove(entity); + } + } + + + template + void addComponent(Entity entity, T component) { + getPool().insert(entity, std::move(component)); + } + + template + void removeComponent(Entity entity) { + getPool().remove(entity); + } + + template + [[nodiscard]] bool hasComponent(Entity entity) { + auto key = std::type_index(typeid(T)); + auto it = m_pools.find(key); + if (it == m_pools.end()) return false; + return static_cast&>(*it->second).has(entity); + } + + template + T& getComponent(Entity entity) { + return getPool().get(entity); + } + + template + ComponentPool& getPool() { + auto key = std::type_index(typeid(T)); + auto it = m_pools.find(key); + if (it == m_pools.end()) { + auto pool = std::make_unique>(); + auto* ptr = pool.get(); + m_pools.emplace(key, std::move(pool)); + return *ptr; + } + return static_cast&>(*it->second); + } + private: + std::uint32_t m_nextId = 0; + std::pmr::unordered_map> m_pools; + }; +} + +#endif //COLORRACE_ENTITYREGISTRY_H