1use crate::{
10 entity,
11 entity::allocator::Location,
12 query::{
13 filter::And,
14 view,
15 view::SubSet,
16 },
17 registry,
18 registry::contains::views::{
19 ContainsViewsOuter,
20 Sealed as ContainsViewsSealed,
21 },
22 Query,
23 World,
24};
25use core::marker::PhantomData;
26
27pub struct Entry<'a, 'b, Registry, Resources, Views, Indices>
31where
32 Registry: registry::Registry,
33{
34 entries: &'b mut Entries<'a, Registry, Resources, Views, Indices>,
35 location: Location<Registry>,
36}
37
38impl<'a, 'b, Registry, Resources, Views, Indices> Entry<'a, 'b, Registry, Resources, Views, Indices>
39where
40 Registry: registry::Registry,
41{
42 fn new(
43 entries: &'b mut Entries<'a, Registry, Resources, Views, Indices>,
44 location: Location<Registry>,
45 ) -> Self {
46 Self { entries, location }
47 }
48}
49
50impl<'a, 'b, Registry, Resources, Views, Indices> Entry<'a, 'b, Registry, Resources, Views, Indices>
51where
52 Views: view::Views<'a>,
53 Registry: registry::ContainsViews<'a, Views, Indices>,
54{
55 pub fn query<SubViews, Filter, FilterIndices, SubViewsFilterIndices, SubSetIndices>(
63 &mut self,
64 #[allow(unused_variables)] query: Query<SubViews, Filter>,
65 ) -> Option<SubViews>
66 where
67 SubViews: SubSet<'a, Views, SubSetIndices> + view::Views<'a>,
68 Views: view::ContainsFilter<
72 'a,
73 And<Filter, SubViews>,
74 And<FilterIndices, SubViewsFilterIndices>,
75 >,
76 {
77 let indices = <<Registry as ContainsViewsSealed<'a, Views, Indices>>::Viewable as ContainsViewsOuter<'a, Views, <Registry as ContainsViewsSealed<'a, Views, Indices>>::Containments, <Registry as ContainsViewsSealed<'a, Views, Indices>>::Indices, <Registry as ContainsViewsSealed<'a, Views, Indices>>::ReshapeIndices>>::indices();
78 if unsafe { Views::filter(&indices, self.location.identifier) } {
81 let super_views = unsafe {
92 (*self.entries.world)
93 .archetypes
94 .get_mut(self.location.identifier)?
95 .view_row_maybe_uninit_unchecked::<Views, Indices>(self.location.index)
96 };
97
98 Some(unsafe { SubViews::view(super_views, indices, self.location.identifier) })
102 } else {
103 None
104 }
105 }
106}
107
108pub struct Entries<'a, Registry, Resources, Views, Indices>
112where
113 Registry: registry::Registry,
114{
115 world: *mut World<Registry, Resources>,
116
117 lifetime: PhantomData<&'a ()>,
118 views: PhantomData<Views>,
119 indices: PhantomData<Indices>,
120}
121
122impl<'a, Registry, Resources, Views, Indices> Entries<'a, Registry, Resources, Views, Indices>
123where
124 Registry: registry::Registry,
125{
126 pub(crate) unsafe fn new(world: *mut World<Registry, Resources>) -> Self {
173 Entries {
174 world,
175
176 lifetime: PhantomData,
177 views: PhantomData,
178 indices: PhantomData,
179 }
180 }
181
182 pub fn entry<'b>(
188 &'b mut self,
189 entity_identifier: entity::Identifier,
190 ) -> Option<Entry<'a, 'b, Registry, Resources, Views, Indices>> {
191 unsafe { &*self.world }
194 .entity_allocator
195 .get(entity_identifier)
196 .map(|location| Entry::new(self, location))
197 }
198}
199
200unsafe impl<'a, Registry, Resources, Views, Indices> Send
203 for Entries<'a, Registry, Resources, Views, Indices>
204where
205 Registry: registry::Registry,
206{
207}
208
209unsafe impl<'a, Registry, Resources, Views, Indices> Sync
212 for Entries<'a, Registry, Resources, Views, Indices>
213where
214 Registry: registry::Registry,
215{
216}
217
218#[cfg(test)]
219mod tests {
220 use super::Entries;
221 use crate::{
222 entity,
223 query::{
224 filter,
225 result,
226 Views,
227 },
228 Query,
229 Registry,
230 World,
231 };
232 use claims::{
233 assert_none,
234 assert_some,
235 };
236
237 #[derive(Debug, PartialEq)]
239 struct A(u32);
240 #[derive(Debug, PartialEq)]
241 struct B(char);
242 #[derive(Debug, PartialEq)]
243 struct C(f32);
244
245 type Registry = Registry!(A, B, C);
246
247 #[test]
248 fn empty_query() {
249 let mut world = World::<Registry!()>::new();
250 let identifier = world.insert(entity!());
251
252 let mut entries = unsafe { Entries::<_, _, Views!(), _>::new(&mut world) };
253 let mut entry = assert_some!(entries.entry(identifier));
254
255 assert_some!(entry.query(Query::<Views!()>::new()));
256 }
257
258 #[test]
259 fn empty_query_with_filter_succeeds() {
260 let mut world = World::<Registry>::new();
261 let identifier = world.insert(entity!(A(42)));
262
263 let mut entries = unsafe { Entries::<_, _, Views!(&A), _>::new(&mut world) };
264 let mut entry = assert_some!(entries.entry(identifier));
265
266 assert_some!(entry.query(Query::<Views!(), filter::Has<A>>::new()));
267 }
268
269 #[test]
270 fn empty_query_with_filter_fails() {
271 let mut world = World::<Registry>::new();
272 let identifier = world.insert(entity!(A(42)));
273
274 let mut entries = unsafe { Entries::<_, _, Views!(&B), _>::new(&mut world) };
275 let mut entry = assert_some!(entries.entry(identifier));
276
277 assert_none!(entry.query(Query::<Views!(), filter::Has<B>>::new()));
278 }
279
280 #[test]
281 fn empty_query_with_filter_on_mutable_ref_in_super_views() {
282 let mut world = World::<Registry>::new();
283 let identifier = world.insert(entity!(A(42)));
284
285 let mut entries = unsafe { Entries::<_, _, Views!(&mut A), _>::new(&mut world) };
286 let mut entry = assert_some!(entries.entry(identifier));
287
288 assert_some!(entry.query(Query::<Views!(), filter::Has<A>>::new()));
289 }
290
291 #[test]
292 fn empty_query_with_filter_on_optional_ref_in_super_views() {
293 let mut world = World::<Registry>::new();
294 let identifier = world.insert(entity!(A(42)));
295
296 let mut entries = unsafe { Entries::<_, _, Views!(Option<&A>), _>::new(&mut world) };
297 let mut entry = assert_some!(entries.entry(identifier));
298
299 assert_some!(entry.query(Query::<Views!(), filter::Has<A>>::new()));
300 }
301
302 #[test]
303 fn empty_query_with_filter_on_optional_mutable_ref_in_super_views() {
304 let mut world = World::<Registry>::new();
305 let identifier = world.insert(entity!(A(42)));
306
307 let mut entries = unsafe { Entries::<_, _, Views!(Option<&mut A>), _>::new(&mut world) };
308 let mut entry = assert_some!(entries.entry(identifier));
309
310 assert_some!(entry.query(Query::<Views!(), filter::Has<A>>::new()));
311 }
312
313 #[test]
314 fn empty_query_with_filter_on_second_view_in_super_views() {
315 let mut world = World::<Registry>::new();
316 let identifier = world.insert(entity!(A(42)));
317
318 let mut entries = unsafe { Entries::<_, _, Views!(&C, &A), _>::new(&mut world) };
319 let mut entry = assert_some!(entries.entry(identifier));
320
321 assert_some!(entry.query(Query::<Views!(), filter::Has<A>>::new()));
322 }
323
324 #[test]
325 fn empty_query_with_or_filter() {
326 let mut world = World::<Registry>::new();
327 let identifier = world.insert(entity!(A(42)));
328
329 let mut entries = unsafe { Entries::<_, _, Views!(&A, &B), _>::new(&mut world) };
330 let mut entry = assert_some!(entries.entry(identifier));
331
332 assert_some!(
333 entry.query(Query::<Views!(), filter::Or<filter::Has<A>, filter::Has<B>>>::new())
334 );
335 }
336
337 #[test]
338 fn empty_query_with_or_filter_second() {
339 let mut world = World::<Registry>::new();
340 let identifier = world.insert(entity!(A(42)));
341
342 let mut entries = unsafe { Entries::<_, _, Views!(&A, &B), _>::new(&mut world) };
343 let mut entry = assert_some!(entries.entry(identifier));
344
345 assert_some!(
346 entry.query(Query::<Views!(), filter::Or<filter::Has<B>, filter::Has<A>>>::new())
347 );
348 }
349
350 #[test]
351 fn empty_query_with_and_filter() {
352 let mut world = World::<Registry>::new();
353 let identifier = world.insert(entity!(A(42), B('a')));
354
355 let mut entries = unsafe { Entries::<_, _, Views!(&A, &B), _>::new(&mut world) };
356 let mut entry = assert_some!(entries.entry(identifier));
357
358 assert_some!(
359 entry.query(Query::<Views!(), filter::And<filter::Has<A>, filter::Has<B>>>::new())
360 );
361 }
362
363 #[test]
364 fn empty_query_with_not_filter() {
365 let mut world = World::<Registry>::new();
366 let identifier = world.insert(entity!(A(42)));
367
368 let mut entries = unsafe { Entries::<_, _, Views!(&B), _>::new(&mut world) };
369 let mut entry = assert_some!(entries.entry(identifier));
370
371 assert_some!(entry.query(Query::<Views!(), filter::Not<filter::Has<B>>>::new()));
372 }
373
374 #[test]
375 fn empty_query_with_nonempty_superset() {
376 let mut world = World::<Registry>::new();
377 let identifier = world.insert(entity!());
378
379 let mut entries = unsafe { Entries::<_, _, Views!(&A, &mut C), _>::new(&mut world) };
380 let mut entry = assert_some!(entries.entry(identifier));
381
382 assert_some!(entry.query(Query::<Views!()>::new()));
383 }
384
385 #[test]
386 fn query_immutable_superset_immutable() {
387 let mut world = World::<Registry>::new();
388 let identifier = world.insert(entity!(A(42), B('a'), C(3.14)));
389
390 let mut entries = unsafe { Entries::<_, _, Views!(&A, &mut C), _>::new(&mut world) };
391 let mut entry = assert_some!(entries.entry(identifier));
392
393 let result!(a) = assert_some!(entry.query(Query::<Views!(&A)>::new()));
394 assert_eq!(a, &A(42));
395 }
396
397 #[test]
398 fn query_immutable_superset_mutable() {
399 let mut world = World::<Registry>::new();
400 let identifier = world.insert(entity!(A(42), B('a'), C(3.14)));
401
402 let mut entries = unsafe { Entries::<_, _, Views!(&A, &mut C), _>::new(&mut world) };
403 let mut entry = assert_some!(entries.entry(identifier));
404
405 let result!(c) = assert_some!(entry.query(Query::<Views!(&C)>::new()));
406 assert_eq!(c, &C(3.14));
407 }
408
409 #[test]
410 fn query_mutable_superset_mutable() {
411 let mut world = World::<Registry>::new();
412 let identifier = world.insert(entity!(A(42), B('a'), C(3.14)));
413
414 let mut entries = unsafe { Entries::<_, _, Views!(&A, &mut C), _>::new(&mut world) };
415 let mut entry = assert_some!(entries.entry(identifier));
416
417 let result!(c) = assert_some!(entry.query(Query::<Views!(&mut C)>::new()));
418 assert_eq!(c, &mut C(3.14));
419 }
420
421 #[test]
422 fn query_optional_immutable_superset_immutable() {
423 let mut world = World::<Registry>::new();
424 let identifier = world.insert(entity!(A(42), B('a'), C(3.14)));
425
426 let mut entries = unsafe { Entries::<_, _, Views!(&A, &mut C), _>::new(&mut world) };
427 let mut entry = assert_some!(entries.entry(identifier));
428
429 let result!(a) = assert_some!(entry.query(Query::<Views!(Option<&A>)>::new()));
430 assert_eq!(a, Some(&A(42)));
431 }
432
433 #[test]
434 fn query_optional_immutable_superset_mutable() {
435 let mut world = World::<Registry>::new();
436 let identifier = world.insert(entity!(A(42), B('a'), C(3.14)));
437
438 let mut entries = unsafe { Entries::<_, _, Views!(&A, &mut C), _>::new(&mut world) };
439 let mut entry = assert_some!(entries.entry(identifier));
440
441 let result!(c) = assert_some!(entry.query(Query::<Views!(Option<&C>)>::new()));
442 assert_eq!(c, Some(&C(3.14)));
443 }
444
445 #[test]
446 fn query_optional_immutable_superset_mutable_not_present() {
447 let mut world = World::<Registry>::new();
448 let identifier = world.insert(entity!(A(42), B('a')));
449
450 let mut entries = unsafe { Entries::<_, _, Views!(&A, &mut C), _>::new(&mut world) };
451 let mut entry = assert_some!(entries.entry(identifier));
452
453 let result!(c) = assert_some!(entry.query(Query::<Views!(Option<&C>)>::new()));
454 assert_eq!(c, None);
455 }
456
457 #[test]
458 fn query_optional_mutable_superset_mutable() {
459 let mut world = World::<Registry>::new();
460 let identifier = world.insert(entity!(A(42), B('a'), C(3.14)));
461
462 let mut entries = unsafe { Entries::<_, _, Views!(&A, &mut C), _>::new(&mut world) };
463 let mut entry = assert_some!(entries.entry(identifier));
464
465 let result!(c) = assert_some!(entry.query(Query::<Views!(Option<&mut C>)>::new()));
466 assert_eq!(c, Some(&mut C(3.14)));
467 }
468
469 #[test]
470 fn query_optional_mutable_superset_mutable_not_present() {
471 let mut world = World::<Registry>::new();
472 let identifier = world.insert(entity!(A(42), B('a')));
473
474 let mut entries = unsafe { Entries::<_, _, Views!(&A, &mut C), _>::new(&mut world) };
475 let mut entry = assert_some!(entries.entry(identifier));
476
477 let result!(c) = assert_some!(entry.query(Query::<Views!(Option<&mut C>)>::new()));
478 assert_eq!(c, None);
479 }
480
481 #[test]
482 fn query_optional_none() {
483 let mut world = World::<Registry>::new();
484 let identifier = world.insert(entity!(A(42), C(3.14)));
485
486 let mut entries = unsafe { Entries::<_, _, Views!(&A, &mut C, &B), _>::new(&mut world) };
487 let mut entry = assert_some!(entries.entry(identifier));
488
489 let result!(b) = assert_some!(entry.query(Query::<Views!(Option<&B>)>::new()));
490 assert_eq!(b, None);
491 }
492
493 #[test]
494 fn query_entity_identifier() {
495 let mut world = World::<Registry>::new();
496 let identifier = world.insert(entity!(A(42), B('a'), C(3.14)));
497
498 let mut entries =
499 unsafe { Entries::<_, _, Views!(&A, &mut C, entity::Identifier), _>::new(&mut world) };
500 let mut entry = assert_some!(entries.entry(identifier));
501
502 let result!(queried_identifier) =
503 assert_some!(entry.query(Query::<Views!(entity::Identifier)>::new()));
504 assert_eq!(queried_identifier, identifier);
505 }
506
507 #[test]
508 fn query_multiple() {
509 let mut world = World::<Registry>::new();
510 let identifier = world.insert(entity!(B('a'), C(3.14)));
511
512 let mut entries =
513 unsafe { Entries::<_, _, Views!(&A, &mut B, entity::Identifier), _>::new(&mut world) };
514 let mut entry = assert_some!(entries.entry(identifier));
515
516 let result!(queried_identifier, b, a) =
517 assert_some!(entry.query(Query::<Views!(entity::Identifier, &B, Option<&A>)>::new()));
518 assert_eq!(queried_identifier, identifier);
519 assert_eq!(a, None);
520 assert_eq!(b, &B('a'));
521 }
522
523 #[test]
524 fn query_ref_with_optional_super_view() {
525 let mut world = World::<Registry>::new();
526 let identifier = world.insert(entity!(A(42)));
527
528 let mut entries = unsafe { Entries::<_, _, Views!(Option<&A>), _>::new(&mut world) };
529 let mut entry = assert_some!(entries.entry(identifier));
530
531 let result!(a) = assert_some!(entry.query(Query::<Views!(&A)>::new()));
532 assert_eq!(a, &A(42));
533 }
534
535 #[test]
536 fn query_ref_with_optional_mutable_super_view() {
537 let mut world = World::<Registry>::new();
538 let identifier = world.insert(entity!(A(42)));
539
540 let mut entries = unsafe { Entries::<_, _, Views!(Option<&mut A>), _>::new(&mut world) };
541 let mut entry = assert_some!(entries.entry(identifier));
542
543 let result!(a) = assert_some!(entry.query(Query::<Views!(&A)>::new()));
544 assert_eq!(a, &A(42));
545 }
546
547 #[test]
548 fn query_mutable_ref_with_optional_mutable_super_view() {
549 let mut world = World::<Registry>::new();
550 let identifier = world.insert(entity!(A(42)));
551
552 let mut entries = unsafe { Entries::<_, _, Views!(Option<&mut A>), _>::new(&mut world) };
553 let mut entry = assert_some!(entries.entry(identifier));
554
555 let result!(a) = assert_some!(entry.query(Query::<Views!(&mut A)>::new()));
556 assert_eq!(a, &mut A(42));
557 }
558
559 #[test]
560 fn query_optional_with_optional_super_view() {
561 let mut world = World::<Registry>::new();
562 let identifier = world.insert(entity!(A(42)));
563
564 let mut entries = unsafe { Entries::<_, _, Views!(Option<&A>), _>::new(&mut world) };
565 let mut entry = assert_some!(entries.entry(identifier));
566
567 let result!(a) = assert_some!(entry.query(Query::<Views!(Option<&A>)>::new()));
568 assert_eq!(a, Some(&A(42)));
569 }
570
571 #[test]
572 fn query_optional_with_optional_mutable_super_view() {
573 let mut world = World::<Registry>::new();
574 let identifier = world.insert(entity!(A(42)));
575
576 let mut entries = unsafe { Entries::<_, _, Views!(Option<&mut A>), _>::new(&mut world) };
577 let mut entry = assert_some!(entries.entry(identifier));
578
579 let result!(a) = assert_some!(entry.query(Query::<Views!(Option<&A>)>::new()));
580 assert_eq!(a, Some(&A(42)));
581 }
582
583 #[test]
584 fn query_optional_mutable_with_optional_mutable_super_view() {
585 let mut world = World::<Registry>::new();
586 let identifier = world.insert(entity!(A(42)));
587
588 let mut entries = unsafe { Entries::<_, _, Views!(Option<&mut A>), _>::new(&mut world) };
589 let mut entry = assert_some!(entries.entry(identifier));
590
591 let result!(a) = assert_some!(entry.query(Query::<Views!(Option<&mut A>)>::new()));
592 assert_eq!(a, Some(&mut A(42)));
593 }
594}