Gaia-ECS v0.9.3
A simple and powerful entity component system
Loading...
Searching...
No Matches
chunk_iterator_typed.inl
1#pragma once
2
3namespace gaia {
4 namespace ecs {
5 namespace detail {
6 template <typename T>
7 IterTermDesc ChunkIterTypedOps::term_desc(const ChunkIterImpl& self) {
8 using Arg = std::remove_cv_t<std::remove_reference_t<T>>;
9 IterTermDesc desc;
10 if constexpr (std::is_same_v<Arg, Entity>) {
11 desc.termId = EntityBad;
12 desc.isEntity = true;
13 } else {
14 using FT = typename component_type_t<Arg>::TypeFull;
15 if constexpr (is_pair<FT>::value) {
16 desc.termId = EntityBad;
17 desc.isEntity = false;
18 } else {
19 desc.termId = world_query_arg_id<Arg>(*const_cast<World*>(self.world()));
20 desc.isEntity = false;
21 if constexpr (!mem::is_soa_layout_v<Arg>)
22 desc.isOutOfLine = world_is_out_of_line_component(*self.world(), desc.termId);
23 }
24 }
25 return desc;
26 }
27
28 template <typename T>
29 auto ChunkIterTypedOps::view_any(const ChunkIterImpl& self) {
30 using U = typename actual_type_t<T>::Type;
31 if constexpr (std::is_same_v<U, Entity> || mem::is_soa_layout_v<U>)
32 return self.m_pChunk->template view<T>(self.from(), self.to());
33 else {
34 const auto desc = ChunkIterTypedOps::template term_desc<T>(self);
35 const auto id = desc.isOutOfLine ? desc.termId : EntityBad;
36
37 if (id != EntityBad)
38 return EntityTermViewGet<U>::entity(
39 self.m_pChunk->entity_view().data() + self.from(), const_cast<World*>(self.world()), id, self.size());
40
41 auto* pData = reinterpret_cast<const U*>(self.m_pChunk->template view<T>(self.from(), self.to()).data());
42 return EntityTermViewGet<U>::pointer(pData, self.size());
43 }
44 }
45
46 template <typename T>
47 auto ChunkIterTypedOps::view_any(ChunkIterImpl& self, uint32_t termIdx) {
48 using U = typename actual_type_t<T>::Type;
49
50 if constexpr (mem::is_soa_layout_v<U>) {
51 const auto compIdx = self.m_pCompIndices[termIdx];
52 if (compIdx == 0xFF) {
53 const auto* pEntities = self.m_pChunk->entity_view().data() + self.from();
54 const auto desc = self.resolved_term_desc(termIdx, ChunkIterTypedOps::template term_desc<T>(self));
55 GAIA_ASSERT(desc.termId != EntityBad);
56 return SoATermViewGet<U>{nullptr, 0, pEntities, const_cast<World*>(self.world()),
57 desc.termId, 0, self.size()};
58 }
59
60 GAIA_ASSERT(compIdx < self.m_pChunk->ids_view().size());
61 return SoATermViewGet<U>{
62 self.m_pChunk->comp_ptr(compIdx),
63 self.m_pChunk->capacity(),
64 nullptr,
65 const_cast<World*>(self.world()),
66 EntityBad,
67 self.from(),
68 self.size()};
69 } else {
70 const auto desc = self.resolved_term_desc(termIdx, ChunkIterTypedOps::template term_desc<T>(self));
71 const auto compIdx = self.m_pCompIndices[termIdx];
72 if (desc.isOutOfLine)
73 return EntityTermViewGet<U>::entity(
74 self.m_pChunk->entity_view().data() + self.from(), const_cast<World*>(self.world()), desc.termId,
75 self.size());
76
77 if (compIdx == 0xFF) {
78 GAIA_ASSERT(desc.termId != EntityBad);
79 if (!self.m_inheritedData.empty()) {
80 const auto* pInheritedValue = reinterpret_cast<const U*>(self.m_inheritedData[termIdx]);
81 if (pInheritedValue != nullptr)
82 return EntityTermViewGet<U>::inherited(pInheritedValue, self.size());
83 }
84 if (world_term_uses_inherit_policy(*self.world(), desc.termId)) {
85 return EntityTermViewGet<U>::entity_chunk_stable(
86 self.m_pChunk->entity_view().data() + self.from(), self.m_pChunk, const_cast<World*>(self.world()),
87 desc.termId, self.from(), self.size());
88 }
89 return EntityTermViewGet<U>::entity(
90 self.m_pChunk->entity_view().data() + self.from(), const_cast<World*>(self.world()), desc.termId,
91 self.size());
92 }
93 GAIA_ASSERT(compIdx < self.m_pChunk->ids_view().size());
94
95 auto* pData = reinterpret_cast<const U*>(self.m_pChunk->comp_ptr_mut(compIdx, self.from()));
96 return EntityTermViewGet<U>::pointer(pData, self.size());
97 }
98 }
99
100 template <typename T>
101 auto ChunkIterTypedOps::view(const ChunkIterImpl& self) {
102 using U = typename actual_type_t<T>::Type;
103 if constexpr (std::is_same_v<U, Entity>)
104 return self.m_pChunk->template view<T>(self.from(), self.to());
105 else if constexpr (mem::is_soa_layout_v<U>) {
106 const auto view = self.m_pChunk->template view<T>(self.from(), self.to());
107 return SoATermViewGetPointer<U>{
108 (const uint8_t*)view.data(), (uint32_t)view.size(), self.from(), self.size()};
109 } else {
110 auto* pData = reinterpret_cast<const U*>(self.m_pChunk->template view<T>(self.from(), self.to()).data());
111 return EntityTermViewGetPointer<U>{pData, self.size()};
112 }
113 }
114
115 template <typename T>
116 auto ChunkIterTypedOps::view(const ChunkIterImpl& self, uint32_t termIdx) {
117 using U = typename actual_type_t<T>::Type;
118 const auto compIdx = self.m_pCompIndices[termIdx];
119 GAIA_ASSERT(compIdx != 0xFF);
120
121 if constexpr (mem::is_soa_layout_v<U>)
122 return SoATermViewGetPointer<U>{
123 self.m_pChunk->comp_ptr(compIdx), self.m_pChunk->capacity(), self.from(), self.size()};
124 else {
125 auto* pData = reinterpret_cast<const U*>(self.m_pChunk->comp_ptr(compIdx, self.from()));
126 return EntityTermViewGetPointer<U>{pData, self.size()};
127 }
128 }
129
130 template <typename T>
131 auto ChunkIterTypedOps::view_any_mut(ChunkIterImpl& self) {
132 using U = typename actual_type_t<T>::Type;
133 static_assert(!std::is_same_v<U, Entity>, "Modifying chunk entities via view_mut is forbidden");
134 if constexpr (mem::is_soa_layout_v<U>) {
135 const auto desc = ChunkIterTypedOps::template term_desc<T>(self);
136 self.touch_term_desc(desc);
137 if (self.m_writeIm)
138 return self.m_pChunk->template view_mut<T>(self.from(), self.to());
139 return self.m_pChunk->template sview_mut<T>(self.from(), self.to());
140 } else {
141 const auto desc = ChunkIterTypedOps::template term_desc<T>(self);
142 const auto id = desc.isOutOfLine ? desc.termId : EntityBad;
143
144 if (id != EntityBad) {
145 self.touch_term(id);
146 return self.template entity_view_set<U>(id, self.m_writeIm);
147 }
148
149 self.touch_term_desc(desc);
150 auto* pData =
151 reinterpret_cast<U*>((self.m_writeIm ? self.m_pChunk->template view_mut<T>(self.from(), self.to())
152 : self.m_pChunk->template sview_mut<T>(self.from(), self.to()))
153 .data());
154 return EntityTermViewSet<U>::pointer(pData, self.size());
155 }
156 }
157
158 template <typename T>
159 auto ChunkIterTypedOps::view_mut(ChunkIterImpl& self) {
160 using U = typename actual_type_t<T>::Type;
161 static_assert(!std::is_same_v<U, Entity>, "Modifying chunk entities via view_mut is forbidden");
162 const auto desc = ChunkIterTypedOps::template term_desc<T>(self);
163 self.touch_term_desc(desc);
164 if constexpr (mem::is_soa_layout_v<U>) {
165 auto view = self.m_writeIm ? self.m_pChunk->template view_mut<T>(self.from(), self.to())
166 : self.m_pChunk->template sview_mut<T>(self.from(), self.to());
167 return SoATermViewSetPointer<U>{(uint8_t*)view.data(), (uint32_t)view.size(), self.from(), self.size()};
168 } else {
169 auto* pData =
170 reinterpret_cast<U*>((self.m_writeIm ? self.m_pChunk->template view_mut<T>(self.from(), self.to())
171 : self.m_pChunk->template sview_mut<T>(self.from(), self.to()))
172 .data());
173 return EntityTermViewSetPointer<U>{pData, self.size()};
174 }
175 }
176
177 template <typename T>
178 auto ChunkIterTypedOps::view_mut(ChunkIterImpl& self, uint32_t termIdx) {
179 using U = typename actual_type_t<T>::Type;
180 static_assert(!std::is_same_v<U, Entity>, "Modifying chunk entities via view_mut is forbidden");
181 const auto compIdx = self.m_pCompIndices[termIdx];
182 GAIA_ASSERT(compIdx != 0xFF);
183 self.touch_comp_idx(compIdx);
184
185 if constexpr (mem::is_soa_layout_v<U>) {
186 if (self.m_writeIm)
187 self.m_pChunk->update_world_version(compIdx);
188 return SoATermViewSetPointer<U>{
189 self.m_pChunk->comp_ptr_mut(compIdx), self.m_pChunk->capacity(), self.from(), self.size()};
190 } else {
191 if (self.m_writeIm)
192 self.m_pChunk->update_world_version(compIdx);
193 auto* pData = reinterpret_cast<U*>(self.m_pChunk->comp_ptr_mut(compIdx, self.from()));
194 return EntityTermViewSetPointer<U>{pData, self.size()};
195 }
196 }
197
198 template <typename T>
199 auto ChunkIterTypedOps::view_any_mut(ChunkIterImpl& self, uint32_t termIdx) {
200 using U = typename actual_type_t<T>::Type;
201
202 if constexpr (mem::is_soa_layout_v<U>) {
203 const auto compIdx = self.m_pCompIndices[termIdx];
204 if (compIdx == 0xFF) {
205 const auto desc = self.resolved_term_desc(termIdx, ChunkIterTypedOps::template term_desc<T>(self));
206 GAIA_ASSERT(desc.termId != EntityBad);
207 self.touch_term(desc.termId);
208 return self.template entity_soa_view_set<U>(desc.termId, self.m_writeIm);
209 }
210
211 GAIA_ASSERT(compIdx < self.m_pChunk->comp_rec_view().size());
212 self.touch_comp_idx(compIdx);
213 if (self.m_writeIm)
214 self.m_pChunk->update_world_version(compIdx);
215 return SoATermViewSet<U>{
216 self.m_pChunk->comp_ptr_mut(compIdx),
217 self.m_pChunk->capacity(),
218 nullptr,
219 self.world(),
220 EntityBad,
221 self.from(),
222 self.size(),
223 self.m_writeIm};
224 } else {
225 const auto desc = self.resolved_term_desc(termIdx, ChunkIterTypedOps::template term_desc<T>(self));
226 const auto compIdx = self.m_pCompIndices[termIdx];
227 if (desc.isOutOfLine) {
228 self.touch_term(desc.termId);
229 return self.template entity_view_set<U>(desc.termId, self.m_writeIm);
230 }
231
232 if (compIdx == 0xFF) {
233 GAIA_ASSERT(desc.termId != EntityBad);
234 self.touch_term(desc.termId);
235 return self.template entity_view_set<U>(desc.termId, self.m_writeIm);
236 }
237 GAIA_ASSERT(compIdx < self.m_pChunk->comp_rec_view().size());
238
239 self.touch_comp_idx(compIdx);
240 if (self.m_writeIm)
241 self.m_pChunk->update_world_version(compIdx);
242
243 auto* pData = reinterpret_cast<U*>(self.m_pChunk->comp_ptr_mut(compIdx, self.from()));
244 return EntityTermViewSet<U>::pointer(pData, self.size());
245 }
246 }
247
248 template <typename T>
249 auto ChunkIterTypedOps::sview_any_mut(ChunkIterImpl& self) {
250 using U = typename actual_type_t<T>::Type;
251 static_assert(!std::is_same_v<U, Entity>, "Modifying chunk entities via sview_mut is forbidden");
252 if constexpr (mem::is_soa_layout_v<U>)
253 return self.m_pChunk->template sview_mut<T>(self.from(), self.to());
254 else {
255 const auto desc = ChunkIterTypedOps::template term_desc<T>(self);
256 const auto id = desc.isOutOfLine ? desc.termId : EntityBad;
257
258 if (id != EntityBad)
259 return self.template entity_view_set<U>(id, false);
260
261 auto* pData = reinterpret_cast<U*>(self.m_pChunk->template sview_mut<T>(self.from(), self.to()).data());
262 return EntityTermViewSet<U>::pointer(pData, self.size());
263 }
264 }
265
266 template <typename T>
267 auto ChunkIterTypedOps::sview_mut(ChunkIterImpl& self) {
268 using U = typename actual_type_t<T>::Type;
269 static_assert(!std::is_same_v<U, Entity>, "Modifying chunk entities via sview_mut is forbidden");
270 if constexpr (mem::is_soa_layout_v<U>) {
271 auto view = self.m_pChunk->template sview_mut<T>(self.from(), self.to());
272 return SoATermViewSetPointer<U>{(uint8_t*)view.data(), (uint32_t)view.size(), self.from(), self.size()};
273 } else {
274 auto* pData = reinterpret_cast<U*>(self.m_pChunk->template sview_mut<T>(self.from(), self.to()).data());
275 return EntityTermViewSetPointer<U>{pData, self.size()};
276 }
277 }
278
279 template <typename T>
280 auto ChunkIterTypedOps::sview_mut(ChunkIterImpl& self, uint32_t termIdx) {
281 using U = typename actual_type_t<T>::Type;
282 static_assert(!std::is_same_v<U, Entity>, "Modifying chunk entities via sview_mut is forbidden");
283 const auto compIdx = self.m_pCompIndices[termIdx];
284 GAIA_ASSERT(compIdx != 0xFF);
285
286 if constexpr (mem::is_soa_layout_v<U>)
287 return SoATermViewSetPointer<U>{
288 self.m_pChunk->comp_ptr_mut(compIdx), self.m_pChunk->capacity(), self.from(), self.size()};
289 else {
290 auto* pData = reinterpret_cast<U*>(self.m_pChunk->comp_ptr_mut(compIdx, self.from()));
291 return EntityTermViewSetPointer<U>{pData, self.size()};
292 }
293 }
294
295 template <typename T>
296 auto ChunkIterTypedOps::sview_any_mut(ChunkIterImpl& self, uint32_t termIdx) {
297 using U = typename actual_type_t<T>::Type;
298
299 if constexpr (mem::is_soa_layout_v<U>) {
300 const auto compIdx = self.m_pCompIndices[termIdx];
301 if (compIdx == 0xFF) {
302 const auto desc = self.resolved_term_desc(termIdx, ChunkIterTypedOps::template term_desc<T>(self));
303 GAIA_ASSERT(desc.termId != EntityBad);
304 return self.template entity_soa_view_set<U>(desc.termId, false);
305 }
306
307 GAIA_ASSERT(compIdx < self.m_pChunk->ids_view().size());
308 return SoATermViewSet<U>{
309 self.m_pChunk->comp_ptr_mut(compIdx),
310 self.m_pChunk->capacity(),
311 nullptr,
312 self.world(),
313 EntityBad,
314 self.from(),
315 self.size(),
316 false};
317 } else {
318 const auto desc = self.resolved_term_desc(termIdx, ChunkIterTypedOps::template term_desc<T>(self));
319 const auto compIdx = self.m_pCompIndices[termIdx];
320 if (desc.isOutOfLine)
321 return self.template entity_view_set<U>(desc.termId, false);
322
323 if (compIdx == 0xFF) {
324 GAIA_ASSERT(desc.termId != EntityBad);
325 return self.template entity_view_set<U>(desc.termId, false);
326 }
327 GAIA_ASSERT(compIdx < self.m_pChunk->ids_view().size());
328
329 auto* pData = reinterpret_cast<U*>(self.m_pChunk->comp_ptr_mut(compIdx, self.from()));
330 return EntityTermViewSet<U>::pointer(pData, self.size());
331 }
332 }
333
334 } // namespace detail
335
336 } // namespace ecs
337} // namespace gaia
Checks if endianess was detected correctly at compile-time.
Definition bitset.h:9