Repository navigation
Expand file tree
/
Copy pathregistry_tpp.cpp
More file actions
152 lines (131 loc) · 3.89 KB
/
Copy pathregistry_tpp.cpp
File metadata and controls
152 lines (131 loc) · 3.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include "registry.h"
template<typename T>
void Registry::removeComponent(EntityHandle handle) {
componentDeletionQueue.push_back(
{
handle,
getComponentType<T>()
}
);
ISparseCompStorage* storage = getComponentStorage<T>();
storage->setCompDead(storage->sparseToDenseIndex(handle.index));
}
template<typename T>
inline void Registry::addComponent(EntityHandle handle, T component) {
//first, let's check if the entity we are adding to even exists/is correct
if (entityList[handle.index] < 0) {
std::string error =
"Tried to add a component to an entity index that isn't registered: "
+ std::to_string(handle.index)
;
throw std::runtime_error(error);
}
if (entityList[handle.index] != handle.generation) {
std::string error =
"(addComponent) The given EntityHandle's generation ("
+ std::to_string(handle.generation)
+ ") differs from the one registered ("
+ std::to_string(entityList[handle.index])
+ "), this is most definitely a bad logic error (entity ID/index "
+ std::to_string(handle.index)
+ "). "
;
throw std::runtime_error(error);
}
auto& storage = getComponentStorageDirect<T>();
//make sure our storage is big enough to actually index
if (storage.size() <= handle.index) {
if (handle.index - storage.size() > STORAGE_EXPANSION_WARN_SIZE) {
Debug::log("Warning: indice expansion by >10, investigate potential bad registry bookkeeping");
}
storage.resize(handle.index + 1);
}
ComponentType type = getComponentType<T>();
//make sure we are not overwriting a component
if (storage.isMapped(handle.index)) {
std::string error =
"Tried to add a component of type ";
error.append(
typeid(T).name()
);
error.append(
" to entity ("
+ std::to_string(handle.index)
+ ") that already has the component "
+ "mapped to that index. Components should be "
+ "removed in advance to encourage "
+ "safeguards against bugs like "
+ "memory leaks. "
);
throw std::runtime_error(error);
}
//yay, finally we can add our component
storage.addAt(handle.index, component);
//getStorage<T>().add(std::move(component));
}
template<typename T>
inline SparseSet<T>& Registry::getComponentStorageDirect()
{
ComponentType type = getComponentType<T>();
//ensure the storage for this component type exists
if (!componentStorages[type])
{
componentStorages[type] =
std::make_unique<SparseCompStorage<T>>();
}
return static_cast<SparseCompStorage<T>*>(
componentStorages[type].get()
)->storage;
}
template<typename T>
inline SparseCompStorage<T>* Registry::getComponentStorage() {
ComponentType type = getComponentType<T>();
//ensure the storage for this component type exists
if (!componentStorages[type])
{
componentStorages[type] =
std::make_unique<SparseCompStorage<T>>();
}
return static_cast<SparseCompStorage<T>*>(
componentStorages[type].get()
);
}
/// <summary>
/// Note: iterating over EntityHandles is not as performant because you are
/// jumping unpredictably within dense vectors.
/// </summary>
/// <typeparam name="...Components"></typeparam>
/// <returns></returns>
template<typename ...Components>
inline std::vector<EntityHandle> Registry::queryComponents()
{
std::vector<EntityHandle> result;
for (int index = 0; index < entityList.size(); ++index)
{
if (entityList[index] < 0)
continue;
EntityHandle entity{
index,
entityList[index]
};
if (hasComponents<Components...>(entity))
result.push_back(entity);
}
return result;
}
template<typename ...Components>
inline bool Registry::hasComponents(EntityHandle entity) {
return (hasComponent<Components>(entity) && ...);
}
template<typename T>
inline bool Registry::hasComponent(EntityHandle entity) {
assertEntityValid(entity);
auto& storage = getComponentStorageDirect<T>();
return storage.isMapped(entity.index);
}
template<typename ...Components>
inline Query<Components...> Registry::query() {
return Query<Components...>(
*this
);
}