1use super::select::{
2 FilterInfo, FilterKey, FilteredRaw, SelectInfo, SelectKey, SelectedRaw, StoreSelectInfo,
3};
4use crate::{
5 ds::{ATypeId, Borrowed, ManagedConstPtr, ManagedMutPtr, NonNullExt},
6 ecs::resource::ResourceKey,
7 util::TakeRecur,
8};
9use my_ecs_macros::repeat_macro;
10use std::{
11 fmt,
12 ops::{Deref, DerefMut},
13 sync::Arc,
14};
15
16pub(crate) trait StoreQueryInfo: StoreSelectInfo {
17 fn contains(&self, key: &QueryKey) -> bool;
18 fn get(&self, key: &QueryKey) -> Option<&Arc<QueryInfo>>;
19 fn insert(&mut self, key: QueryKey, info: Arc<QueryInfo>);
20}
21
22pub(crate) trait StoreResQueryInfo {
23 fn contains(&self, key: &ResQueryKey) -> bool;
24 fn get(&self, key: &ResQueryKey) -> Option<&Arc<ResQueryInfo>>;
25 fn insert(&mut self, key: ResQueryKey, info: Arc<ResQueryInfo>);
26}
27
28pub(crate) trait StoreEntQueryInfo: StoreSelectInfo {
29 fn contains(&self, key: &EntQueryKey) -> bool;
30 fn get(&self, key: &EntQueryKey) -> Option<&Arc<EntQueryInfo>>;
31 fn insert(&mut self, key: EntQueryKey, info: Arc<EntQueryInfo>);
32}
33
34#[allow(private_interfaces, private_bounds)]
35pub trait Query: 'static {
36 type Output<'buf>;
37
38 #[doc(hidden)]
39 fn info_from<S>(stor: &mut S) -> QueryInfo
40 where
41 S: StoreQueryInfo + ?Sized;
42
43 #[doc(hidden)]
44 fn convert(buf: &mut [SelectedRaw]) -> Self::Output<'_>;
45
46 #[doc(hidden)]
47 fn key() -> QueryKey {
48 QueryKey::of::<Self>()
49 }
50
51 #[doc(hidden)]
52 fn get_info_from<S>(stor: &mut S) -> &Arc<QueryInfo>
53 where
54 S: StoreQueryInfo + ?Sized,
55 {
56 let key = Self::key();
57
58 if !StoreQueryInfo::contains(stor, &key) {
59 let qinfo = Arc::new(Self::info_from(stor));
60 StoreQueryInfo::insert(stor, key, qinfo);
61 }
62
63 unsafe { StoreQueryInfo::get(stor, &key).unwrap_unchecked() }
65 }
66}
67
68#[allow(private_interfaces, private_bounds)]
69pub trait QueryMut: 'static {
70 type Output<'buf>;
71
72 #[doc(hidden)]
73 fn info_from<S>(stor: &mut S) -> QueryInfo
74 where
75 S: StoreQueryInfo + ?Sized;
76
77 #[doc(hidden)]
78 fn convert(buf: &mut [SelectedRaw]) -> Self::Output<'_>;
79
80 #[doc(hidden)]
81 fn key() -> QueryKey {
82 QueryKey::of::<Self>()
83 }
84
85 #[doc(hidden)]
86 fn get_info_from<S>(stor: &mut S) -> &Arc<QueryInfo>
87 where
88 S: StoreQueryInfo + ?Sized,
89 {
90 let key = Self::key();
91
92 if !StoreQueryInfo::contains(stor, &key) {
93 let qinfo = Arc::new(Self::info_from(stor));
94 StoreQueryInfo::insert(stor, key, qinfo);
95 }
96
97 unsafe { StoreQueryInfo::get(stor, &key).unwrap_unchecked() }
99 }
100}
101
102#[allow(private_interfaces, private_bounds)]
103pub trait ResQuery: 'static {
104 type Output<'buf>;
105
106 #[doc(hidden)]
107 fn info() -> ResQueryInfo;
108
109 #[doc(hidden)]
110 fn convert(buf: &mut Vec<Borrowed<ManagedConstPtr<u8>>>) -> Self::Output<'_>;
111
112 #[doc(hidden)]
113 fn key() -> ResQueryKey {
114 ResQueryKey::of::<Self>()
115 }
116
117 #[doc(hidden)]
118 fn get_info_from<S>(stor: &mut S) -> &Arc<ResQueryInfo>
119 where
120 S: StoreResQueryInfo + ?Sized,
121 {
122 let key = Self::key();
123
124 if !stor.contains(&key) {
125 let rqinfo = Arc::new(Self::info());
126 stor.insert(key, rqinfo);
127 }
128
129 unsafe { stor.get(&key).unwrap_unchecked() }
131 }
132}
133
134#[allow(private_interfaces, private_bounds)]
135pub trait ResQueryMut: 'static {
136 type Output<'buf>;
137
138 fn info() -> ResQueryInfo;
139
140 fn convert(buf: &mut Vec<Borrowed<ManagedMutPtr<u8>>>) -> Self::Output<'_>;
141
142 #[doc(hidden)]
143 fn key() -> ResQueryKey {
144 ResQueryKey::of::<Self>()
145 }
146
147 #[doc(hidden)]
148 fn get_info_from<S>(stor: &mut S) -> &Arc<ResQueryInfo>
149 where
150 S: StoreResQueryInfo + ?Sized,
151 {
152 let key = Self::key();
153
154 if !stor.contains(&key) {
155 let rqinfo = Arc::new(Self::info());
156 stor.insert(key, rqinfo);
157 }
158
159 unsafe { stor.get(&key).unwrap_unchecked() }
161 }
162}
163
164#[allow(private_interfaces, private_bounds)]
165pub trait EntQueryMut: 'static {
166 type Output<'buf>;
167
168 #[doc(hidden)]
169 fn info_from<S>(stor: &mut S) -> EntQueryInfo
170 where
171 S: StoreEntQueryInfo + ?Sized;
172
173 fn convert(buf: &mut [FilteredRaw]) -> Self::Output<'_>;
174
175 #[doc(hidden)]
176 fn key() -> EntQueryKey {
177 EntQueryKey::of::<Self>()
178 }
179
180 #[doc(hidden)]
181 fn get_info_from<S>(stor: &mut S) -> &Arc<EntQueryInfo>
182 where
183 S: StoreEntQueryInfo + ?Sized,
184 {
185 let key = Self::key();
186
187 if !StoreEntQueryInfo::contains(stor, &key) {
188 let eqinfo = Arc::new(Self::info_from(stor));
189 StoreEntQueryInfo::insert(stor, key, eqinfo);
190 }
191
192 unsafe { StoreEntQueryInfo::get(stor, &key).unwrap_unchecked() }
194 }
195}
196
197#[repr(transparent)]
202pub struct Read<'buf, R: Query>(pub(crate) R::Output<'buf>);
203
204impl<'buf, R: Query> Read<'buf, R> {
205 pub fn take(self) -> R::Output<'buf> {
206 self.0
207 }
208}
209
210impl<'buf, R: Query> Deref for Read<'buf, R> {
211 type Target = R::Output<'buf>;
212
213 fn deref(&self) -> &Self::Target {
214 &self.0
215 }
216}
217
218impl<'buf, R: Query> TakeRecur for Read<'buf, R>
219where
220 R::Output<'buf>: TakeRecur,
221{
222 type Inner = <R::Output<'buf> as TakeRecur>::Inner;
223
224 fn take_recur(self) -> Self::Inner {
225 self.0.take_recur()
226 }
227}
228
229#[repr(transparent)]
234pub struct Write<'buf, W: QueryMut>(pub(crate) W::Output<'buf>);
235
236impl<'buf, W: QueryMut> Write<'buf, W> {
237 pub fn take(self) -> W::Output<'buf> {
238 self.0
239 }
240}
241
242impl<'buf, W: QueryMut> Deref for Write<'buf, W> {
243 type Target = W::Output<'buf>;
244
245 fn deref(&self) -> &Self::Target {
246 &self.0
247 }
248}
249
250impl<W: QueryMut> DerefMut for Write<'_, W> {
251 fn deref_mut(&mut self) -> &mut Self::Target {
252 &mut self.0
253 }
254}
255
256impl<'buf, W: QueryMut> TakeRecur for Write<'buf, W>
257where
258 W::Output<'buf>: TakeRecur,
259{
260 type Inner = <W::Output<'buf> as TakeRecur>::Inner;
261
262 fn take_recur(self) -> Self::Inner {
263 self.0.take_recur()
264 }
265}
266
267#[repr(transparent)]
272pub struct ResRead<'buf, RR: ResQuery>(pub(crate) RR::Output<'buf>);
273
274impl<'buf, RR: ResQuery> ResRead<'buf, RR> {
275 pub fn take(self) -> RR::Output<'buf> {
276 self.0
277 }
278}
279
280impl<'buf, RR: ResQuery> Deref for ResRead<'buf, RR> {
281 type Target = RR::Output<'buf>;
282
283 fn deref(&self) -> &Self::Target {
284 &self.0
285 }
286}
287
288impl<'buf, RR: ResQuery> TakeRecur for ResRead<'buf, RR>
289where
290 RR::Output<'buf>: TakeRecur,
291{
292 type Inner = <RR::Output<'buf> as TakeRecur>::Inner;
293
294 fn take_recur(self) -> Self::Inner {
295 self.0.take_recur()
296 }
297}
298
299#[repr(transparent)]
304pub struct ResWrite<'buf, RW: ResQueryMut>(pub(crate) RW::Output<'buf>);
305
306impl<'buf, RW: ResQueryMut> ResWrite<'buf, RW> {
307 pub fn take(self) -> RW::Output<'buf> {
308 self.0
309 }
310}
311
312impl<'buf, RW: ResQueryMut> Deref for ResWrite<'buf, RW> {
313 type Target = RW::Output<'buf>;
314
315 fn deref(&self) -> &Self::Target {
316 &self.0
317 }
318}
319
320impl<RW: ResQueryMut> DerefMut for ResWrite<'_, RW> {
321 fn deref_mut(&mut self) -> &mut Self::Target {
322 &mut self.0
323 }
324}
325
326impl<'buf, RW: ResQueryMut> TakeRecur for ResWrite<'buf, RW>
327where
328 RW::Output<'buf>: TakeRecur,
329{
330 type Inner = <RW::Output<'buf> as TakeRecur>::Inner;
331
332 fn take_recur(self) -> Self::Inner {
333 self.0.take_recur()
334 }
335}
336
337#[repr(transparent)]
342pub struct EntWrite<'buf, EW: EntQueryMut>(pub(crate) EW::Output<'buf>);
343
344impl<'buf, EW: EntQueryMut> EntWrite<'buf, EW> {
345 pub fn take(self) -> EW::Output<'buf> {
346 self.0
347 }
348}
349
350impl<'buf, EW: EntQueryMut> Deref for EntWrite<'buf, EW> {
351 type Target = EW::Output<'buf>;
352
353 fn deref(&self) -> &Self::Target {
354 &self.0
355 }
356}
357
358impl<EW: EntQueryMut> DerefMut for EntWrite<'_, EW> {
359 fn deref_mut(&mut self) -> &mut Self::Target {
360 &mut self.0
361 }
362}
363
364impl<'buf, EW: EntQueryMut> TakeRecur for EntWrite<'buf, EW>
365where
366 EW::Output<'buf>: TakeRecur,
367{
368 type Inner = <EW::Output<'buf> as TakeRecur>::Inner;
369
370 fn take_recur(self) -> Self::Inner {
371 self.0.take_recur()
372 }
373}
374
375pub(crate) type QueryKey = ATypeId<QueryKey_>;
377pub(crate) struct QueryKey_;
378
379pub(crate) type ResQueryKey = ATypeId<ResQueryKey_>;
381pub(crate) struct ResQueryKey_;
382
383pub(crate) type EntQueryKey = ATypeId<EntQueryKey_>;
385pub(crate) struct EntQueryKey_;
386
387#[derive(Clone)]
388pub(crate) struct QueryInfo {
389 sels: Box<[(SelectKey, Arc<SelectInfo>)]>,
390 name: &'static str,
391}
392
393impl fmt::Debug for QueryInfo {
394 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
395 let sinfos = self.select_infos().collect::<Vec<_>>();
396
397 f.debug_struct("QueryInfo")
398 .field("name", &self.name())
399 .field("sels", &sinfos)
400 .finish()
401 }
402}
403
404impl QueryInfo {
405 const fn new(sels: Box<[(SelectKey, Arc<SelectInfo>)]>, name: &'static str) -> Self {
406 Self { sels, name }
407 }
408
409 pub(crate) const fn selectors(&self) -> &[(SelectKey, Arc<SelectInfo>)] {
410 &self.sels
411 }
412
413 pub(crate) fn select_infos(&self) -> impl ExactSizeIterator<Item = &Arc<SelectInfo>> + Clone {
414 self.sels.iter().map(|(_key, info)| info)
415 }
416
417 pub(crate) const fn name(&self) -> &'static str {
418 self.name
419 }
420}
421
422#[derive(Clone)]
423pub(crate) struct ResQueryInfo {
424 rkeys: Box<[ResourceKey]>,
425 name: &'static str,
426}
427
428impl fmt::Debug for ResQueryInfo {
429 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
430 f.debug_struct("ResQueryInfo")
431 .field("name", &self.name())
432 .field("rkeys", &self.resource_keys())
433 .finish()
434 }
435}
436
437impl ResQueryInfo {
438 const fn new(rkeys: Box<[ResourceKey]>, name: &'static str) -> Self {
439 Self { rkeys, name }
440 }
441
442 pub(crate) const fn resource_keys(&self) -> &[ResourceKey] {
443 &self.rkeys
444 }
445
446 pub(crate) const fn name(&self) -> &'static str {
447 self.name
448 }
449}
450
451#[derive(Clone)]
452pub(crate) struct EntQueryInfo {
453 filters: Box<[(FilterKey, Arc<FilterInfo>)]>,
454 name: &'static str,
455}
456
457impl fmt::Debug for EntQueryInfo {
458 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
459 f.debug_struct("EntQueryInfo")
460 .field("name", &self.name())
461 .field("filters", &self.filters())
462 .finish()
463 }
464}
465
466impl EntQueryInfo {
467 const fn new(filters: Box<[(FilterKey, Arc<FilterInfo>)]>, name: &'static str) -> Self {
468 Self { filters, name }
469 }
470
471 pub(crate) const fn filters(&self) -> &[(FilterKey, Arc<FilterInfo>)] {
472 &self.filters
473 }
474
475 pub(crate) const fn name(&self) -> &'static str {
476 self.name
477 }
478}
479
480macro_rules! impl_query {
483 ($n:expr, $($i:expr),*) => {const _: () = {
484 #[allow(unused_imports)]
485 use $crate::ecs::sys::{
486 query::{Query, QueryInfo, StoreQueryInfo, StoreSelectInfo},
487 select::{Select, SelectKey, SelectedRaw, Selected, SelectedMut},
488 };
489 use std::{any::type_name, sync::Arc};
490 use paste::paste;
491
492 paste! {
494 #[allow(unused_parens)]
495 #[allow(private_interfaces, private_bounds)]
496 impl<$([<A $i>]: Select),*> Query for ( $([<A $i>]),* ) {
497 type Output<'buf> = ( $(Selected<'buf, [<A $i>]::Target>),* );
498
499 fn info_from<S>(_stor: &mut S) -> QueryInfo
500 where
501 S: StoreQueryInfo + ?Sized
502 {
503 let sels = [ $(
504 (
505 [<A $i>]::key(),
506 Arc::clone([<A $i>]::get_info_from(_stor))
507 )
508 ),* ];
509 let sels: Box<[(SelectKey, Arc<SelectInfo>)]> = sels.into();
510 let name = type_name::<Self>();
511 QueryInfo::new(sels, name)
512 }
513
514 fn convert(buf: &mut [SelectedRaw]) -> Self::Output<'_> {
515 debug_assert_eq!($n, buf.len());
516
517 #[allow(clippy::unused_unit)]
518 ( $(
519 {
524 let x: *mut SelectedRaw = &mut buf[$i] as *mut _;
525 let x: &mut SelectedRaw = unsafe { x.as_mut().unwrap_unchecked() };
526 Selected::new(x)
527 }
528 ),* )
529 }
530 }
531 }
532
533 paste! {
535 #[allow(unused_parens)]
536 #[allow(private_interfaces, private_bounds)]
537 impl<$([<A $i>]: Select),*> QueryMut for ( $([<A $i>]),* ) {
538 type Output<'buf> = ( $(SelectedMut<'buf, [<A $i>]::Target>),* );
539
540 fn info_from<S>(_stor: &mut S) -> QueryInfo
541 where
542 S: StoreQueryInfo + ?Sized
543 {
544 let sels = [ $(
545 (
546 [<A $i>]::key(),
547 Arc::clone([<A $i>]::get_info_from(_stor))
548 )
549 ),* ];
550 let sels: Box<[(SelectKey, Arc<SelectInfo>)]> = sels.into();
551 let name = type_name::<Self>();
552 QueryInfo::new(sels, name)
553 }
554
555 fn convert(buf: &mut [SelectedRaw]) -> Self::Output<'_> {
556 debug_assert_eq!($n, buf.len());
557
558 #[allow(clippy::unused_unit)]
559 ( $(
560 {
565 let x: *mut SelectedRaw = &mut buf[$i] as *mut _;
566 let x: &mut SelectedRaw = unsafe { x.as_mut().unwrap_unchecked() };
567 SelectedMut::new(x)
568 }
569 ),* )
570 }
571 }
572 }
573 };};
574}
575repeat_macro!(impl_query, ..=8);
576
577macro_rules! impl_res_query {
579 ($n:expr, $($i:expr),*) => {const _: () = {
580 #[allow(unused_imports)]
581 use $crate::{
582 ecs::{
583 sys::query::{ResQuery, ResQueryInfo},
584 resource::Resource,
585 },
586 ds::{Borrowed, ManagedConstPtr, ManagedMutPtr, TypeIdExt},
587 };
588 use std::any::type_name;
589 use paste::paste;
590
591 paste! {
593 #[allow(unused_parens)]
594 #[allow(private_interfaces, private_bounds)]
595 impl<$([<A $i>]: Resource),*> ResQuery for ( $([<A $i>]),* ) {
596 type Output<'buf> = ( $( &'buf [<A $i>] ),* );
597
598 fn info() -> ResQueryInfo {
599 let rkeys = [$([<A $i>]::key()),*].into();
600 let name = type_name::<Self>();
601 ResQueryInfo::new(rkeys, name)
602 }
603
604 fn convert(_buf: &mut Vec<Borrowed<ManagedConstPtr<u8>>>) -> Self::Output<'_> {
605 debug_assert_eq!($n, _buf.len());
606
607 #[cfg(feature = "check")]
611 {
612 $(
613 let ptr: NonNullExt<_> = _buf[$i].as_nonnullext();
614 let lhs: &TypeIdExt = ptr.get_type().unwrap();
615
616 let rkey: ResourceKey = [<A $i>]::key();
617 let rhs: &TypeIdExt = rkey.get_inner();
618
619 assert_eq!(lhs, rhs);
620 )*
621 }
622
623 #[allow(clippy::unused_unit)]
624 ( $( {
625 let ptr: NonNullExt<[<A $i>]> = _buf[$i].as_nonnullext().cast();
626 unsafe { ptr.as_ref() } } ),* )
630 }
631 }
632 }
633
634 paste!{
636 #[allow(unused_parens)]
637 #[allow(private_interfaces, private_bounds)]
638 impl<$([<A $i>]: Resource),*> ResQueryMut for ( $([<A $i>]),* ) {
639 type Output<'buf> = ( $( &'buf mut [<A $i>] ),* );
640
641 fn info() -> ResQueryInfo {
642 let rkeys = [$([<A $i>]::key()),*].into();
643 let name = type_name::<Self>();
644 ResQueryInfo::new(rkeys, name)
645 }
646
647 fn convert(_buf: &mut Vec<Borrowed<ManagedMutPtr<u8>>>) -> Self::Output<'_> {
648 debug_assert_eq!($n, _buf.len());
649
650 #[cfg(feature = "check")]
654 { $(
655 let ptr: NonNullExt<_> = _buf[$i].as_nonnullext();
656 let lhs: &TypeIdExt = ptr.get_type().unwrap();
657
658 let rkey: ResourceKey = [<A $i>]::key();
659 let rhs: &TypeIdExt = rkey.get_inner();
660
661 assert_eq!(lhs, rhs);
662 )* }
663
664 #[allow(clippy::unused_unit)]
665 ( $( {
666 let mut ptr: NonNullExt<[<A $i>]> = _buf[$i].as_nonnullext().cast();
667 unsafe { ptr.as_mut() } } ),* )
671 }
672 }
673 }
674 };};
675}
676repeat_macro!(impl_res_query, ..=8);
677
678macro_rules! impl_ent_query {
680 ($n:expr, $($i:expr),*) => {const _: () = {
681 #[allow(unused_imports)]
682 use $crate::{
683 ecs::{
684 sys::{
685 query::{EntQueryMut, EntQueryInfo},
686 select::{Filter, FilteredMut},
687 },
688 ent::{
689 entity::{Entity, ContainEntity},
690 storage::EntityContainerRef
691 },
692 },
693 ds::Borrowed,
694 };
695 use std::any::type_name;
696 use paste::paste;
697
698 paste! {
700 #[allow(unused_parens)]
701 #[allow(private_interfaces, private_bounds)]
702 impl<$([<A $i>]: Filter),*> EntQueryMut for ( $([<A $i>]),* ) {
703 type Output<'buf> = ( $(FilteredMut<'buf, [<A $i>]>),* );
704
705 fn info_from<S>(_stor: &mut S) -> EntQueryInfo
706 where
707 S: StoreEntQueryInfo + ?Sized
708 {
709 let finfos = [$(
710 (
711 [<A $i>]::key(),
712 Arc::clone([<A $i>]::get_info_from(_stor))
713 )
714 ),*].into();
715 let name = type_name::<Self>();
716 EntQueryInfo::new(finfos, name)
717 }
718
719 fn convert(buf: &mut [FilteredRaw]) -> Self::Output<'_> {
720 debug_assert_eq!($n, buf.len());
721
722 #[allow(clippy::unused_unit)]
723 ( $(
724 {
729 let x: *mut FilteredRaw = &mut buf[$i] as *mut _;
730 let x: &mut FilteredRaw = unsafe { x.as_mut().unwrap_unchecked() };
731 FilteredMut::new(x)
732 }
733 ),* )
734 }
735 }
736 }
737 };};
738}
739repeat_macro!(impl_ent_query, ..=8);