VEX Engine
Retro looking game engine made in vulkan mostly because i wanted to understand it better.
Loading...
Searching...
No Matches
ComponentStorage.hpp
1#pragma once
2#include <vector>
3#include <functional>
4#include <cassert>
5#include <cstddef>
6#include "Types.hpp"
7
8namespace vex {
9
19template <typename T>
21private:
23 std::vector<T> m_components;
25 std::vector<Entity> m_indexToEntity;
27 std::vector<size_t> m_entityToIndex;
28
30 std::vector<std::function<void(Entity, T&)>> m_onCreate;
32 std::vector<std::function<void(Entity, T&)>> m_onDestroy;
33
34public:
38 bool has(Entity entity) const {
39 return entity < m_entityToIndex.size() && m_entityToIndex[entity] != static_cast<size_t>(-1);
40 }
41
49 template<typename... Args>
50 T& add_or_replace(Entity entity, Args&&... args) {
51 if (entity >= m_entityToIndex.size()) {
52 m_entityToIndex.resize(entity + 1, static_cast<size_t>(-1));
53 }
54
55 if (has(entity)) {
56 m_components[m_entityToIndex[entity]] = T{std::forward<Args>(args)...};
57 return m_components[m_entityToIndex[entity]];
58 }
59
60 size_t newIndex = m_components.size();
61 m_entityToIndex[entity] = newIndex;
62 m_indexToEntity.push_back(entity);
63 m_components.emplace_back(std::forward<Args>(args)...);
64
65 T& component = m_components.back();
66 for (auto& cb : m_onCreate) cb(entity, component);
67
68 return component;
69 }
70
76 void remove(Entity entity) {
77 if (!has(entity)) return;
78
79 size_t indexOfRemoved = m_entityToIndex[entity];
80 size_t indexOfLast = m_components.size() - 1;
81
82 for (auto& cb : m_onDestroy) cb(entity, m_components[indexOfRemoved]);
83
84 if (indexOfRemoved != indexOfLast) {
85 Entity entityOfLast = m_indexToEntity[indexOfLast];
86 m_components[indexOfRemoved] = std::move(m_components[indexOfLast]);
87 m_indexToEntity[indexOfRemoved] = entityOfLast;
88 m_entityToIndex[entityOfLast] = indexOfRemoved;
89 }
90
91 m_components.pop_back();
92 m_indexToEntity.pop_back();
93 m_entityToIndex[entity] = static_cast<size_t>(-1);
94 }
95
100 T& get(Entity entity) {
101 assert(has(entity) && "Retrieving non-existent component.");
102 return m_components[m_entityToIndex[entity]];
103 }
104
108 void entity_destroyed(Entity entity) override {
109 remove(entity);
110 }
111
115 void on_create(std::function<void(Entity, T&)> cb) { m_onCreate.push_back(cb); }
116
120 void on_destroy(std::function<void(Entity, T&)> cb) { m_onDestroy.push_back(cb); }
121
124 const std::vector<Entity>& get_entities() const { return m_indexToEntity; }
125};
126
127}
Template-based storage container for components of a specific type.
std::vector< std::function< void(Entity, T &)> > m_onCreate
Callbacks invoked when a component is created for an entity.
T & add_or_replace(Entity entity, Args &&... args)
Adds or replaces a component for an entity.
void on_destroy(std::function< void(Entity, T &)> cb)
Registers a callback to be invoked when a component is destroyed.
void remove(Entity entity)
Removes the component from an entity.
std::vector< std::function< void(Entity, T &)> > m_onDestroy
Callbacks invoked when a component is destroyed for an entity.
void entity_destroyed(Entity entity) override
Called by the Registry when an entity is destroyed.
std::vector< size_t > m_entityToIndex
Maps entity ID to the component storage index, or -1 if not present.
std::vector< Entity > m_indexToEntity
Maps component storage index to the entity that owns the component.
const std::vector< Entity > & get_entities() const
Returns the list of all entities that have this component type.
void on_create(std::function< void(Entity, T &)> cb)
Registers a callback to be invoked when a component is created.
std::vector< T > m_components
Dense array of component instances, cache-optimized for iteration.
bool has(Entity entity) const
Checks if the given entity has a component of type T.
T & get(Entity entity)
Retrieves a reference to the component for an entity.
Abstract base class for component storage implementations.
Definition Types.hpp:21
uint32_t Entity
Type alias representing a unique entity identifier in the ECS system.
Definition Types.hpp:11