Skip to main content

shipyard/
world.rs

1mod builder;
2mod run_batches;
3
4pub use builder::WorldBuilder;
5
6use crate::all_storages::{
7    AllStorages, CustomStorageAccess, TupleClone, TupleDeleteAny, TupleRetainStorage,
8};
9use crate::atomic_refcell::{ARef, ARefMut, AtomicRefCell};
10use crate::borrow::WorldBorrow;
11use crate::component::{Component, Unique};
12use crate::entities::Entities;
13use crate::entity_id::EntityId;
14use crate::error;
15use crate::get_component::GetComponent;
16use crate::get_unique::GetUnique;
17use crate::iter::{ShiperatorCaptain, ShiperatorSailor};
18use crate::iter_component::{into_iter, IntoIterRef, IterComponent};
19use crate::memory_usage::WorldMemoryUsage;
20use crate::r#mut::Mut;
21use crate::reserve::BulkEntityIter;
22use crate::scheduler::info::WorkloadsInfo;
23use crate::scheduler::{AsLabel, Batches, Label, Scheduler};
24use crate::sparse_set::{BulkAddEntity, TupleAddComponent, TupleDelete, TupleRemove};
25use crate::storage::{Storage, StorageId};
26use crate::system::System;
27use crate::tracking::{TrackingTimestamp, TupleTrack};
28use crate::views::EntitiesViewMut;
29use alloc::boxed::Box;
30use alloc::format;
31use alloc::sync::Arc;
32use core::sync::atomic::AtomicU64;
33
34/// `World` contains all data this library will manipulate.
35pub struct World {
36    pub(crate) all_storages: AtomicRefCell<AllStorages>,
37    pub(crate) scheduler: AtomicRefCell<Scheduler>,
38    counter: Arc<AtomicU64>,
39    #[cfg(feature = "parallel")]
40    thread_pool: Option<rayon::ThreadPool>,
41}
42
43#[cfg(feature = "std")]
44impl Default for World {
45    /// Creates an empty `World`.
46    fn default() -> Self {
47        let counter = Arc::new(AtomicU64::new(1));
48        World {
49            #[cfg(not(feature = "thread_local"))]
50            all_storages: AtomicRefCell::new(AllStorages::new(counter.clone())),
51            #[cfg(feature = "thread_local")]
52            all_storages: AtomicRefCell::new_non_send(
53                AllStorages::new(counter.clone()),
54                Arc::new(crate::std_thread_id_generator),
55            ),
56            scheduler: AtomicRefCell::new(Default::default()),
57            counter,
58            #[cfg(feature = "parallel")]
59            thread_pool: None,
60        }
61    }
62}
63
64#[cfg(feature = "std")]
65impl Clone for World {
66    #[track_caller]
67    fn clone(&self) -> Self {
68        let mut other = World::new();
69
70        let other_all_storages = other.all_storages.get_mut();
71
72        self.all_storages
73            .borrow()
74            .unwrap()
75            .clone_storages_to(other_all_storages);
76
77        other
78    }
79}
80
81impl World {
82    /// Creates an empty `World`.
83    #[cfg(feature = "std")]
84    pub fn new() -> World {
85        Default::default()
86    }
87    /// Removes the local [`ThreadPool`](rayon::ThreadPool).
88    #[cfg(feature = "parallel")]
89    pub fn remove_local_thread_pool(&mut self) -> Option<rayon::ThreadPool> {
90        self.thread_pool.take()
91    }
92    /// Adds a new unique storage, unique storages store a single value.
93    /// To access a unique storage value, use [`UniqueView`] or [`UniqueViewMut`].
94    ///
95    /// ### Borrows
96    ///
97    /// - [`AllStorages`] (shared)
98    ///
99    /// ### Panics
100    ///
101    /// - [`AllStorages`] borrow failed.
102    ///
103    /// ### Example
104    ///
105    /// ```
106    /// use shipyard::{Unique, UniqueView, World};
107    ///
108    /// #[derive(Unique)]
109    /// struct U32(u32);
110    ///
111    /// let world = World::new();
112    ///
113    /// world.add_unique(U32(0));
114    ///
115    /// let i = world.borrow::<UniqueView<U32>>().unwrap();
116    /// assert_eq!(i.0, 0);
117    /// ```
118    ///
119    /// [`AllStorages`]: crate::all_storages::AllStorages
120    /// [`UniqueView`]: crate::UniqueView
121    /// [`UniqueViewMut`]: crate::UniqueViewMut
122    #[track_caller]
123    pub fn add_unique<T: Send + Sync + Unique>(&self, component: T) {
124        self.all_storages.borrow().unwrap().add_unique(component);
125    }
126    /// Adds a new unique storage, unique storages store a single value.
127    /// To access a `!Send` unique storage value, use [`NonSend`] with [`UniqueView`] or [`UniqueViewMut`].
128    /// Does nothing if the storage already exists.
129    ///
130    /// ### Borrows
131    ///
132    /// - [`AllStorages`] (shared)
133    ///
134    /// ### Panics
135    ///
136    /// - [`AllStorages`] borrow failed.
137    ///
138    /// ### Example
139    ///
140    /// ```
141    /// use shipyard::{borrow::NonSend, Unique, UniqueView, World};
142    ///
143    /// #[derive(Unique)]
144    /// struct U32(u32);
145    ///
146    /// let world = World::new();
147    ///
148    /// // I'm using `u32` here but imagine it's a `!Send` type
149    /// world.add_unique_non_send(U32(0));
150    ///
151    /// let i = world.borrow::<NonSend<UniqueView<U32>>>().unwrap();
152    /// assert_eq!(i.0, 0);
153    /// ```
154    ///
155    /// [`AllStorages`]: crate::all_storages::AllStorages
156    /// [`UniqueView`]: crate::UniqueView
157    /// [`UniqueViewMut`]: crate::UniqueViewMut
158    /// [`NonSend`]: crate::borrow::NonSend
159    #[cfg(feature = "thread_local")]
160    #[cfg_attr(docsrs, doc(cfg(feature = "thread_local")))]
161    #[track_caller]
162    pub fn add_unique_non_send<T: Sync + Unique>(&self, component: T) {
163        self.all_storages
164            .borrow()
165            .unwrap()
166            .add_unique_non_send(component);
167    }
168    /// Adds a new unique storage, unique storages store a single value.
169    /// To access a `!Sync` unique storage value, use [`NonSync`] with [`UniqueView`] or [`UniqueViewMut`].
170    /// Does nothing if the storage already exists.
171    ///
172    /// ### Borrows
173    ///
174    /// - [`AllStorages`] (shared)
175    ///
176    /// ### Panics
177    ///
178    /// - [`AllStorages`] borrow failed.
179    ///
180    /// ### Example
181    ///
182    /// ```
183    /// use shipyard::{borrow::NonSync, Unique, UniqueView, World};
184    ///
185    /// #[derive(Unique)]
186    /// struct U32(u32);
187    ///
188    /// let world = World::new();
189    ///
190    /// // I'm using `u32` here but imagine it's a `!Sync` type
191    /// world.add_unique_non_sync(U32(0));
192    ///
193    /// let i = world.borrow::<NonSync<UniqueView<U32>>>().unwrap();
194    /// assert_eq!(i.0, 0);
195    /// ```
196    ///
197    /// [`AllStorages`]: crate::all_storages::AllStorages
198    /// [`UniqueView`]: crate::UniqueView
199    /// [`UniqueViewMut`]: crate::UniqueViewMut
200    /// [`NonSync`]: crate::borrow::NonSync
201    #[cfg(feature = "thread_local")]
202    #[cfg_attr(docsrs, doc(cfg(feature = "thread_local")))]
203    #[track_caller]
204    pub fn add_unique_non_sync<T: Send + Unique>(&self, component: T) {
205        self.all_storages
206            .borrow()
207            .unwrap()
208            .add_unique_non_sync(component);
209    }
210    /// Adds a new unique storage, unique storages store a single value.
211    /// To access a `!Send + !Sync` unique storage value, use [`NonSendSync`] with [`UniqueView`] or [`UniqueViewMut`].
212    /// Does nothing if the storage already exists.
213    ///
214    /// ### Borrows
215    ///
216    /// - [`AllStorages`] (shared)
217    ///
218    /// ### Panics
219    ///
220    /// - [`AllStorages`] borrow failed.
221    ///
222    /// ### Example
223    ///
224    /// ```
225    /// use shipyard::{borrow::NonSendSync, Unique, UniqueView, World};
226    ///
227    /// let world = World::new();
228    ///
229    /// #[derive(Unique)]
230    /// struct U32(u32);
231    ///
232    /// // I'm using `u32` here but imagine it's a `!Send + !Sync` type
233    /// world.add_unique_non_send_sync(U32(0));
234    ///
235    /// let i = world.borrow::<NonSendSync<UniqueView<U32>>>().unwrap();
236    /// assert_eq!(i.0, 0);
237    /// ```
238    ///
239    /// [`AllStorages`]: crate::all_storages::AllStorages
240    /// [`UniqueView`]: crate::UniqueView
241    /// [`UniqueViewMut`]: crate::UniqueViewMut
242    /// [`NonSendSync`]: crate::borrow::NonSync
243    #[cfg(feature = "thread_local")]
244    #[cfg_attr(docsrs, doc(cfg(feature = "thread_local")))]
245    #[track_caller]
246    pub fn add_unique_non_send_sync<T: Unique>(&self, component: T) {
247        self.all_storages
248            .borrow()
249            .unwrap()
250            .add_unique_non_send_sync(component);
251    }
252    /// Removes a unique storage.
253    ///
254    /// ### Borrows
255    ///
256    /// - [`AllStorages`] (shared)
257    /// - `Unique<T>` storage (exclusive)
258    ///
259    /// ### Errors
260    ///
261    /// - [`AllStorages`] borrow failed.
262    /// - `Unique<T>` storage borrow failed.
263    /// - `Unique<T>` storage did not exist.
264    ///
265    /// ### Example
266    ///
267    /// ```
268    /// use shipyard::{Unique, UniqueView, World};
269    ///
270    /// #[derive(Unique, Debug)]
271    /// struct U32(u32);
272    ///
273    /// let world = World::new();
274    ///
275    /// world.add_unique(U32(0));
276    ///
277    /// let i = world.remove_unique::<U32>().unwrap();
278    /// assert_eq!(i.0, 0);
279    /// ```
280    ///
281    /// [`AllStorages`]: crate::all_storages::AllStorages
282    pub fn remove_unique<T: Unique>(&self) -> Result<T, error::UniqueRemove> {
283        self.all_storages
284            .borrow()
285            .map_err(|_| error::UniqueRemove::AllStorages)?
286            .remove_unique::<T>()
287    }
288    #[doc = "Borrows the requested storages, if they don't exist they'll get created.
289You can use a tuple to get multiple storages at once.
290
291You can use:
292* [View]\\<T\\> for a shared access to `T` storage
293* [ViewMut]\\<T\\> for an exclusive access to `T` storage
294* [EntitiesView] for a shared access to the entity storage
295* [EntitiesViewMut] for an exclusive reference to the entity storage
296* [AllStoragesViewMut] for an exclusive access to the storage of all components, ⚠️ can't coexist with any other storage borrow
297* [UniqueView]\\<T\\> for a shared access to a `T` unique storage
298* [UniqueViewMut]\\<T\\> for an exclusive access to a `T` unique storage
299* `Option<V>` with one or multiple views for fallible access to one or more storages"]
300    #[cfg_attr(
301        all(feature = "thread_local", docsrs),
302        doc = "* <span style=\"display: table;color: #2f2f2f;background-color: #C4ECFF;border-width: 1px;border-style: solid;border-color: #7BA5DB;padding: 3px;margin-bottom: 5px; font-size: 90%\">This is supported on <strong><code style=\"background-color: #C4ECFF\">feature=\"thread_local\"</code></strong> only:</span>"
303    )]
304    #[cfg_attr(
305        all(feature = "thread_local", docsrs),
306        doc = "    * [NonSend]<[View]\\<T\\>> for a shared access to a `T` storage where `T` isn't `Send`
307    * [NonSend]<[ViewMut]\\<T\\>> for an exclusive access to a `T` storage where `T` isn't `Send`
308[NonSend] and [UniqueView]/[UniqueViewMut] can be used together to access a `!Send` unique storage."
309    )]
310    #[cfg_attr(
311        all(feature = "thread_local", not(docsrs)),
312        doc = "* [NonSend]<[View]\\<T\\>> for a shared access to a `T` storage where `T` isn't `Send`
313* [NonSend]<[ViewMut]\\<T\\>> for an exclusive access to a `T` storage where `T` isn't `Send`
314[NonSend] and [UniqueView]/[UniqueViewMut] can be used together to access a `!Send` unique storage."
315    )]
316    #[cfg_attr(
317        not(feature = "thread_local"),
318        doc = "* NonSend: must activate the *thread_local* feature"
319    )]
320    #[cfg_attr(
321        all(feature = "thread_local", docsrs),
322        doc = "    * [NonSync]<[View]\\<T\\>> for a shared access to a `T` storage where `T` isn't `Sync`
323    * [NonSync]<[ViewMut]\\<T\\>> for an exclusive access to a `T` storage where `T` isn't `Sync`
324[NonSync] and [UniqueView]/[UniqueViewMut] can be used together to access a `!Sync` unique storage."
325    )]
326    #[cfg_attr(
327        all(feature = "thread_local", not(docsrs)),
328        doc = "* [NonSync]<[View]\\<T\\>> for a shared access to a `T` storage where `T` isn't `Sync`
329* [NonSync]<[ViewMut]\\<T\\>> for an exclusive access to a `T` storage where `T` isn't `Sync`
330[NonSync] and [UniqueView]/[UniqueViewMut] can be used together to access a `!Sync` unique storage."
331    )]
332    #[cfg_attr(
333        not(feature = "thread_local"),
334        doc = "* NonSync: must activate the *thread_local* feature"
335    )]
336    #[cfg_attr(
337        all(feature = "thread_local", docsrs),
338        doc = "    * [NonSendSync]<[View]\\<T\\>> for a shared access to a `T` storage where `T` isn't `Send` nor `Sync`
339    * [NonSendSync]<[ViewMut]\\<T\\>> for an exclusive access to a `T` storage where `T` isn't `Send` nor `Sync`
340[NonSendSync] and [UniqueView]/[UniqueViewMut] can be used together to access a `!Send + !Sync` unique storage."
341    )]
342    #[cfg_attr(
343        all(feature = "thread_local", not(docsrs)),
344        doc = "* [NonSendSync]<[View]\\<T\\>> for a shared access to a `T` storage where `T` isn't `Send` nor `Sync`
345* [NonSendSync]<[ViewMut]\\<T\\>> for an exclusive access to a `T` storage where `T` isn't `Send` nor `Sync`
346[NonSendSync] and [UniqueView]/[UniqueViewMut] can be used together to access a `!Send + !Sync` unique storage."
347    )]
348    #[cfg_attr(
349        not(feature = "thread_local"),
350        doc = "* NonSendSync: must activate the *thread_local* feature"
351    )]
352    #[doc = "
353### Borrows
354
355- [AllStorages] (exclusive) when requesting [AllStoragesViewMut]
356- [AllStorages] (shared) + storage (exclusive or shared) for all other views
357
358### Errors
359
360- [AllStorages] borrow failed.
361- Storage borrow failed.
362- Unique storage did not exist.
363
364### Example
365```
366use shipyard::{Component, EntitiesView, View, ViewMut, World};
367
368#[derive(Component)]
369struct U32(u32);
370
371#[derive(Component)]
372struct USIZE(usize);
373
374let world = World::new();
375
376let u32s = world.borrow::<View<U32>>().unwrap();
377let (entities, mut usizes) = world
378    .borrow::<(EntitiesView, ViewMut<USIZE>)>()
379    .unwrap();
380```
381[AllStorages]: crate::all_storages::AllStorages
382[EntitiesView]: crate::EntitiesView
383[EntitiesViewMut]: crate::EntitiesViewMut
384[AllStoragesViewMut]: crate::AllStoragesViewMut
385[World]: crate::World
386[View]: crate::View
387[ViewMut]: crate::ViewMut
388[UniqueView]: crate::UniqueView
389[UniqueViewMut]: crate::UniqueViewMut"]
390    #[cfg_attr(feature = "thread_local", doc = "[NonSend]: crate::borrow::NonSend")]
391    #[cfg_attr(feature = "thread_local", doc = "[NonSync]: crate::borrow::NonSync")]
392    #[cfg_attr(
393        feature = "thread_local",
394        doc = "[NonSendSync]: crate::borrow::NonSendSync"
395    )]
396    pub fn borrow<V: WorldBorrow>(&self) -> Result<V::WorldView<'_>, error::GetStorage> {
397        let current = self.get_current();
398
399        V::world_borrow(self, None, current)
400    }
401    #[doc = "Borrows the requested storages, runs the function and evaluates to the function's return value.
402Data can be passed to the function, this always has to be a single type but you can use a tuple if needed.
403
404You can use:
405* [View]\\<T\\> for a shared access to `T` storage
406* [ViewMut]\\<T\\> for an exclusive access to `T` storage
407* [EntitiesView] for a shared access to the entity storage
408* [EntitiesViewMut] for an exclusive reference to the entity storage
409* [AllStoragesViewMut] for an exclusive access to the storage of all components, ⚠️ can't coexist with any other storage borrow
410* [UniqueView]\\<T\\> for a shared access to a `T` unique storage
411* [UniqueViewMut]\\<T\\> for an exclusive access to a `T` unique storage
412* `Option<V>` with one or multiple views for fallible access to one or more storages"]
413    #[cfg_attr(
414        all(feature = "thread_local", docsrs),
415        doc = "* <span style=\"display: table;color: #2f2f2f;background-color: #C4ECFF;border-width: 1px;border-style: solid;border-color: #7BA5DB;padding: 3px;margin-bottom: 5px; font-size: 90%\">This is supported on <strong><code style=\"background-color: #C4ECFF\">feature=\"thread_local\"</code></strong> only:</span>"
416    )]
417    #[cfg_attr(
418        all(feature = "thread_local", docsrs),
419        doc = "    * [NonSend]<[View]\\<T\\>> for a shared access to a `T` storage where `T` isn't `Send`
420    * [NonSend]<[ViewMut]\\<T\\>> for an exclusive access to a `T` storage where `T` isn't `Send`
421[NonSend] and [UniqueView]/[UniqueViewMut] can be used together to access a `!Send` unique storage."
422    )]
423    #[cfg_attr(
424        all(feature = "thread_local", not(docsrs)),
425        doc = "* [NonSend]<[View]\\<T\\>> for a shared access to a `T` storage where `T` isn't `Send`
426* [NonSend]<[ViewMut]\\<T\\>> for an exclusive access to a `T` storage where `T` isn't `Send`
427[NonSend] and [UniqueView]/[UniqueViewMut] can be used together to access a `!Send` unique storage."
428    )]
429    #[cfg_attr(
430        not(feature = "thread_local"),
431        doc = "* NonSend: must activate the *thread_local* feature"
432    )]
433    #[cfg_attr(
434        all(feature = "thread_local", docsrs),
435        doc = "    * [NonSync]<[View]\\<T\\>> for a shared access to a `T` storage where `T` isn't `Sync`
436    * [NonSync]<[ViewMut]\\<T\\>> for an exclusive access to a `T` storage where `T` isn't `Sync`
437[NonSync] and [UniqueView]/[UniqueViewMut] can be used together to access a `!Sync` unique storage."
438    )]
439    #[cfg_attr(
440        all(feature = "thread_local", not(docsrs)),
441        doc = "* [NonSync]<[View]\\<T\\>> for a shared access to a `T` storage where `T` isn't `Sync`
442* [NonSync]<[ViewMut]\\<T\\>> for an exclusive access to a `T` storage where `T` isn't `Sync`
443[NonSync] and [UniqueView]/[UniqueViewMut] can be used together to access a `!Sync` unique storage."
444    )]
445    #[cfg_attr(
446        not(feature = "thread_local"),
447        doc = "* NonSync: must activate the *thread_local* feature"
448    )]
449    #[cfg_attr(
450        all(feature = "thread_local", docsrs),
451        doc = "    * [NonSendSync]<[View]\\<T\\>> for a shared access to a `T` storage where `T` isn't `Send` nor `Sync`
452    * [NonSendSync]<[ViewMut]\\<T\\>> for an exclusive access to a `T` storage where `T` isn't `Send` nor `Sync`
453[NonSendSync] and [UniqueView]/[UniqueViewMut] can be used together to access a `!Send + !Sync` unique storage."
454    )]
455    #[cfg_attr(
456        all(feature = "thread_local", not(docsrs)),
457        doc = "* [NonSendSync]<[View]\\<T\\>> for a shared access to a `T` storage where `T` isn't `Send` nor `Sync`
458* [NonSendSync]<[ViewMut]\\<T\\>> for an exclusive access to a `T` storage where `T` isn't `Send` nor `Sync`
459[NonSendSync] and [UniqueView]/[UniqueViewMut] can be used together to access a `!Send + !Sync` unique storage."
460    )]
461    #[cfg_attr(
462        not(feature = "thread_local"),
463        doc = "* NonSendSync: must activate the *thread_local* feature"
464    )]
465    #[doc = "
466### Borrows
467
468- [AllStorages] (exclusive) when requesting [AllStoragesViewMut]
469- [AllStorages] (shared) + storage (exclusive or shared) for all other views
470
471### Panics
472
473- [AllStorages] borrow failed.
474- Storage borrow failed.
475- Unique storage did not exist.
476- Error returned by user.
477
478### Example
479```
480use shipyard::{Component, EntityId, Get, ViewMut, World};
481
482#[derive(Component)]
483struct Position([f32; 2]);
484
485fn sys1((entity, [x, y]): (EntityId, [f32; 2]), mut positions: ViewMut<Position>) {
486    if let Ok(mut pos) = (&mut positions).get(entity) {
487        pos.0 = [x, y];
488    }
489}
490
491let world = World::new();
492
493world.run_with_data(sys1, (EntityId::dead(), [0., 0.]));
494```
495[AllStorages]: crate::all_storages::AllStorages
496[EntitiesView]: crate::EntitiesView
497[EntitiesViewMut]: crate::EntitiesViewMut
498[AllStoragesViewMut]: crate::AllStoragesViewMut
499[World]: crate::World
500[View]: crate::View
501[ViewMut]: crate::ViewMut
502[UniqueView]: crate::UniqueView
503[UniqueViewMut]: crate::UniqueViewMut"]
504    #[cfg_attr(feature = "thread_local", doc = "[NonSend]: crate::borrow::NonSend")]
505    #[cfg_attr(feature = "thread_local", doc = "[NonSync]: crate::borrow::NonSync")]
506    #[cfg_attr(
507        feature = "thread_local",
508        doc = "[NonSendSync]: crate::borrow::NonSendSync"
509    )]
510    #[track_caller]
511    pub fn run_with_data<Data, B, S: System<(Data,), B>>(
512        &self,
513        system: S,
514        data: Data,
515    ) -> S::Return {
516        #[cfg(feature = "tracing")]
517        let system_span = tracing::info_span!("system", name = ?core::any::type_name::<S>());
518        #[cfg(feature = "tracing")]
519        let _system_span = system_span.enter();
520
521        system
522            .run((data,), self)
523            .map_err(error::Run::GetStorage)
524            .unwrap()
525    }
526    #[doc = "Borrows the requested storages, runs the function and evaluates to the function's return value.
527
528You can use:
529* [View]\\<T\\> for a shared access to `T` storage
530* [ViewMut]\\<T\\> for an exclusive access to `T` storage
531* [EntitiesView] for a shared access to the entity storage
532* [EntitiesViewMut] for an exclusive reference to the entity storage
533* [AllStoragesViewMut] for an exclusive access to the storage of all components, ⚠️ can't coexist with any other storage borrow
534* [UniqueView]\\<T\\> for a shared access to a `T` unique storage
535* [UniqueViewMut]\\<T\\> for an exclusive access to a `T` unique storage
536* `Option<V>` with one or multiple views for fallible access to one or more storages"]
537    #[cfg_attr(
538        all(feature = "thread_local", docsrs),
539        doc = "* <span style=\"display: table;color: #2f2f2f;background-color: #C4ECFF;border-width: 1px;border-style: solid;border-color: #7BA5DB;padding: 3px;margin-bottom: 5px; font-size: 90%\">This is supported on <strong><code style=\"background-color: #C4ECFF\">feature=\"thread_local\"</code></strong> only:</span>"
540    )]
541    #[cfg_attr(
542        all(feature = "thread_local", docsrs),
543        doc = "    * [NonSend]<[View]\\<T\\>> for a shared access to a `T` storage where `T` isn't `Send`
544    * [NonSend]<[ViewMut]\\<T\\>> for an exclusive access to a `T` storage where `T` isn't `Send`
545[NonSend] and [UniqueView]/[UniqueViewMut] can be used together to access a `!Send` unique storage."
546    )]
547    #[cfg_attr(
548        all(feature = "thread_local", not(docsrs)),
549        doc = "* [NonSend]<[View]\\<T\\>> for a shared access to a `T` storage where `T` isn't `Send`
550* [NonSend]<[ViewMut]\\<T\\>> for an exclusive access to a `T` storage where `T` isn't `Send`
551[NonSend] and [UniqueView]/[UniqueViewMut] can be used together to access a `!Send` unique storage."
552    )]
553    #[cfg_attr(
554        not(feature = "thread_local"),
555        doc = "* NonSend: must activate the *thread_local* feature"
556    )]
557    #[cfg_attr(
558        all(feature = "thread_local", docsrs),
559        doc = "    * [NonSync]<[View]\\<T\\>> for a shared access to a `T` storage where `T` isn't `Sync`
560    * [NonSync]<[ViewMut]\\<T\\>> for an exclusive access to a `T` storage where `T` isn't `Sync`
561[NonSync] and [UniqueView]/[UniqueViewMut] can be used together to access a `!Sync` unique storage."
562    )]
563    #[cfg_attr(
564        all(feature = "thread_local", not(docsrs)),
565        doc = "* [NonSync]<[View]\\<T\\>> for a shared access to a `T` storage where `T` isn't `Sync`
566* [NonSync]<[ViewMut]\\<T\\>> for an exclusive access to a `T` storage where `T` isn't `Sync`
567[NonSync] and [UniqueView]/[UniqueViewMut] can be used together to access a `!Sync` unique storage."
568    )]
569    #[cfg_attr(
570        not(feature = "thread_local"),
571        doc = "* NonSync: must activate the *thread_local* feature"
572    )]
573    #[cfg_attr(
574        all(feature = "thread_local", docsrs),
575        doc = "    * [NonSendSync]<[View]\\<T\\>> for a shared access to a `T` storage where `T` isn't `Send` nor `Sync`
576    * [NonSendSync]<[ViewMut]\\<T\\>> for an exclusive access to a `T` storage where `T` isn't `Send` nor `Sync`
577[NonSendSync] and [UniqueView]/[UniqueViewMut] can be used together to access a `!Send + !Sync` unique storage."
578    )]
579    #[cfg_attr(
580        all(feature = "thread_local", not(docsrs)),
581        doc = "* [NonSendSync]<[View]\\<T\\>> for a shared access to a `T` storage where `T` isn't `Send` nor `Sync`
582* [NonSendSync]<[ViewMut]\\<T\\>> for an exclusive access to a `T` storage where `T` isn't `Send` nor `Sync`
583[NonSendSync] and [UniqueView]/[UniqueViewMut] can be used together to access a `!Send + !Sync` unique storage."
584    )]
585    #[cfg_attr(
586        not(feature = "thread_local"),
587        doc = "* NonSendSync: must activate the *thread_local* feature"
588    )]
589    #[doc = "
590### Borrows
591
592- [AllStorages] (exclusive) when requesting [AllStoragesViewMut]
593- [AllStorages] (shared) + storage (exclusive or shared) for all other views
594
595### Panics
596
597- [AllStorages] borrow failed.
598- Storage borrow failed.
599- Unique storage did not exist.
600- Error returned by user.
601
602### Example
603```
604use shipyard::{Component, View, ViewMut, World};
605
606#[derive(Component)]
607struct I32(i32);
608
609#[derive(Component)]
610struct USIZE(usize);
611
612#[derive(Component)]
613struct U32(u32);
614
615fn sys1(i32s: View<I32>) -> i32 {
616    0
617}
618
619let world = World::new();
620
621world
622    .run(|usizes: View<USIZE>, mut u32s: ViewMut<U32>| {
623        // -- snip --
624    });
625
626let i = world.run(sys1);
627```
628[AllStorages]: crate::all_storages::AllStorages
629[EntitiesView]: crate::EntitiesView
630[EntitiesViewMut]: crate::EntitiesViewMut
631[AllStoragesViewMut]: crate::AllStoragesViewMut
632[World]: crate::World
633[View]: crate::View
634[ViewMut]: crate::ViewMut
635[UniqueView]: crate::UniqueView
636[UniqueViewMut]: crate::UniqueViewMut"]
637    #[cfg_attr(feature = "thread_local", doc = "[NonSend]: crate::borrow::NonSend")]
638    #[cfg_attr(feature = "thread_local", doc = "[NonSync]: crate::borrow::NonSync")]
639    #[cfg_attr(
640        feature = "thread_local",
641        doc = "[NonSendSync]: crate::borrow::NonSendSync"
642    )]
643    #[track_caller]
644    pub fn run<B, S: System<(), B>>(&self, system: S) -> S::Return {
645        #[cfg(feature = "tracing")]
646        let system_span = tracing::info_span!("system", name = ?core::any::type_name::<S>());
647        #[cfg(feature = "tracing")]
648        let _system_span = system_span.enter();
649
650        system
651            .run((), self)
652            .map_err(error::Run::GetStorage)
653            .unwrap()
654    }
655    /// Modifies the current default workload to `name`.
656    ///
657    /// ### Borrows
658    ///
659    /// - Scheduler (exclusive)
660    ///
661    /// ### Errors
662    ///
663    /// - Scheduler borrow failed.
664    /// - Workload did not exist.
665    pub fn set_default_workload<T>(
666        &self,
667        name: impl AsLabel<T>,
668    ) -> Result<(), error::SetDefaultWorkload> {
669        self.scheduler
670            .borrow_mut()
671            .map_err(|_| error::SetDefaultWorkload::Borrow)?
672            .set_default(name.as_label())
673    }
674    /// Changes the name of a workload if it exists.
675    ///
676    /// ### Borrows
677    ///
678    /// - Scheduler (exclusive)
679    ///
680    /// ### Panics
681    ///
682    /// - Scheduler borrow failed.
683    #[track_caller]
684    pub fn rename_workload<T, U>(&self, old_name: impl AsLabel<T>, new_name: impl AsLabel<U>) {
685        let old_label = old_name.as_label();
686        let new_label = new_name.as_label();
687
688        self.scheduler
689            .borrow_mut()
690            .unwrap()
691            .rename(&old_label, Box::new(new_label));
692    }
693    /// Runs the `name` workload.
694    ///
695    /// ### Borrows
696    ///
697    /// - Scheduler (shared)
698    /// - Systems' borrow as they are executed
699    ///
700    /// ### Errors
701    ///
702    /// - Scheduler borrow failed.
703    /// - Workload did not exist.
704    /// - Storage borrow failed.
705    /// - User error returned by system.
706    pub fn run_workload<T>(&self, label: impl AsLabel<T>) -> Result<(), error::RunWorkload> {
707        let scheduler = self
708            .scheduler
709            .borrow()
710            .map_err(|_| error::RunWorkload::Scheduler)?;
711
712        let label = label.as_label();
713        let batches = scheduler.workload(&*label)?;
714
715        self.run_batches(
716            &scheduler.systems,
717            &scheduler.system_names,
718            batches,
719            &*label,
720        )
721    }
722    /// Returns `true` if the world contains the `name` workload.
723    ///
724    /// ### Borrows
725    ///
726    /// - Scheduler (shared)
727    ///
728    /// ### Panics
729    ///
730    /// - Scheduler borrow failed.
731    ///
732    /// ### Example
733    /// ```
734    /// use shipyard::{Workload, World};
735    ///
736    /// let world = World::new();
737    ///
738    /// Workload::new("foo").add_to_world(&world).unwrap();
739    ///
740    /// assert!(world.contains_workload("foo"));
741    /// assert!(!world.contains_workload("bar"));
742    /// ```
743    #[track_caller]
744    pub fn contains_workload<T>(&self, name: impl AsLabel<T>) -> bool {
745        let label = name.as_label();
746
747        self.scheduler.borrow().unwrap().contains_workload(&*label)
748    }
749    #[allow(clippy::type_complexity)]
750    pub(crate) fn run_batches(
751        &self,
752        systems: &[Box<dyn Fn(&World) -> Result<(), error::Run> + Send + Sync + 'static>],
753        system_names: &[Box<dyn Label>],
754        batches: &Batches,
755        workload_name: &dyn Label,
756    ) -> Result<(), error::RunWorkload> {
757        if let Some(run_if) = &batches.workload_run_if {
758            if !run_if
759                .run(self)
760                .map_err(|err| error::RunWorkload::Run((workload_name.dyn_clone(), err)))?
761            {
762                return Ok(());
763            }
764        }
765
766        #[cfg(feature = "parallel")]
767        {
768            self.run_batches_parallel(systems, system_names, batches, workload_name)
769        }
770
771        #[cfg(not(feature = "parallel"))]
772        {
773            self.run_batches_sequential(systems, system_names, batches, workload_name)
774        }
775    }
776    /// Run the default workload if there is one.
777    ///
778    /// ### Borrows
779    ///
780    /// - Scheduler (shared)
781    /// - Systems' borrow as they are executed
782    ///
783    /// ### Errors
784    ///
785    /// - Scheduler borrow failed.
786    /// - Storage borrow failed.
787    /// - User error returned by system.
788    pub fn run_default_workload(&self) -> Result<(), error::RunWorkload> {
789        let scheduler = self
790            .scheduler
791            .borrow()
792            .map_err(|_| error::RunWorkload::Scheduler)?;
793
794        if !scheduler.is_empty() {
795            self.run_batches(
796                &scheduler.systems,
797                &scheduler.system_names,
798                scheduler.default_workload(),
799                &scheduler.default,
800            )?
801        }
802        Ok(())
803    }
804    /// Returns a `Ref<&AllStorages>`, used to implement custom storages.
805    /// To borrow `AllStorages` you should use `borrow` or `run` with `AllStoragesViewMut`.
806    ///
807    /// ### Errors
808    ///
809    /// - `AllStorages` is already borrowed.
810    pub fn all_storages(&self) -> Result<ARef<'_, &'_ AllStorages>, error::Borrow> {
811        self.all_storages.borrow()
812    }
813    /// Returns a `RefMut<&mut AllStorages>`, used to implement custom storages.
814    /// To borrow `AllStorages` you should use `borrow` or `run` with `AllStoragesViewMut`.
815    ///
816    /// ### Errors
817    ///
818    /// - `AllStorages` is already borrowed.
819    pub fn all_storages_mut(&self) -> Result<ARefMut<'_, &'_ mut AllStorages>, error::Borrow> {
820        self.all_storages.borrow_mut()
821    }
822    /// Inserts a custom storage to the `World`.
823    ///
824    /// ### Errors
825    ///
826    /// - `AllStorages` is already borrowed exclusively.
827    pub fn add_custom_storage<S: 'static + Storage + Send + Sync>(
828        &self,
829        storage_id: StorageId,
830        storage: S,
831    ) -> Result<(), error::Borrow> {
832        let _ = self
833            .all_storages
834            .borrow()?
835            .custom_storage_or_insert_by_id(storage_id, || storage);
836
837        Ok(())
838    }
839
840    /// Increments the current tracking cycle and returns the previous value.
841    #[inline]
842    pub(crate) fn get_current(&self) -> TrackingTimestamp {
843        TrackingTimestamp::new(
844            self.counter
845                .fetch_add(1, core::sync::atomic::Ordering::Acquire),
846        )
847    }
848
849    /// Returns a timestamp used to clear tracking information.
850    pub fn get_tracking_timestamp(&self) -> TrackingTimestamp {
851        TrackingTimestamp::new(self.counter.load(core::sync::atomic::Ordering::Acquire))
852    }
853}
854
855impl World {
856    /// Creates a new entity with the components passed as argument and returns its `EntityId`.
857    /// `component` must always be a tuple, even for a single component.
858    ///
859    /// ### Example
860    ///
861    /// ```
862    /// use shipyard::{Component, World};
863    ///
864    /// #[derive(Component)]
865    /// struct U32(u32);
866    ///
867    /// #[derive(Component)]
868    /// struct USIZE(usize);
869    ///
870    /// let mut world = World::new();
871    ///
872    /// let entity0 = world.add_entity((U32(0),));
873    /// let entity1 = world.add_entity((U32(1), USIZE(11)));
874    /// ```
875    #[inline]
876    #[track_caller]
877    pub fn add_entity<C: TupleAddComponent>(&mut self, component: C) -> EntityId {
878        self.all_storages.get_mut().add_entity(component)
879    }
880    /// Creates multiple new entities and returns an iterator yielding the new `EntityId`s.
881    /// `source` must always yield a tuple, even for a single component.
882    ///
883    /// ### Example
884    ///
885    /// ```
886    /// use shipyard::{Component, World};
887    ///
888    /// #[derive(Component)]
889    /// struct U32(u32);
890    ///
891    /// #[derive(Component)]
892    /// struct USIZE(usize);
893    ///
894    /// let mut world = World::new();
895    ///
896    /// let new_entities = world.bulk_add_entity((10..20).map(|i| (U32(i as u32), USIZE(i))));
897    /// ```
898    #[inline]
899    #[track_caller]
900    pub fn bulk_add_entity<T: BulkAddEntity>(&mut self, source: T) -> BulkEntityIter<'_> {
901        self.all_storages.get_mut().bulk_add_entity(source)
902    }
903    /// Adds components to an existing entity.
904    /// If the entity already owned a component it will be replaced.
905    /// `component` must always be a tuple, even for a single component.
906    ///
907    /// ### Panics
908    ///
909    /// - `entity` is not alive.
910    ///
911    /// ### Example
912    ///
913    /// ```
914    /// use shipyard::{Component, World};
915    ///
916    /// #[derive(Component)]
917    /// struct U32(u32);
918    ///
919    /// #[derive(Component)]
920    /// struct USIZE(usize);
921    ///
922    /// let mut world = World::new();
923    ///
924    /// // make an empty entity
925    /// let entity = world.add_entity(());
926    ///
927    /// world.add_component(entity, (U32(0),));
928    /// // entity already had a `U32` component so it will be replaced
929    /// world.add_component(entity, (U32(1), USIZE(11)));
930    /// ```
931    #[inline]
932    #[track_caller]
933    pub fn add_component<C: TupleAddComponent>(&mut self, entity: EntityId, component: C) {
934        self.all_storages.get_mut().add_component(entity, component)
935    }
936    /// Deletes components from an entity. As opposed to `remove`, `delete` doesn't return anything.
937    /// `C` must always be a tuple, even for a single component.
938    ///
939    /// ### Example
940    ///
941    /// ```
942    /// use shipyard::{Component, World};
943    ///
944    /// #[derive(Component, Debug, PartialEq, Eq)]
945    /// struct U32(u32);
946    ///
947    /// #[derive(Component)]
948    /// struct USIZE(usize);
949    ///
950    /// let mut world = World::new();
951    ///
952    /// let entity = world.add_entity((U32(0), USIZE(1)));
953    ///
954    /// world.delete_component::<(U32,)>(entity);
955    /// ```
956    #[inline]
957    #[track_caller]
958    pub fn delete_component<C: TupleDelete>(&mut self, entity: EntityId) {
959        self.all_storages.get_mut().delete_component::<C>(entity)
960    }
961    /// Removes components from an entity.
962    /// `C` must always be a tuple, even for a single component.
963    ///
964    /// ### Example
965    ///
966    /// ```
967    /// use shipyard::{Component, World};
968    ///
969    /// #[derive(Component, Debug, PartialEq, Eq)]
970    /// struct U32(u32);
971    ///
972    /// #[derive(Component)]
973    /// struct USIZE(usize);
974    ///
975    /// let mut world = World::new();
976    ///
977    /// let entity = world.add_entity((U32(0), USIZE(1)));
978    ///
979    /// let (i,) = world.remove::<(U32,)>(entity);
980    /// assert_eq!(i, Some(U32(0)));
981    /// ```
982    #[inline]
983    #[track_caller]
984    pub fn remove<C: TupleRemove>(&mut self, entity: EntityId) -> C::Out {
985        self.all_storages.get_mut().remove::<C>(entity)
986    }
987    /// Deletes an entity with all its components. Returns true if the entity were alive.
988    ///
989    /// ### Example
990    ///
991    /// ```
992    /// use shipyard::{Component, World};
993    ///
994    /// #[derive(Component)]
995    /// struct U32(u32);
996    ///
997    /// #[derive(Component)]
998    /// struct USIZE(usize);
999    ///
1000    /// let mut world = World::new();
1001    ///
1002    /// let entity = world.add_entity((U32(0), USIZE(1)));
1003    ///
1004    /// assert!(world.delete_entity(entity));
1005    /// ```
1006    #[inline]
1007    #[track_caller]
1008    pub fn delete_entity(&mut self, entity: EntityId) -> bool {
1009        self.all_storages.get_mut().delete_entity(entity)
1010    }
1011    /// Deletes all components of an entity without deleting the entity.
1012    ///
1013    /// ### Example
1014    ///
1015    /// ```
1016    /// use shipyard::{Component, World};
1017    ///
1018    /// #[derive(Component)]
1019    /// struct U32(u32);
1020    ///
1021    /// #[derive(Component)]
1022    /// struct USIZE(usize);
1023    ///
1024    /// let mut world = World::new();
1025    ///
1026    /// let entity = world.add_entity((U32(0), USIZE(1)));
1027    ///
1028    /// world.strip(entity);
1029    /// ```
1030    #[inline]
1031    #[track_caller]
1032    pub fn strip(&mut self, entity: EntityId) {
1033        self.all_storages.get_mut().strip(entity);
1034    }
1035
1036    /// Deletes all components of multiple entities without deleting them.
1037    ///
1038    /// ### Example
1039    ///
1040    /// ```
1041    /// use shipyard::{Component, View, World};
1042    ///
1043    /// #[derive(Component)]
1044    /// struct U32(u32);
1045    ///
1046    /// #[derive(Component)]
1047    /// struct USIZE(usize);
1048    ///
1049    /// let mut world = World::new();
1050    ///
1051    /// let eid0 = world.add_entity((U32(0), USIZE(1)));
1052    /// let eid1 = world.add_entity(USIZE(10));
1053    /// let eid2 = world.add_entity(U32(30));
1054    ///
1055    /// world.bulk_strip([eid0, eid1, eid2]);
1056    ///
1057    /// let (v_u32, v_usize) = world.borrow::<(View<U32>, View<USIZE>)>().unwrap();
1058    /// assert_eq!(v_u32.len(), 0);
1059    /// assert_eq!(v_usize.len(), 0);
1060    /// ```
1061    #[inline]
1062    #[track_caller]
1063    pub fn bulk_strip<I: IntoIterator<Item = EntityId>>(&mut self, entities: I)
1064    where
1065        I::IntoIter: Clone,
1066    {
1067        self.all_storages.get_mut().bulk_strip(entities);
1068    }
1069
1070    /// Deletes in parallel all components of multiple entities without deleting them.
1071    ///
1072    /// ### Example
1073    ///
1074    /// ```
1075    /// use shipyard::{Component, View, World};
1076    ///
1077    /// #[derive(Component)]
1078    /// struct U32(u32);
1079    ///
1080    /// #[derive(Component)]
1081    /// struct USIZE(usize);
1082    ///
1083    /// let mut world = World::new();
1084    ///
1085    /// let eid0 = world.add_entity((U32(0), USIZE(1)));
1086    /// let eid1 = world.add_entity(USIZE(10));
1087    /// let eid2 = world.add_entity(U32(30));
1088    ///
1089    /// world.par_strip([eid0, eid1, eid2]);
1090    ///
1091    /// let (v_u32, v_usize) = world.borrow::<(View<U32>, View<USIZE>)>().unwrap();
1092    /// assert_eq!(v_u32.len(), 0);
1093    /// assert_eq!(v_usize.len(), 0);
1094    /// ```
1095    #[inline]
1096    #[track_caller]
1097    #[cfg(all(feature = "parallel", not(feature = "thread_local")))]
1098    pub fn par_strip<I: IntoIterator<Item = EntityId>>(&mut self, entities: I)
1099    where
1100        I::IntoIter: Clone + Sync,
1101    {
1102        self.all_storages.get_mut().par_strip(entities);
1103    }
1104
1105    /// Deletes all entities with any of the given components.
1106    /// The storage's type has to be used and not the component.
1107    /// `SparseSet` is the default storage.
1108    ///
1109    /// ### Example
1110    ///
1111    /// ```
1112    /// use shipyard::{Component, sparse_set::SparseSet, World};
1113    ///
1114    /// #[derive(Component)]
1115    /// struct U32(u32);
1116    ///
1117    /// #[derive(Component)]
1118    /// struct USIZE(usize);
1119    ///
1120    /// #[derive(Component)]
1121    /// struct STR(&'static str);
1122    ///
1123    /// let mut world = World::new();
1124    ///
1125    /// let entity0 = world.add_entity((U32(0),));
1126    /// let entity1 = world.add_entity((USIZE(1),));
1127    /// let entity2 = world.add_entity((STR("2"),));
1128    ///
1129    /// // deletes `entity2`
1130    /// world.delete_any::<SparseSet<STR>>();
1131    /// // deletes `entity0` and `entity1`
1132    /// world.delete_any::<(SparseSet<U32>, SparseSet<USIZE>)>();
1133    /// ```
1134    #[inline]
1135    #[track_caller]
1136    pub fn delete_any<S: TupleDeleteAny>(&mut self) {
1137        self.all_storages.get_mut().delete_any::<S>();
1138    }
1139    /// Deletes all components of an entity except the ones passed in `S`.
1140    /// The storage's type has to be used and not the component.
1141    /// `SparseSet` is the default storage.
1142    ///
1143    /// ### Example
1144    ///
1145    /// ```
1146    /// use shipyard::{Component, sparse_set::SparseSet, World};
1147    ///
1148    /// #[derive(Component)]
1149    /// struct U32(u32);
1150    ///
1151    /// #[derive(Component)]
1152    /// struct USIZE(usize);
1153    ///
1154    /// let mut world = World::new();
1155    ///
1156    /// let entity = world.add_entity((U32(0), USIZE(1)));
1157    ///
1158    /// world.retain_storage::<SparseSet<U32>>(entity);
1159    /// ```
1160    #[inline]
1161    #[track_caller]
1162    pub fn retain_storage<S: TupleRetainStorage>(&mut self, entity: EntityId) {
1163        self.all_storages.get_mut().retain_storage::<S>(entity);
1164    }
1165    /// Same as `retain_storage` but uses `StorageId` and not generics.
1166    /// You should only use this method if you use a custom storage with a runtime id.
1167    #[inline]
1168    #[track_caller]
1169    pub fn retain_storage_by_id(&mut self, entity: EntityId, excluded_storage: &[StorageId]) {
1170        self.all_storages
1171            .get_mut()
1172            .retain_storage_by_id(entity, excluded_storage);
1173    }
1174    /// Deletes all entities and components in the `World`.
1175    ///
1176    /// ### Example
1177    ///
1178    /// ```
1179    /// use shipyard::World;
1180    ///
1181    /// let mut world = World::new();
1182    ///
1183    /// world.clear();
1184    /// ```
1185    #[inline]
1186    #[track_caller]
1187    pub fn clear(&mut self) {
1188        self.all_storages.get_mut().clear();
1189    }
1190    /// Clear all deletion and removal tracking data.
1191    #[track_caller]
1192    pub fn clear_all_removed_and_deleted(&mut self) {
1193        self.all_storages.get_mut().clear_all_removed_and_deleted()
1194    }
1195    /// Clear all deletion and removal tracking data older than some timestamp.
1196    #[track_caller]
1197    pub fn clear_all_removed_and_deleted_older_than_timestamp(
1198        &mut self,
1199        timestamp: TrackingTimestamp,
1200    ) {
1201        self.all_storages
1202            .get_mut()
1203            .clear_all_removed_and_deleted_older_than_timestamp(timestamp)
1204    }
1205    /// Clear all insertion tracking data.
1206    #[track_caller]
1207    pub fn clear_all_inserted(&mut self) {
1208        self.all_storages.get_mut().clear_all_inserted()
1209    }
1210    /// Clear all modification tracking data.
1211    #[track_caller]
1212    pub fn clear_all_modified(&mut self) {
1213        self.all_storages.get_mut().clear_all_modified()
1214    }
1215    /// Clear all insertion and modification tracking data.
1216    #[track_caller]
1217    pub fn clear_all_inserted_and_modified(&mut self) {
1218        self.all_storages
1219            .get_mut()
1220            .clear_all_inserted_and_modified()
1221    }
1222    /// Make the given entity alive.
1223    /// Does nothing if an entity with a greater generation is already at this index.
1224    /// Returns `true` if the entity is successfully spawned.
1225    #[inline]
1226    #[track_caller]
1227    pub fn spawn(&mut self, entity: EntityId) -> bool {
1228        self.all_storages.get_mut().spawn(entity)
1229    }
1230
1231    /// Deletes all components for which `f(id, &component)` returns `false`.
1232    ///
1233    /// # Panics
1234    ///
1235    /// - Storage borrow failed.
1236    #[track_caller]
1237    pub fn retain<T: Component + Send + Sync>(&mut self, f: impl FnMut(EntityId, &T) -> bool) {
1238        self.all_storages.get_mut().retain(f);
1239    }
1240
1241    /// Deletes all components for which `f(id, Mut<component>)` returns `false`.
1242    ///
1243    /// # Panics
1244    ///
1245    /// - Storage borrow failed.
1246    #[track_caller]
1247    pub fn retain_mut<T: Component + Send + Sync>(
1248        &mut self,
1249        f: impl FnMut(EntityId, Mut<'_, T>) -> bool,
1250    ) {
1251        self.all_storages.get_mut().retain_mut(f);
1252    }
1253
1254    /// Displays storages memory information.
1255    pub fn memory_usage(&self) -> WorldMemoryUsage<'_> {
1256        WorldMemoryUsage(self)
1257    }
1258
1259    /// Returns a list of workloads and all information related to them.
1260    ///
1261    /// ### Borrows
1262    ///
1263    /// - Scheduler (shared)
1264    ///
1265    /// ### Panics
1266    ///
1267    /// - Scheduler borrow failed.
1268    #[track_caller]
1269    pub fn workloads_info(&self) -> WorkloadsInfo {
1270        let scheduler = self.scheduler.borrow().unwrap();
1271
1272        WorkloadsInfo(
1273            scheduler
1274                .workloads_info
1275                .iter()
1276                .map(|(name, workload_info)| (format!("{:?}", name), workload_info.clone()))
1277                .collect(),
1278        )
1279    }
1280
1281    /// Enable insertion tracking for the given components.
1282    #[track_caller]
1283    pub fn track_insertion<T: TupleTrack>(&mut self) -> &mut World {
1284        self.all_storages.get_mut().track_insertion::<T>();
1285        self
1286    }
1287
1288    /// Enable modification tracking for the given components.
1289    #[track_caller]
1290    pub fn track_modification<T: TupleTrack>(&mut self) -> &mut World {
1291        self.all_storages.get_mut().track_modification::<T>();
1292        self
1293    }
1294
1295    /// Enable deletion tracking for the given components.
1296    #[track_caller]
1297    pub fn track_deletion<T: TupleTrack>(&mut self) -> &mut World {
1298        self.all_storages.get_mut().track_deletion::<T>();
1299        self
1300    }
1301
1302    /// Enable removal tracking for the given components.
1303    #[track_caller]
1304    pub fn track_removal<T: TupleTrack>(&mut self) -> &mut World {
1305        self.all_storages.get_mut().track_removal::<T>();
1306        self
1307    }
1308
1309    /// Enable insertion, deletion and removal tracking for the given components.
1310    #[track_caller]
1311    pub fn track_all<T: TupleTrack>(&mut self) {
1312        self.all_storages.get_mut().track_all::<T>();
1313    }
1314
1315    #[doc = "Retrieve components of `entity`.
1316
1317Multiple components can be queried at the same time using a tuple.
1318
1319You can use:
1320* `&T` for a shared access to `T` component
1321* `&mut T` for an exclusive access to `T` component"]
1322    #[cfg_attr(
1323        all(feature = "thread_local", docsrs),
1324        doc = "* <span style=\"display: table;color: #2f2f2f;background-color: #C4ECFF;border-width: 1px;border-style: solid;border-color: #7BA5DB;padding: 3px;margin-bottom: 5px; font-size: 90%\">This is supported on <strong><code style=\"background-color: #C4ECFF\">feature=\"thread_local\"</code></strong> only:</span>"
1325    )]
1326    #[cfg_attr(
1327        all(feature = "thread_local"),
1328        doc = "* [NonSend]<&T> for a shared access to a `T` component where `T` isn't `Send`
1329* [NonSend]<&mut T> for an exclusive access to a `T` component where `T` isn't `Send`
1330* [NonSync]<&T> for a shared access to a `T` component where `T` isn't `Sync`
1331* [NonSync]<&mut T> for an exclusive access to a `T` component where `T` isn't `Sync`
1332* [NonSendSync]<&T> for a shared access to a `T` component where `T` isn't `Send` nor `Sync`
1333* [NonSendSync]<&mut T> for an exclusive access to a `T` component where `T` isn't `Send` nor `Sync`"
1334    )]
1335    #[cfg_attr(
1336        not(feature = "thread_local"),
1337        doc = "* NonSend: must activate the *thread_local* feature
1338* NonSync: must activate the *thread_local* feature
1339* NonSendSync: must activate the *thread_local* feature"
1340    )]
1341    #[doc = "
1342### Borrows
1343
1344- [AllStorages] (shared) + storage (exclusive or shared)
1345
1346### Errors
1347
1348- [AllStorages] borrow failed.
1349- Storage borrow failed.
1350- Entity does not have the component.
1351
1352### Example
1353```
1354use shipyard::{Component, World};
1355
1356#[derive(Component, Debug, PartialEq, Eq)]
1357struct U32(u32);
1358
1359#[derive(Component, Debug, PartialEq, Eq)]
1360struct USIZE(usize);
1361
1362let mut world = World::new();
1363
1364let entity = world.add_entity((USIZE(0), U32(1)));
1365
1366let (i, j) = world.get::<(&USIZE, &mut U32)>(entity).unwrap();
1367
1368assert!(*i == &USIZE(0));
1369assert!(*j == &U32(1));
1370```"]
1371    #[cfg_attr(
1372        feature = "thread_local",
1373        doc = "[NonSend]: crate::borrow::NonSend
1374[NonSync]: crate::borrow::NonSync
1375[NonSendSync]: crate::borrow::NonSendSync"
1376    )]
1377    #[inline]
1378    pub fn get<T: GetComponent>(
1379        &self,
1380        entity: EntityId,
1381    ) -> Result<T::Out<'_>, error::GetComponent> {
1382        let (all_storages, all_borrow) = unsafe {
1383            ARef::destructure(
1384                self.all_storages
1385                    .borrow()
1386                    .map_err(error::GetStorage::AllStoragesBorrow)?,
1387            )
1388        };
1389
1390        let current = self.get_current();
1391
1392        T::get(all_storages, Some(all_borrow), current, entity)
1393    }
1394
1395    #[doc = "Retrieve a unique component.
1396
1397You can use:
1398* `&T` for a shared access to `T` unique component
1399* `&mut T` for an exclusive access to `T` unique component"]
1400    #[cfg_attr(
1401        all(feature = "thread_local", docsrs),
1402        doc = "* <span style=\"display: table;color: #2f2f2f;background-color: #C4ECFF;border-width: 1px;border-style: solid;border-color: #7BA5DB;padding: 3px;margin-bottom: 5px; font-size: 90%\">This is supported on <strong><code style=\"background-color: #C4ECFF\">feature=\"thread_local\"</code></strong> only:</span>"
1403    )]
1404    #[cfg_attr(
1405        all(feature = "thread_local"),
1406        doc = "* [NonSend]<&T> for a shared access to a `T` unique component where `T` isn't `Send`
1407* [NonSend]<&mut T> for an exclusive access to a `T` unique component where `T` isn't `Send`
1408* [NonSync]<&T> for a shared access to a `T` unique component where `T` isn't `Sync`
1409* [NonSync]<&mut T> for an exclusive access to a `T` unique component where `T` isn't `Sync`
1410* [NonSendSync]<&T> for a shared access to a `T` unique component where `T` isn't `Send` nor `Sync`
1411* [NonSendSync]<&mut T> for an exclusive access to a `T` unique component where `T` isn't `Send` nor `Sync`"
1412    )]
1413    #[cfg_attr(
1414        not(feature = "thread_local"),
1415        doc = "* NonSend: must activate the *thread_local* feature
1416* NonSync: must activate the *thread_local* feature
1417* NonSendSync: must activate the *thread_local* feature"
1418    )]
1419    #[doc = "
1420### Borrows
1421
1422- [AllStorages] (shared) + storage (exclusive or shared)
1423
1424### Errors
1425
1426- [AllStorages] borrow failed.
1427- Storage borrow failed.
1428
1429### Example
1430```
1431use shipyard::{Unique, World};
1432
1433#[derive(Unique, Debug, PartialEq, Eq)]
1434struct U32(u32);
1435
1436let mut world = World::new();
1437
1438world.add_unique(U32(0));
1439
1440let i = world.get_unique::<&U32>().unwrap();
1441
1442assert!(*i == U32(0));
1443```"]
1444    #[cfg_attr(
1445        feature = "thread_local",
1446        doc = "[NonSend]: crate::borrow::NonSend
1447[NonSync]: crate::borrow::NonSync
1448[NonSendSync]: crate::borrow::NonSendSync"
1449    )]
1450    #[inline]
1451    pub fn get_unique<T: GetUnique>(&self) -> Result<T::Out<'_>, error::GetStorage> {
1452        let (all_storages, all_borrow) = unsafe {
1453            ARef::destructure(
1454                self.all_storages
1455                    .borrow()
1456                    .map_err(error::GetStorage::AllStoragesBorrow)?,
1457            )
1458        };
1459
1460        T::get_unique(all_storages, Some(all_borrow))
1461    }
1462
1463    #[doc = "Iterate components.
1464
1465Multiple components can be iterated at the same time using a tuple.
1466
1467You can use:
1468* `&T` for a shared access to `T` component
1469* `&mut T` for an exclusive access to `T` component"]
1470    #[cfg_attr(
1471        all(feature = "thread_local", docsrs),
1472        doc = "* <span style=\"display: table;color: #2f2f2f;background-color: #C4ECFF;border-width: 1px;border-style: solid;border-color: #7BA5DB;padding: 3px;margin-bottom: 5px; font-size: 90%\">This is supported on <strong><code style=\"background-color: #C4ECFF\">feature=\"thread_local\"</code></strong> only:</span>"
1473    )]
1474    #[cfg_attr(
1475        all(feature = "thread_local"),
1476        doc = "* [NonSend]<&T> for a shared access to a `T` component where `T` isn't `Send`
1477* [NonSend]<&mut T> for an exclusive access to a `T` component where `T` isn't `Send`
1478* [NonSync]<&T> for a shared access to a `T` component where `T` isn't `Sync`
1479* [NonSync]<&mut T> for an exclusive access to a `T` component where `T` isn't `Sync`
1480* [NonSendSync]<&T> for a shared access to a `T` component where `T` isn't `Send` nor `Sync`
1481* [NonSendSync]<&mut T> for an exclusive access to a `T` component where `T` isn't `Send` nor `Sync`"
1482    )]
1483    #[cfg_attr(
1484        not(feature = "thread_local"),
1485        doc = "* NonSend: must activate the *thread_local* feature
1486* NonSync: must activate the *thread_local* feature
1487* NonSendSync: must activate the *thread_local* feature"
1488    )]
1489    #[doc = "
1490### Borrows
1491
1492- [AllStorages] (shared)
1493
1494### Panics
1495
1496- [AllStorages] borrow failed.
1497
1498### Example
1499```
1500use shipyard::{Component, World};
1501
1502#[derive(Component, Debug, PartialEq, Eq)]
1503struct U32(u32);
1504
1505#[derive(Component, Debug, PartialEq, Eq)]
1506struct USIZE(usize);
1507
1508let mut world = World::new();
1509
1510let entity = world.add_entity((USIZE(0), U32(1)));
1511
1512let mut iter = world.iter::<(&USIZE, &mut U32)>();
1513
1514for (i, j) in &mut iter {
1515    // <-- SNIP -->
1516}
1517```"]
1518    #[cfg_attr(
1519        feature = "thread_local",
1520        doc = "[NonSend]: crate::borrow::NonSend
1521[NonSync]: crate::borrow::NonSync
1522[NonSendSync]: crate::borrow::NonSendSync"
1523    )]
1524    #[inline]
1525    #[track_caller]
1526    pub fn iter<'a, T: IterComponent>(&'a self) -> IntoIterRef<'a, T>
1527    where
1528        <T as IterComponent>::Shiperator<'a>: ShiperatorCaptain + ShiperatorSailor,
1529    {
1530        let (all_storages, all_borrow) = unsafe {
1531            ARef::destructure(
1532                self.all_storages
1533                    .borrow()
1534                    .map_err(error::GetStorage::AllStoragesBorrow)
1535                    .unwrap(),
1536            )
1537        };
1538
1539        let current = self.get_current();
1540
1541        into_iter(all_storages, Some(all_borrow), current).unwrap()
1542    }
1543
1544    /// Sets the on entity deletion callback.
1545    ///
1546    /// ### Borrows
1547    ///
1548    /// - AllStorages (shared)
1549    /// - Entities (exclusive)
1550    ///
1551    /// ### Panics
1552    ///
1553    /// - AllStorages borrow failed.
1554    /// - Entities borrow failed.
1555    #[track_caller]
1556    pub fn on_deletion(&self, f: impl FnMut(EntityId) + Send + Sync + 'static) {
1557        let mut entities = self.borrow::<EntitiesViewMut<'_>>().unwrap();
1558
1559        entities.on_deletion(f);
1560    }
1561
1562    /// Returns true if entity matches a living entity.
1563    pub fn is_entity_alive(&mut self, entity: EntityId) -> bool {
1564        self.all_storages
1565            .get_mut()
1566            .exclusive_storage_mut::<Entities>()
1567            .unwrap()
1568            .is_alive(entity)
1569    }
1570
1571    /// Moves an entity from a `World` to another.
1572    ///
1573    /// ### Panics
1574    ///
1575    /// - `entity` is not alive
1576    ///
1577    /// ### Example
1578    ///
1579    /// ```
1580    /// use shipyard::{Component, World};
1581    ///
1582    /// #[derive(Component, Debug, PartialEq, Eq)]
1583    /// struct USIZE(usize);
1584    ///
1585    /// let mut world1 = World::new();
1586    /// let mut world2 = World::new();
1587    ///
1588    /// let entity = world1.add_entity(USIZE(1));
1589    ///
1590    /// world1.move_entity(&mut world2, entity);
1591    ///
1592    /// assert!(!world1.is_entity_alive(entity));
1593    /// assert_eq!(world2.get::<&USIZE>(entity).as_deref(), Ok(&&USIZE(1)));
1594    /// ```
1595    #[inline]
1596    #[track_caller]
1597    pub fn move_entity(&mut self, other: &mut World, entity: EntityId) {
1598        let other_all_storages = other.all_storages.get_mut();
1599
1600        self.all_storages
1601            .get_mut()
1602            .move_entity(other_all_storages, entity);
1603    }
1604
1605    /// Moves all components from an entity to another in another `World`.
1606    ///
1607    /// ### Panics
1608    ///
1609    /// - `from` is not alive
1610    /// - `to` is not alive
1611    ///
1612    /// ### Example
1613    ///
1614    /// ```
1615    /// use shipyard::{Component, World};
1616    ///
1617    /// #[derive(Component, Debug, PartialEq, Eq)]
1618    /// struct USIZE(usize);
1619    ///
1620    /// let mut world1 = World::new();
1621    /// let mut world2 = World::new();
1622    ///
1623    /// let from = world1.add_entity(USIZE(1));
1624    /// let to = world2.add_entity(());
1625    ///
1626    /// world1.move_components(&mut world2, from, to);
1627    ///
1628    /// assert!(world1.get::<&USIZE>(from).is_err());
1629    /// assert_eq!(world2.get::<&USIZE>(to).as_deref(), Ok(&&USIZE(1)));
1630    /// ```
1631    #[inline]
1632    #[track_caller]
1633    pub fn move_components(&mut self, other: &mut World, from: EntityId, to: EntityId) {
1634        let other_all_storages = other.all_storages.get_mut();
1635
1636        self.all_storages
1637            .get_mut()
1638            .move_components(other_all_storages, from, to);
1639    }
1640
1641    /// Registers the function to clone these components.
1642    ///
1643    /// The type of the storage is used and not the component itself.\
1644    /// That would be [`SparseSet<T>`](crate::sparse_set::SparseSet) and [`UniqueStorage<T>`](crate::unique::UniqueStorage).
1645    ///
1646    /// ### Example
1647    ///
1648    /// ```
1649    /// use shipyard::{Component, sparse_set::SparseSet, Unique, UniqueStorage, World};
1650    ///
1651    /// #[derive(Component, Clone)]
1652    /// struct USIZE(usize);
1653    ///
1654    /// #[derive(Unique, Clone)]
1655    /// struct U32(u32);
1656    ///
1657    /// let mut world = World::new();
1658    ///
1659    /// world.add_unique(U32(0));
1660    ///
1661    /// world.register_clone::<(SparseSet<USIZE>, UniqueStorage<U32>)>();
1662    /// ```
1663    #[inline]
1664    #[track_caller]
1665    pub fn register_clone<T: TupleClone>(&mut self) {
1666        self.all_storages.get_mut().register_clone::<T>();
1667    }
1668
1669    /// Clones `entity` from this `World` to `other` alongside all its with a registered clone function.
1670    ///
1671    /// ### Borrows
1672    ///
1673    /// - AllStorages (shared)
1674    /// - Every Storage (shared)
1675    ///
1676    /// ### Panics
1677    ///
1678    /// - `entity` is not alive
1679    ///
1680    /// ### Example
1681    ///
1682    /// ```
1683    /// use shipyard::{Component, sparse_set::SparseSet, World};
1684    ///
1685    /// #[derive(Component, Clone, Debug, PartialEq, Eq)]
1686    /// struct USIZE(usize);
1687    ///
1688    /// let mut world1 = World::new();
1689    /// let mut world2 = World::new();
1690    ///
1691    /// world1.register_clone::<SparseSet<USIZE>>();
1692    ///
1693    /// let entity = world1.add_entity(USIZE(1));
1694    ///
1695    /// world1.clone_entity_to(&mut world2, entity);
1696    ///
1697    /// assert_eq!(world1.get::<&USIZE>(entity).as_deref(), Ok(&&USIZE(1)));
1698    /// assert_eq!(world2.get::<&USIZE>(entity).as_deref(), Ok(&&USIZE(1)));
1699    #[inline]
1700    #[track_caller]
1701    pub fn clone_entity_to(&self, other: &mut World, entity: EntityId) {
1702        let other_all_storages = other.all_storages.get_mut();
1703
1704        self.all_storages
1705            .borrow()
1706            .unwrap()
1707            .clone_entity_to(other_all_storages, entity);
1708    }
1709
1710    /// Clones all components of `from` entity with a registered clone function from
1711    /// this `World` to `other`'s `to` entity.
1712    ///
1713    /// ### Borrows
1714    ///
1715    /// - AllStorages (shared)
1716    /// - Every Storage (shared)
1717    ///
1718    /// ### Panics
1719    ///
1720    /// - `from` is not alive
1721    /// - `to` is not alive
1722    ///
1723    /// ### Example
1724    ///
1725    /// ```
1726    /// use shipyard::{Component, sparse_set::SparseSet, World};
1727    ///
1728    /// #[derive(Component, Clone, Debug, PartialEq, Eq)]
1729    /// struct USIZE(usize);
1730    ///
1731    /// let mut world1 = World::new();
1732    /// let mut world2 = World::new();
1733    ///
1734    /// world1.register_clone::<SparseSet<USIZE>>();
1735    ///
1736    /// let from = world1.add_entity(USIZE(1));
1737    /// let to = world2.add_entity(());
1738    ///
1739    /// world1.clone_components_to(&mut world2, from, to);
1740    ///
1741    /// assert_eq!(world1.get::<&USIZE>(from).as_deref(), Ok(&&USIZE(1)));
1742    /// assert_eq!(world2.get::<&USIZE>(to).as_deref(), Ok(&&USIZE(1)));
1743    /// ```
1744    #[inline]
1745    #[track_caller]
1746    pub fn clone_components_to(&self, other: &mut World, from: EntityId, to: EntityId) {
1747        let other_all_storages = other.all_storages.get_mut();
1748
1749        self.all_storages
1750            .borrow()
1751            .unwrap()
1752            .clone_components_to(other_all_storages, from, to);
1753    }
1754}
1755
1756impl core::fmt::Debug for World {
1757    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1758        let mut debug_struct = f.debug_tuple("World");
1759
1760        if let Ok(all_storages) = self.all_storages.borrow() {
1761            debug_struct.field(&*all_storages);
1762        } else {
1763            debug_struct.field(&"Could not borrow AllStorages");
1764        }
1765
1766        if let Ok(scheduler) = self.scheduler.borrow() {
1767            debug_struct.field(&*scheduler);
1768        } else {
1769            debug_struct.field(&"Could not borrow Scheduler");
1770        }
1771
1772        debug_struct.finish()
1773    }
1774}
1775
1776impl core::fmt::Debug for WorldMemoryUsage<'_> {
1777    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1778        if let Ok(all_storages) = self.0.all_storages.borrow() {
1779            all_storages.memory_usage().fmt(f)
1780        } else {
1781            f.write_str("Could not borrow AllStorages")
1782        }
1783    }
1784}
1785
1786#[cfg(feature = "serde1")]
1787impl World {
1788    /// Serializes the view using the provided serializer.
1789    ///
1790    /// ### Example
1791    ///
1792    /// ```
1793    /// use shipyard::{Component, View, World};
1794    ///
1795    /// #[derive(Component, serde::Serialize)]
1796    /// struct Name(String);
1797    ///
1798    /// let mut world = World::new();
1799    ///
1800    /// let eid1 = world.add_entity(Name("Alice".to_string()));
1801    ///
1802    /// let mut serialized = Vec::new();
1803    /// world
1804    ///     .serialize::<_, View<Name>>(&mut serde_json::ser::Serializer::new(&mut serialized))
1805    ///     .unwrap_or_else(|_| panic!());
1806    ///
1807    /// let serialized_str = String::from_utf8(serialized).unwrap();
1808    /// assert_eq!(serialized_str, r#"[[{"index":0,"gen":0},"Alice"]]"#);
1809    /// ```
1810    pub fn serialize<'w, S: serde::Serializer, V: WorldBorrow>(
1811        &'w self,
1812        serializer: S,
1813    ) -> Result<S::Ok, error::Serialize<S>>
1814    where
1815        V::WorldView<'w>: serde::Serialize,
1816    {
1817        use serde::Serialize;
1818
1819        match self.borrow::<V>() {
1820            Ok(view) => match view.serialize(serializer) {
1821                Ok(ok) => Ok(ok),
1822                Err(err) => Err(error::Serialize::Serialization(err)),
1823            },
1824            Err(err) => Err(error::Serialize::Borrow(err)),
1825        }
1826    }
1827
1828    /// Deserializes the view using the provided deserializer.
1829    ///
1830    /// ### Example
1831    ///
1832    /// ```
1833    /// use shipyard::{Component, EntityId, ViewMut, World};
1834    ///
1835    /// #[derive(Component, serde::Deserialize)]
1836    /// struct Name(String);
1837    ///
1838    /// let mut world = World::new();
1839    ///
1840    /// let mut serialized = r#"[[{"index":0,"gen":0},"Alice"]]"#;
1841    /// world
1842    ///     .deserialize::<_, ViewMut<Name>>(&mut serde_json::de::Deserializer::from_str(serialized))
1843    ///     .unwrap_or_else(|_| panic!());
1844    ///
1845    /// let alice_eid = EntityId::new_from_index_and_gen(0, 0);
1846    /// assert_eq!(world.get::<&Name>(alice_eid).unwrap().0, "Alice");
1847    ///
1848    /// // Careful here, the World is not in a stable state
1849    ///
1850    /// assert_eq!(world.is_entity_alive(alice_eid), false);
1851    ///
1852    /// // We can use World::spawn for example to fix the problem
1853    /// // another solution would be to serialize EntitiesViewMut
1854    ///
1855    /// world.spawn(alice_eid);
1856    ///
1857    /// assert_eq!(world.is_entity_alive(alice_eid), true);
1858    /// ```
1859    pub fn deserialize<'w, 'de, D: serde::Deserializer<'de>, V: WorldBorrow>(
1860        &'w self,
1861        deserializer: D,
1862    ) -> Result<(), error::Deserialize<'de, D>>
1863    where
1864        V::WorldView<'w>: serde::Deserialize<'de>,
1865    {
1866        match self.borrow::<V>() {
1867            Ok(mut view) => match serde::Deserialize::deserialize_in_place(deserializer, &mut view)
1868            {
1869                Ok(ok) => Ok(ok),
1870                Err(err) => Err(error::Deserialize::Deserialization(err)),
1871            },
1872            Err(err) => Err(error::Deserialize::Borrow(err)),
1873        }
1874    }
1875}