ECSTASY
All in the name
Loading...
Searching...
No Matches
VectorStorage.hpp
Go to the documentation of this file.
1
11
12#ifndef ECSTASY_STORAGE_VECTORSTORAGE_HPP_
13#define ECSTASY_STORAGE_VECTORSTORAGE_HPP_
14
15#include <vector>
16
17#include "AStorage.hpp"
18
19namespace ecstasy
20{
34 template <typename C>
35 class VectorStorage : public AStorage<C> {
36 public:
39
48 VectorStorage(size_t initialCapacity = 0) : _components(), _mask()
49 {
50 if (initialCapacity) {
51 _components.reserve(initialCapacity);
52 _mask.resize(initialCapacity);
53 }
54 };
55
64 VectorStorage(const VectorStorage &other) = delete;
65
83 template <typename... Args>
84 Component &emplace(Entity::Index index, Args &&...args)
85 {
86 // Component at index already existing
87 if (_components.size() > index)
88 _components[index] = std::move(Component(std::forward<Args>(args)...));
89 else {
90 _mask.resize(std::max(_mask.size(), index + 1));
91 // Padding elements
92 if (_components.size() < index)
93 _components.resize(index);
94 // New component
95 _components.emplace_back(std::forward<Args>(args)...);
96 }
97 _mask[index] = true;
98 return _components[index];
99 }
100
102 Component &insert(Entity::Index index, Component &&c) override final
103 {
104 if constexpr (!std::movable<Component>)
105 throw std::runtime_error("VectorStorage: Component is not movable");
106 else {
107 // Component at index already existing
108 if (_components.size() > index)
109 _components[index] = std::move(c);
110 else {
111 _mask.resize(std::max(_mask.size(), index + 1));
112 // Padding elements
113 if (_components.size() < index)
114 _components.resize(index);
115 // New component
116 _components.push_back(std::move(c));
117 }
118 _mask[index] = true;
119 return _components[index];
120 }
121 }
122
127 bool erase(Entity::Index index) override final
128 {
129 if (index >= _components.size()) [[unlikely]]
130 return false;
131 size_t effectiveSize;
132
133 _mask[index] = false;
134 effectiveSize = _mask.lastSet() + 1;
135
136 // Last component, we can safely remove it and the padding elements until the last set bit
137 // The size is never lower than 1 because 0 is returned if no bit is set (unsigned number)
138 if (effectiveSize < _mask.size()) {
139 _mask.resize(effectiveSize);
140 _components.resize(effectiveSize);
141 }
142 return true;
143 }
144
146 [[nodiscard]] Component &operator[](Entity::Index index) noexcept override final
147 {
148 return _components[index];
149 }
150
152 [[nodiscard]] const Component &operator[](Entity::Index index) const noexcept override final
153 {
154 return _components[index];
155 }
156
158 [[nodiscard]] constexpr const util::BitSet &getMask() const noexcept override final
159 {
160 return _mask;
161 }
162
163 private:
168
169 friend class VectorStorageTest;
170 };
171} // namespace ecstasy
172
173#endif /* !ECSTASY_STORAGE_VECTORSTORAGE_HPP_ */
Abstract class for all components storage.
Definition AStorage.hpp:34
C Component
IsStorage constraint.
Definition AStorage.hpp:37
size_t Index
The entity identifier type.
Definition Entity.hpp:38
Linear vector to store entity components.
Component & operator[](Entity::Index index) noexcept override final
Retrieve the Component instance associated to the given entity.
VectorStorage(const VectorStorage &other)=delete
Copy constructor is deleted.
Component & insert(Entity::Index index, Component &&c) override final
Insert a new Component instance associated to the given entity.
typename AStorage< C >::Component Component
IsStorage constraint.
Component & emplace(Entity::Index index, Args &&...args)
Emplace a new Component instance for a given entity.
util::BitSet _mask
Mask to know if a component is set for an entity.
const Component & operator[](Entity::Index index) const noexcept override final
Retrieve the Component instance associated to the given entity.
std::vector< Component > _components
Components vector.
constexpr const util::BitSet & getMask() const noexcept override final
Get the Component Mask.
bool erase(Entity::Index index) override final
Erase the Component instance associated to the given entity.
VectorStorage(size_t initialCapacity=0)
Construct a new Vector Storage for a given Component type.
Mimics the API of std::bitset but with the dynamic properties of std::vector<bool>
Definition BitSet.hpp:35
void resize(std::size_t size)
Changes the number of bits stored in this set.
Definition BitSet.hpp:199
BIT_SET_CONSTEXPR std::size_t lastSet() const
Finds the last set bit in the set.
Definition BitSet.hpp:247
constexpr std::size_t size() const noexcept
Definition BitSet.hpp:87
T emplace_back(T... args)
T max(T... args)
Namespace containing all symbols specific to ecstasy.
Definition ecstasy.hpp:30
T push_back(T... args)
T reserve(T... args)
T resize(T... args)
T size(T... args)