12 using Entity =
unsigned long;
16 using UID =
unsigned long;
17 inline UID get_next_id() {
18 static UID counter = 0;
23 auto getTypeId() -> decltype(
auto) {
24 static auto id = get_next_id();
28 template <
typename T,
typename = std::enable_if<std::is_
integral_v<T>>>
31 auto data()
const ->
const std::vector<T>& {
35 void append(T elmnt) {
36 m_packed.emplace_back(elmnt);
37 m_sparse[elmnt] = m_packed.size() - 1;
40 virtual void remove(T elmnt) {
41 const auto index = m_sparse[elmnt];
43 if (index != m_packed.size() - 1) {
44 m_packed[index] = m_packed[m_packed.size() - 1];
45 m_sparse[m_packed[index]] = index;
49 m_sparse.erase(elmnt);
52 auto size()
const -> std::size_t {
53 return m_packed.size();
56 auto contains(T elmnt)
const ->
bool {
57 return m_sparse.find(elmnt) != m_sparse.end();
60 auto index(T elmnt)
const -> std::size_t {
61 return m_sparse.at(elmnt);
65 std::map<T, size_t> m_sparse;
66 std::vector<T> m_packed;
69 template <
typename TEntity,
typename...>
74 template <
typename TEntity,
typename TComp>
78 auto components() -> std::vector<TComp>& {
82 template <
typename ...Targs>
83 auto add(TEntity ent, Targs&& ...args) -> TComp& {
84 if (this->contains(ent))
88 if constexpr(
sizeof...(args) == 0)
89 return m_components.emplace_back();
90 else if constexpr(std::is_aggregate_v<TComp>) {
91 m_components.push_back({std::forward<Targs>(args)...});
92 return m_components.back();
95 return m_components.emplace_back(std::forward<Targs>(args)...);
98 void remove(TEntity ent)
override {
99 if (!this->contains(ent))
102 const auto i = this->index(ent);
104 if (i != m_components.size() - 1) {
105 m_components[i] = std::move(m_components[m_components.size() - 1]);
107 m_components.pop_back();
112 auto get(TEntity ent) -> TComp& {
113 if (this->contains(ent))
114 return m_components[this->index(ent)];
115 throw std::runtime_error(
"Trying to get unexisting entity " + std::to_string(ent)
116 +
" from pool of type " +
typeid(TComp).name());
120 std::vector<TComp> m_components;