Replace vector with deque for Component storage

When reallocating more data, vector moves the original data to a new
buffer. Deque preserves the location of the original data, preventing
invalidated pointers to existing data when additional allocation is
required.
This commit is contained in:
Stephen Seo 2019-11-06 15:47:16 +09:00
parent 4db5e0caed
commit e0da16a63e

View file

@ -12,6 +12,7 @@
#include <cstddef> #include <cstddef>
#include <vector> #include <vector>
#include <deque>
#include <tuple> #include <tuple>
#include <utility> #include <utility>
#include <functional> #include <functional>
@ -67,14 +68,14 @@ namespace EC
template <typename... Types> template <typename... Types>
struct Storage struct Storage
{ {
using type = std::tuple<std::vector<Types>..., std::vector<char> >; using type = std::tuple<std::deque<Types>..., std::deque<char> >;
}; };
using ComponentsStorage = using ComponentsStorage =
typename EC::Meta::Morph<ComponentsList, Storage<> >::type; typename EC::Meta::Morph<ComponentsList, Storage<> >::type;
// Entity: isAlive, ComponentsTags Info // Entity: isAlive, ComponentsTags Info
using EntitiesTupleType = std::tuple<bool, BitsetType>; using EntitiesTupleType = std::tuple<bool, BitsetType>;
using EntitiesType = std::vector<EntitiesTupleType>; using EntitiesType = std::deque<EntitiesTupleType>;
EntitiesType entities; EntitiesType entities;
ComponentsStorage componentsStorage; ComponentsStorage componentsStorage;
@ -103,7 +104,7 @@ namespace EC
} }
EC::Meta::forEach<ComponentsList>([this, newCapacity] (auto t) { EC::Meta::forEach<ComponentsList>([this, newCapacity] (auto t) {
std::get<std::vector<decltype(t)> >( std::get<std::deque<decltype(t)> >(
this->componentsStorage).resize(newCapacity); this->componentsStorage).resize(newCapacity);
}); });
@ -410,10 +411,10 @@ namespace EC
constexpr auto index = constexpr auto index =
EC::Meta::IndexOf<Component, Components>::value; EC::Meta::IndexOf<Component, Components>::value;
// Cast required due to compiler thinking that vector<char> at // Cast required due to compiler thinking that deque<char> at
// index = Components::size is being used, even if the previous // index = Components::size is being used, even if the previous
// if statement will prevent this from ever happening. // if statement will prevent this from ever happening.
(*((std::vector<Component>*)(&std::get<index>( (*((std::deque<Component>*)(&std::get<index>(
componentsStorage componentsStorage
))))[entityID] = std::move(component); ))))[entityID] = std::move(component);
} }