1mod borrow_info;
2#[cfg(feature = "thread_local")]
3mod non_send;
4#[cfg(feature = "thread_local")]
5mod non_send_sync;
6#[cfg(feature = "thread_local")]
7mod non_sync;
8mod world_borrow;
9
10pub use borrow_info::BorrowInfo;
11#[cfg(feature = "thread_local")]
12pub use non_send::NonSend;
13#[cfg(feature = "thread_local")]
14pub use non_send_sync::NonSendSync;
15#[cfg(feature = "thread_local")]
16pub use non_sync::NonSync;
17pub use world_borrow::WorldBorrow;
18
19use crate::all_storages::{AllStorages, CustomStorageAccess};
20use crate::atomic_refcell::{ARef, ARefMut, SharedBorrow};
21use crate::component::{Component, Unique};
22use crate::error;
23use crate::sparse_set::SparseSet;
24#[cfg(feature = "thread_local")]
25use crate::storage::StorageId;
26use crate::system::Nothing;
27use crate::tracking::{Tracking, TrackingTimestamp};
28use crate::unique::UniqueStorage;
29use crate::views::{EntitiesView, EntitiesViewMut, UniqueView, UniqueViewMut, View, ViewMut};
30use core::marker::PhantomData;
31
32#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
35#[cfg_attr(feature = "serde1", derive(serde::Serialize, serde::Deserialize))]
36pub enum Mutability {
37 #[allow(missing_docs)]
38 Shared,
39 #[allow(missing_docs)]
40 Exclusive,
41}
42
43pub trait Borrow {
82 #[allow(missing_docs)]
83 type View<'a>;
84
85 fn borrow<'a>(
87 all_storages: &'a AllStorages,
88 all_borrow: Option<SharedBorrow<'a>>,
89 last_run: Option<TrackingTimestamp>,
90 current: TrackingTimestamp,
91 ) -> Result<Self::View<'a>, error::GetStorage>;
92}
93
94impl Borrow for Nothing {
96 type View<'a> = ();
97
98 fn borrow<'a>(
99 _all_storages: &'a AllStorages,
100 _all_borrow: Option<SharedBorrow<'a>>,
101 _last_run: Option<TrackingTimestamp>,
102 _current: TrackingTimestamp,
103 ) -> Result<Self::View<'a>, error::GetStorage> {
104 Ok(())
105 }
106}
107
108impl Borrow for () {
109 type View<'a> = ();
110
111 #[inline]
112 fn borrow<'a>(
113 _all_storages: &'a AllStorages,
114 _all_borrow: Option<SharedBorrow<'a>>,
115 _last_run: Option<TrackingTimestamp>,
116 _current: TrackingTimestamp,
117 ) -> Result<Self::View<'a>, error::GetStorage>
118 where
119 Self: Sized,
120 {
121 Ok(())
122 }
123}
124
125impl Borrow for EntitiesView<'_> {
126 type View<'a> = EntitiesView<'a>;
127
128 #[inline]
129 fn borrow<'a>(
130 all_storages: &'a AllStorages,
131 all_borrow: Option<SharedBorrow<'a>>,
132 _last_run: Option<TrackingTimestamp>,
133 _current: TrackingTimestamp,
134 ) -> Result<Self::View<'a>, error::GetStorage> {
135 let entities = all_storages.entities()?;
136
137 let (entities, borrow) = unsafe { ARef::destructure(entities) };
138
139 Ok(EntitiesView {
140 entities,
141 borrow: Some(borrow),
142 all_borrow,
143 })
144 }
145}
146
147impl Borrow for EntitiesViewMut<'_> {
148 type View<'a> = EntitiesViewMut<'a>;
149
150 #[inline]
151 fn borrow<'a>(
152 all_storages: &'a AllStorages,
153 all_borrow: Option<SharedBorrow<'a>>,
154 _last_run: Option<TrackingTimestamp>,
155 _current: TrackingTimestamp,
156 ) -> Result<Self::View<'a>, error::GetStorage> {
157 let entities = all_storages.entities_mut()?;
158
159 let (entities, borrow) = unsafe { ARefMut::destructure(entities) };
160
161 Ok(EntitiesViewMut {
162 entities,
163 _borrow: Some(borrow),
164 _all_borrow: all_borrow,
165 })
166 }
167}
168
169impl<T: Send + Sync + Component, Track> Borrow for View<'_, T, Track>
170where
171 Track: Tracking,
172{
173 type View<'a> = View<'a, T, Track>;
174
175 #[inline]
176 fn borrow<'a>(
177 all_storages: &'a AllStorages,
178 all_borrow: Option<SharedBorrow<'a>>,
179 last_run: Option<TrackingTimestamp>,
180 current: TrackingTimestamp,
181 ) -> Result<Self::View<'a>, error::GetStorage> {
182 let view = all_storages.custom_storage_or_insert(SparseSet::new)?;
183
184 let (sparse_set, borrow) = unsafe { ARef::destructure(view) };
185
186 sparse_set.check_tracking::<Track>()?;
187
188 Ok(View::new(sparse_set, borrow, all_borrow, last_run, current))
189 }
190}
191
192#[cfg(feature = "thread_local")]
193impl<T: Sync + Component, Track> Borrow for NonSend<View<'_, T, Track>>
194where
195 Track: Tracking,
196{
197 type View<'a> = NonSend<View<'a, T, Track>>;
198
199 #[inline]
200 fn borrow<'a>(
201 all_storages: &'a AllStorages,
202 all_borrow: Option<SharedBorrow<'a>>,
203 last_run: Option<TrackingTimestamp>,
204 current: TrackingTimestamp,
205 ) -> Result<Self::View<'a>, error::GetStorage> {
206 let view = all_storages.custom_storage_or_insert_non_send(|| NonSend(SparseSet::new()))?;
207
208 let (sparse_set, borrow) = unsafe { ARef::destructure(view) };
209
210 sparse_set.check_tracking::<Track>()?;
211
212 Ok(NonSend(View::new(
213 sparse_set, borrow, all_borrow, last_run, current,
214 )))
215 }
216}
217
218#[cfg(feature = "thread_local")]
219impl<T: Send + Component, Track> Borrow for NonSync<View<'_, T, Track>>
220where
221 Track: Tracking,
222{
223 type View<'a> = NonSync<View<'a, T, Track>>;
224
225 #[inline]
226 fn borrow<'a>(
227 all_storages: &'a AllStorages,
228 all_borrow: Option<SharedBorrow<'a>>,
229 last_run: Option<TrackingTimestamp>,
230 current: TrackingTimestamp,
231 ) -> Result<Self::View<'a>, error::GetStorage> {
232 let view = all_storages.custom_storage_or_insert_non_sync(|| NonSync(SparseSet::new()))?;
233
234 let (sparse_set, borrow) = unsafe { ARef::destructure(view) };
235
236 sparse_set.check_tracking::<Track>()?;
237
238 Ok(NonSync(View::new(
239 sparse_set, borrow, all_borrow, last_run, current,
240 )))
241 }
242}
243
244#[cfg(feature = "thread_local")]
245impl<T: Component, Track> Borrow for NonSendSync<View<'_, T, Track>>
246where
247 Track: Tracking,
248{
249 type View<'a> = NonSendSync<View<'a, T, Track>>;
250
251 #[inline]
252 fn borrow<'a>(
253 all_storages: &'a AllStorages,
254 all_borrow: Option<SharedBorrow<'a>>,
255 last_run: Option<TrackingTimestamp>,
256 current: TrackingTimestamp,
257 ) -> Result<Self::View<'a>, error::GetStorage> {
258 let view = all_storages
259 .custom_storage_or_insert_non_send_sync(|| NonSendSync(SparseSet::new()))?;
260
261 let (sparse_set, borrow) = unsafe { ARef::destructure(view) };
262
263 sparse_set.check_tracking::<Track>()?;
264
265 Ok(NonSendSync(View::new(
266 sparse_set, borrow, all_borrow, last_run, current,
267 )))
268 }
269}
270
271impl<T: Send + Sync + Component, Track> Borrow for ViewMut<'_, T, Track>
272where
273 Track: Tracking,
274{
275 type View<'a> = ViewMut<'a, T, Track>;
276
277 #[inline]
278 fn borrow<'a>(
279 all_storages: &'a AllStorages,
280 all_borrow: Option<SharedBorrow<'a>>,
281 last_run: Option<TrackingTimestamp>,
282 current: TrackingTimestamp,
283 ) -> Result<Self::View<'a>, error::GetStorage> {
284 let view = all_storages.custom_storage_or_insert_mut(SparseSet::new)?;
285
286 let (sparse_set, borrow) = unsafe { ARefMut::destructure(view) };
287
288 sparse_set.check_tracking::<Track>()?;
289
290 Ok(ViewMut {
291 last_insertion: last_run.unwrap_or(sparse_set.last_insert),
292 last_modification: last_run.unwrap_or(sparse_set.last_modified),
293 last_removal_or_deletion: last_run.unwrap_or(TrackingTimestamp::origin()),
294 current,
295 sparse_set,
296 borrow,
297 all_borrow,
298 phantom: PhantomData,
299 })
300 }
301}
302
303#[cfg(feature = "thread_local")]
304impl<T: Sync + Component, Track> Borrow for NonSend<ViewMut<'_, T, Track>>
305where
306 Track: Tracking,
307{
308 type View<'a> = NonSend<ViewMut<'a, T, Track>>;
309
310 #[inline]
311 fn borrow<'a>(
312 all_storages: &'a AllStorages,
313 all_borrow: Option<SharedBorrow<'a>>,
314 last_run: Option<TrackingTimestamp>,
315 current: TrackingTimestamp,
316 ) -> Result<Self::View<'a>, error::GetStorage> {
317 let view =
318 all_storages.custom_storage_or_insert_non_send_mut(|| NonSend(SparseSet::new()))?;
319
320 let (sparse_set, borrow) = unsafe { ARefMut::destructure(view) };
321
322 sparse_set.check_tracking::<Track>()?;
323
324 Ok(NonSend(ViewMut {
325 last_insertion: last_run.unwrap_or(sparse_set.last_insert),
326 last_modification: last_run.unwrap_or(sparse_set.last_modified),
327 last_removal_or_deletion: last_run.unwrap_or(TrackingTimestamp::origin()),
328 current,
329 sparse_set,
330 borrow: borrow,
331 all_borrow: all_borrow,
332 phantom: PhantomData,
333 }))
334 }
335}
336
337#[cfg(feature = "thread_local")]
338impl<T: Send + Component, Track> Borrow for NonSync<ViewMut<'_, T, Track>>
339where
340 Track: Tracking,
341{
342 type View<'a> = NonSync<ViewMut<'a, T, Track>>;
343
344 #[inline]
345 fn borrow<'a>(
346 all_storages: &'a AllStorages,
347 all_borrow: Option<SharedBorrow<'a>>,
348 last_run: Option<TrackingTimestamp>,
349 current: TrackingTimestamp,
350 ) -> Result<Self::View<'a>, error::GetStorage> {
351 let view =
352 all_storages.custom_storage_or_insert_non_sync_mut(|| NonSync(SparseSet::new()))?;
353
354 let (sparse_set, borrow) = unsafe { ARefMut::destructure(view) };
355
356 sparse_set.check_tracking::<Track>()?;
357
358 Ok(NonSync(ViewMut {
359 last_insertion: last_run.unwrap_or(sparse_set.last_insert),
360 last_modification: last_run.unwrap_or(sparse_set.last_modified),
361 last_removal_or_deletion: last_run.unwrap_or(TrackingTimestamp::origin()),
362 current,
363 sparse_set,
364 borrow: borrow,
365 all_borrow: all_borrow,
366 phantom: PhantomData,
367 }))
368 }
369}
370
371#[cfg(feature = "thread_local")]
372impl<T: Component, Track> Borrow for NonSendSync<ViewMut<'_, T, Track>>
373where
374 Track: Tracking,
375{
376 type View<'a> = NonSendSync<ViewMut<'a, T, Track>>;
377
378 #[inline]
379 fn borrow<'a>(
380 all_storages: &'a AllStorages,
381 all_borrow: Option<SharedBorrow<'a>>,
382 last_run: Option<TrackingTimestamp>,
383 current: TrackingTimestamp,
384 ) -> Result<Self::View<'a>, error::GetStorage> {
385 let view = all_storages
386 .custom_storage_or_insert_non_send_sync_mut(|| NonSendSync(SparseSet::new()))?;
387
388 let (sparse_set, borrow) = unsafe { ARefMut::destructure(view) };
389
390 sparse_set.check_tracking::<Track>()?;
391
392 Ok(NonSendSync(ViewMut {
393 last_insertion: last_run.unwrap_or(sparse_set.last_insert),
394 last_modification: last_run.unwrap_or(sparse_set.last_modified),
395 last_removal_or_deletion: last_run.unwrap_or(TrackingTimestamp::origin()),
396 current,
397 sparse_set,
398 borrow: borrow,
399 all_borrow: all_borrow,
400 phantom: PhantomData,
401 }))
402 }
403}
404
405impl<T: Send + Sync + Unique> Borrow for UniqueView<'_, T> {
406 type View<'a> = UniqueView<'a, T>;
407
408 #[inline]
409 fn borrow<'a>(
410 all_storages: &'a AllStorages,
411 all_borrow: Option<SharedBorrow<'a>>,
412 last_run: Option<TrackingTimestamp>,
413 current: TrackingTimestamp,
414 ) -> Result<Self::View<'a>, error::GetStorage> {
415 let view = all_storages.custom_storage()?;
416
417 let (unique, borrow) = unsafe { ARef::destructure(view) };
418
419 Ok(UniqueView {
420 unique,
421 borrow: Some(borrow),
422 all_borrow,
423 last_insertion: last_run.unwrap_or(unique.last_insert),
424 last_modification: last_run.unwrap_or(unique.last_modification),
425 current,
426 })
427 }
428}
429
430#[cfg(feature = "thread_local")]
431impl<T: Sync + Unique> Borrow for NonSend<UniqueView<'_, T>> {
432 type View<'a> = NonSend<UniqueView<'a, T>>;
433
434 #[inline]
435 fn borrow<'a>(
436 all_storages: &'a AllStorages,
437 all_borrow: Option<SharedBorrow<'a>>,
438 last_run: Option<TrackingTimestamp>,
439 current: TrackingTimestamp,
440 ) -> Result<Self::View<'a>, error::GetStorage> {
441 let view = all_storages.custom_storage_by_id(StorageId::of::<UniqueStorage<T>>())?;
442 let view = ARef::map(view, |storage| {
443 storage
444 .as_any()
445 .downcast_ref::<NonSend<UniqueStorage<T>>>()
446 .unwrap()
447 });
448
449 let (unique, borrow) = unsafe { ARef::destructure(view) };
450
451 Ok(NonSend(UniqueView {
452 unique,
453 borrow: Some(borrow),
454 all_borrow,
455 last_insertion: last_run.unwrap_or(unique.last_insert),
456 last_modification: last_run.unwrap_or(unique.last_modification),
457 current,
458 }))
459 }
460}
461
462#[cfg(feature = "thread_local")]
463impl<T: Send + Unique> Borrow for NonSync<UniqueView<'_, T>> {
464 type View<'a> = NonSync<UniqueView<'a, T>>;
465
466 #[inline]
467 fn borrow<'a>(
468 all_storages: &'a AllStorages,
469 all_borrow: Option<SharedBorrow<'a>>,
470 last_run: Option<TrackingTimestamp>,
471 current: TrackingTimestamp,
472 ) -> Result<Self::View<'a>, error::GetStorage> {
473 let view = all_storages.custom_storage_by_id(StorageId::of::<UniqueStorage<T>>())?;
474 let view = ARef::map(view, |storage| {
475 storage
476 .as_any()
477 .downcast_ref::<NonSync<UniqueStorage<T>>>()
478 .unwrap()
479 });
480
481 let (unique, borrow) = unsafe { ARef::destructure(view) };
482
483 Ok(NonSync(UniqueView {
484 unique,
485 borrow: Some(borrow),
486 all_borrow,
487 last_insertion: last_run.unwrap_or(unique.last_insert),
488 last_modification: last_run.unwrap_or(unique.last_modification),
489 current,
490 }))
491 }
492}
493
494#[cfg(feature = "thread_local")]
495impl<T: Unique> Borrow for NonSendSync<UniqueView<'_, T>> {
496 type View<'a> = NonSendSync<UniqueView<'a, T>>;
497
498 #[inline]
499 fn borrow<'a>(
500 all_storages: &'a AllStorages,
501 all_borrow: Option<SharedBorrow<'a>>,
502 last_run: Option<TrackingTimestamp>,
503 current: TrackingTimestamp,
504 ) -> Result<Self::View<'a>, error::GetStorage> {
505 let view = all_storages.custom_storage_by_id(StorageId::of::<UniqueStorage<T>>())?;
506 let view = ARef::map(view, |storage| {
507 storage
508 .as_any()
509 .downcast_ref::<NonSendSync<UniqueStorage<T>>>()
510 .unwrap()
511 });
512
513 let (unique, borrow) = unsafe { ARef::destructure(view) };
514
515 Ok(NonSendSync(UniqueView {
516 unique,
517 borrow: Some(borrow),
518 all_borrow,
519 last_insertion: last_run.unwrap_or(unique.last_insert),
520 last_modification: last_run.unwrap_or(unique.last_modification),
521 current,
522 }))
523 }
524}
525
526impl<T: Send + Sync + Unique> Borrow for UniqueViewMut<'_, T> {
527 type View<'a> = UniqueViewMut<'a, T>;
528
529 #[inline]
530 fn borrow<'a>(
531 all_storages: &'a AllStorages,
532 all_borrow: Option<SharedBorrow<'a>>,
533 last_run: Option<TrackingTimestamp>,
534 current: TrackingTimestamp,
535 ) -> Result<Self::View<'a>, error::GetStorage> {
536 let view = all_storages.custom_storage_mut::<UniqueStorage<T>>()?;
537
538 let (unique, borrow) = unsafe { ARefMut::destructure(view) };
539
540 Ok(UniqueViewMut {
541 last_insertion: last_run.unwrap_or(unique.last_insert),
542 last_modification: last_run.unwrap_or(unique.last_modification),
543 current,
544 unique,
545 _borrow: Some(borrow),
546 _all_borrow: all_borrow,
547 })
548 }
549}
550
551#[cfg(feature = "thread_local")]
552impl<T: Sync + Unique> Borrow for NonSend<UniqueViewMut<'_, T>> {
553 type View<'a> = NonSend<UniqueViewMut<'a, T>>;
554
555 #[inline]
556 fn borrow<'a>(
557 all_storages: &'a AllStorages,
558 all_borrow: Option<SharedBorrow<'a>>,
559 last_run: Option<TrackingTimestamp>,
560 current: TrackingTimestamp,
561 ) -> Result<Self::View<'a>, error::GetStorage> {
562 let view = all_storages.custom_storage_mut_by_id(StorageId::of::<UniqueStorage<T>>())?;
563 let view = ARefMut::map(view, |storage| {
564 storage
565 .as_any_mut()
566 .downcast_mut::<NonSend<UniqueStorage<T>>>()
567 .unwrap()
568 });
569
570 let (unique, borrow) = unsafe { ARefMut::destructure(view) };
571
572 Ok(NonSend(UniqueViewMut {
573 last_insertion: last_run.unwrap_or(unique.last_insert),
574 last_modification: last_run.unwrap_or(unique.last_modification),
575 current,
576 unique,
577 _borrow: Some(borrow),
578 _all_borrow: all_borrow,
579 }))
580 }
581}
582
583#[cfg(feature = "thread_local")]
584impl<T: Send + Unique> Borrow for NonSync<UniqueViewMut<'_, T>> {
585 type View<'a> = NonSync<UniqueViewMut<'a, T>>;
586
587 #[inline]
588 fn borrow<'a>(
589 all_storages: &'a AllStorages,
590 all_borrow: Option<SharedBorrow<'a>>,
591 last_run: Option<TrackingTimestamp>,
592 current: TrackingTimestamp,
593 ) -> Result<Self::View<'a>, error::GetStorage> {
594 let view = all_storages.custom_storage_mut_by_id(StorageId::of::<UniqueStorage<T>>())?;
595 let view = ARefMut::map(view, |storage| {
596 storage
597 .as_any_mut()
598 .downcast_mut::<NonSync<UniqueStorage<T>>>()
599 .unwrap()
600 });
601
602 let (unique, borrow) = unsafe { ARefMut::destructure(view) };
603
604 Ok(NonSync(UniqueViewMut {
605 last_insertion: last_run.unwrap_or(unique.last_insert),
606 last_modification: last_run.unwrap_or(unique.last_modification),
607 current,
608 unique,
609 _borrow: Some(borrow),
610 _all_borrow: all_borrow,
611 }))
612 }
613}
614
615#[cfg(feature = "thread_local")]
616impl<T: Unique> Borrow for NonSendSync<UniqueViewMut<'_, T>> {
617 type View<'a> = NonSendSync<UniqueViewMut<'a, T>>;
618
619 #[inline]
620 fn borrow<'a>(
621 all_storages: &'a AllStorages,
622 all_borrow: Option<SharedBorrow<'a>>,
623 last_run: Option<TrackingTimestamp>,
624 current: TrackingTimestamp,
625 ) -> Result<Self::View<'a>, error::GetStorage> {
626 let view = all_storages.custom_storage_mut_by_id(StorageId::of::<UniqueStorage<T>>())?;
627 let view = ARefMut::map(view, |storage| {
628 storage
629 .as_any_mut()
630 .downcast_mut::<NonSendSync<UniqueStorage<T>>>()
631 .unwrap()
632 });
633
634 let (unique, borrow) = unsafe { ARefMut::destructure(view) };
635
636 Ok(NonSendSync(UniqueViewMut {
637 last_insertion: last_run.unwrap_or(unique.last_insert),
638 last_modification: last_run.unwrap_or(unique.last_modification),
639 current,
640 unique,
641 _borrow: Some(borrow),
642 _all_borrow: all_borrow,
643 }))
644 }
645}
646
647impl<T: Borrow> Borrow for Option<T> {
648 type View<'a> = Option<T::View<'a>>;
649
650 #[inline]
651 fn borrow<'a>(
652 all_storages: &'a AllStorages,
653 all_borrow: Option<SharedBorrow<'a>>,
654 last_run: Option<TrackingTimestamp>,
655 current: TrackingTimestamp,
656 ) -> Result<Self::View<'a>, error::GetStorage> {
657 Ok(T::borrow(all_storages, all_borrow, last_run, current).ok())
658 }
659}
660
661macro_rules! impl_borrow {
662 ($(($type: ident, $index: tt))+) => {
663 impl<$($type: Borrow),+> Borrow for ($($type,)+) {
664 type View<'a> = ($($type::View<'a>,)+);
665
666 #[inline]
667 fn borrow<'a>(
668 all_storages: &'a AllStorages,
669 all_borrow: Option<SharedBorrow<'a>>,
670 last_run: Option<TrackingTimestamp>,
671 current: TrackingTimestamp
672 ) -> Result<Self::View<'a>, error::GetStorage> {
673 Ok(($($type::borrow(all_storages, all_borrow.clone(), last_run, current)?,)+))
674 }
675 }
676 }
677}
678
679macro_rules! borrow {
680 ($(($type: ident, $index: tt))*;($type1: ident, $index1: tt) $(($queue_type: ident, $queue_index: tt))*) => {
681 impl_borrow![$(($type, $index))*];
682 borrow![$(($type, $index))* ($type1, $index1); $(($queue_type, $queue_index))*];
683 };
684 ($(($type: ident, $index: tt))*;) => {
685 impl_borrow![$(($type, $index))*];
686 }
687}
688
689#[cfg(not(feature = "extended_tuple"))]
690borrow![(A, 0); (B, 1) (C, 2) (D, 3) (E, 4) (F, 5) (G, 6) (H, 7) (I, 8) (J, 9)];
691#[cfg(feature = "extended_tuple")]
692borrow![
693 (A, 0); (B, 1) (C, 2) (D, 3) (E, 4) (F, 5) (G, 6) (H, 7) (I, 8) (J, 9)
694 (K, 10) (L, 11) (M, 12) (N, 13) (O, 14) (P, 15) (Q, 16) (R, 17) (S, 18) (T, 19)
695 (U, 20) (V, 21) (W, 22) (X, 23) (Y, 24) (Z, 25) (AA, 26) (BB, 27) (CC, 28) (DD, 29)
696 (EE, 30) (FF, 31)
697];