VOX
A little voxel engine
Loading...
Searching...
No Matches
SparseSet.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <array>
4#include <typeinfo>
5#include <iterator>
6#include <vector>
7#include "ecs_utils.hpp"
8#include "ecs_CONSTANTS.hpp"
9
10namespace ecs
11{
12 template <ValidEntity entityType, typename ComponentType>
14 {
15 entityType entity;
16 };
17
18 template <ValidEntity entityType>
20 {
21 public:
22 typedef entityType node_type;
23 typedef std::vector<node_type> dense_type;
24 typedef std::vector<size_t> sparse_type;
25
26 typedef dense_type::iterator iterator;
27 typedef dense_type::const_iterator const_iterator;
28 typedef dense_type::reverse_iterator reverse_iterator;
29 typedef dense_type::const_reverse_iterator const_reverse_iterator;
30
33 : m_dense(size), m_sparse(size) {};
34 virtual ~SparseSet() = default;
35
36 SparseSet(SparseSet & other) = default;
37 SparseSet(SparseSet && other) = default;
38 SparseSet & operator=(SparseSet & other) = default;
39 SparseSet & operator=(SparseSet && other) = default;
40
41 size_t insert(entityType entity)
42 {
44 if (contains(entity))
45 return 0;
46
47 m_dense.push_back({entity});
48
49 if (m_sparse.size() <= entity_index)
50 m_sparse.resize(entity_index + 1);
51
52 auto dense_index = m_dense.size() - 1;
53 m_sparse[entity_index] = dense_index;
54 return dense_index;
55 }
56
57 virtual size_t remove(entityType entity)
58 {
59 if (!contains(entity) || m_dense.size() == 0)
60 return 0;
62 size_t dense_index = m_sparse[entity_index];
63
64 if (m_dense.size() > 1)
65 {
66 //swap with last element and then destroy
67 entityType last_entity = m_dense.back();
68 size_t last_entity_index = ecs::Manager<entityType>::getEntityIndex(last_entity);
69 //update sparse array before swapping
70 m_sparse[last_entity_index] = dense_index;
71
72 std::swap(m_dense[dense_index], m_dense.back());
73 }
74 m_dense.pop_back();
75 return dense_index;
76 }
77
78 // ComponentType & get(entityType entity)
79 // {
80 // if (!contains(entity))
81 // throw std::logic_error("Entity does not have component");
82
83 // size_t dense_index = m_sparse[entity];
84 // return m_dense[dense_index].component;
85 // }
86
87 // const ComponentType & get(entityType entity) const
88 // {
89 // if (!contains(entity))
90 // throw std::logic_error("Entity does not have component");
91
92 // size_t dense_index = m_sparse[entity];
93 // return m_dense[dense_index].component;
94 // }
95
96 // ComponentType * tryGet(entityType entity)
97 // {
98 // if (!contains(entity))
99 // return nullptr;
100
101 // size_t dense_index = m_sparse[entity];
102 // return &m_dense[dense_index].component;
103 // }
104
105 // const ComponentType * tryGet(entityType entity) const
106 // {
107 // if (!contains(entity))
108 // return nullptr;
109
110 // size_t dense_index = m_sparse[entity];
111 // return &m_dense[dense_index].component;
112 // }
113
114 size_t index(entityType entity) const
115 {
117 return m_sparse[entity_index];
118 }
119
120 bool contains(entityType entity) const
121 {
123 //check that entity could be in sparse array
124 //then check that it could be in dense array
125 //then check that the entity is the same
126
127 //we check the whole entity in the dense array and not just the index because
128 //the index could be the same be the entity metadata ( version ) could be different
129 return (
130 m_sparse.size() > entity_index
131 && m_sparse[entity_index] < m_dense.size()
132 && m_dense[m_sparse[entity_index]] == entity);
133 }
134
135 size_t size() const
136 {
137 return m_dense.size();
138 }
139
140 iterator begin() { return m_dense.begin(); }
141 const_iterator begin() const { return m_dense.begin(); }
142 reverse_iterator rbegin() { return std::make_reverse_iterator(end()); }
143 const_reverse_iterator rbegin() const { return std::make_reverse_iterator(end()); }
144
145 iterator end() { return m_dense.end(); }
146 const_iterator end() const { return m_dense.end(); }
147 reverse_iterator rend() { return std::make_reverse_iterator(begin()); }
148 const_reverse_iterator rend() const { return std::make_reverse_iterator(begin()); }
149
150 private:
155 dense_type m_dense = {};
156
161 sparse_type m_sparse = {};
162 };
163
164}
static constexpr uint32_t getEntityIndex(const entityType &entity)
Get the index of the entity in the entity array, see the entity doc for more info.
Definition: Manager.hpp:137
Definition: SparseSet.hpp:20
const_reverse_iterator rend() const
Definition: SparseSet.hpp:148
size_t index(entityType entity) const
Definition: SparseSet.hpp:114
SparseSet & operator=(SparseSet &&other)=default
dense_type::const_iterator const_iterator
Definition: SparseSet.hpp:27
SparseSet & operator=(SparseSet &other)=default
size_t insert(entityType entity)
Definition: SparseSet.hpp:41
reverse_iterator rbegin()
Definition: SparseSet.hpp:142
const_reverse_iterator rbegin() const
Definition: SparseSet.hpp:143
std::vector< size_t > sparse_type
Definition: SparseSet.hpp:24
size_t size() const
Definition: SparseSet.hpp:135
dense_type::const_reverse_iterator const_reverse_iterator
Definition: SparseSet.hpp:29
const_iterator end() const
Definition: SparseSet.hpp:146
reverse_iterator rend()
Definition: SparseSet.hpp:147
dense_type::iterator iterator
Definition: SparseSet.hpp:26
dense_type::reverse_iterator reverse_iterator
Definition: SparseSet.hpp:28
std::vector< node_type > dense_type
Definition: SparseSet.hpp:23
entityType node_type
Definition: SparseSet.hpp:22
SparseSet(SparseSet &other)=default
virtual ~SparseSet()=default
iterator begin()
Definition: SparseSet.hpp:140
const_iterator begin() const
Definition: SparseSet.hpp:141
SparseSet()
Definition: SparseSet.hpp:31
SparseSet(SparseSet &&other)=default
virtual size_t remove(entityType entity)
Definition: SparseSet.hpp:57
SparseSet(size_t size)
Definition: SparseSet.hpp:32
iterator end()
Definition: SparseSet.hpp:145
bool contains(entityType entity) const
Definition: SparseSet.hpp:120
Definition: ComponentStorage.hpp:9
uint32_t entity
Definition: ecs_CONSTANTS.hpp:10
Definition: SparseSet.hpp:14
entityType entity
Definition: SparseSet.hpp:15