1use super::{
2 query::{
3 EntQueryInfo, EntQueryKey, EntQueryMut, Query, QueryInfo, QueryKey, QueryMut, ResQuery,
4 ResQueryInfo, ResQueryKey, ResQueryMut, StoreEntQueryInfo, StoreQueryInfo,
5 StoreResQueryInfo,
6 },
7 select::{
8 FilterInfo, FilterKey, FilteredRaw, SelectInfo, SelectKey, SelectedRaw, StoreFilterInfo,
9 StoreSelectInfo,
10 },
11};
12use crate::{
13 ds::{ATypeId, Borrowed, ManagedConstPtr, ManagedMutPtr},
14 ecs::resource::ResourceKey,
15 util::macros::debug_format,
16 DefaultRandomState,
17};
18use std::{
19 any,
20 collections::HashMap,
21 fmt,
22 hash::BuildHasher,
23 marker::PhantomData,
24 ptr::NonNull,
25 sync::{Arc, LazyLock, Mutex},
26};
27
28pub(crate) static RINFO_STOR: LazyLock<Arc<Mutex<RequestInfoStorage<DefaultRandomState>>>> =
35 const { LazyLock::new(|| Arc::new(Mutex::new(RequestInfoStorage::new()))) };
36
37#[derive(Debug)]
39pub(crate) struct RequestInfoStorage<S> {
40 rinfo: HashMap<RequestKey, Arc<RequestInfo>, S>,
42
43 qinfo: HashMap<QueryKey, Arc<QueryInfo>, S>,
45
46 rqinfo: HashMap<ResQueryKey, Arc<ResQueryInfo>, S>,
48
49 eqinfo: HashMap<EntQueryKey, Arc<EntQueryInfo>, S>,
51
52 sinfo: HashMap<SelectKey, Arc<SelectInfo>, S>,
54
55 finfo: HashMap<FilterKey, Arc<FilterInfo>, S>,
57}
58
59impl<S> RequestInfoStorage<S>
60where
61 S: Default,
62{
63 fn new() -> Self {
64 Self {
65 rinfo: HashMap::default(),
66 qinfo: HashMap::default(),
67 rqinfo: HashMap::default(),
68 eqinfo: HashMap::default(),
69 sinfo: HashMap::default(),
70 finfo: HashMap::default(),
71 }
72 }
73}
74
75impl<S> RequestInfoStorage<S>
76where
77 S: BuildHasher,
78{
79 #[allow(dead_code)]
81 pub(crate) fn get_request_info(&self, key: &RequestKey) -> Option<&Arc<RequestInfo>> {
82 StoreRequestInfo::get(self, key)
83 }
84
85 #[allow(dead_code)]
87 pub(crate) fn get_query_info(&self, key: &QueryKey) -> Option<&Arc<QueryInfo>> {
88 StoreQueryInfo::get(self, key)
89 }
90
91 #[allow(dead_code)]
93 pub(crate) fn get_resource_query_info(&self, key: &ResQueryKey) -> Option<&Arc<ResQueryInfo>> {
94 StoreResQueryInfo::get(self, key)
95 }
96
97 #[allow(dead_code)]
99 pub(crate) fn get_entity_query_info(&self, key: &EntQueryKey) -> Option<&Arc<EntQueryInfo>> {
100 StoreEntQueryInfo::get(self, key)
101 }
102
103 #[allow(dead_code)]
105 pub(crate) fn get_select_info(&self, key: &SelectKey) -> Option<&Arc<SelectInfo>> {
106 StoreSelectInfo::get(self, key)
107 }
108
109 #[allow(dead_code)]
111 pub(crate) fn get_filter_info(&self, key: &FilterKey) -> Option<&Arc<FilterInfo>> {
112 StoreFilterInfo::get(self, key)
113 }
114
115 fn remove(&mut self, key: &RequestKey) {
116 if matches!(self.rinfo.get(key), Some(x) if Arc::strong_count(x) == 1) {
118 let rinfo = unsafe { self.rinfo.remove(key).unwrap_unchecked() };
120
121 let read_key = rinfo.read().0;
124 let write_key = rinfo.write().0;
125 let res_read_key = rinfo.res_read().0;
126 let res_write_key = rinfo.res_write().0;
127 let ent_write_key = rinfo.ent_write().0;
128 drop(rinfo);
129
130 remove_qinfo_sinfo(self, &read_key);
132 remove_qinfo_sinfo(self, &write_key);
133
134 remove_rqinfo(self, &res_read_key);
136 remove_rqinfo(self, &res_write_key);
137
138 remove_eqinfo(self, &ent_write_key);
140 }
141
142 fn remove_qinfo_sinfo<S>(this: &mut RequestInfoStorage<S>, key: &QueryKey)
145 where
146 S: BuildHasher,
147 {
148 const QINFO_EMPTY_STRONG_CNT: usize = 1;
150
151 if matches! (
152 this.qinfo.get(key),
153 Some(x) if Arc::strong_count(x) == QINFO_EMPTY_STRONG_CNT
154 ) {
155 let qinfo = unsafe { this.qinfo.remove(key).unwrap_unchecked() };
159
160 for (fkey, sinfo) in qinfo.selectors() {
162 const FINFO_EMPTY_STRONG_CNT: usize = 2;
164
165 if Arc::strong_count(sinfo) == FINFO_EMPTY_STRONG_CNT {
166 this.sinfo.remove(fkey);
167 }
168 }
169 }
170 }
171
172 fn remove_rqinfo<S>(this: &mut RequestInfoStorage<S>, key: &ResQueryKey)
175 where
176 S: BuildHasher,
177 {
178 const EMPTY_STRONG_CNT: usize = 1;
180
181 if matches! (
182 this.rqinfo.get(key),
183 Some(x) if Arc::strong_count(x) == EMPTY_STRONG_CNT
184 ) {
185 this.rqinfo.remove(key);
186 }
187 }
188
189 fn remove_eqinfo<S>(this: &mut RequestInfoStorage<S>, key: &EntQueryKey)
192 where
193 S: BuildHasher,
194 {
195 const EMPTY_STRONG_CNT: usize = 1;
197
198 if matches! (
199 this.eqinfo.get(key),
200 Some(x) if Arc::strong_count(x) == EMPTY_STRONG_CNT
201 ) {
202 this.eqinfo.remove(key);
203 }
204 }
205 }
206}
207
208impl<S> Default for RequestInfoStorage<S>
209where
210 S: Default,
211{
212 fn default() -> Self {
213 Self::new()
214 }
215}
216
217impl<S> StoreRequestInfo for RequestInfoStorage<S>
218where
219 S: BuildHasher,
220{
221 fn contains(&self, key: &RequestKey) -> bool {
222 self.rinfo.contains_key(key)
223 }
224
225 fn get(&self, key: &RequestKey) -> Option<&Arc<RequestInfo>> {
226 self.rinfo.get(key)
227 }
228
229 fn insert(&mut self, key: RequestKey, info: Arc<RequestInfo>) {
230 self.rinfo.insert(key, info);
231 }
232
233 fn remove(&mut self, key: &RequestKey) {
235 self.remove(key)
236 }
237}
238
239impl<S> StoreQueryInfo for RequestInfoStorage<S>
240where
241 S: BuildHasher,
242{
243 fn contains(&self, key: &QueryKey) -> bool {
244 self.qinfo.contains_key(key)
245 }
246
247 fn get(&self, key: &QueryKey) -> Option<&Arc<QueryInfo>> {
248 self.qinfo.get(key)
249 }
250
251 fn insert(&mut self, key: QueryKey, info: Arc<QueryInfo>) {
252 self.qinfo.insert(key, info);
253 }
254}
255
256impl<S> StoreResQueryInfo for RequestInfoStorage<S>
257where
258 S: BuildHasher,
259{
260 fn contains(&self, key: &ResQueryKey) -> bool {
261 self.rqinfo.contains_key(key)
262 }
263
264 fn get(&self, key: &ResQueryKey) -> Option<&Arc<ResQueryInfo>> {
265 self.rqinfo.get(key)
266 }
267
268 fn insert(&mut self, key: ResQueryKey, info: Arc<ResQueryInfo>) {
269 self.rqinfo.insert(key, info);
270 }
271}
272
273impl<S> StoreEntQueryInfo for RequestInfoStorage<S>
274where
275 S: BuildHasher,
276{
277 fn contains(&self, key: &EntQueryKey) -> bool {
278 self.eqinfo.contains_key(key)
279 }
280
281 fn get(&self, key: &EntQueryKey) -> Option<&Arc<EntQueryInfo>> {
282 self.eqinfo.get(key)
283 }
284
285 fn insert(&mut self, key: EntQueryKey, info: Arc<EntQueryInfo>) {
286 self.eqinfo.insert(key, info);
287 }
288}
289
290impl<S> StoreSelectInfo for RequestInfoStorage<S>
291where
292 S: BuildHasher,
293{
294 fn contains(&self, key: &SelectKey) -> bool {
295 self.sinfo.contains_key(key)
296 }
297
298 fn get(&self, key: &SelectKey) -> Option<&Arc<SelectInfo>> {
299 self.sinfo.get(key)
300 }
301
302 fn insert(&mut self, key: SelectKey, info: Arc<SelectInfo>) {
303 self.sinfo.insert(key, info);
304 }
305}
306
307impl<S> StoreFilterInfo for RequestInfoStorage<S>
308where
309 S: BuildHasher,
310{
311 fn contains(&self, key: &FilterKey) -> bool {
312 self.finfo.contains_key(key)
313 }
314
315 fn get(&self, key: &FilterKey) -> Option<&Arc<FilterInfo>> {
316 self.finfo.get(key)
317 }
318
319 fn insert(&mut self, key: FilterKey, info: Arc<FilterInfo>) {
320 self.finfo.insert(key, info);
321 }
322}
323
324#[allow(private_interfaces, private_bounds)]
336pub trait Request: 'static {
337 type Read: Query;
338 type Write: QueryMut;
339 type ResRead: ResQuery;
340 type ResWrite: ResQueryMut;
341 type EntWrite: EntQueryMut;
342
343 #[doc(hidden)]
344 fn key() -> RequestKey {
345 RequestKey::of::<Self>()
346 }
347
348 #[doc(hidden)]
349 fn get_info_from<S>(stor: &mut S) -> &Arc<RequestInfo>
350 where
351 S: StoreRequestInfo + ?Sized,
352 {
353 let key = Self::key();
354
355 if !StoreRequestInfo::contains(stor, &key) {
356 let rinfo = Arc::new(Self::info_from(stor));
357 StoreRequestInfo::insert(stor, key, rinfo);
358 }
359
360 unsafe { StoreRequestInfo::get(stor, &key).unwrap_unchecked() }
362 }
363
364 #[doc(hidden)]
365 fn info_from<S>(stor: &mut S) -> RequestInfo
366 where
367 S: StoreRequestInfo + ?Sized,
368 {
369 RequestInfo {
371 name: any::type_name::<Self>(),
372 read: (
373 Self::Read::key(),
374 Arc::clone(Self::Read::get_info_from(stor)),
375 ),
376 write: (
377 Self::Write::key(),
378 Arc::clone(Self::Write::get_info_from(stor)),
379 ),
380 res_read: (
381 Self::ResRead::key(),
382 Arc::clone(Self::ResRead::get_info_from(stor)),
383 ),
384 res_write: (
385 Self::ResWrite::key(),
386 Arc::clone(Self::ResWrite::get_info_from(stor)),
387 ),
388 ent_write: (
389 Self::EntWrite::key(),
390 Arc::clone(Self::EntWrite::get_info_from(stor)),
391 ),
392 }
393 }
394}
395
396impl<R, W, RR, RW, EW> Request for (R, W, RR, RW, EW)
398where
399 R: Query,
400 W: QueryMut,
401 RR: ResQuery,
402 RW: ResQueryMut,
403 EW: EntQueryMut,
404{
405 type Read = R;
406 type Write = W;
407 type ResRead = RR;
408 type ResWrite = RW;
409 type EntWrite = EW;
410}
411
412pub(crate) trait StoreRequestInfo:
413 StoreQueryInfo + StoreResQueryInfo + StoreEntQueryInfo
414{
415 fn contains(&self, key: &RequestKey) -> bool;
416 fn get(&self, key: &RequestKey) -> Option<&Arc<RequestInfo>>;
417 fn insert(&mut self, key: RequestKey, info: Arc<RequestInfo>);
418 fn remove(&mut self, key: &RequestKey);
419}
420
421pub(crate) type RequestKey = ATypeId<RequestKey_>;
423pub(crate) struct RequestKey_;
424
425#[derive(Clone)]
426pub(crate) struct RequestInfo {
427 read: (QueryKey, Arc<QueryInfo>),
428 write: (QueryKey, Arc<QueryInfo>),
429 res_read: (ResQueryKey, Arc<ResQueryInfo>),
430 res_write: (ResQueryKey, Arc<ResQueryInfo>),
431 ent_write: (EntQueryKey, Arc<EntQueryInfo>),
432 name: &'static str,
433}
434
435impl fmt::Debug for RequestInfo {
436 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
437 f.debug_struct("RequestInfo")
438 .field("name", &self.name())
439 .field("read", &self.read())
440 .field("write", &self.write())
441 .field("res_read", &self.res_read())
442 .field("res_write", &self.res_write())
443 .field("ent_write", &self.ent_write())
444 .finish()
445 }
446}
447
448impl RequestInfo {
449 pub(crate) const fn read(&self) -> &(QueryKey, Arc<QueryInfo>) {
450 &self.read
451 }
452
453 pub(crate) const fn write(&self) -> &(QueryKey, Arc<QueryInfo>) {
454 &self.write
455 }
456
457 pub(crate) const fn res_read(&self) -> &(ResQueryKey, Arc<ResQueryInfo>) {
458 &self.res_read
459 }
460
461 pub(crate) const fn res_write(&self) -> &(ResQueryKey, Arc<ResQueryInfo>) {
462 &self.res_write
463 }
464
465 pub(crate) const fn ent_write(&self) -> &(EntQueryKey, Arc<EntQueryInfo>) {
466 &self.ent_write
467 }
468
469 pub(crate) const fn name(&self) -> &'static str {
470 self.name
471 }
472
473 pub(crate) fn resource_keys(&self) -> impl Iterator<Item = &ResourceKey> {
474 let read = self.res_read().1.as_ref();
475 let write = self.res_write().1.as_ref();
476 read.resource_keys().iter().chain(write.resource_keys())
477 }
478
479 pub(crate) fn filters(&self) -> &[(FilterKey, Arc<FilterInfo>)] {
480 self.ent_write().1.as_ref().filters()
481 }
482
483 pub(crate) fn validate(&self) -> Result<(), String> {
492 let (_, r_qinfo) = self.read();
494 let (_, w_qinfo) = self.write();
495 let r_sels = r_qinfo.selectors();
496 let w_sels = w_qinfo.selectors();
497 for i in 0..w_sels.len() {
498 for j in i + 1..w_sels.len() {
500 if !w_sels[i].1.is_disjoint(&w_sels[j].1) {
501 let reason = debug_format!(
502 "`{}` and `{}` are not disjoint in request `{}`",
503 w_sels[i].1.name(),
504 w_sels[j].1.name(),
505 self.name(),
506 );
507 return Err(reason);
508 }
509 }
510 for (_, r_sel) in r_sels.iter() {
512 if !w_sels[i].1.is_disjoint(r_sel) {
513 let reason = debug_format!(
514 "`{}` and `{}` are not disjoint in request `{}`",
515 w_sels[i].1.name(),
516 r_sel.name(),
517 self.name(),
518 );
519 return Err(reason);
520 }
521 }
522 }
523
524 let (_, r_rqinfo) = self.res_read();
526 let (_, w_rqinfo) = self.res_write();
527 let r_keys = r_rqinfo.resource_keys();
528 let w_keys = w_rqinfo.resource_keys();
529 for i in 0..w_keys.len() {
530 for j in i + 1..w_keys.len() {
532 if w_keys[i] == w_keys[j] {
533 let reason = debug_format!(
534 "duplicate resource query `{:?}` in request `{}`",
535 w_keys[i],
536 self.name(),
537 );
538 return Err(reason);
539 }
540 }
541 for r_key in r_keys.iter() {
543 if &w_keys[i] == r_key {
544 let reason = debug_format!(
545 "duplicate resource query `{:?}` in request `{}`",
546 w_keys[i],
547 self.name(),
548 );
549 return Err(reason);
550 }
551 }
552 }
553
554 Ok(())
555 }
556}
557
558impl Request for () {
560 type Read = ();
561 type Write = ();
562 type ResRead = ();
563 type ResWrite = ();
564 type EntWrite = ();
565}
566
567#[derive(Debug)]
586pub struct SystemBuffer {
587 pub(crate) read: Box<[SelectedRaw]>,
589
590 pub(crate) write: Box<[SelectedRaw]>,
592
593 pub(crate) res_read: Vec<Borrowed<ManagedConstPtr<u8>>>,
595
596 pub(crate) res_write: Vec<Borrowed<ManagedMutPtr<u8>>>,
598
599 pub(crate) ent_write: Box<[FilteredRaw]>,
601}
602
603unsafe impl Send for SystemBuffer {}
608
609impl SystemBuffer {
610 pub(crate) fn new() -> Self {
611 Self {
612 read: [].into(),
613 write: [].into(),
614 res_read: Vec::new(),
615 res_write: Vec::new(),
616 ent_write: [].into(),
617 }
618 }
619
620 pub(crate) fn clear(&mut self) {
621 #[cfg(feature = "check")]
622 self.clear_force();
623 }
624
625 pub(crate) fn clear_force(&mut self) {
626 for read in self.read.iter_mut() {
627 read.clear();
628 }
629 for write in self.write.iter_mut() {
630 write.clear();
631 }
632 self.res_read.clear();
633 self.res_write.clear();
634 for ent_write in self.ent_write.iter_mut() {
635 ent_write.clear();
636 }
637 }
638}
639
640impl Default for SystemBuffer {
641 fn default() -> Self {
642 Self::new()
643 }
644}
645
646pub struct Response<'buf, Req: Request> {
648 pub read: <Req::Read as Query>::Output<'buf>,
649 pub write: <Req::Write as QueryMut>::Output<'buf>,
650 pub res_read: <Req::ResRead as ResQuery>::Output<'buf>,
651 pub res_write: <Req::ResWrite as ResQueryMut>::Output<'buf>,
652 pub ent_write: <Req::EntWrite as EntQueryMut>::Output<'buf>,
653 _cleaner: BufferCleaner<'buf>,
654}
655
656impl<'buf, Req: Request> Response<'buf, Req> {
657 pub(crate) fn new(buf: &'buf mut SystemBuffer) -> Self {
658 let _cleaner = BufferCleaner {
660 buf_ptr: unsafe { NonNull::new_unchecked(buf as *mut _) },
661 _marker: PhantomData,
662 };
663
664 Self {
665 read: <Req::Read as Query>::convert(&mut buf.read),
666 write: <Req::Write as QueryMut>::convert(&mut buf.write),
667 res_read: <Req::ResRead as ResQuery>::convert(&mut buf.res_read),
668 res_write: <Req::ResWrite as ResQueryMut>::convert(&mut buf.res_write),
669 ent_write: <Req::EntWrite as EntQueryMut>::convert(&mut buf.ent_write),
670 _cleaner,
671 }
672 }
673}
674
675struct BufferCleaner<'buf> {
676 buf_ptr: NonNull<SystemBuffer>,
677 _marker: PhantomData<&'buf ()>,
678}
679
680impl Drop for BufferCleaner<'_> {
681 fn drop(&mut self) {
682 let buf = unsafe { self.buf_ptr.as_mut() };
684 buf.clear();
685 }
686}