diff --git a/Cargo.toml b/Cargo.toml index e0d0ea95..fcdb6e81 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ parking_lot = { version = "^0.10" } hashbrown = "^0.7" [features] -default = ["parallel", "proc"] +default = ["parallel"] parallel = ["rayon", "num_cpus", "std"] proc = ["shipyard_proc"] non_send = ["std"] diff --git a/README.md b/README.md index ec90d525..e7144137 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ If you are new here, the [user guide](https://leudz.github.io/shipyard/book) is ## Simple Example ```rust -use shipyard::prelude::*; +use shipyard::*; struct Health(f32); struct Position { x: f32, y: f32 } @@ -91,7 +91,7 @@ There is still a lot of room for optimization, the current focus is more on addi ## Features - **parallel** *(default)* — adds parallel iterators and dispatch -- **proc** *(default)* — adds `system` proc macro +- **proc** — adds `system` proc macro - **serde** — adds (de)serialization support with [serde](https://github.com/serde-rs/serde) - **non_send** — add methods and types required to work with `!Send` components - **non_sync** — add methods and types required to work with `!Sync` components diff --git a/demo/src/init.rs b/demo/src/init.rs index afa503b9..b92e4a02 100644 --- a/demo/src/init.rs +++ b/demo/src/init.rs @@ -13,7 +13,7 @@ use awsm_web::webgl::{ }; use awsm_web::window::get_window_size; use gloo_events::EventListener; -use shipyard::prelude::*; +use shipyard::*; use std::cell::RefCell; use std::rc::Rc; use wasm_bindgen::prelude::*; diff --git a/demo/src/input.rs b/demo/src/input.rs index d9c3961e..402370b7 100644 --- a/demo/src/input.rs +++ b/demo/src/input.rs @@ -1,7 +1,7 @@ use crate::components::*; use gloo_events::EventListener; -use shipyard::prelude::*; +use shipyard::*; use std::rc::Rc; use web_sys::HtmlCanvasElement; diff --git a/demo/src/systems.rs b/demo/src/systems.rs index a52bac83..78dc8c07 100644 --- a/demo/src/systems.rs +++ b/demo/src/systems.rs @@ -2,7 +2,7 @@ use crate::components::*; use crate::config::*; use crate::geometry::*; use rand::prelude::*; -use shipyard::prelude::*; +use shipyard::*; pub const TICK: &str = "TICK"; diff --git a/demo/src/world.rs b/demo/src/world.rs index ff3aba82..029541df 100644 --- a/demo/src/world.rs +++ b/demo/src/world.rs @@ -2,7 +2,7 @@ use crate::components::*; use crate::geometry::*; use crate::hud::Hud; use crate::renderer::SceneRenderer; -use shipyard::prelude::*; +use shipyard::*; pub fn init_world(img_area: Area, stage_area: Area, hud: Hud, renderer: SceneRenderer) -> World { let world = World::default(); diff --git a/shipyard_proc/src/lib.rs b/shipyard_proc/src/lib.rs index 4ca0e614..9c04d352 100644 --- a/shipyard_proc/src/lib.rs +++ b/shipyard_proc/src/lib.rs @@ -76,10 +76,10 @@ fn expand_system(name: syn::Ident, mut run: syn::ItemFn) -> Result // transform &Entities into Entites and &mut Entities into EntitiesMut if path.path.segments.last().unwrap().ident == "Entities" { if reference.mutability.is_some() { - **ty = parse_quote!(::shipyard::prelude::EntitiesMut); + **ty = parse_quote!(::shipyard::EntitiesMut); exclusive_borrows.push((i, parse_quote!(Entities))); } else { - **ty = parse_quote!(::shipyard::prelude::Entities); + **ty = parse_quote!(::shipyard::Entities); shared_borrows.push((i, parse_quote!(Entities))); } @@ -101,7 +101,7 @@ fn expand_system(name: syn::Ident, mut run: syn::ItemFn) -> Result "You probably forgot a mut, &AllStorages isn't a valid storage access" )); } else { - **ty = parse_quote!(::shipyard::prelude::AllStorages); + **ty = parse_quote!(::shipyard::AllStorages); match &mut conflict { Conflict::AllStorages(all_storages) => { @@ -118,7 +118,7 @@ fn expand_system(name: syn::Ident, mut run: syn::ItemFn) -> Result } } else if path.path.segments.last().unwrap().ident == "ThreadPool" { if reference.mutability.is_none() { - **ty = parse_quote!(::shipyard::prelude::ThreadPool); + **ty = parse_quote!(::shipyard::ThreadPool); } else { return Err(Error::new_spanned( path, @@ -557,9 +557,9 @@ fn expand_system(name: syn::Ident, mut run: syn::ItemFn) -> Result Ok(quote! { #vis struct #name; - impl<'sys> ::shipyard::prelude::System<'sys> for #name { + impl<'sys> ::shipyard::System<'sys> for #name { type Data = (#(#data,)*); - fn run((#(#binding,)*): (#(<#data as ::shipyard::prelude::SystemData<'sys>>::View,)*)) #body + fn run((#(#binding,)*): (#(<#data as ::shipyard::SystemData<'sys>>::View,)*)) #body } }) } diff --git a/src/atomic_refcell.rs b/src/atomic_refcell.rs index 9dfc564d..fe6c7540 100644 --- a/src/atomic_refcell.rs +++ b/src/atomic_refcell.rs @@ -34,23 +34,14 @@ impl AtomicRefCell { where T: Sized, { - #[cfg(feature = "std")] - { - AtomicRefCell { - inner: UnsafeCell::new(value), - borrow_state: Default::default(), - is_sync, - send, - _non_send: core::marker::PhantomData, - } - } - #[cfg(not(feature = "std"))] - { - AtomicRefCell { - inner: UnsafeCell::new(value), - borrow_state: Default::default(), - _non_send: core::marker::PhantomData, - } + AtomicRefCell { + borrow_state: Default::default(), + #[cfg(feature = "std")] + send, + #[cfg(feature = "std")] + is_sync, + _non_send: core::marker::PhantomData, + inner: UnsafeCell::new(value), } } /// Immutably borrows the wrapped value, returning an error if the value is currently mutably diff --git a/src/borrow/all_storages.rs b/src/borrow/all_storages.rs new file mode 100644 index 00000000..bba7fce7 --- /dev/null +++ b/src/borrow/all_storages.rs @@ -0,0 +1,172 @@ +//use super::FakeBorrow; +use crate::error; +use crate::storage::AllStorages; +use crate::view::{EntitiesView, EntitiesViewMut, UniqueView, UniqueViewMut, View, ViewMut}; +#[cfg(feature = "non_send")] +use crate::NonSend; +#[cfg(all(feature = "non_send", feature = "non_sync"))] +use crate::NonSendSync; +#[cfg(feature = "non_sync")] +use crate::NonSync; +use core::convert::TryInto; + +pub trait AllStoragesBorrow<'a> { + fn try_borrow(all_storages: &'a AllStorages) -> Result + where + Self: Sized; +} + +impl<'a> AllStoragesBorrow<'a> for () { + fn try_borrow(_: &'a AllStorages) -> Result + where + Self: Sized, + { + Ok(()) + } +} + +impl<'a> AllStoragesBorrow<'a> for EntitiesView<'a> { + fn try_borrow(all_storages: &'a AllStorages) -> Result { + all_storages.try_into() + } +} + +impl<'a> AllStoragesBorrow<'a> for EntitiesViewMut<'a> { + fn try_borrow(all_storages: &'a AllStorages) -> Result { + all_storages.try_into() + } +} + +impl<'a, T: 'static + Send + Sync> AllStoragesBorrow<'a> for View<'a, T> { + fn try_borrow(all_storages: &'a AllStorages) -> Result { + all_storages.try_into() + } +} + +impl<'a, T: 'static + Send + Sync> AllStoragesBorrow<'a> for ViewMut<'a, T> { + fn try_borrow(all_storages: &'a AllStorages) -> Result { + all_storages.try_into() + } +} + +impl<'a, T: 'static + Send + Sync> AllStoragesBorrow<'a> for UniqueView<'a, T> { + fn try_borrow(all_storages: &'a AllStorages) -> Result { + all_storages.try_into() + } +} + +impl<'a, T: 'static + Send + Sync> AllStoragesBorrow<'a> for UniqueViewMut<'a, T> { + fn try_borrow(all_storages: &'a AllStorages) -> Result { + all_storages.try_into() + } +} + +#[cfg(feature = "non_send")] +impl<'a, T: 'static + Sync> AllStoragesBorrow<'a> for NonSend> { + fn try_borrow(all_storages: &'a AllStorages) -> Result { + View::try_storage_from_non_send(all_storages).map(|view| NonSend(view)) + } +} + +#[cfg(feature = "non_send")] +impl<'a, T: 'static + Sync> AllStoragesBorrow<'a> for NonSend> { + fn try_borrow(all_storages: &'a AllStorages) -> Result { + ViewMut::try_storage_from_non_send(all_storages).map(|view| NonSend(view)) + } +} + +#[cfg(feature = "non_sync")] +impl<'a, T: 'static + Send> AllStoragesBorrow<'a> for NonSync> { + fn try_borrow(all_storages: &'a AllStorages) -> Result { + View::try_storage_from_non_sync(all_storages).map(|view| NonSync(view)) + } +} + +#[cfg(feature = "non_sync")] +impl<'a, T: 'static + Send> AllStoragesBorrow<'a> for NonSync> { + fn try_borrow(all_storages: &'a AllStorages) -> Result { + ViewMut::try_storage_from_non_sync(all_storages).map(|view| NonSync(view)) + } +} + +#[cfg(all(feature = "non_send", feature = "non_sync"))] +impl<'a, T: 'static + Sync> AllStoragesBorrow<'a> for NonSendSync> { + fn try_borrow(all_storages: &'a AllStorages) -> Result { + View::try_storage_from_non_send_sync(all_storages).map(|view| NonSendSync(view)) + } +} + +#[cfg(all(feature = "non_send", feature = "non_sync"))] +impl<'a, T: 'static + Sync> AllStoragesBorrow<'a> for NonSendSync> { + fn try_borrow(all_storages: &'a AllStorages) -> Result { + ViewMut::try_storage_from_non_send_sync(all_storages).map(|view| NonSendSync(view)) + } +} + +#[cfg(feature = "non_send")] +impl<'a, T: 'static + Sync> AllStoragesBorrow<'a> for NonSend> { + fn try_borrow(all_storages: &'a AllStorages) -> Result { + UniqueView::try_storage_from_non_send(all_storages).map(|view| NonSend(view)) + } +} + +#[cfg(feature = "non_send")] +impl<'a, T: 'static + Sync> AllStoragesBorrow<'a> for NonSend> { + fn try_borrow(all_storages: &'a AllStorages) -> Result { + UniqueViewMut::try_storage_from_non_send(all_storages).map(|view| NonSend(view)) + } +} + +#[cfg(feature = "non_sync")] +impl<'a, T: 'static + Send> AllStoragesBorrow<'a> for NonSync> { + fn try_borrow(all_storages: &'a AllStorages) -> Result { + UniqueView::try_storage_from_non_sync(all_storages).map(|view| NonSync(view)) + } +} + +#[cfg(feature = "non_sync")] +impl<'a, T: 'static + Send> AllStoragesBorrow<'a> for NonSync> { + fn try_borrow(all_storages: &'a AllStorages) -> Result { + UniqueViewMut::try_storage_from_non_sync(all_storages).map(|view| NonSync(view)) + } +} + +#[cfg(all(feature = "non_send", feature = "non_sync"))] +impl<'a, T: 'static + Sync> AllStoragesBorrow<'a> for NonSendSync> { + fn try_borrow(all_storages: &'a AllStorages) -> Result { + UniqueView::try_storage_from_non_send_sync(all_storages).map(|view| NonSendSync(view)) + } +} + +#[cfg(all(feature = "non_send", feature = "non_sync"))] +impl<'a, T: 'static + Sync> AllStoragesBorrow<'a> for NonSendSync> { + fn try_borrow(all_storages: &'a AllStorages) -> Result { + UniqueViewMut::try_storage_from_non_send_sync(all_storages).map(|view| NonSendSync(view)) + } +} + +macro_rules! impl_system_data { + ($(($type: ident, $index: tt))+) => { + impl<'a, $($type: AllStoragesBorrow<'a>),+> AllStoragesBorrow<'a> for ($($type,)+) { + fn try_borrow( + all_storages: &'a AllStorages, + ) -> Result { + Ok(($( + <$type as AllStoragesBorrow>::try_borrow(all_storages)?, + )+)) + } + } + } +} + +macro_rules! system_data { + ($(($type: ident, $index: tt))*;($type1: ident, $index1: tt) $(($queue_type: ident, $queue_index: tt))*) => { + impl_system_data![$(($type, $index))*]; + system_data![$(($type, $index))* ($type1, $index1); $(($queue_type, $queue_index))*]; + }; + ($(($type: ident, $index: tt))*;) => { + impl_system_data![$(($type, $index))*]; + } +} + +system_data![(A, 0); (B, 1) (C, 2) (D, 3) (E, 4) (F, 5) (G, 6) (H, 7) (I, 8) (J, 9)]; diff --git a/src/borrow/fake_borrow.rs b/src/borrow/fake_borrow.rs new file mode 100644 index 00000000..16094d74 --- /dev/null +++ b/src/borrow/fake_borrow.rs @@ -0,0 +1,9 @@ +use core::marker::PhantomData; + +pub struct FakeBorrow(PhantomData); + +impl FakeBorrow { + pub(crate) fn new() -> Self { + FakeBorrow(PhantomData) + } +} diff --git a/src/run/system_data.rs b/src/borrow/mod.rs similarity index 62% rename from src/run/system_data.rs rename to src/borrow/mod.rs index 7a5e92bf..5d3a5130 100644 --- a/src/run/system_data.rs +++ b/src/borrow/mod.rs @@ -1,21 +1,32 @@ -use super::FakeBorrow; -use crate::atomic_refcell::AtomicRefCell; -use crate::storage::{AllStorages, Entities, EntitiesMut}; -use crate::views::{ - AllStoragesViewMut, EntitiesView, EntitiesViewMut, UniqueView, UniqueViewMut, View, ViewMut, -}; +mod all_storages; +mod fake_borrow; #[cfg(feature = "non_send")] -use crate::NonSend; +mod non_send; #[cfg(all(feature = "non_send", feature = "non_sync"))] -use crate::NonSendSync; +mod non_send_sync; #[cfg(feature = "non_sync")] -use crate::NonSync; -use crate::{error, Unique}; +mod non_sync; + +pub use all_storages::AllStoragesBorrow; +pub use fake_borrow::FakeBorrow; +#[cfg(feature = "non_send")] +pub use non_send::NonSend; +#[cfg(all(feature = "non_send", feature = "non_sync"))] +pub use non_send_sync::NonSendSync; +#[cfg(feature = "non_sync")] +pub use non_sync::NonSync; + +use crate::atomic_refcell::AtomicRefCell; +use crate::error; +use crate::storage::{AllStorages, Entities}; +#[cfg(feature = "parallel")] +use crate::view::ThreadPoolView; +use crate::view::{ + AllStoragesViewMut, EntitiesView, EntitiesViewMut, UniqueView, UniqueViewMut, View, ViewMut, +}; use alloc::vec::Vec; use core::any::TypeId; use core::convert::TryInto; -#[cfg(feature = "parallel")] -use rayon::ThreadPool; #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub enum Mutation { @@ -23,26 +34,27 @@ pub enum Mutation { Unique, } -pub trait SystemData<'a> { - type View; - +pub trait Borrow<'a> { fn try_borrow( all_storages: &'a AtomicRefCell, - #[cfg(feature = "parallel")] thread_pool: &'a ThreadPool, - ) -> Result; + #[cfg(feature = "parallel")] thread_pool: &'a rayon::ThreadPool, + ) -> Result + where + Self: Sized; fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>); fn is_send_sync() -> bool; } -impl<'a> SystemData<'a> for () { - type View = (); - +impl<'a> Borrow<'a> for () { fn try_borrow( _: &'a AtomicRefCell, - #[cfg(feature = "parallel")] _: &'a ThreadPool, - ) -> Result { + #[cfg(feature = "parallel")] _: &'a rayon::ThreadPool, + ) -> Result + where + Self: Sized, + { Ok(()) } @@ -53,13 +65,11 @@ impl<'a> SystemData<'a> for () { } } -impl<'a> SystemData<'a> for AllStorages { - type View = AllStoragesViewMut<'a>; - +impl<'a> Borrow<'a> for AllStoragesViewMut<'a> { fn try_borrow( all_storages: &'a AtomicRefCell, - #[cfg(feature = "parallel")] _: &'a ThreadPool, - ) -> Result { + #[cfg(feature = "parallel")] _: &'a rayon::ThreadPool, + ) -> Result { all_storages.try_into() } @@ -72,13 +82,11 @@ impl<'a> SystemData<'a> for AllStorages { } } -impl<'a> SystemData<'a> for Entities { - type View = EntitiesView<'a>; - +impl<'a> Borrow<'a> for EntitiesView<'a> { fn try_borrow( all_storages: &'a AtomicRefCell, - #[cfg(feature = "parallel")] _: &'a ThreadPool, - ) -> Result { + #[cfg(feature = "parallel")] _: &'a rayon::ThreadPool, + ) -> Result { all_storages .try_borrow() .map_err(error::GetStorage::AllStoragesBorrow)? @@ -94,13 +102,11 @@ impl<'a> SystemData<'a> for Entities { } } -impl<'a> SystemData<'a> for EntitiesMut { - type View = EntitiesViewMut<'a>; - +impl<'a> Borrow<'a> for EntitiesViewMut<'a> { fn try_borrow( all_storages: &'a AtomicRefCell, - #[cfg(feature = "parallel")] _: &'a ThreadPool, - ) -> Result { + #[cfg(feature = "parallel")] _: &'a rayon::ThreadPool, + ) -> Result { all_storages .try_borrow() .map_err(error::GetStorage::AllStoragesBorrow)? @@ -117,14 +123,12 @@ impl<'a> SystemData<'a> for EntitiesMut { } #[cfg(feature = "parallel")] -impl<'a> SystemData<'a> for crate::ThreadPool { - type View = &'a ThreadPool; - +impl<'a> Borrow<'a> for ThreadPoolView<'a> { fn try_borrow( _: &'a AtomicRefCell, - thread_pool: &'a ThreadPool, - ) -> Result { - Ok(thread_pool) + thread_pool: &'a rayon::ThreadPool, + ) -> Result { + Ok(ThreadPoolView(thread_pool)) } fn borrow_infos(_: &mut Vec<(TypeId, Mutation)>) {} @@ -134,13 +138,11 @@ impl<'a> SystemData<'a> for crate::ThreadPool { } } -impl<'a, T: 'static + Send + Sync> SystemData<'a> for &T { - type View = View<'a, T>; - +impl<'a, T: 'static + Send + Sync> Borrow<'a> for View<'a, T> { fn try_borrow( all_storages: &'a AtomicRefCell, - #[cfg(feature = "parallel")] _: &'a ThreadPool, - ) -> Result { + #[cfg(feature = "parallel")] _: &'a rayon::ThreadPool, + ) -> Result { all_storages .try_borrow() .map_err(error::GetStorage::AllStoragesBorrow)? @@ -156,13 +158,11 @@ impl<'a, T: 'static + Send + Sync> SystemData<'a> for &T { } } -impl<'a, T: 'static + Send + Sync> SystemData<'a> for &mut T { - type View = ViewMut<'a, T>; - +impl<'a, T: 'static + Send + Sync> Borrow<'a> for ViewMut<'a, T> { fn try_borrow( all_storages: &'a AtomicRefCell, - #[cfg(feature = "parallel")] _: &'a ThreadPool, - ) -> Result { + #[cfg(feature = "parallel")] _: &'a rayon::ThreadPool, + ) -> Result { all_storages .try_borrow() .map_err(error::GetStorage::AllStoragesBorrow)? @@ -178,13 +178,11 @@ impl<'a, T: 'static + Send + Sync> SystemData<'a> for &mut T { } } -impl<'a, T: 'static + Send + Sync> SystemData<'a> for Unique<&T> { - type View = UniqueView<'a, T>; - +impl<'a, T: 'static + Send + Sync> Borrow<'a> for UniqueView<'a, T> { fn try_borrow( all_storages: &'a AtomicRefCell, - #[cfg(feature = "parallel")] _: &'a ThreadPool, - ) -> Result { + #[cfg(feature = "parallel")] _: &'a rayon::ThreadPool, + ) -> Result { all_storages .try_borrow() .map_err(error::GetStorage::AllStoragesBorrow)? @@ -192,21 +190,19 @@ impl<'a, T: 'static + Send + Sync> SystemData<'a> for Unique<&T> { } fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { - <&T as SystemData>::borrow_infos(infos) + as Borrow>::borrow_infos(infos) } fn is_send_sync() -> bool { - <&T as SystemData>::is_send_sync() + as Borrow>::is_send_sync() } } -impl<'a, T: 'static + Send + Sync> SystemData<'a> for Unique<&mut T> { - type View = UniqueViewMut<'a, T>; - +impl<'a, T: 'static + Send + Sync> Borrow<'a> for UniqueViewMut<'a, T> { fn try_borrow( all_storages: &'a AtomicRefCell, - #[cfg(feature = "parallel")] _: &'a ThreadPool, - ) -> Result { + #[cfg(feature = "parallel")] _: &'a rayon::ThreadPool, + ) -> Result { all_storages .try_borrow() .map_err(error::GetStorage::AllStoragesBorrow)? @@ -214,27 +210,26 @@ impl<'a, T: 'static + Send + Sync> SystemData<'a> for Unique<&mut T> { } fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { - <&mut T as SystemData>::borrow_infos(infos) + as Borrow>::borrow_infos(infos) } fn is_send_sync() -> bool { - <&mut T as SystemData>::is_send_sync() + as Borrow>::is_send_sync() } } #[cfg(feature = "non_send")] -impl<'a, T: 'static + Sync> SystemData<'a> for NonSend<&T> { - type View = View<'a, T>; - +impl<'a, T: 'static + Sync> Borrow<'a> for NonSend> { fn try_borrow( all_storages: &'a AtomicRefCell, - #[cfg(feature = "parallel")] _: &'a ThreadPool, - ) -> Result { + #[cfg(feature = "parallel")] _: &'a rayon::ThreadPool, + ) -> Result { View::try_from_non_send( all_storages .try_borrow() .map_err(error::GetStorage::AllStoragesBorrow)?, ) + .map(|view| NonSend(view)) } fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { @@ -247,18 +242,17 @@ impl<'a, T: 'static + Sync> SystemData<'a> for NonSend<&T> { } #[cfg(feature = "non_send")] -impl<'a, T: 'static + Sync> SystemData<'a> for NonSend<&mut T> { - type View = ViewMut<'a, T>; - +impl<'a, T: 'static + Sync> Borrow<'a> for NonSend> { fn try_borrow( all_storages: &'a AtomicRefCell, - #[cfg(feature = "parallel")] _: &'a ThreadPool, - ) -> Result { + #[cfg(feature = "parallel")] _: &'a rayon::ThreadPool, + ) -> Result { ViewMut::try_from_non_send( all_storages .try_borrow() .map_err(error::GetStorage::AllStoragesBorrow)?, ) + .map(|view| NonSend(view)) } fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { @@ -271,66 +265,63 @@ impl<'a, T: 'static + Sync> SystemData<'a> for NonSend<&mut T> { } #[cfg(feature = "non_send")] -impl<'a, T: 'static + Sync> SystemData<'a> for Unique> { - type View = UniqueView<'a, T>; - +impl<'a, T: 'static + Sync> Borrow<'a> for NonSend> { fn try_borrow( all_storages: &'a AtomicRefCell, - #[cfg(feature = "parallel")] _: &'a ThreadPool, - ) -> Result { + #[cfg(feature = "parallel")] _: &'a rayon::ThreadPool, + ) -> Result { UniqueView::try_from_non_send( all_storages .try_borrow() .map_err(error::GetStorage::AllStoragesBorrow)?, ) + .map(|view| NonSend(view)) } fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { - as SystemData>::borrow_infos(infos) + > as Borrow>::borrow_infos(infos) } fn is_send_sync() -> bool { - as SystemData>::is_send_sync() + false } } #[cfg(feature = "non_send")] -impl<'a, T: 'static + Sync> SystemData<'a> for Unique> { - type View = UniqueViewMut<'a, T>; - +impl<'a, T: 'static + Sync> Borrow<'a> for NonSend> { fn try_borrow( all_storages: &'a AtomicRefCell, - #[cfg(feature = "parallel")] _: &'a ThreadPool, - ) -> Result { + #[cfg(feature = "parallel")] _: &'a rayon::ThreadPool, + ) -> Result { UniqueViewMut::try_from_non_send( all_storages .try_borrow() .map_err(error::GetStorage::AllStoragesBorrow)?, ) + .map(|view| NonSend(view)) } fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { - as SystemData>::borrow_infos(infos) + > as Borrow>::borrow_infos(infos) } fn is_send_sync() -> bool { - as SystemData>::is_send_sync() + false } } #[cfg(feature = "non_sync")] -impl<'a, T: 'static + Send> SystemData<'a> for NonSync<&T> { - type View = View<'a, T>; - +impl<'a, T: 'static + Send> Borrow<'a> for NonSync> { fn try_borrow( all_storages: &'a AtomicRefCell, - #[cfg(feature = "parallel")] _: &'a ThreadPool, - ) -> Result { + #[cfg(feature = "parallel")] _: &'a rayon::ThreadPool, + ) -> Result { View::try_from_non_sync( all_storages .try_borrow() .map_err(error::GetStorage::AllStoragesBorrow)?, ) + .map(|view| NonSync(view)) } fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { @@ -343,18 +334,17 @@ impl<'a, T: 'static + Send> SystemData<'a> for NonSync<&T> { } #[cfg(feature = "non_sync")] -impl<'a, T: 'static + Send> SystemData<'a> for NonSync<&mut T> { - type View = ViewMut<'a, T>; - +impl<'a, T: 'static + Send> Borrow<'a> for NonSync> { fn try_borrow( all_storages: &'a AtomicRefCell, - #[cfg(feature = "parallel")] _: &'a ThreadPool, - ) -> Result { + #[cfg(feature = "parallel")] _: &'a rayon::ThreadPool, + ) -> Result { ViewMut::try_from_non_sync( all_storages .try_borrow() .map_err(error::GetStorage::AllStoragesBorrow)?, ) + .map(|view| NonSync(view)) } fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { @@ -367,66 +357,63 @@ impl<'a, T: 'static + Send> SystemData<'a> for NonSync<&mut T> { } #[cfg(feature = "non_sync")] -impl<'a, T: 'static + Send> SystemData<'a> for Unique> { - type View = UniqueView<'a, T>; - +impl<'a, T: 'static + Send> Borrow<'a> for NonSync> { fn try_borrow( all_storages: &'a AtomicRefCell, - #[cfg(feature = "parallel")] _: &'a ThreadPool, - ) -> Result { + #[cfg(feature = "parallel")] _: &'a rayon::ThreadPool, + ) -> Result { UniqueView::try_from_non_sync( all_storages .try_borrow() .map_err(error::GetStorage::AllStoragesBorrow)?, ) + .map(|view| NonSync(view)) } fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { - as SystemData>::borrow_infos(infos) + > as Borrow>::borrow_infos(infos) } fn is_send_sync() -> bool { - as SystemData>::is_send_sync() + > as Borrow>::is_send_sync() } } #[cfg(feature = "non_sync")] -impl<'a, T: 'static + Send> SystemData<'a> for Unique> { - type View = UniqueViewMut<'a, T>; - +impl<'a, T: 'static + Send> Borrow<'a> for NonSync> { fn try_borrow( all_storages: &'a AtomicRefCell, - #[cfg(feature = "parallel")] _: &'a ThreadPool, - ) -> Result { + #[cfg(feature = "parallel")] _: &'a rayon::ThreadPool, + ) -> Result { UniqueViewMut::try_from_non_sync( all_storages .try_borrow() .map_err(error::GetStorage::AllStoragesBorrow)?, ) + .map(|view| NonSync(view)) } fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { - as SystemData>::borrow_infos(infos) + > as Borrow>::borrow_infos(infos) } fn is_send_sync() -> bool { - as SystemData>::is_send_sync() + > as Borrow>::is_send_sync() } } #[cfg(all(feature = "non_send", feature = "non_sync"))] -impl<'a, T: 'static> SystemData<'a> for NonSendSync<&T> { - type View = View<'a, T>; - +impl<'a, T: 'static> Borrow<'a> for NonSendSync> { fn try_borrow( all_storages: &'a AtomicRefCell, - #[cfg(feature = "parallel")] _: &'a ThreadPool, - ) -> Result { + #[cfg(feature = "parallel")] _: &'a rayon::ThreadPool, + ) -> Result { View::try_from_non_send_sync( all_storages .try_borrow() .map_err(error::GetStorage::AllStoragesBorrow)?, ) + .map(|view| NonSendSync(view)) } fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { @@ -439,18 +426,17 @@ impl<'a, T: 'static> SystemData<'a> for NonSendSync<&T> { } #[cfg(all(feature = "non_send", feature = "non_sync"))] -impl<'a, T: 'static> SystemData<'a> for NonSendSync<&mut T> { - type View = ViewMut<'a, T>; - +impl<'a, T: 'static> Borrow<'a> for NonSendSync> { fn try_borrow( all_storages: &'a AtomicRefCell, - #[cfg(feature = "parallel")] _: &'a ThreadPool, - ) -> Result { + #[cfg(feature = "parallel")] _: &'a rayon::ThreadPool, + ) -> Result { ViewMut::try_from_non_send_sync( all_storages .try_borrow() .map_err(error::GetStorage::AllStoragesBorrow)?, ) + .map(|view| NonSendSync(view)) } fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { @@ -463,61 +449,56 @@ impl<'a, T: 'static> SystemData<'a> for NonSendSync<&mut T> { } #[cfg(all(feature = "non_send", feature = "non_sync"))] -impl<'a, T: 'static> SystemData<'a> for Unique> { - type View = UniqueView<'a, T>; - +impl<'a, T: 'static> Borrow<'a> for NonSendSync> { fn try_borrow( all_storages: &'a AtomicRefCell, - #[cfg(feature = "parallel")] _: &'a ThreadPool, - ) -> Result { + #[cfg(feature = "parallel")] _: &'a rayon::ThreadPool, + ) -> Result { UniqueView::try_from_non_send_sync( all_storages .try_borrow() .map_err(error::GetStorage::AllStoragesBorrow)?, ) + .map(|view| NonSendSync(view)) } - fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { - as SystemData>::borrow_infos(infos) + > as Borrow>::borrow_infos(infos) } fn is_send_sync() -> bool { - as SystemData>::is_send_sync() + > as Borrow>::is_send_sync() } } #[cfg(all(feature = "non_send", feature = "non_sync"))] -impl<'a, T: 'static> SystemData<'a> for Unique> { - type View = UniqueViewMut<'a, T>; - +impl<'a, T: 'static> Borrow<'a> for NonSendSync> { fn try_borrow( all_storages: &'a AtomicRefCell, - #[cfg(feature = "parallel")] _: &'a ThreadPool, - ) -> Result { + #[cfg(feature = "parallel")] _: &'a rayon::ThreadPool, + ) -> Result { UniqueViewMut::try_from_non_send_sync( all_storages .try_borrow() .map_err(error::GetStorage::AllStoragesBorrow)?, ) + .map(|view| NonSendSync(view)) } fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { - as SystemData>::borrow_infos(infos) + > as Borrow>::borrow_infos(infos) } fn is_send_sync() -> bool { - as SystemData>::is_send_sync() + > as Borrow>::is_send_sync() } } -impl<'a, T: 'static> SystemData<'a> for FakeBorrow { - type View = (); - +impl<'a, T: 'static> Borrow<'a> for FakeBorrow { fn try_borrow( _: &'a AtomicRefCell, - #[cfg(feature = "parallel")] _: &'a ThreadPool, - ) -> Result { - Ok(()) + #[cfg(feature = "parallel")] _: &'a rayon::ThreadPool, + ) -> Result { + Ok(FakeBorrow::new()) } fn borrow_infos(infos: &mut Vec<(TypeId, Mutation)>) { @@ -531,23 +512,21 @@ impl<'a, T: 'static> SystemData<'a> for FakeBorrow { macro_rules! impl_system_data { ($(($type: ident, $index: tt))+) => { - impl<'a, $($type: SystemData<'a>),+> SystemData<'a> for ($($type,)+) { - type View = ($($type::View,)+); - + impl<'a, $($type: Borrow<'a>),+> Borrow<'a> for ($($type,)+) { fn try_borrow( - storages: &'a AtomicRefCell, - #[cfg(feature = "parallel")] thread_pool: &'a ThreadPool, - ) -> Result { + all_storages: &'a AtomicRefCell, + #[cfg(feature = "parallel")] thread_pool: &'a rayon::ThreadPool, + ) -> Result { #[cfg(feature = "parallel")] { Ok(($( - <$type as SystemData>::try_borrow(storages, thread_pool)?, + <$type as Borrow>::try_borrow(all_storages, thread_pool)?, )+)) } #[cfg(not(feature = "parallel"))] { Ok(($( - <$type as SystemData>::try_borrow(storages)?, + <$type as Borrow>::try_borrow(all_storages)?, )+)) } } diff --git a/src/borrow/non_send.rs b/src/borrow/non_send.rs new file mode 100644 index 00000000..52a310fc --- /dev/null +++ b/src/borrow/non_send.rs @@ -0,0 +1,31 @@ +use core::convert::{AsMut, AsRef}; +use core::ops::{Deref, DerefMut}; + +/// Type used to access `!Send` storages. +#[cfg_attr(docsrs, doc(cfg(feature = "non_send")))] +pub struct NonSend(pub(crate) T); + +impl AsRef for NonSend { + fn as_ref(&self) -> &T { + &self.0 + } +} + +impl AsMut for NonSend { + fn as_mut(&mut self) -> &mut T { + &mut self.0 + } +} + +impl Deref for NonSend { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for NonSend { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} diff --git a/src/borrow/non_send_sync.rs b/src/borrow/non_send_sync.rs new file mode 100644 index 00000000..16f71414 --- /dev/null +++ b/src/borrow/non_send_sync.rs @@ -0,0 +1,31 @@ +use core::convert::{AsMut, AsRef}; +use core::ops::{Deref, DerefMut}; + +/// Type used to access `!Send + !Sync` storages. +#[cfg_attr(docsrs, doc(cfg(all(feature = "non_send", feature = "non_sync"))))] +pub struct NonSendSync(pub(crate) T); + +impl AsRef for NonSendSync { + fn as_ref(&self) -> &T { + &self.0 + } +} + +impl AsMut for NonSendSync { + fn as_mut(&mut self) -> &mut T { + &mut self.0 + } +} + +impl Deref for NonSendSync { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for NonSendSync { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} diff --git a/src/borrow/non_sync.rs b/src/borrow/non_sync.rs new file mode 100644 index 00000000..5e95ae9c --- /dev/null +++ b/src/borrow/non_sync.rs @@ -0,0 +1,31 @@ +use core::convert::{AsMut, AsRef}; +use core::ops::{Deref, DerefMut}; + +/// Type used to access `!Sync` storages. +#[cfg_attr(docsrs, doc(cfg(feature = "non_sync")))] +pub struct NonSync(pub(crate) T); + +impl AsRef for NonSync { + fn as_ref(&self) -> &T { + &self.0 + } +} + +impl AsMut for NonSync { + fn as_mut(&mut self) -> &mut T { + &mut self.0 + } +} + +impl Deref for NonSync { + type Target = T; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for NonSync { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} diff --git a/src/delete.rs b/src/delete.rs index 8bf4c5f0..b8e82ac4 100644 --- a/src/delete.rs +++ b/src/delete.rs @@ -1,7 +1,7 @@ use crate::error; use crate::sparse_set::Pack; use crate::storage::EntityId; -use crate::views::ViewMut; +use crate::view::ViewMut; use alloc::vec::Vec; use core::any::{type_name, TypeId}; @@ -12,7 +12,7 @@ pub trait Delete { /// /// ### Example: /// ``` - /// # use shipyard::prelude::*; + /// # use shipyard::*; /// let world = World::new(); /// /// let (mut entities, mut usizes, mut u32s) = world.borrow::<(EntitiesMut, &mut usize, &mut u32)>(); @@ -29,7 +29,7 @@ pub trait Delete { /// /// ### Example: /// ``` - /// # use shipyard::prelude::*; + /// # use shipyard::*; /// let world = World::new(); /// /// let (mut entities, mut usizes, mut u32s) = world.borrow::<(EntitiesMut, &mut usize, &mut u32)>(); diff --git a/src/error.rs b/src/error.rs index 9cf559c0..0f220241 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,4 +1,5 @@ use crate::EntityId; +use alloc::boxed::Box; use core::fmt::{Debug, Display, Formatter}; #[cfg(feature = "std")] use std::error::Error; @@ -274,30 +275,25 @@ impl Display for SetDefaultWorkload { /// Error related to `run_default` and `run_workload`. /// The error can be a storage error, problem with the scheduler's borrowing or a non existant workload. -#[derive(Clone, Copy, PartialEq, Eq)] pub enum RunWorkload { Scheduler, - GetStorage(GetStorage), + Run((&'static str, Run)), MissingWorkload, } #[cfg(feature = "std")] impl Error for RunWorkload {} -impl From for RunWorkload { - fn from(get_storage: GetStorage) -> Self { - RunWorkload::GetStorage(get_storage) - } -} - impl Debug for RunWorkload { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), core::fmt::Error> { match self { Self::Scheduler => { - fmt.write_str("Cannot borrow scheduler while it's already mutably borrowed.") + fmt.write_str("Cannot borrow the scheduler while it's already mutably borrowed.") } Self::MissingWorkload => fmt.write_str("No workload with this name exists."), - Self::GetStorage(get_storage) => Debug::fmt(get_storage, fmt), + Self::Run((system_name, run)) => { + fmt.write_fmt(format_args!("System {} failed: {:?}", system_name, run)) + } } } } @@ -308,6 +304,41 @@ impl Display for RunWorkload { } } +pub enum Run { + GetStorage(GetStorage), + Custom(Box), +} + +impl From for Run { + fn from(get_storage: GetStorage) -> Self { + Run::GetStorage(get_storage) + } +} + +impl Run { + pub fn from_custom(error: E) -> Self { + Run::Custom(Box::new(error)) + } +} + +#[cfg(feature = "std")] +impl Error for Run {} + +impl Debug for Run { + fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), core::fmt::Error> { + match self { + Self::GetStorage(get_storage) => Debug::fmt(&get_storage, fmt), + Self::Custom(_) => fmt.write_fmt(format_args!("run failed with a custom error.")), + } + } +} + +impl Display for Run { + fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), core::fmt::Error> { + Debug::fmt(self, fmt) + } +} + /// Error occuring when trying to sort a packed storage but providing too few or too many storages. #[derive(Clone, Copy, PartialEq, Eq)] pub enum Sort { diff --git a/src/get.rs b/src/get.rs index 74816893..1f9c7150 100644 --- a/src/get.rs +++ b/src/get.rs @@ -1,7 +1,7 @@ use crate::error; use crate::sparse_set::{Window, WindowMut}; use crate::storage::EntityId; -use crate::views::{View, ViewMut}; +use crate::view::{View, ViewMut}; use core::any::type_name; /// Retrives components based on their type and entity id. @@ -13,7 +13,7 @@ pub trait GetComponent { /// /// ### Example: /// ``` - /// # use shipyard::prelude::*; + /// # use shipyard::*; /// let world = World::new(); /// /// world.run::<(EntitiesMut, &mut usize, &mut u32), _, _>(|(mut entities, mut usizes, mut u32s)| { diff --git a/src/internal.rs b/src/internal.rs deleted file mode 100644 index 5d583675..00000000 --- a/src/internal.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub use crate::iter::iterators; -pub use crate::iter::{Enumerate, Filter, Map, WithId}; -pub use crate::sparse_set::sort::{ - Sort1, Sort10, Sort2, Sort3, Sort4, Sort5, Sort6, Sort7, Sort8, Sort9, -}; -pub use crate::sparse_set::WindowSort1; -pub use crate::storage::StorageId; diff --git a/src/iter/enumerate.rs b/src/iter/enumerate.rs index 55e96abe..4b1aa85f 100644 --- a/src/iter/enumerate.rs +++ b/src/iter/enumerate.rs @@ -1,4 +1,4 @@ -use super::{CurrentId, Shiperator}; +use super::{CurrentId, IntoIterator, Shiperator}; /// Shiperator yielding iteration count as well. pub struct Enumerate { @@ -36,3 +36,11 @@ impl CurrentId for Enumerate { self.iter.current_id() } } + +impl core::iter::IntoIterator for Enumerate { + type IntoIter = IntoIterator; + type Item = ::Item; + fn into_iter(self) -> Self::IntoIter { + IntoIterator(self) + } +} diff --git a/src/iter/filter.rs b/src/iter/filter.rs index aa0d94cb..7310c653 100644 --- a/src/iter/filter.rs +++ b/src/iter/filter.rs @@ -1,4 +1,4 @@ -use super::{CurrentId, Shiperator}; +use super::{CurrentId, IntoIterator, Shiperator}; /// Shiperator filtering all components with `pred`. pub struct Filter { @@ -44,3 +44,14 @@ where self.iter.current_id() } } + +impl core::iter::IntoIterator for Filter +where + P: FnMut(&I::Item) -> bool, +{ + type IntoIter = IntoIterator; + type Item = ::Item; + fn into_iter(self) -> Self::IntoIter { + IntoIterator(self) + } +} diff --git a/src/iter/into_abstract.rs b/src/iter/into_abstract.rs index 59352800..baeef4b3 100644 --- a/src/iter/into_abstract.rs +++ b/src/iter/into_abstract.rs @@ -1,7 +1,7 @@ use super::abstract_mut::AbstractMut; use crate::not::Not; use crate::sparse_set::{Pack, PackInfo, RawWindowMut, Window, WindowMut}; -use crate::views::{View, ViewMut}; +use crate::view::{View, ViewMut}; use core::any::TypeId; // Allows to make ViewMut's sparse and dense fields immutable diff --git a/src/iter/into_iter/mod.rs b/src/iter/into_iter/mod.rs index 6aea3d13..e6ca2487 100644 --- a/src/iter/into_iter/mod.rs +++ b/src/iter/into_iter/mod.rs @@ -20,7 +20,7 @@ pub trait IntoIter { /// Iterators can only be made inside [run] closure and systems. /// ### Example /// ``` - /// # use shipyard::prelude::*; + /// # use shipyard::*; /// let world = World::new(); /// /// world.run::<(EntitiesMut, &mut usize, &mut u32), _, _>(|(mut entities, mut usizes, mut u32s)| { @@ -38,7 +38,7 @@ pub trait IntoIter { /// Iterators can only be made inside [run] closure and systems. /// ### Example /// ``` - /// # use shipyard::prelude::*; + /// # use shipyard::*; /// use rayon::prelude::ParallelIterator; /// /// let world = World::new(); diff --git a/src/iter/iterators/iter/mod.rs b/src/iter/iterators/iter/mod.rs index 61dc5e6a..6779045a 100644 --- a/src/iter/iterators/iter/mod.rs +++ b/src/iter/iterators/iter/mod.rs @@ -6,7 +6,8 @@ mod par_single; mod single; use super::{ - loose::*, non_packed::*, tight::*, update::*, AbstractMut, CurrentId, IntoAbstract, Shiperator, + loose::*, non_packed::*, tight::*, update::*, AbstractMut, CurrentId, IntoAbstract, + IntoIterator, Shiperator, }; pub use multiple::*; diff --git a/src/iter/iterators/iter/multiple.rs b/src/iter/iterators/iter/multiple.rs index e787163f..8dbe096c 100644 --- a/src/iter/iterators/iter/multiple.rs +++ b/src/iter/iterators/iter/multiple.rs @@ -79,6 +79,14 @@ This enum allows to abstract away what kind of iterator you really get. That doe } } } + + impl<$($type: IntoAbstract),+> core::iter::IntoIterator for $iter<$($type),+> { + type IntoIter = IntoIterator; + type Item = ::Item; + fn into_iter(self) -> Self::IntoIter { + IntoIterator(self) + } + } } } diff --git a/src/iter/iterators/iter/single.rs b/src/iter/iterators/iter/single.rs index 5c3fe5e3..12c8b5a8 100644 --- a/src/iter/iterators/iter/single.rs +++ b/src/iter/iterators/iter/single.rs @@ -1,5 +1,6 @@ use super::{ - AbstractMut, Chunk1, ChunkExact1, CurrentId, IntoAbstract, Shiperator, Tight1, Update1, + AbstractMut, Chunk1, ChunkExact1, CurrentId, IntoAbstract, IntoIterator, Shiperator, Tight1, + Update1, }; use crate::EntityId; @@ -63,3 +64,11 @@ impl CurrentId for Iter1 { } } } + +impl core::iter::IntoIterator for Iter1 { + type IntoIter = IntoIterator; + type Item = ::Item; + fn into_iter(self) -> Self::IntoIter { + IntoIterator(self) + } +} diff --git a/src/iter/iterators/loose/mod.rs b/src/iter/iterators/loose/mod.rs index 73626a12..6175894c 100644 --- a/src/iter/iterators/loose/mod.rs +++ b/src/iter/iterators/loose/mod.rs @@ -2,10 +2,9 @@ mod multiple; #[cfg(feature = "parallel")] mod par_multiple; -#[cfg(feature = "parallel")] -use super::IntoIterator; use super::{ - AbstractMut, CurrentId, DoubleEndedShiperator, ExactSizeShiperator, IntoAbstract, Shiperator, + AbstractMut, CurrentId, DoubleEndedShiperator, ExactSizeShiperator, IntoAbstract, IntoIterator, + Shiperator, }; pub use multiple::*; diff --git a/src/iter/iterators/loose/multiple.rs b/src/iter/iterators/loose/multiple.rs index af381b97..1c5e879e 100644 --- a/src/iter/iterators/loose/multiple.rs +++ b/src/iter/iterators/loose/multiple.rs @@ -1,7 +1,6 @@ -#[cfg(feature = "parallel")] -use super::IntoIterator; use super::{ - AbstractMut, CurrentId, DoubleEndedShiperator, ExactSizeShiperator, IntoAbstract, Shiperator, + AbstractMut, CurrentId, DoubleEndedShiperator, ExactSizeShiperator, IntoAbstract, IntoIterator, + Shiperator, }; use crate::EntityId; use core::ptr; @@ -99,7 +98,7 @@ macro_rules! impl_iterators { type Item = ($(<$type::AbsView as AbstractMut>::Out),+); type IntoIter = IntoIterator; fn into_iter(self) -> Self::IntoIter { - ::into_iter(self) + core::iter::IntoIterator::into_iter(self) } fn split_at(mut self, index: usize) -> (Self, Self) { let clone = $loose { @@ -113,6 +112,14 @@ macro_rules! impl_iterators { (self, clone) } } + + impl<$($type: IntoAbstract),+> core::iter::IntoIterator for $loose<$($type),+> { + type IntoIter = IntoIterator; + type Item = ::Item; + fn into_iter(self) -> Self::IntoIter { + IntoIterator(self) + } + } } } diff --git a/src/iter/iterators/mod.rs b/src/iter/iterators/mod.rs index 99643392..9049d436 100644 --- a/src/iter/iterators/mod.rs +++ b/src/iter/iterators/mod.rs @@ -6,9 +6,7 @@ mod update; use super::abstract_mut::AbstractMut; use super::into_abstract::IntoAbstract; -#[cfg(feature = "parallel")] -use super::IntoIterator; -use super::{CurrentId, DoubleEndedShiperator, ExactSizeShiperator, Shiperator}; +use super::{CurrentId, DoubleEndedShiperator, ExactSizeShiperator, IntoIterator, Shiperator}; pub use iter::*; pub use loose::*; diff --git a/src/iter/iterators/non_packed/mod.rs b/src/iter/iterators/non_packed/mod.rs index d0c1115f..b64ee52a 100644 --- a/src/iter/iterators/non_packed/mod.rs +++ b/src/iter/iterators/non_packed/mod.rs @@ -2,7 +2,7 @@ mod multiple; #[cfg(feature = "parallel")] mod par_multiple; -use super::{AbstractMut, CurrentId, IntoAbstract, Shiperator}; +use super::{AbstractMut, CurrentId, IntoAbstract, IntoIterator, Shiperator}; pub use multiple::*; #[cfg(feature = "parallel")] diff --git a/src/iter/iterators/non_packed/multiple.rs b/src/iter/iterators/non_packed/multiple.rs index d10c7b77..59b943f5 100644 --- a/src/iter/iterators/non_packed/multiple.rs +++ b/src/iter/iterators/non_packed/multiple.rs @@ -1,5 +1,5 @@ use super::super::update::*; -use super::{AbstractMut, CurrentId, IntoAbstract, Shiperator}; +use super::{AbstractMut, CurrentId, IntoAbstract, IntoIterator, Shiperator}; use crate::EntityId; use core::ptr; #[cfg(feature = "parallel")] @@ -97,7 +97,15 @@ macro_rules! impl_iterators { } } fn fold_with(self, folder: Fold) -> Fold where Fold: Folder { - folder.consume_iter(::into_iter(self)) + folder.consume_iter(core::iter::IntoIterator::into_iter(self)) + } + } + + impl<$($type: IntoAbstract),+> core::iter::IntoIterator for $non_packed<$($type),+> { + type IntoIter = IntoIterator; + type Item = ::Item; + fn into_iter(self) -> Self::IntoIter { + IntoIterator(self) } } } diff --git a/src/iter/iterators/tight/chunk/mod.rs b/src/iter/iterators/tight/chunk/mod.rs index ab4e5228..f45b6936 100644 --- a/src/iter/iterators/tight/chunk/mod.rs +++ b/src/iter/iterators/tight/chunk/mod.rs @@ -1,7 +1,7 @@ pub(super) mod multiple; mod single; -use super::{AbstractMut, IntoAbstract, Shiperator}; +use super::{AbstractMut, IntoAbstract, IntoIterator, Shiperator}; pub use multiple::*; pub use single::Chunk1; diff --git a/src/iter/iterators/tight/chunk/multiple.rs b/src/iter/iterators/tight/chunk/multiple.rs index 79ed18a3..5ea659ee 100644 --- a/src/iter/iterators/tight/chunk/multiple.rs +++ b/src/iter/iterators/tight/chunk/multiple.rs @@ -1,4 +1,4 @@ -use super::{AbstractMut, IntoAbstract, Shiperator}; +use super::{AbstractMut, IntoAbstract, IntoIterator, Shiperator}; macro_rules! impl_iterators { ( @@ -43,6 +43,14 @@ The last chunk's length will be smaller than `size` if `size` does not divide th (len, Some(len)) } } + + impl<$($type: IntoAbstract),+> core::iter::IntoIterator for $chunk<$($type),+> { + type IntoIter = IntoIterator; + type Item = ::Item; + fn into_iter(self) -> Self::IntoIter { + IntoIterator(self) + } + } } } diff --git a/src/iter/iterators/tight/chunk/single.rs b/src/iter/iterators/tight/chunk/single.rs index cc5080a4..b8088e0c 100644 --- a/src/iter/iterators/tight/chunk/single.rs +++ b/src/iter/iterators/tight/chunk/single.rs @@ -1,4 +1,4 @@ -use super::{AbstractMut, IntoAbstract, Shiperator}; +use super::{AbstractMut, IntoAbstract, IntoIterator, Shiperator}; /// Chunk iterator over a single component. /// Returns slices `size` long except for the last one that might be smaller. @@ -32,3 +32,11 @@ impl Shiperator for Chunk1 { (len, Some(len)) } } + +impl core::iter::IntoIterator for Chunk1 { + type IntoIter = IntoIterator; + type Item = ::Item; + fn into_iter(self) -> Self::IntoIter { + IntoIterator(self) + } +} diff --git a/src/iter/iterators/tight/chunk_exact/mod.rs b/src/iter/iterators/tight/chunk_exact/mod.rs index 5c7861b7..04ebf29f 100644 --- a/src/iter/iterators/tight/chunk_exact/mod.rs +++ b/src/iter/iterators/tight/chunk_exact/mod.rs @@ -1,7 +1,7 @@ pub(super) mod multiple; mod single; -use super::{AbstractMut, IntoAbstract, Shiperator}; +use super::{AbstractMut, IntoAbstract, IntoIterator, Shiperator}; pub use multiple::*; pub use single::ChunkExact1; diff --git a/src/iter/iterators/tight/chunk_exact/multiple.rs b/src/iter/iterators/tight/chunk_exact/multiple.rs index 03297e3e..f9e9190d 100644 --- a/src/iter/iterators/tight/chunk_exact/multiple.rs +++ b/src/iter/iterators/tight/chunk_exact/multiple.rs @@ -1,4 +1,4 @@ -use super::{AbstractMut, IntoAbstract, Shiperator}; +use super::{AbstractMut, IntoAbstract, IntoIterator, Shiperator}; macro_rules! impl_iterators { ( @@ -51,6 +51,14 @@ To get the remaining items (if any) use the `remainder` method."] )+) } } + + impl<$($type: IntoAbstract),+> core::iter::IntoIterator for $chunk_exact<$($type),+> { + type IntoIter = IntoIterator; + type Item = ::Item; + fn into_iter(self) -> Self::IntoIter { + IntoIterator(self) + } + } } } diff --git a/src/iter/iterators/tight/chunk_exact/single.rs b/src/iter/iterators/tight/chunk_exact/single.rs index 309d08ea..658f87a9 100644 --- a/src/iter/iterators/tight/chunk_exact/single.rs +++ b/src/iter/iterators/tight/chunk_exact/single.rs @@ -1,4 +1,4 @@ -use super::{AbstractMut, IntoAbstract, Shiperator}; +use super::{AbstractMut, IntoAbstract, IntoIterator, Shiperator}; /// Chunk iterator over a single component. /// Returns slices `size` long, to get the remaining items (if any) use the `remainder` method. @@ -38,3 +38,11 @@ impl Shiperator for ChunkExact1 { (len, Some(len)) } } + +impl core::iter::IntoIterator for ChunkExact1 { + type IntoIter = IntoIterator; + type Item = ::Item; + fn into_iter(self) -> Self::IntoIter { + IntoIterator(self) + } +} diff --git a/src/iter/iterators/tight/mod.rs b/src/iter/iterators/tight/mod.rs index 9462fc3c..264911f8 100644 --- a/src/iter/iterators/tight/mod.rs +++ b/src/iter/iterators/tight/mod.rs @@ -7,10 +7,9 @@ mod par_multiple; mod par_single; mod single; -#[cfg(feature = "parallel")] -use super::IntoIterator; use super::{ - AbstractMut, CurrentId, DoubleEndedShiperator, ExactSizeShiperator, IntoAbstract, Shiperator, + AbstractMut, CurrentId, DoubleEndedShiperator, ExactSizeShiperator, IntoAbstract, IntoIterator, + Shiperator, }; pub use chunk::*; diff --git a/src/iter/iterators/tight/multiple.rs b/src/iter/iterators/tight/multiple.rs index 01ba87a6..2e5761e6 100644 --- a/src/iter/iterators/tight/multiple.rs +++ b/src/iter/iterators/tight/multiple.rs @@ -1,9 +1,8 @@ use super::chunk::multiple::*; use super::chunk_exact::multiple::*; -#[cfg(feature = "parallel")] -use super::IntoIterator; use super::{ - AbstractMut, CurrentId, DoubleEndedShiperator, ExactSizeShiperator, IntoAbstract, Shiperator, + AbstractMut, CurrentId, DoubleEndedShiperator, ExactSizeShiperator, IntoAbstract, IntoIterator, + Shiperator, }; use crate::EntityId; #[cfg(feature = "parallel")] @@ -98,7 +97,7 @@ Tight iterators are fast but are limited to components tightly packed together." type Item = ($(<$type::AbsView as AbstractMut>::Out),+); type IntoIter = IntoIterator; fn into_iter(self) -> Self::IntoIter { - ::into_iter(self) + core::iter::IntoIterator::into_iter(self) } fn split_at(mut self, index: usize) -> (Self, Self) { let clone = $tight { @@ -110,6 +109,14 @@ Tight iterators are fast but are limited to components tightly packed together." (self, clone) } } + + impl<$($type: IntoAbstract),+> core::iter::IntoIterator for $tight<$($type),+> { + type IntoIter = IntoIterator; + type Item = ::Item; + fn into_iter(self) -> Self::IntoIter { + IntoIterator(self) + } + } } } diff --git a/src/iter/iterators/tight/single.rs b/src/iter/iterators/tight/single.rs index fa15a5af..1b6f77c1 100644 --- a/src/iter/iterators/tight/single.rs +++ b/src/iter/iterators/tight/single.rs @@ -1,8 +1,6 @@ -#[cfg(feature = "parallel")] -use super::IntoIterator; use super::{ AbstractMut, Chunk1, ChunkExact1, CurrentId, DoubleEndedShiperator, ExactSizeShiperator, - IntoAbstract, Shiperator, + IntoAbstract, IntoIterator, Shiperator, }; use crate::EntityId; #[cfg(feature = "parallel")] @@ -98,7 +96,7 @@ where type Item = ::Out; type IntoIter = IntoIterator; fn into_iter(self) -> Self::IntoIter { - ::into_iter(self) + core::iter::IntoIterator::into_iter(self) } fn split_at(mut self, index: usize) -> (Self, Self) { let clone = Tight1 { @@ -110,3 +108,11 @@ where (self, clone) } } + +impl core::iter::IntoIterator for Tight1 { + type IntoIter = IntoIterator; + type Item = ::Item; + fn into_iter(self) -> Self::IntoIter { + IntoIterator(self) + } +} diff --git a/src/iter/iterators/update/mod.rs b/src/iter/iterators/update/mod.rs index 0bf47976..4bc88c11 100644 --- a/src/iter/iterators/update/mod.rs +++ b/src/iter/iterators/update/mod.rs @@ -4,12 +4,10 @@ mod par_single; mod single; use super::{ - AbstractMut, CurrentId, DoubleEndedShiperator, ExactSizeShiperator, IntoAbstract, Shiperator, + AbstractMut, CurrentId, DoubleEndedShiperator, ExactSizeShiperator, IntoAbstract, IntoIterator, + Shiperator, }; -#[cfg(feature = "parallel")] -use super::IntoIterator; - pub use multiple::*; #[cfg(feature = "parallel")] pub use par_single::ParUpdate1; diff --git a/src/iter/iterators/update/multiple.rs b/src/iter/iterators/update/multiple.rs index 2fa01a58..18a50333 100644 --- a/src/iter/iterators/update/multiple.rs +++ b/src/iter/iterators/update/multiple.rs @@ -1,4 +1,4 @@ -use super::{AbstractMut, CurrentId, IntoAbstract, Shiperator}; +use super::{AbstractMut, CurrentId, IntoAbstract, IntoIterator, Shiperator}; use crate::EntityId; use core::ptr; @@ -66,6 +66,14 @@ macro_rules! impl_iterators { self.current_id } } + + impl<$($type: IntoAbstract),+> core::iter::IntoIterator for $update<$($type),+> { + type IntoIter = IntoIterator; + type Item = ::Item; + fn into_iter(self) -> Self::IntoIter { + IntoIterator(self) + } + } } } diff --git a/src/iter/iterators/update/single.rs b/src/iter/iterators/update/single.rs index 32937cfd..ce19ccfd 100644 --- a/src/iter/iterators/update/single.rs +++ b/src/iter/iterators/update/single.rs @@ -1,5 +1,6 @@ use super::{ - AbstractMut, CurrentId, DoubleEndedShiperator, ExactSizeShiperator, IntoAbstract, Shiperator, + AbstractMut, CurrentId, DoubleEndedShiperator, ExactSizeShiperator, IntoAbstract, IntoIterator, + Shiperator, }; use crate::EntityId; @@ -70,3 +71,11 @@ impl DoubleEndedShiperator for Update1 { } } } + +impl core::iter::IntoIterator for Update1 { + type IntoIter = IntoIterator; + type Item = ::Item; + fn into_iter(self) -> Self::IntoIter { + IntoIterator(self) + } +} diff --git a/src/iter/map.rs b/src/iter/map.rs index 9b2b21f2..41719433 100644 --- a/src/iter/map.rs +++ b/src/iter/map.rs @@ -1,4 +1,4 @@ -use super::{CurrentId, Shiperator}; +use super::{CurrentId, IntoIterator, Shiperator}; /// Shiperator mapping all components with `f`. pub struct Map { @@ -39,3 +39,14 @@ where self.iter.current_id() } } + +impl core::iter::IntoIterator for Map +where + F: FnMut(I::Item) -> I::Item, +{ + type IntoIter = IntoIterator; + type Item = ::Item; + fn into_iter(self) -> Self::IntoIter { + IntoIterator(self) + } +} diff --git a/src/iter/shiperator.rs b/src/iter/shiperator.rs index 26e5a0e2..f0a4ea61 100644 --- a/src/iter/shiperator.rs +++ b/src/iter/shiperator.rs @@ -211,7 +211,7 @@ impl DoubleEndedShiperator for &mut S { pub struct IntoIterator(pub(crate) S); impl Iterator for IntoIterator { - type Item = ::Item; + type Item = S::Item; fn next(&mut self) -> Option { self.0.next() diff --git a/src/iter/with_id.rs b/src/iter/with_id.rs index 0c0c958f..986bc52f 100644 --- a/src/iter/with_id.rs +++ b/src/iter/with_id.rs @@ -1,4 +1,4 @@ -use super::{CurrentId, Shiperator}; +use super::{CurrentId, IntoIterator, Shiperator}; /// Shiperator yielding `EntityId` as well. pub struct WithId { @@ -34,3 +34,11 @@ impl CurrentId for WithId { self.iter.current_id() } } + +impl core::iter::IntoIterator for WithId { + type IntoIter = IntoIterator; + type Item = ::Item; + fn into_iter(self) -> Self::IntoIter { + IntoIterator(self) + } +} diff --git a/src/lib.rs b/src/lib.rs index 02a32b23..3cf84a96 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,7 +7,7 @@ //! ``` //! # #[cfg(feature = "proc")] //! # { -//! use shipyard::prelude::*; +//! use shipyard::*; //! //! struct Health(f32); //! struct Position { x: f32, y: f32 } @@ -46,7 +46,7 @@ //! ``` //! # #[cfg(all(feature = "parallel", feature = "proc"))] //! # { -//! use shipyard::prelude::*; +//! use shipyard::*; //! //! struct Health(f32); //! struct Fat(f32); @@ -110,7 +110,7 @@ //! ## Features //! //! - **parallel** *(default)* — adds parallel iterators and dispatch -//! - **proc** *(default)* — adds `system` proc macro +//! - **proc** — adds `system` proc macro //! - **serde** — adds (de)serialization support with [serde](https://github.com/serde-rs/serde) //! - **non_send** — add methods and types required to work with `!Send` components //! - **non_sync** — add methods and types required to work with `!Sync` components @@ -130,28 +130,35 @@ #![cfg_attr(not(any(feature = "std", test)), no_std)] #![cfg_attr(docsrs, feature(doc_cfg))] -#[macro_use] extern crate alloc; mod atomic_refcell; +mod borrow; mod delete; /// Contains all error types. pub mod error; mod get; -/// Re-export types that aren't needed in most use cases. -pub mod internal; mod iter; mod not; mod pack; -pub mod prelude; mod remove; -mod run; mod sparse_set; mod storage; +mod system_macro; mod unknown_storage; -mod views; +mod view; mod world; +#[cfg(feature = "non_send")] +pub use crate::borrow::NonSend; +#[cfg(all(feature = "non_send", feature = "non_sync"))] +pub use crate::borrow::NonSendSync; +#[cfg(feature = "non_sync")] +#[cfg_attr(docsrs, doc(cfg(feature = "non_sync")))] +pub use crate::borrow::NonSync; +#[doc(hidden)] +pub use crate::borrow::{AllStoragesBorrow, Borrow}; +pub use borrow::FakeBorrow; pub use delete::Delete; pub use get::GetComponent; pub use iter::{ @@ -161,52 +168,17 @@ pub use iter::{ pub use not::Not; pub use pack::{LoosePack, TightPack}; pub use remove::Remove; -pub use run::{FakeBorrow, System}; -#[doc(hidden)] -pub use run::{Run, StorageBorrow, SystemData}; #[doc(hidden)] #[cfg(feature = "proc")] -pub use shipyard_proc::system; +pub use shipyard_proc::system as system_fn; +pub use sparse_set::SparseSet; pub use sparse_set::{sort, sort::IntoSortable, Window, WindowMut}; pub use storage::{AllStorages, Entities, EntitiesMut, EntityId}; -pub use views::{ +#[cfg(feature = "parallel")] +pub use view::ThreadPoolView; +pub use view::{ AllStoragesViewMut, EntitiesView, EntitiesViewMut, UniqueView, UniqueViewMut, View, ViewMut, }; #[doc(hidden)] -pub use world::IntoWorkload; +pub use world::WorkloadBuilder; pub use world::World; - -/// Type used to borrow the rayon::ThreadPool inside `World`. -#[cfg(feature = "parallel")] -#[cfg_attr(docsrs, doc(cfg(feature = "parallel")))] -pub struct ThreadPool; - -/// Type used to access the value of a unique storage. -/// -/// You may know it as "Resource". -/// ### Example: -/// ``` -/// # use shipyard::prelude::*; -/// let world = World::default(); -/// world.add_unique(0usize); -/// -/// world.run::, _, _>(|mut x| { -/// *x += 1; -/// }); -/// ``` -pub struct Unique(T); - -/// Type used to access `!Send` storages. -#[cfg(feature = "non_send")] -#[cfg_attr(docsrs, doc(cfg(feature = "non_send")))] -pub struct NonSend(T); - -/// Type used to access `!Sync` storages. -#[cfg(feature = "non_sync")] -#[cfg_attr(docsrs, doc(cfg(feature = "non_sync")))] -pub struct NonSync(T); - -/// Type used to access `!Send + !Sync` storages. -#[cfg(all(feature = "non_send", feature = "non_sync"))] -#[cfg_attr(docsrs, doc(cfg(all(feature = "non_send", feature = "non_sync"))))] -pub struct NonSendSync(T); diff --git a/src/not.rs b/src/not.rs index 07805db5..92d1cc8d 100644 --- a/src/not.rs +++ b/src/not.rs @@ -1,11 +1,11 @@ -use crate::views::{View, ViewMut}; +use crate::view::{View, ViewMut}; use core::ops::Not as NotOps; /// Used to filter out components. /// Get and iterators will skip entities that have this component. /// ### Example /// ``` -/// # use shipyard::prelude::*; +/// # use shipyard::*; /// let world = World::new(); /// /// world.run::<(EntitiesMut, &mut usize, &mut u32), _, _>(|(mut entities, mut usizes, mut u32s)| { diff --git a/src/pack/loose.rs b/src/pack/loose.rs index e01a5915..0aa11d31 100644 --- a/src/pack/loose.rs +++ b/src/pack/loose.rs @@ -1,7 +1,7 @@ use crate::error; use crate::iter::{IntoIterIds, Shiperator}; use crate::sparse_set::{LoosePack as LoosePackInfo, Pack}; -use crate::views::ViewMut; +use crate::view::ViewMut; use alloc::boxed::Box; use alloc::sync::Arc; use alloc::vec::Vec; @@ -15,7 +15,7 @@ pub trait LoosePack { /// /// ### Example: /// ``` - /// # use shipyard::prelude::*; + /// # use shipyard::*; /// let world = World::new(); /// let (mut usizes, mut u32s) = world.borrow::<(&mut usize, &mut u32)>(); /// usizes.update_pack(); @@ -28,7 +28,7 @@ pub trait LoosePack { /// /// ### Example: /// ``` - /// # use shipyard::prelude::*; + /// # use shipyard::*; /// let world = World::new(); /// let (mut usizes, mut u32s) = world.borrow::<(&mut usize, &mut u32)>(); /// usizes.update_pack(); diff --git a/src/pack/tight.rs b/src/pack/tight.rs index b0adc510..d3375c83 100644 --- a/src/pack/tight.rs +++ b/src/pack/tight.rs @@ -1,6 +1,6 @@ use crate::error; use crate::sparse_set::{Pack, TightPack as TightPackInfo}; -use crate::views::ViewMut; +use crate::view::ViewMut; use alloc::boxed::Box; use alloc::sync::Arc; use alloc::vec::Vec; @@ -13,7 +13,7 @@ pub trait TightPack { /// /// ### Example: /// ``` - /// # use shipyard::prelude::*; + /// # use shipyard::*; /// let world = World::new(); /// let (mut usizes, mut u32s) = world.borrow::<(&mut usize, &mut u32)>(); /// (&mut usizes, &mut u32s).try_tight_pack().unwrap(); @@ -25,7 +25,7 @@ pub trait TightPack { /// /// ### Example: /// ``` - /// # use shipyard::prelude::*; + /// # use shipyard::*; /// let world = World::new(); /// let (mut usizes, mut u32s) = world.borrow::<(&mut usize, &mut u32)>(); /// (&mut usizes, &mut u32s).tight_pack(); diff --git a/src/prelude.rs b/src/prelude.rs deleted file mode 100644 index 2b9e8db3..00000000 --- a/src/prelude.rs +++ /dev/null @@ -1,33 +0,0 @@ -pub use crate::delete::Delete; -pub use crate::get::GetComponent; -pub use crate::iter::{CurrentId, ExactSizeShiperator, IntoIter, IntoIterIds, Shiperator}; -pub use crate::not::Not; -pub use crate::pack::{LoosePack, TightPack}; -pub use crate::remove::Remove; -pub use crate::run::{FakeBorrow, System}; -#[doc(hidden)] -pub use crate::run::{StorageBorrow, SystemData}; -pub use crate::sparse_set::sort::IntoSortable; -pub use crate::sparse_set::{Window, WindowMut}; -pub use crate::storage::{AllStorages, Entities, EntitiesMut, EntityId}; -pub use crate::views::{ - AllStoragesViewMut, EntitiesView, EntitiesViewMut, UniqueView, UniqueViewMut, View, ViewMut, -}; -pub use crate::world::World; -pub use crate::Unique; - -#[cfg(feature = "non_send")] -pub use crate::NonSend; - -#[cfg(feature = "non_sync")] -pub use crate::NonSync; - -#[cfg(all(feature = "non_send", feature = "non_sync"))] -pub use crate::NonSendSync; - -#[cfg(feature = "parallel")] -pub use crate::ThreadPool; - -#[doc(hidden)] -#[cfg(feature = "proc")] -pub use shipyard_proc::system; diff --git a/src/remove.rs b/src/remove.rs index f7735d30..cfaacd92 100644 --- a/src/remove.rs +++ b/src/remove.rs @@ -1,7 +1,7 @@ use crate::error; use crate::sparse_set::Pack; use crate::storage::EntityId; -use crate::views::ViewMut; +use crate::view::ViewMut; use alloc::vec::Vec; use core::any::{type_name, TypeId}; @@ -22,7 +22,7 @@ pub trait Remove { /// You'll often have to use the full path `Remove::::try_remove`. /// ### Example /// ``` - /// # use shipyard::prelude::*; + /// # use shipyard::*; /// let world = World::new(); /// /// world.run::<(EntitiesMut, &mut usize, &mut u32), _, _>(|(mut entities, mut usizes, mut u32s)| { @@ -35,7 +35,7 @@ pub trait Remove { /// even if you don't remove any component from it. /// ### Example /// ``` - /// # use shipyard::prelude::*; + /// # use shipyard::*; /// let world = World::new(); /// /// world.run::<(EntitiesMut, &mut usize, &mut u32), _, _>(|(mut entities, mut usizes, mut u32s)| { @@ -59,7 +59,7 @@ pub trait Remove { /// Unwraps errors. /// ### Example /// ``` - /// # use shipyard::prelude::*; + /// # use shipyard::*; /// let world = World::new(); /// /// world.run::<(EntitiesMut, &mut usize, &mut u32), _, _>(|(mut entities, mut usizes, mut u32s)| { @@ -72,7 +72,7 @@ pub trait Remove { /// even if you don't remove any component from it. /// ### Example /// ``` - /// # use shipyard::prelude::*; + /// # use shipyard::*; /// let world = World::new(); /// /// world.run::<(EntitiesMut, &mut usize, &mut u32), _, _>(|(mut entities, mut usizes, mut u32s)| { diff --git a/src/run/mod.rs b/src/run/mod.rs deleted file mode 100644 index 7473929c..00000000 --- a/src/run/mod.rs +++ /dev/null @@ -1,73 +0,0 @@ -mod storage_borrow; -mod system; -mod system_data; - -pub use storage_borrow::StorageBorrow; -pub(crate) use system::Dispatch; -pub use system::System; -pub(crate) use system_data::Mutation; -pub use system_data::SystemData; - -use crate::atomic_refcell::AtomicRefCell; -use crate::error; -use crate::storage::AllStorages; -#[cfg(feature = "parallel")] -use rayon::ThreadPool; - -pub trait Run<'a> { - type Storage; - - fn try_run R>( - storages: &'a AtomicRefCell, - #[cfg(feature = "parallel")] thread_pool: &'a ThreadPool, - f: F, - ) -> Result; -} - -impl<'a, T: SystemData<'a>> Run<'a> for T { - type Storage = T::View; - - fn try_run R>( - storages: &'a AtomicRefCell, - #[cfg(feature = "parallel")] thread_pool: &'a ThreadPool, - f: F, - ) -> Result { - let storage = { - #[cfg(feature = "parallel")] - { - T::try_borrow(storages, thread_pool)? - } - #[cfg(not(feature = "parallel"))] - { - T::try_borrow(storages)? - } - }; - - Ok(f(storage)) - } -} - -/// Mimics a system accessing a storage exclusively without actually doing it. -/// -/// Can be useful to correctly schedule `Sync` types. -/// # Example: -/// ``` -/// # #[cfg(feature = "proc")] -/// # { -/// # use shipyard::*; -/// #[system(DisplayFirst)] -/// fn run(positions: &usize) {} -/// -/// #[system(DisplaySecond)] -/// fn run(positions: &usize) {} -/// -/// let world = World::new(); -/// world.add_workload::<(DisplayFirst, FakeBorrow, DisplaySecond), _>("Display"); -/// # } -/// ``` -pub struct FakeBorrow(T); - -impl<'a, T: 'static> System<'a> for FakeBorrow { - type Data = FakeBorrow; - fn run(_: >::View) {} -} diff --git a/src/run/storage_borrow.rs b/src/run/storage_borrow.rs deleted file mode 100644 index 8fb63521..00000000 --- a/src/run/storage_borrow.rs +++ /dev/null @@ -1,208 +0,0 @@ -use crate::storage::{AllStorages, Entities, EntitiesMut}; -use crate::views::{EntitiesView, EntitiesViewMut, UniqueView, UniqueViewMut, View, ViewMut}; -#[cfg(feature = "non_send")] -use crate::NonSend; -#[cfg(all(feature = "non_send", feature = "non_sync"))] -use crate::NonSendSync; -#[cfg(feature = "non_sync")] -use crate::NonSync; -use crate::{error, Unique}; -use core::convert::TryInto; - -pub trait StorageBorrow<'a> { - type View; - - fn try_borrow(all_storages: &'a AllStorages) -> Result; -} - -impl<'a> StorageBorrow<'a> for () { - type View = (); - - fn try_borrow(_: &'a AllStorages) -> Result { - Ok(()) - } -} - -impl<'a> StorageBorrow<'a> for Entities { - type View = EntitiesView<'a>; - - fn try_borrow(all_storages: &'a AllStorages) -> Result { - all_storages.try_into() - } -} - -impl<'a> StorageBorrow<'a> for EntitiesMut { - type View = EntitiesViewMut<'a>; - - fn try_borrow(all_storages: &'a AllStorages) -> Result { - all_storages.try_into() - } -} - -impl<'a, T: 'static + Send + Sync> StorageBorrow<'a> for &T { - type View = View<'a, T>; - - fn try_borrow(all_storages: &'a AllStorages) -> Result { - all_storages.try_into() - } -} - -impl<'a, T: 'static + Send + Sync> StorageBorrow<'a> for &mut T { - type View = ViewMut<'a, T>; - - fn try_borrow(all_storages: &'a AllStorages) -> Result { - all_storages.try_into() - } -} - -impl<'a, T: 'static + Send + Sync> StorageBorrow<'a> for Unique<&T> { - type View = UniqueView<'a, T>; - - fn try_borrow(all_storages: &'a AllStorages) -> Result { - all_storages.try_into() - } -} - -impl<'a, T: 'static + Send + Sync> StorageBorrow<'a> for Unique<&mut T> { - type View = UniqueViewMut<'a, T>; - - fn try_borrow(all_storages: &'a AllStorages) -> Result { - all_storages.try_into() - } -} - -#[cfg(feature = "non_send")] -impl<'a, T: 'static + Sync> StorageBorrow<'a> for NonSend<&T> { - type View = View<'a, T>; - - fn try_borrow(all_storages: &'a AllStorages) -> Result { - View::try_storage_from_non_send(all_storages) - } -} - -#[cfg(feature = "non_send")] -impl<'a, T: 'static + Sync> StorageBorrow<'a> for NonSend<&mut T> { - type View = ViewMut<'a, T>; - - fn try_borrow(all_storages: &'a AllStorages) -> Result { - ViewMut::try_storage_from_non_send(all_storages) - } -} - -#[cfg(feature = "non_send")] -impl<'a, T: 'static + Sync> StorageBorrow<'a> for Unique> { - type View = UniqueView<'a, T>; - - fn try_borrow(all_storages: &'a AllStorages) -> Result { - UniqueView::try_storage_from_non_send(all_storages) - } -} - -#[cfg(feature = "non_send")] -impl<'a, T: 'static + Sync> StorageBorrow<'a> for Unique> { - type View = UniqueViewMut<'a, T>; - - fn try_borrow(all_storages: &'a AllStorages) -> Result { - UniqueViewMut::try_storage_from_non_send(all_storages) - } -} - -#[cfg(feature = "non_sync")] -impl<'a, T: 'static + Send> StorageBorrow<'a> for NonSync<&T> { - type View = View<'a, T>; - - fn try_borrow(all_storages: &'a AllStorages) -> Result { - View::try_storage_from_non_sync(all_storages) - } -} - -#[cfg(feature = "non_sync")] -impl<'a, T: 'static + Send> StorageBorrow<'a> for NonSync<&mut T> { - type View = ViewMut<'a, T>; - - fn try_borrow(all_storages: &'a AllStorages) -> Result { - ViewMut::try_storage_from_non_sync(all_storages) - } -} - -#[cfg(feature = "non_sync")] -impl<'a, T: 'static + Send> StorageBorrow<'a> for Unique> { - type View = UniqueView<'a, T>; - - fn try_borrow(all_storages: &'a AllStorages) -> Result { - UniqueView::try_storage_from_non_sync(all_storages) - } -} - -#[cfg(feature = "non_sync")] -impl<'a, T: 'static + Send> StorageBorrow<'a> for Unique> { - type View = UniqueViewMut<'a, T>; - - fn try_borrow(all_storages: &'a AllStorages) -> Result { - UniqueViewMut::try_storage_from_non_sync(all_storages) - } -} - -#[cfg(all(feature = "non_send", feature = "non_sync"))] -impl<'a, T: 'static> StorageBorrow<'a> for NonSendSync<&T> { - type View = View<'a, T>; - - fn try_borrow(all_storages: &'a AllStorages) -> Result { - View::try_storage_from_non_send_sync(all_storages) - } -} - -#[cfg(all(feature = "non_send", feature = "non_sync"))] -impl<'a, T: 'static> StorageBorrow<'a> for NonSendSync<&mut T> { - type View = ViewMut<'a, T>; - - fn try_borrow(all_storages: &'a AllStorages) -> Result { - ViewMut::try_storage_from_non_send_sync(all_storages) - } -} - -#[cfg(all(feature = "non_send", feature = "non_sync"))] -impl<'a, T: 'static> StorageBorrow<'a> for Unique> { - type View = UniqueView<'a, T>; - - fn try_borrow(all_storages: &'a AllStorages) -> Result { - UniqueView::try_storage_from_non_send_sync(all_storages) - } -} - -#[cfg(all(feature = "non_send", feature = "non_sync"))] -impl<'a, T: 'static> StorageBorrow<'a> for Unique> { - type View = UniqueViewMut<'a, T>; - - fn try_borrow(all_storages: &'a AllStorages) -> Result { - UniqueViewMut::try_storage_from_non_send_sync(all_storages) - } -} - -macro_rules! impl_system_data { - ($(($type: ident, $index: tt))+) => { - impl<'a, $($type: StorageBorrow<'a>),+> StorageBorrow<'a> for ($($type,)+) { - type View = ($($type::View,)+); - - fn try_borrow( - storages: &'a AllStorages, - ) -> Result { - Ok(($( - <$type as StorageBorrow>::try_borrow(storages)?, - )+)) - } - } - } -} - -macro_rules! system_data { - ($(($type: ident, $index: tt))*;($type1: ident, $index1: tt) $(($queue_type: ident, $queue_index: tt))*) => { - impl_system_data![$(($type, $index))*]; - system_data![$(($type, $index))* ($type1, $index1); $(($queue_type, $queue_index))*]; - }; - ($(($type: ident, $index: tt))*;) => { - impl_system_data![$(($type, $index))*]; - } -} - -system_data![(A, 0); (B, 1) (C, 2) (D, 3) (E, 4) (F, 5) (G, 6) (H, 7) (I, 8) (J, 9)]; diff --git a/src/run/system.rs b/src/run/system.rs deleted file mode 100644 index f9519934..00000000 --- a/src/run/system.rs +++ /dev/null @@ -1,83 +0,0 @@ -use super::SystemData; -use crate::error; -use crate::world::World; - -/// Trait to define systems. -/// -/// `System::Data` can be: -/// * `&T` for a shared access to `T` storage -/// * `&mut T` for an exclusive access to `T` storage -/// * [Entities] for a shared access to the entity storage -/// * [EntitiesMut] for an exclusive reference to the entity storage -/// * [AllStorages] for an exclusive access to the storage of all components -/// * [ThreadPool] for a shared access to the `ThreadPool` used by the [World] -/// * [Unique]<&T> for a shared access to a `T` unique storage -/// * [Unique]<&mut T> for an exclusive access to a `T` unique storage -/// * `NonSend<&T>` for a shared access to a `T` storage where `T` isn't `Send` -/// * `NonSend<&mut T>` for an exclusive access to a `T` storage where `T` isn't `Send` -/// * `NonSync<&T>` for a shared access to a `T` storage where `T` isn't `Sync` -/// * `NonSync<&mut T>` for an exclusive access to a `T` storage where `T` isn't `Sync` -/// * `NonSendSync<&T>` for a shared access to a `T` storage where `T` isn't `Send` nor `Sync` -/// * `NonSendSync<&mut T>` for an exclusive access to a `T` storage where `T` isn't `Send` nor `Sync` -/// -/// [Unique] and `NonSend`/`NonSync`/`NonSendSync` can be used together to access a unique storage missing `Send` and/or `Sync` bound(s). -/// -/// A tuple will allow multiple references. -/// ### Example -/// ``` -/// # use shipyard::prelude::*; -/// struct Single; -/// impl<'a> System<'a> for Single { -/// type Data = &'a usize; -/// fn run(usizes: ::View) { -/// // -- snip -- -/// } -/// } -/// -/// struct Double; -/// impl<'a> System<'a> for Double { -/// type Data = (&'a usize, &'a mut u32); -/// fn run((usizes, u32s): ::View) { -/// // -- snip -- -/// } -/// } -/// ``` -/// [Entities]: struct.Entities.html -/// [EntitiesMut]: struct.EntitiesMut.html -/// [AllStorages]: struct.AllStorages.html -/// [ThreadPool]: struct.ThreadPool.html -/// [World]: struct.World.html -/// [Unique]: struct.Unique.html -pub trait System<'a> { - type Data: SystemData<'a>; - fn run(storage: >::View); -} - -pub(crate) trait Dispatch { - fn try_dispatch(world: &World) -> Result<(), error::GetStorage>; -} - -impl Dispatch for T -where - T: for<'a> System<'a>, -{ - fn try_dispatch(world: &World) -> Result<(), error::GetStorage> { - let storages = &world.all_storages; - - let data = { - #[cfg(feature = "parallel")] - { - let thread_pool = &world.thread_pool; - ::try_borrow(&storages, &thread_pool)? - } - #[cfg(not(feature = "parallel"))] - { - ::try_borrow(&storages)? - } - }; - - T::run(data); - - Ok(()) - } -} diff --git a/src/sparse_set/mod.rs b/src/sparse_set/mod.rs index a643c5c0..bb5412a7 100644 --- a/src/sparse_set/mod.rs +++ b/src/sparse_set/mod.rs @@ -17,6 +17,7 @@ pub use windows::{Window, WindowMut, WindowSort1}; pub(crate) const BUCKET_SIZE: usize = 128 / core::mem::size_of::(); +/// Component storage. // A sparse array is a data structure with 2 vectors: one sparse, the other dense. // Only usize can be added. On insertion, the number is pushed into the dense vector // and sparse[number] is set to dense.len() - 1. diff --git a/src/sparse_set/sort/mod.rs b/src/sparse_set/sort/mod.rs index 717f53c9..be0e5c1c 100644 --- a/src/sparse_set/sort/mod.rs +++ b/src/sparse_set/sort/mod.rs @@ -11,7 +11,7 @@ pub trait IntoSortable { /// /// ### Example: /// ``` - /// # use shipyard::prelude::*; + /// # use shipyard::*; /// let world = World::new(); /// let (mut entities, mut usizes) = world.borrow::<(EntitiesMut, &mut usize)>(); /// entities.add_entity(&mut usizes, 1); diff --git a/src/sparse_set/sort/unstable.rs b/src/sparse_set/sort/unstable.rs index 9832adae..5cc203b0 100644 --- a/src/sparse_set/sort/unstable.rs +++ b/src/sparse_set/sort/unstable.rs @@ -1,7 +1,7 @@ use super::{IntoSortable, SparseSet}; use crate::error; use crate::sparse_set::{EntityId, Pack}; -use crate::views::ViewMut; +use crate::view::ViewMut; use alloc::vec::Vec; use core::any::TypeId; use core::cmp::Ordering; diff --git a/src/sparse_set/view_add_entity.rs b/src/sparse_set/view_add_entity.rs index 3a605075..641eb62d 100644 --- a/src/sparse_set/view_add_entity.rs +++ b/src/sparse_set/view_add_entity.rs @@ -1,6 +1,6 @@ use crate::sparse_set::Pack; use crate::storage::EntityId; -use crate::views::ViewMut; +use crate::view::ViewMut; use alloc::vec::Vec; use core::any::TypeId; diff --git a/src/storage/all/mod.rs b/src/storage/all/mod.rs index 4767a4a5..d4e3409f 100644 --- a/src/storage/all/mod.rs +++ b/src/storage/all/mod.rs @@ -2,8 +2,8 @@ mod hasher; use super::{Entities, EntityId, Storage}; use crate::atomic_refcell::{AtomicRefCell, Ref, RefMut}; +use crate::borrow::AllStoragesBorrow; use crate::error; -use crate::run::StorageBorrow; use crate::sparse_set::SparseSet; use alloc::boxed::Box; use alloc::vec::Vec; @@ -50,20 +50,11 @@ impl Default for AllStorages { ); } - #[cfg(not(feature = "non_send"))] - { - AllStorages { - storages: UnsafeCell::new(storages), - lock: RawRwLock::INIT, - } - } - #[cfg(feature = "non_send")] - { - AllStorages { - storages: UnsafeCell::new(storages), - lock: RawRwLock::INIT, - thread_id: std::thread::current().id(), - } + AllStorages { + storages: UnsafeCell::new(storages), + lock: RawRwLock::INIT, + #[cfg(feature = "non_send")] + thread_id: std::thread::current().id(), } } } @@ -352,7 +343,7 @@ impl AllStorages { /// Returns `true` if `entity` was alive. /// ### Example /// ``` - /// # use shipyard::prelude::*; + /// # use shipyard::*; /// let world = World::new(); /// /// let (mut entities, mut usizes, mut u32s) = world.borrow::<(EntitiesMut, &mut usize, &mut u32)>(); @@ -500,7 +491,7 @@ You can use: )] #[doc = "### Example ``` -# use shipyard::prelude::*; +# use shipyard::*; let world = World::new(); let all_storages = world.borrow::(); let u32s = all_storages.try_borrow::<&u32>().unwrap(); @@ -517,10 +508,8 @@ let u32s = all_storages.try_borrow::<&u32>().unwrap(); all(feature = "non_send", feature = "non_sync"), doc = "[NonSendSync]: struct.NonSendSync.html" )] - pub fn try_borrow<'a, C: StorageBorrow<'a>>( - &'a self, - ) -> Result<>::View, error::GetStorage> { - >::try_borrow(self) + pub fn try_borrow<'s, V: AllStoragesBorrow<'s>>(&'s self) -> Result { + V::try_borrow(self) } #[doc = "Borrows the requested storage, if it doesn't exist it'll get created. Unwraps errors. @@ -611,7 +600,7 @@ You can use: )] #[doc = "### Example ``` -# use shipyard::prelude::*; +# use shipyard::*; let world = World::new(); let all_storages = world.borrow::(); let u32s = all_storages.borrow::<&u32>(); @@ -628,7 +617,7 @@ let u32s = all_storages.borrow::<&u32>(); all(feature = "non_send", feature = "non_sync"), doc = "[NonSendSync]: struct.NonSendSync.html" )] - pub fn borrow<'a, C: StorageBorrow<'a>>(&'a self) -> >::View { - self.try_borrow::().unwrap() + pub fn borrow<'s, V: AllStoragesBorrow<'s>>(&'s self) -> V { + self.try_borrow::().unwrap() } } diff --git a/src/storage/entity/add_component.rs b/src/storage/entity/add_component.rs index 7a19958b..67924ac4 100644 --- a/src/storage/entity/add_component.rs +++ b/src/storage/entity/add_component.rs @@ -1,7 +1,7 @@ use super::{Entities, EntityId}; use crate::error; use crate::sparse_set::Pack; -use crate::views::ViewMut; +use crate::view::ViewMut; use alloc::vec::Vec; use core::any::{type_name, TypeId}; diff --git a/src/storage/entity/mod.rs b/src/storage/entity/mod.rs index 4ce39b3d..069ddae0 100644 --- a/src/storage/entity/mod.rs +++ b/src/storage/entity/mod.rs @@ -59,7 +59,7 @@ impl Entities { /// /// ### Example /// ``` - /// # use shipyard::prelude::*; + /// # use shipyard::*; /// let world = World::new(); /// let entity = world.run::(|mut entities| { /// entities.add_entity((), ()) @@ -81,7 +81,7 @@ impl Entities { /// /// ### Example /// ``` - /// # use shipyard::prelude::*; + /// # use shipyard::*; /// let world = World::new(); /// let entity = world.run::(|mut entities| { /// entities.add_entity((), ()) @@ -151,7 +151,7 @@ impl Entities { /// Multiple components can be added at the same time using a tuple. /// ### Example: /// ``` - /// # use shipyard::prelude::*; + /// # use shipyard::*; /// let world = World::new(); /// /// world.run::<(EntitiesMut, &mut usize, &mut u32), _, _>(|(mut entities, mut usizes, mut u32s)| { diff --git a/src/system_macro.rs b/src/system_macro.rs new file mode 100644 index 00000000..5558bc30 --- /dev/null +++ b/src/system_macro.rs @@ -0,0 +1,23 @@ +#[macro_export] +macro_rules! system { + ($function: expr) => {{ + ( + |world: &shipyard::World| world.try_run($function).map(drop), + $function, + ) + }}; +} + +#[macro_export] +macro_rules! try_system { + ($function: expr) => {{ + ( + |world: &shipyard::World| { + world + .try_run($function)? + .map_err(shipyard::error::Run::from_custom) + }, + $function, + ) + }}; +} diff --git a/src/views.rs b/src/view.rs similarity index 98% rename from src/views.rs rename to src/view.rs index 707521a5..c8343ef8 100644 --- a/src/views.rs +++ b/src/view.rs @@ -916,3 +916,22 @@ impl DerefMut for UniqueViewMut<'_, T> { &mut self.unique } } + +#[cfg(feature = "parallel")] +#[cfg_attr(docsrs, doc(cfg(feature = "parallel")))] +pub struct ThreadPoolView<'a>(pub(crate) &'a rayon::ThreadPool); + +#[cfg(feature = "parallel")] +impl AsRef for ThreadPoolView<'_> { + fn as_ref(&self) -> &rayon::ThreadPool { + &self.0 + } +} + +#[cfg(feature = "parallel")] +impl Deref for ThreadPoolView<'_> { + type Target = rayon::ThreadPool; + fn deref(&self) -> &Self::Target { + &self.0 + } +} diff --git a/src/world/mod.rs b/src/world/mod.rs index a18a4316..0abd1097 100644 --- a/src/world/mod.rs +++ b/src/world/mod.rs @@ -1,10 +1,11 @@ mod scheduler; -pub use scheduler::IntoWorkload; +pub use scheduler::WorkloadBuilder; use crate::atomic_refcell::AtomicRefCell; use crate::error; -use crate::run::{Dispatch, Run, System, SystemData}; +//use crate::run::{Dispatch, Run, System, SystemData}; +use crate::borrow::Borrow; use crate::storage::AllStorages; use alloc::borrow::Cow; use core::ops::Range; @@ -53,7 +54,7 @@ impl Default for World { impl World { /// Create an empty `World`. pub fn new() -> Self { - World::default() + Default::default() } /// Returns a new `World` with custom threads. /// Custom threads can be useful when working with wasm for example. @@ -272,7 +273,7 @@ You can use: )] #[doc = "### Example ``` -# use shipyard::prelude::*; +# use shipyard::*; let world = World::new(); let u32s = world.borrow::<&u32>(); let (entities, mut usizes) = world.try_borrow::<(Entities, &mut usize)>().unwrap(); @@ -289,16 +290,14 @@ let (entities, mut usizes) = world.try_borrow::<(Entities, &mut usize)>().unwrap all(feature = "non_send", feature = "non_sync"), doc = "[NonSendSync]: struct.NonSendSync.html" )] - pub fn try_borrow<'s, C: SystemData<'s>>( - &'s self, - ) -> Result<>::View, error::GetStorage> { + pub fn try_borrow<'s, V: Borrow<'s>>(&'s self) -> Result { #[cfg(feature = "parallel")] { - >::try_borrow(&self.all_storages, &self.thread_pool) + V::try_borrow(&self.all_storages, &self.thread_pool) } #[cfg(not(feature = "parallel"))] { - >::try_borrow(&self.all_storages) + V::try_borrow(&self.all_storages) } } #[doc = "Borrows the requested storage(s), if it doesn't exist it'll get created. @@ -391,7 +390,7 @@ You can use: )] #[doc = "### Example ``` -# use shipyard::prelude::*; +# use shipyard::*; let world = World::new(); let u32s = world.borrow::<&u32>(); let (entities, mut usizes) = world.borrow::<(Entities, &mut usize)>(); @@ -408,12 +407,11 @@ let (entities, mut usizes) = world.borrow::<(Entities, &mut usize)>(); all(feature = "non_send", feature = "non_sync"), doc = "[NonSendSync]: struct.NonSendSync.html" )] - pub fn borrow<'s, C: SystemData<'s>>(&'s self) -> >::View { - self.try_borrow::().unwrap() + pub fn borrow<'s, V: Borrow<'s>>(&'s self) -> V { + self.try_borrow::().unwrap() } #[doc = "Borrows the requested storages and runs `f`, this is an unnamed system. -You can use a tuple to get multiple storages at once. -Unwraps errors. +You can use a tuple to get multiple storages at once. You can use: * `&T` for a shared access to `T` storage @@ -501,11 +499,11 @@ You can use: )] #[doc = "### Example ``` -# use shipyard::prelude::*; +# use shipyard::*; let world = World::new(); -world.run::<(&usize, &mut u32), _, _>(|(usizes, u32s)| { +world.try_run::<(&usize, &mut u32), _, _>(|(usizes, u32s)| { // -- snip -- -}); +}).unwrap(); ``` [Entities]: struct.Entities.html [EntitiesMut]: struct.Entities.html @@ -519,11 +517,24 @@ world.run::<(&usize, &mut u32), _, _>(|(usizes, u32s)| { all(feature = "non_send", feature = "non_sync"), doc = "[NonSendSync]: struct.NonSendSync.html" )] - pub fn run<'a, T: Run<'a>, R, F: FnOnce(T::Storage) -> R>(&'a self, f: F) -> R { - self.try_run::(f).unwrap() + pub fn try_run<'s, V: Borrow<'s>, R, F: FnOnce(V) -> R>( + &'s self, + f: F, + ) -> Result { + Ok((f)({ + #[cfg(feature = "parallel")] + { + V::try_borrow(&self.all_storages, &self.thread_pool)? + } + #[cfg(not(feature = "parallel"))] + { + V::try_borrow(&self.all_storages)? + } + })) } #[doc = "Borrows the requested storages and runs `f`, this is an unnamed system. -You can use a tuple to get multiple storages at once. +You can use a tuple to get multiple storages at once. +Unwraps errors. You can use: * `&T` for a shared access to `T` storage @@ -611,11 +622,11 @@ You can use: )] #[doc = "### Example ``` -# use shipyard::prelude::*; +# use shipyard::*; let world = World::new(); -world.try_run::<(&usize, &mut u32), _, _>(|(usizes, u32s)| { +world.run::<(&usize, &mut u32), _, _>(|(usizes, u32s)| { // -- snip -- -}).unwrap(); +}); ``` [Entities]: struct.Entities.html [EntitiesMut]: struct.Entities.html @@ -629,74 +640,16 @@ world.try_run::<(&usize, &mut u32), _, _>(|(usizes, u32s)| { all(feature = "non_send", feature = "non_sync"), doc = "[NonSendSync]: struct.NonSendSync.html" )] - pub fn try_run<'a, T: Run<'a>, R, F: FnOnce(T::Storage) -> R>( - &'a self, - f: F, - ) -> Result { - #[cfg(feature = "parallel")] - { - T::try_run(&self.all_storages, &self.thread_pool, f) - } - #[cfg(not(feature = "parallel"))] - { - T::try_run(&self.all_storages, f) - } - } - /// Runs the `S` system immediately, borrowing the storages necessary to do so. - /// - /// ### Example - /// ``` - /// # #[cfg(feature = "proc")] - /// # { - /// # use shipyard::prelude::*; - /// struct Clock(u32); - /// - /// #[system(Tick)] - /// fn run(mut clocks: &mut Clock) { - /// (&mut clocks).iter().for_each(|clock| { - /// clock.0 += 1; - /// }); - /// } - /// - /// let world = World::default(); - /// world.try_run_system::().unwrap(); - /// # } - /// ``` - pub fn try_run_system System<'a> + 'static>(&self) -> Result<(), error::GetStorage> { - S::try_dispatch(self) - } - /// Runs the `S` system immediately, borrowing the storages necessary to do so. - /// Unwraps errors. - /// - /// ### Example - /// ``` - /// # #[cfg(feature = "proc")] - /// # { - /// # use shipyard::prelude::*; - /// struct Clock(u32); - /// - /// #[system(Tick)] - /// fn run(mut clocks: &mut Clock) { - /// (&mut clocks).iter().for_each(|clock| { - /// clock.0 += 1; - /// }); - /// } - /// - /// let world = World::default(); - /// world.run_system::(); - /// # } - /// ``` - pub fn run_system System<'a> + 'static>(&self) { - self.try_run_system::().unwrap() + pub fn run<'s, V: Borrow<'s>, R, F: FnOnce(V) -> R>(&'s self, f: F) -> R { + self.try_run(f).unwrap() } /// Modifies the current default workload to `name`. pub fn try_set_default_workload( &self, name: impl Into>, ) -> Result<(), error::SetDefaultWorkload> { - let name = name.into(); let mut scheduler = self.scheduler.try_borrow_mut()?; - if let Some(workload) = scheduler.workloads.get(&name) { + if let Some(workload) = scheduler.workloads.get(&name.into()) { scheduler.default = workload.clone(); Ok(()) } else { @@ -714,7 +667,7 @@ world.try_run::<(&usize, &mut u32), _, _>(|(usizes, u32s)| { /// /// ### Example /// ``` - /// # use shipyard::prelude::*; + /// # use shipyard::*; /// struct Adder; /// impl<'a> System<'a> for Adder { /// type Data = (&'a mut usize, &'a u32); @@ -747,13 +700,14 @@ world.try_run::<(&usize, &mut u32), _, _>(|(usizes, u32s)| { /// world.try_add_workload::<(Adder, Checker), _>("Add & Check").unwrap(); /// world.run_default(); /// ``` - pub fn try_add_workload>>( + pub fn try_add_workload( &self, - name: N, - ) -> Result<(), error::Borrow> { - let mut scheduler = self.scheduler.try_borrow_mut()?; - S::into_workload(name, &mut *scheduler); - Ok(()) + name: impl Into>, + ) -> Result, error::Borrow> { + Ok(WorkloadBuilder::new( + self.scheduler.try_borrow_mut()?, + name.into(), + )) } /// A workload is a collection of systems. They will execute as much in parallel as possible. /// They are evaluated left to right when they can't be parallelized. @@ -762,7 +716,7 @@ world.try_run::<(&usize, &mut u32), _, _>(|(usizes, u32s)| { /// /// ### Example /// ``` - /// # use shipyard::prelude::*; + /// # use shipyard::*; /// struct Adder; /// impl<'a> System<'a> for Adder { /// type Data = (&'a mut usize, &'a u32); @@ -795,41 +749,24 @@ world.try_run::<(&usize, &mut u32), _, _>(|(usizes, u32s)| { /// world.add_workload::<(Adder, Checker), _>("Add & Check"); /// world.run_default(); /// ``` - pub fn add_workload>>(&self, name: N) { - self.try_add_workload::(name).unwrap(); - } - /* WIP - pub fn try_add_workload_fn( - &self, - name: impl Into>, - systems: S, - ) -> Result<(), error::Borrow> { - let mut scheduler = self.scheduler.try_borrow_mut()?; - systems.into_workload(name, &mut *scheduler); - Ok(()) + pub fn add_workload(&self, name: impl Into>) -> WorkloadBuilder<'_> { + self.try_add_workload(name).unwrap() } - pub fn add_workload_fn( - &self, - name: impl Into>, - systems: S, - ) { - self.try_add_workload_fn(name, systems).unwrap() - }*/ /// Runs the `name` workload. - pub fn try_run_workload(&self, name: impl AsRef) -> Result<(), error::RunWorkload> { + pub fn try_run_workload(&self, name: impl AsRef + Sync) -> Result<(), error::RunWorkload> { let scheduler = self .scheduler .try_borrow() .map_err(|_| error::RunWorkload::Scheduler)?; - if let Some(workload) = scheduler.workloads.get(name.as_ref()).cloned() { - self.try_run_workload_index(&*scheduler, workload) + if let Some(range) = scheduler.workloads.get(name.as_ref()) { + self.try_run_workload_index(&*scheduler, range.clone()) } else { Err(error::RunWorkload::MissingWorkload) } } /// Runs the `name` workload. /// Unwraps error. - pub fn run_workload(&self, name: impl AsRef) { + pub fn run_workload(&self, name: impl AsRef + Sync) { self.try_run_workload(name).unwrap(); } fn try_run_workload_index( @@ -839,33 +776,43 @@ world.try_run::<(&usize, &mut u32), _, _>(|(usizes, u32s)| { ) -> Result<(), error::RunWorkload> { for batch in &scheduler.batch[workload] { if batch.len() == 1 { - scheduler.systems[batch[0]](&self)?; + scheduler.systems[batch[0]](self).map_err(|err| { + error::RunWorkload::Run((scheduler.system_names[batch[0]], err)) + })?; } else { #[cfg(feature = "parallel")] { use rayon::prelude::*; self.thread_pool.install(|| { - batch - .into_par_iter() - .try_for_each(|&index| (scheduler.systems[index])(&self)) + batch.into_par_iter().try_for_each(|&index| { + (scheduler.systems[index])(self).map_err(|err| { + error::RunWorkload::Run((scheduler.system_names[index], err)) + }) + }) })? } #[cfg(not(feature = "parallel"))] { - batch - .iter() - .try_for_each(|&index| (scheduler.systems[index])(&self))? + batch.iter().try_for_each(|&index| { + (scheduler.systems[index])(self).map_err(|err| { + error::RunWorkload::Run((scheduler.system_names[index], err)) + }) + })? } } } Ok(()) } /// Run the default workload. - pub fn try_run_default(&self) -> Result<(), error::Borrow> { - let scheduler = self.scheduler.try_borrow()?; - self.try_run_workload_index(&scheduler, scheduler.default.clone()) - .unwrap(); + pub fn try_run_default(&self) -> Result<(), error::RunWorkload> { + let scheduler = self + .scheduler + .try_borrow() + .map_err(|_| error::RunWorkload::Scheduler)?; + if !scheduler.batch.is_empty() { + self.try_run_workload_index(&scheduler, scheduler.default.clone())? + } Ok(()) } /// Run the default workload. diff --git a/src/world/scheduler/builder.rs b/src/world/scheduler/builder.rs new file mode 100644 index 00000000..aa0957c1 --- /dev/null +++ b/src/world/scheduler/builder.rs @@ -0,0 +1,659 @@ +use super::Scheduler; +use crate::atomic_refcell::RefMut; +use crate::borrow::{Borrow, Mutation}; +use crate::error; +use crate::storage::AllStorages; +use crate::world::World; +use alloc::borrow::Cow; +use alloc::boxed::Box; +use alloc::vec; +use alloc::vec::Vec; +use core::any::type_name; +use core::any::TypeId; +use core::ops::Range; +use hashbrown::hash_map::Entry; + +pub struct WorkloadBuilder<'a> { + scheduler: RefMut<'a, Scheduler>, + systems: Vec<( + TypeId, + &'static str, + Range, + bool, + Box Result<(), error::Run> + Send + Sync + 'static>, + )>, + borrow_info: Vec<(TypeId, Mutation)>, + name: Cow<'static, str>, +} + +impl<'a> WorkloadBuilder<'a> { + pub(crate) fn new(scheduler: RefMut<'a, Scheduler>, name: Cow<'static, str>) -> Self { + WorkloadBuilder { + scheduler, + systems: Vec::new(), + borrow_info: Vec::new(), + name: name.into(), + } + } +} + +impl<'a> WorkloadBuilder<'a> { + pub fn with_system< + V: Borrow<'a>, + R, + F: Fn(V) -> R, + S: Fn(&World) -> Result<(), error::Run> + Send + Sync + 'static, + >( + &mut self, + (system, _): (S, F), + ) -> &mut WorkloadBuilder<'a> { + let old_len = self.borrow_info.len(); + V::borrow_infos(&mut self.borrow_info); + let is_send_sync = V::is_send_sync(); + self.systems.push(( + core::any::TypeId::of::(), + type_name::(), + old_len..self.borrow_info.len(), + is_send_sync, + Box::new(system), + )); + self + } + pub fn build(&mut self) { + if self.systems.len() == 1 { + let (type_id, system_name, _, _, system) = self.systems.pop().unwrap(); + let mut name = "".into(); + core::mem::swap(&mut name, &mut self.name); + let range = self.scheduler.batch.len()..(self.scheduler.batch.len() + 1); + if self.scheduler.workloads.is_empty() { + self.scheduler.default = range.clone(); + } + self.scheduler.workloads.insert(name, range); + let len = self.scheduler.systems.len(); + self.scheduler.batch.push(Box::new([len])); + + if let Entry::Vacant(vacant) = self.scheduler.lookup_table.entry(type_id) { + vacant.insert(len); + self.scheduler.system_names.push(system_name); + self.scheduler.systems.push(system); + } + } else { + let batch_start = self.scheduler.batch.len(); + let mut new_batch = vec![Vec::new()]; + let mut batch_info = vec![Vec::new()]; + + for (type_id, name, info_range, is_send_sync, system) in self.systems.drain(..) { + let len = self.scheduler.systems.len(); + let system_index = match self.scheduler.lookup_table.entry(type_id) { + Entry::Vacant(vacant) => { + vacant.insert(len); + self.scheduler.systems.push(system); + self.scheduler.system_names.push(name); + self.scheduler.systems.len() - 1 + } + Entry::Occupied(occupied) => *occupied.get(), + }; + + if is_send_sync { + let mut batch_index = new_batch.len(); + for batch in batch_info.iter().rev() { + let mut conflict = false; + for &(type_id, mutation) in &self.borrow_info[info_range.clone()] { + match mutation { + Mutation::Shared => { + for &(batch_type_id, mutation) in batch.iter() { + #[cfg(feature = "parallel")] + { + if type_id == batch_type_id + && mutation == Mutation::Unique + || type_id == TypeId::of::() + || batch_type_id == TypeId::of::() + { + conflict = true; + break; + } + } + #[cfg(not(feature = "parallel"))] + { + if type_id == batch_type_id + && mutation == Mutation::Unique + || type_id == TypeId::of::() + || batch_type_id == TypeId::of::() + { + conflict = true; + break; + } + } + } + } + Mutation::Unique => { + for &(batch_type_id, _) in batch.iter() { + #[cfg(feature = "parallel")] + { + if type_id == batch_type_id + || type_id == TypeId::of::() + || batch_type_id == TypeId::of::() + { + conflict = true; + break; + } + } + #[cfg(not(feature = "parallel"))] + { + if type_id == batch_type_id + || type_id == TypeId::of::() + || batch_type_id == TypeId::of::() + { + conflict = true; + break; + } + } + } + } + } + } + + if conflict { + break; + } else { + batch_index -= 1; + } + } + + if batch_index == batch_info.len() { + new_batch.push(vec![system_index]); + batch_info.push(self.borrow_info[info_range].to_vec()); + } else { + new_batch[batch_index].push(system_index); + batch_info[batch_index].extend_from_slice(&self.borrow_info[info_range]); + } + } else { + let last = new_batch.last_mut().unwrap(); + if last.is_empty() { + last.push(system_index); + new_batch.push(Vec::new()); + batch_info + .last_mut() + .unwrap() + .push((TypeId::of::(), Mutation::Unique)); + batch_info.push(Vec::new()); + } else { + new_batch.push(vec![system_index]); + new_batch.push(Vec::new()); + batch_info.push(vec![(TypeId::of::(), Mutation::Unique)]); + batch_info.push(Vec::new()); + } + } + } + + if new_batch.last().unwrap().is_empty() { + new_batch.pop(); + } + + self.scheduler + .batch + .extend(new_batch.into_iter().map(Vec::into_boxed_slice)); + + if self.scheduler.workloads.is_empty() { + self.scheduler.default = batch_start..(self.scheduler.batch.len()); + } + + let mut name = "".into(); + core::mem::swap(&mut name, &mut self.name); + let len = self.scheduler.batch.len(); + self.scheduler.workloads.insert(name, batch_start..len); + } + } +} + +#[test] +fn single_immutable() { + use crate::atomic_refcell::AtomicRefCell; + use crate::{View, World}; + + fn system1(_: View<'_, usize>) {} + + let scheduler = { + #[cfg(feature = "std")] + { + AtomicRefCell::new(Scheduler::default(), None, true) + } + #[cfg(not(feature = "std"))] + { + AtomicRefCell::new(Scheduler::default()) + } + }; + WorkloadBuilder::new(scheduler.try_borrow_mut().unwrap(), "System1".into()) + .with_system((|world: &World| world.try_run(system1), system1)) + .build(); + + let scheduler = scheduler.try_borrow_mut().unwrap(); + assert_eq!(scheduler.systems.len(), 1); + assert_eq!(scheduler.batch.len(), 1); + assert_eq!(&*scheduler.batch[0], &[0]); + assert_eq!(scheduler.workloads.len(), 1); + assert_eq!(scheduler.workloads.get("System1"), Some(&(0..1))); + assert_eq!(scheduler.default, 0..1); +} +#[test] +fn single_mutable() { + use crate::atomic_refcell::AtomicRefCell; + use crate::{ViewMut, World}; + + fn system1(_: ViewMut<'_, usize>) {} + + let scheduler = { + #[cfg(feature = "std")] + { + AtomicRefCell::new(Scheduler::default(), None, true) + } + #[cfg(not(feature = "std"))] + { + AtomicRefCell::new(Scheduler::default()) + } + }; + WorkloadBuilder::new(scheduler.try_borrow_mut().unwrap(), "System1".into()) + .with_system((|world: &World| world.try_run(system1), system1)) + .build(); + + let scheduler = scheduler.try_borrow_mut().unwrap(); + assert_eq!(scheduler.systems.len(), 1); + assert_eq!(scheduler.batch.len(), 1); + assert_eq!(&*scheduler.batch[0], &[0]); + assert_eq!(scheduler.workloads.len(), 1); + assert_eq!(scheduler.workloads.get("System1"), Some(&(0..1))); + assert_eq!(scheduler.default, 0..1); +} +#[test] +fn multiple_immutable() { + use crate::atomic_refcell::AtomicRefCell; + use crate::{View, World}; + + fn system1(_: View<'_, usize>) {} + fn system2(_: View<'_, usize>) {} + + let scheduler = { + #[cfg(feature = "std")] + { + AtomicRefCell::new(Scheduler::default(), None, true) + } + #[cfg(not(feature = "std"))] + { + AtomicRefCell::new(Scheduler::default()) + } + }; + WorkloadBuilder::new(scheduler.try_borrow_mut().unwrap(), "Systems".into()) + .with_system((|world: &World| world.try_run(system1), system1)) + .with_system((|world: &World| world.try_run(system2), system2)) + .build(); + + let scheduler = scheduler.try_borrow_mut().unwrap(); + assert_eq!(scheduler.systems.len(), 2); + assert_eq!(scheduler.batch.len(), 1); + assert_eq!(&*scheduler.batch[0], &[0, 1]); + assert_eq!(scheduler.workloads.len(), 1); + assert_eq!(scheduler.workloads.get("Systems"), Some(&(0..1))); + assert_eq!(scheduler.default, 0..1); +} +#[test] +fn multiple_mutable() { + use crate::atomic_refcell::AtomicRefCell; + use crate::{ViewMut, World}; + + fn system1(_: ViewMut<'_, usize>) {} + fn system2(_: ViewMut<'_, usize>) {} + + let scheduler = { + #[cfg(feature = "std")] + { + AtomicRefCell::new(Scheduler::default(), None, true) + } + #[cfg(not(feature = "std"))] + { + AtomicRefCell::new(Scheduler::default()) + } + }; + WorkloadBuilder::new(scheduler.try_borrow_mut().unwrap(), "Systems".into()) + .with_system((|world: &World| world.try_run(system1), system1)) + .with_system((|world: &World| world.try_run(system2), system2)) + .build(); + + let scheduler = scheduler.try_borrow_mut().unwrap(); + assert_eq!(scheduler.systems.len(), 2); + assert_eq!(scheduler.batch.len(), 2); + assert_eq!(&*scheduler.batch[0], &[0]); + assert_eq!(&*scheduler.batch[1], &[1]); + assert_eq!(scheduler.workloads.len(), 1); + assert_eq!(scheduler.workloads.get("Systems"), Some(&(0..2))); + assert_eq!(scheduler.default, 0..2); +} +#[test] +fn multiple_mixed() { + use crate::atomic_refcell::AtomicRefCell; + use crate::{View, ViewMut, World}; + + fn system1(_: ViewMut<'_, usize>) {} + fn system2(_: View<'_, usize>) {} + + let scheduler = { + #[cfg(feature = "std")] + { + AtomicRefCell::new(Scheduler::default(), None, true) + } + #[cfg(not(feature = "std"))] + { + AtomicRefCell::new(Scheduler::default()) + } + }; + WorkloadBuilder::new(scheduler.try_borrow_mut().unwrap(), "Systems".into()) + .with_system((|world: &World| world.try_run(system1), system1)) + .with_system((|world: &World| world.try_run(system2), system2)) + .build(); + + let scheduler = scheduler.try_borrow_mut().unwrap(); + assert_eq!(scheduler.systems.len(), 2); + assert_eq!(scheduler.batch.len(), 2); + assert_eq!(&*scheduler.batch[0], &[0]); + assert_eq!(&*scheduler.batch[1], &[1]); + assert_eq!(scheduler.workloads.len(), 1); + assert_eq!(scheduler.workloads.get("Systems"), Some(&(0..2))); + assert_eq!(scheduler.default, 0..2); + + let scheduler = { + #[cfg(feature = "std")] + { + AtomicRefCell::new(Scheduler::default(), None, true) + } + #[cfg(not(feature = "std"))] + { + AtomicRefCell::new(Scheduler::default()) + } + }; + WorkloadBuilder::new(scheduler.try_borrow_mut().unwrap(), "Systems".into()) + .with_system((|world: &World| world.try_run(system2), system2)) + .with_system((|world: &World| world.try_run(system1), system1)) + .build(); + + let scheduler = scheduler.try_borrow_mut().unwrap(); + assert_eq!(scheduler.systems.len(), 2); + assert_eq!(scheduler.batch.len(), 2); + assert_eq!(&*scheduler.batch[0], &[0]); + assert_eq!(&*scheduler.batch[1], &[1]); + assert_eq!(scheduler.workloads.len(), 1); + assert_eq!(scheduler.workloads.get("Systems"), Some(&(0..2))); + assert_eq!(scheduler.default, 0..2); +} +#[test] +fn all_storages() { + use crate::atomic_refcell::AtomicRefCell; + use crate::{AllStoragesViewMut, View, World}; + + fn system1(_: View<'_, usize>) {} + fn system2(_: AllStoragesViewMut<'_>) {} + + let scheduler = { + #[cfg(feature = "std")] + { + AtomicRefCell::new(Scheduler::default(), None, true) + } + #[cfg(not(feature = "std"))] + { + AtomicRefCell::new(Scheduler::default()) + } + }; + WorkloadBuilder::new(scheduler.try_borrow_mut().unwrap(), "Systems".into()) + .with_system((|world: &World| world.try_run(system2), system2)) + .build(); + + let scheduler = scheduler.try_borrow_mut().unwrap(); + assert_eq!(scheduler.systems.len(), 1); + assert_eq!(scheduler.batch.len(), 1); + assert_eq!(&*scheduler.batch[0], &[0]); + assert_eq!(scheduler.workloads.len(), 1); + assert_eq!(scheduler.workloads.get("Systems"), Some(&(0..1))); + assert_eq!(scheduler.default, 0..1); + + let scheduler = { + #[cfg(feature = "std")] + { + AtomicRefCell::new(Scheduler::default(), None, true) + } + #[cfg(not(feature = "std"))] + { + AtomicRefCell::new(Scheduler::default()) + } + }; + WorkloadBuilder::new(scheduler.try_borrow_mut().unwrap(), "Systems".into()) + .with_system((|world: &World| world.try_run(system2), system2)) + .with_system((|world: &World| world.try_run(system2), system2)) + .build(); + + let scheduler = scheduler.try_borrow_mut().unwrap(); + assert_eq!(scheduler.systems.len(), 2); + assert_eq!(scheduler.batch.len(), 2); + assert_eq!(&*scheduler.batch[0], &[0]); + assert_eq!(&*scheduler.batch[0], &[0]); + assert_eq!(scheduler.workloads.len(), 1); + assert_eq!(scheduler.workloads.get("Systems"), Some(&(0..2))); + assert_eq!(scheduler.default, 0..2); + + let scheduler = { + #[cfg(feature = "std")] + { + AtomicRefCell::new(Scheduler::default(), None, true) + } + #[cfg(not(feature = "std"))] + { + AtomicRefCell::new(Scheduler::default()) + } + }; + WorkloadBuilder::new(scheduler.try_borrow_mut().unwrap(), "Systems".into()) + .with_system((|world: &World| world.try_run(system1), system1)) + .with_system((|world: &World| world.try_run(system2), system2)) + .build(); + + let scheduler = scheduler.try_borrow_mut().unwrap(); + assert_eq!(scheduler.systems.len(), 2); + assert_eq!(scheduler.batch.len(), 2); + assert_eq!(&*scheduler.batch[0], &[0]); + assert_eq!(&*scheduler.batch[1], &[1]); + assert_eq!(scheduler.workloads.len(), 1); + assert_eq!(scheduler.workloads.get("Systems"), Some(&(0..2))); + assert_eq!(scheduler.default, 0..2); + + let scheduler = { + #[cfg(feature = "std")] + { + AtomicRefCell::new(Scheduler::default(), None, true) + } + #[cfg(not(feature = "std"))] + { + AtomicRefCell::new(Scheduler::default()) + } + }; + WorkloadBuilder::new(scheduler.try_borrow_mut().unwrap(), "Systems".into()) + .with_system((|world: &World| world.try_run(system2), system2)) + .with_system((|world: &World| world.try_run(system1), system1)) + .build(); + + let scheduler = scheduler.try_borrow_mut().unwrap(); + assert_eq!(scheduler.systems.len(), 2); + assert_eq!(scheduler.batch.len(), 2); + assert_eq!(&*scheduler.batch[0], &[0]); + assert_eq!(&*scheduler.batch[1], &[1]); + assert_eq!(scheduler.workloads.len(), 1); + assert_eq!(scheduler.workloads.get("Systems"), Some(&(0..2))); + assert_eq!(scheduler.default, 0..2); +} + +#[cfg(feature = "non_send")] +#[test] +fn non_send() { + use crate::atomic_refcell::AtomicRefCell; + use crate::{NonSend, View, ViewMut, World}; + + struct NotSend(*const ()); + unsafe impl Sync for NotSend {} + + fn sys1(_: NonSend>) {} + fn sys2(_: NonSend>) {} + fn sys3(_: View<'_, usize>) {} + fn sys4(_: ViewMut<'_, usize>) {} + + let scheduler = { + #[cfg(feature = "std")] + { + AtomicRefCell::new(Scheduler::default(), None, true) + } + #[cfg(not(feature = "std"))] + { + AtomicRefCell::new(Scheduler::default()) + } + }; + WorkloadBuilder::new(scheduler.try_borrow_mut().unwrap(), "Test".into()) + .with_system((|world: &World| world.try_run(sys1), sys1)) + .with_system((|world: &World| world.try_run(sys1), sys1)) + .build(); + + let scheduler = scheduler.try_borrow_mut().unwrap(); + assert_eq!(scheduler.systems.len(), 2); + assert_eq!(scheduler.batch.len(), 2); + assert_eq!(&*scheduler.batch[0], &[0]); + assert_eq!(&*scheduler.batch[1], &[1]); + assert_eq!(scheduler.workloads.len(), 1); + assert_eq!(scheduler.workloads.get("Test"), Some(&(0..2))); + assert_eq!(scheduler.default, 0..2); + + let scheduler = { + #[cfg(feature = "std")] + { + AtomicRefCell::new(Scheduler::default(), None, true) + } + #[cfg(not(feature = "std"))] + { + AtomicRefCell::new(Scheduler::default()) + } + }; + WorkloadBuilder::new(scheduler.try_borrow_mut().unwrap(), "Test".into()) + .with_system((|world: &World| world.try_run(sys1), sys1)) + .with_system((|world: &World| world.try_run(sys2), sys2)) + .build(); + + let scheduler = scheduler.try_borrow_mut().unwrap(); + assert_eq!(scheduler.systems.len(), 2); + assert_eq!(scheduler.batch.len(), 2); + assert_eq!(&*scheduler.batch[0], &[0]); + assert_eq!(&*scheduler.batch[1], &[1]); + assert_eq!(scheduler.workloads.len(), 1); + assert_eq!(scheduler.workloads.get("Test"), Some(&(0..2))); + assert_eq!(scheduler.default, 0..2); + + let scheduler = { + #[cfg(feature = "std")] + { + AtomicRefCell::new(Scheduler::default(), None, true) + } + #[cfg(not(feature = "std"))] + { + AtomicRefCell::new(Scheduler::default()) + } + }; + WorkloadBuilder::new(scheduler.try_borrow_mut().unwrap(), "Test".into()) + .with_system((|world: &World| world.try_run(sys2), sys2)) + .with_system((|world: &World| world.try_run(sys1), sys1)) + .build(); + + let scheduler = scheduler.try_borrow_mut().unwrap(); + assert_eq!(scheduler.systems.len(), 2); + assert_eq!(scheduler.batch.len(), 2); + assert_eq!(&*scheduler.batch[0], &[0]); + assert_eq!(&*scheduler.batch[1], &[1]); + assert_eq!(scheduler.workloads.len(), 1); + assert_eq!(scheduler.workloads.get("Test"), Some(&(0..2))); + assert_eq!(scheduler.default, 0..2); + + let scheduler = { + #[cfg(feature = "std")] + { + AtomicRefCell::new(Scheduler::default(), None, true) + } + #[cfg(not(feature = "std"))] + { + AtomicRefCell::new(Scheduler::default()) + } + }; + WorkloadBuilder::new(scheduler.try_borrow_mut().unwrap(), "Test".into()) + .with_system((|world: &World| world.try_run(sys1), sys1)) + .with_system((|world: &World| world.try_run(sys3), sys3)) + .build(); + + let scheduler = scheduler.try_borrow_mut().unwrap(); + assert_eq!(scheduler.systems.len(), 2); + assert_eq!(scheduler.batch.len(), 2); + assert_eq!(&*scheduler.batch[0], &[0]); + assert_eq!(&*scheduler.batch[1], &[1]); + assert_eq!(scheduler.workloads.len(), 1); + assert_eq!(scheduler.workloads.get("Test"), Some(&(0..2))); + assert_eq!(scheduler.default, 0..2); + + let scheduler = { + #[cfg(feature = "std")] + { + AtomicRefCell::new(Scheduler::default(), None, true) + } + #[cfg(not(feature = "std"))] + { + AtomicRefCell::new(Scheduler::default()) + } + }; + WorkloadBuilder::new(scheduler.try_borrow_mut().unwrap(), "Test".into()) + .with_system((|world: &World| world.try_run(sys1), sys1)) + .with_system((|world: &World| world.try_run(sys4), sys4)) + .build(); + + let scheduler = scheduler.try_borrow_mut().unwrap(); + assert_eq!(scheduler.systems.len(), 2); + assert_eq!(scheduler.batch.len(), 2); + assert_eq!(&*scheduler.batch[0], &[0]); + assert_eq!(&*scheduler.batch[1], &[1]); + assert_eq!(scheduler.workloads.len(), 1); + assert_eq!(scheduler.workloads.get("Test"), Some(&(0..2))); + assert_eq!(scheduler.default, 0..2); +} + +#[test] +fn fake_borrow() { + use crate::atomic_refcell::AtomicRefCell; + use crate::{FakeBorrow, View, World}; + + fn system1(_: View<'_, usize>) {} + + let scheduler = { + #[cfg(feature = "std")] + { + AtomicRefCell::new(Scheduler::default(), None, true) + } + #[cfg(not(feature = "std"))] + { + AtomicRefCell::new(Scheduler::default()) + } + }; + WorkloadBuilder::new(scheduler.try_borrow_mut().unwrap(), "Systems".into()) + .with_system((|world: &World| world.try_run(system1), system1)) + .with_system(( + |world: &World| world.try_run(|_: FakeBorrow| {}), + |_: FakeBorrow| {}, + )) + .with_system((|world: &World| world.try_run(system1), system1)) + .build(); + + let scheduler = scheduler.try_borrow_mut().unwrap(); + assert_eq!(scheduler.systems.len(), 3); + assert_eq!(scheduler.batch.len(), 3); + assert_eq!(&*scheduler.batch[0], &[0]); + assert_eq!(&*scheduler.batch[1], &[1]); + assert_eq!(&*scheduler.batch[2], &[2]); + assert_eq!(scheduler.workloads.len(), 1); + assert_eq!(scheduler.workloads.get("Systems"), Some(&(0..3))); + assert_eq!(scheduler.default, 0..3); +} diff --git a/src/world/scheduler/function.rs b/src/world/scheduler/function.rs deleted file mode 100644 index a9bd7213..00000000 --- a/src/world/scheduler/function.rs +++ /dev/null @@ -1,61 +0,0 @@ -use super::Scheduler; -use crate::error; -use crate::World; -use std::borrow::Cow; - -pub trait IntoWorkloadFn { - fn into_workload(self, name: impl Into>, scheduler: &mut Scheduler); -} - -impl Fn(&'a World) -> Result<(), error::GetStorage> + Send + Sync + 'static> - IntoWorkloadFn for T -{ - fn into_workload(self, name: impl Into>, scheduler: &mut Scheduler) { - let range = scheduler.batch.len()..(scheduler.batch.len() + 1); - if scheduler.workloads.is_empty() { - scheduler.default = range.clone(); - } - scheduler.workloads.insert(name.into(), range); - scheduler.batch.push(Box::new([scheduler.systems.len()])); - scheduler.systems.push(Box::new(self)); - } -} - -impl Fn(&'a World) -> Result<(), error::GetStorage> + Send + Sync + 'static> - IntoWorkloadFn for (T,) -{ - fn into_workload(self, name: impl Into>, scheduler: &mut Scheduler) { - self.0.into_workload(name, scheduler) - } -} - -macro_rules! impl_scheduler { - ($(($type: ident, $index: tt))+) => { - impl<$($type: for<'a> Fn(&'a World) -> Result<(), error::GetStorage> + Send + Sync + 'static),+> IntoWorkloadFn for ($($type,)+) { - fn into_workload(self, name: impl Into>, scheduler: &mut Scheduler) { - let start = scheduler.batch.len(); - $( - scheduler.batch.push(Box::new([scheduler.systems.len()])); - scheduler.systems.push(Box::new(self.$index)); - )+ - let range = start..scheduler.batch.len(); - if scheduler.workloads.is_empty() { - scheduler.default = range.clone(); - } - scheduler.workloads.insert(name.into(), range); - } - } - } -} - -macro_rules! scheduler { - ($(($type: ident, $index: tt))*;($type1: ident, $index1: tt) $(($queue_type: ident, $queue_index: tt))*) => { - impl_scheduler![$(($type, $index))*]; - scheduler![$(($type, $index))* ($type1, $index1); $(($queue_type, $queue_index))*]; - }; - ($(($type: ident, $index: tt))*;) => { - impl_scheduler![$(($type, $index))*]; - } -} - -scheduler![(A, 0) (B, 1); (C, 2) (D, 3) (E, 4) (F, 5) (G, 6) (H, 7) (I, 8) (J, 9)]; diff --git a/src/world/scheduler/mod.rs b/src/world/scheduler/mod.rs index 831f4d37..5f5c9181 100644 --- a/src/world/scheduler/mod.rs +++ b/src/world/scheduler/mod.rs @@ -1,10 +1,6 @@ -// WIP -//mod function; -mod regular; +mod builder; -// WIP -//pub(super) use function::IntoWorkloadFn; -pub use regular::IntoWorkload; +pub use builder::WorkloadBuilder; use crate::error; use crate::World; @@ -15,15 +11,12 @@ use core::any::TypeId; use core::ops::Range; use hashbrown::HashMap; -#[allow(clippy::type_complexity)] pub struct Scheduler { - pub(super) systems: - Vec Fn(&'a World) -> Result<(), error::GetStorage> + Send + Sync>>, + pub(super) systems: Vec Result<(), error::Run> + Send + Sync + 'static>>, + pub(super) system_names: Vec<&'static str>, pub(super) lookup_table: HashMap, - // a batch list systems running in parallel + // a batch lists systems that can run in parallel pub(super) batch: Vec>, - // first usize is the index where the workload begins - // the second is the number of batch in it pub(super) workloads: HashMap, Range>, pub(super) default: Range, } @@ -32,6 +25,7 @@ impl Default for Scheduler { fn default() -> Self { Scheduler { systems: Vec::new(), + system_names: Vec::new(), lookup_table: HashMap::new(), batch: Vec::new(), workloads: HashMap::new(), diff --git a/src/world/scheduler/regular.rs b/src/world/scheduler/regular.rs deleted file mode 100644 index cfc81442..00000000 --- a/src/world/scheduler/regular.rs +++ /dev/null @@ -1,442 +0,0 @@ -use super::Scheduler; -use crate::run::{Dispatch, Mutation, System, SystemData}; -use crate::storage::AllStorages; -use alloc::borrow::Cow; -use alloc::boxed::Box; -use alloc::vec::Vec; -use core::any::TypeId; -use hashbrown::hash_map::Entry; - -pub trait IntoWorkload { - fn into_workload(name: impl Into>, scheduler: &mut Scheduler); -} - -impl System<'a> + 'static> IntoWorkload for T { - #[allow(clippy::range_plus_one)] - fn into_workload(name: impl Into>, scheduler: &mut Scheduler) { - let range = scheduler.batch.len()..(scheduler.batch.len() + 1); - if scheduler.workloads.is_empty() { - scheduler.default = range.clone(); - } - scheduler.workloads.insert(name.into(), range); - scheduler.batch.push(Box::new([scheduler.systems.len()])); - if let Entry::Vacant(vacant) = scheduler.lookup_table.entry(TypeId::of::()) { - vacant.insert(scheduler.systems.len()); - scheduler - .systems - .push(Box::new(|world| T::try_dispatch(world))); - } - } -} - -impl System<'a> + 'static> IntoWorkload for (T,) { - fn into_workload(name: impl Into>, scheduler: &mut Scheduler) { - T::into_workload(name, scheduler) - } -} - -macro_rules! impl_scheduler { - ($(($system: ident, $index: tt))+) => { - impl<$($system: for<'a> System<'a> + 'static),+> IntoWorkload for ($($system,)+) { - fn into_workload(name: impl Into>, scheduler: &mut Scheduler) { - let batch_start = scheduler.batch.len(); - // new batch added by this workload - let mut new_batch = vec![Vec::new()]; - // what is borrowed by each new batch - let mut batch_info = vec![Vec::new()]; - - $( - // register the system or retrive it's index - let system_index = match scheduler.lookup_table.entry(TypeId::of::<$system>()) { - Entry::Vacant(vacant) => { - vacant.insert(scheduler.systems.len()); - scheduler.systems.push(Box::new(|world| $system::try_dispatch(world))); - scheduler.systems.len() - 1 - }, - Entry::Occupied(occupied) => *occupied.get(), - }; - // for now systems with `!Send` and `!Sync` storages are run sequentially - if $system::Data::is_send_sync() { - // what is borrowed by this system - let mut borrow_infos = Vec::new(); - $system::Data::borrow_infos(&mut borrow_infos); - let mut batch_index = new_batch.len(); - for batch in batch_info.iter().rev() { - let mut conflict = false; - for &(type_id, mutation) in &borrow_infos { - match mutation { - Mutation::Shared => { - for &(batch_type_id, mutation) in batch.iter() { - #[cfg(feature = "parallel")] - { - if type_id == batch_type_id && mutation == Mutation::Unique - || batch_type_id == TypeId::of::() { - conflict = true; - break; - } - } - #[cfg(not(feature = "parallel"))] - { - if type_id == batch_type_id && mutation == Mutation::Unique - || batch_type_id == TypeId::of::() { - conflict = true; - break; - } - } - }; - }, - Mutation::Unique => { - for &(batch_type_id, _) in batch.iter() { - #[cfg(feature = "parallel")] - { - if type_id == batch_type_id - || type_id == TypeId::of::() - { - conflict = true; - break; - } - } - #[cfg(not(feature = "parallel"))] - { - if type_id == batch_type_id - || type_id == TypeId::of::() - { - conflict = true; - break; - } - } - }; - }, - } - } - - if conflict { - break; - } else { - batch_index -= 1; - } - } - - // conflict at the very last new batch - if batch_index == batch_info.len() { - new_batch.push(vec![system_index]); - batch_info.push(borrow_infos); - } else { - new_batch[batch_index].push(system_index); - batch_info[batch_index].append(&mut borrow_infos); - } - } else { - let last = new_batch.last_mut().unwrap(); - if last.is_empty() { - last.push(system_index); - new_batch.push(Vec::new()); - batch_info.last_mut().unwrap().push((TypeId::of::(), Mutation::Unique)); - batch_info.push(Vec::new()); - } else { - new_batch.push(vec![system_index]); - new_batch.push(Vec::new()); - batch_info.push(vec![(TypeId::of::(), Mutation::Unique)]); - batch_info.push(Vec::new()); - } - } - )+ - - if new_batch.last().unwrap().is_empty() { - new_batch.pop(); - } - - scheduler.batch.extend(new_batch.into_iter().map(|batch| batch.into_boxed_slice())); - - if scheduler.workloads.is_empty() { - scheduler.default = batch_start..(scheduler.batch.len()); - } - - scheduler.workloads.insert(name.into(), batch_start..(scheduler.batch.len())); - } - } - } -} - -macro_rules! scheduler { - ($(($system: ident, $index: tt))*;($system1: ident, $index1: tt) $(($queue_type: ident, $queue_index: tt))*) => { - impl_scheduler![$(($system, $index))*]; - scheduler![$(($system, $index))* ($system1, $index1); $(($queue_type, $queue_index))*]; - }; - ($(($system: ident, $index: tt))*;) => { - impl_scheduler![$(($system, $index))*]; - } -} - -scheduler![(A, 0) (B, 1); (C, 2) (D, 3) (E, 4) (F, 5) (G, 6) (H, 7) (I, 8) (J, 9)]; - -#[test] -fn single_immutable() { - struct System1; - impl<'a> System<'a> for System1 { - type Data = (&'a usize,); - fn run(_: >::View) {} - } - - let mut scheduler = Scheduler::default(); - System1::into_workload("System1", &mut scheduler); - assert_eq!(scheduler.systems.len(), 1); - assert_eq!(scheduler.batch.len(), 1); - assert_eq!(&*scheduler.batch[0], &[0]); - assert_eq!(scheduler.workloads.len(), 1); - assert_eq!(scheduler.workloads.get("System1"), Some(&(0..1))); - assert_eq!(scheduler.default, 0..1); -} -#[test] -fn single_mutable() { - struct System1; - impl<'a> System<'a> for System1 { - type Data = (&'a mut usize,); - fn run(_: >::View) {} - } - - let mut scheduler = Scheduler::default(); - System1::into_workload("System1", &mut scheduler); - assert_eq!(scheduler.systems.len(), 1); - assert_eq!(scheduler.batch.len(), 1); - assert_eq!(&*scheduler.batch[0], &[0]); - assert_eq!(scheduler.workloads.len(), 1); - assert_eq!(scheduler.workloads.get("System1"), Some(&(0..1))); - assert_eq!(scheduler.default, 0..1); -} -#[test] -fn multiple_immutable() { - struct System1; - impl<'a> System<'a> for System1 { - type Data = (&'a usize,); - fn run(_: >::View) {} - } - struct System2; - impl<'a> System<'a> for System2 { - type Data = (&'a usize,); - fn run(_: >::View) {} - } - - let mut scheduler = Scheduler::default(); - <(System1, System2)>::into_workload("Systems", &mut scheduler); - assert_eq!(scheduler.systems.len(), 2); - assert_eq!(scheduler.batch.len(), 1); - assert_eq!(&*scheduler.batch[0], &[0, 1]); - assert_eq!(scheduler.workloads.len(), 1); - assert_eq!(scheduler.workloads.get("Systems"), Some(&(0..1))); - assert_eq!(scheduler.default, 0..1); -} -#[test] -fn multiple_mutable() { - struct System1; - impl<'a> System<'a> for System1 { - type Data = (&'a mut usize,); - fn run(_: >::View) {} - } - struct System2; - impl<'a> System<'a> for System2 { - type Data = (&'a mut usize,); - fn run(_: >::View) {} - } - - let mut scheduler = Scheduler::default(); - <(System1, System2)>::into_workload("Systems", &mut scheduler); - assert_eq!(scheduler.systems.len(), 2); - assert_eq!(scheduler.batch.len(), 2); - assert_eq!(&*scheduler.batch[0], &[0]); - assert_eq!(&*scheduler.batch[1], &[1]); - assert_eq!(scheduler.workloads.len(), 1); - assert_eq!(scheduler.workloads.get("Systems"), Some(&(0..2))); - assert_eq!(scheduler.default, 0..2); -} -#[test] -fn multiple_mixed() { - struct System1; - impl<'a> System<'a> for System1 { - type Data = (&'a mut usize,); - fn run(_: >::View) {} - } - struct System2; - impl<'a> System<'a> for System2 { - type Data = (&'a usize,); - fn run(_: >::View) {} - } - - let mut scheduler = Scheduler::default(); - <(System1, System2)>::into_workload("Systems", &mut scheduler); - assert_eq!(scheduler.systems.len(), 2); - assert_eq!(scheduler.batch.len(), 2); - assert_eq!(&*scheduler.batch[0], &[0]); - assert_eq!(&*scheduler.batch[1], &[1]); - assert_eq!(scheduler.workloads.len(), 1); - assert_eq!(scheduler.workloads.get("Systems"), Some(&(0..2))); - assert_eq!(scheduler.default, 0..2); - - let mut scheduler = Scheduler::default(); - <(System2, System1)>::into_workload("Systems", &mut scheduler); - assert_eq!(scheduler.systems.len(), 2); - assert_eq!(scheduler.batch.len(), 2); - assert_eq!(&*scheduler.batch[0], &[0]); - assert_eq!(&*scheduler.batch[1], &[1]); - assert_eq!(scheduler.workloads.len(), 1); - assert_eq!(scheduler.workloads.get("Systems"), Some(&(0..2))); - assert_eq!(scheduler.default, 0..2); -} -#[test] -fn all_storages() { - struct System1; - impl<'a> System<'a> for System1 { - type Data = (&'a usize,); - fn run(_: >::View) {} - } - struct System2; - impl<'a> System<'a> for System2 { - type Data = (AllStorages,); - fn run(_: >::View) {} - } - - let mut scheduler = Scheduler::default(); - System2::into_workload("Systems", &mut scheduler); - assert_eq!(scheduler.systems.len(), 1); - assert_eq!(scheduler.batch.len(), 1); - assert_eq!(&*scheduler.batch[0], &[0]); - assert_eq!(scheduler.workloads.len(), 1); - assert_eq!(scheduler.workloads.get("Systems"), Some(&(0..1))); - assert_eq!(scheduler.default, 0..1); - - let mut scheduler = Scheduler::default(); - <(System2, System2)>::into_workload("Systems", &mut scheduler); - assert_eq!(scheduler.systems.len(), 1); - assert_eq!(scheduler.batch.len(), 2); - assert_eq!(&*scheduler.batch[0], &[0]); - assert_eq!(&*scheduler.batch[0], &[0]); - assert_eq!(scheduler.workloads.len(), 1); - assert_eq!(scheduler.workloads.get("Systems"), Some(&(0..2))); - assert_eq!(scheduler.default, 0..2); - - let mut scheduler = Scheduler::default(); - <(System1, System2)>::into_workload("Systems", &mut scheduler); - assert_eq!(scheduler.systems.len(), 2); - assert_eq!(scheduler.batch.len(), 2); - assert_eq!(&*scheduler.batch[0], &[0]); - assert_eq!(&*scheduler.batch[1], &[1]); - assert_eq!(scheduler.workloads.len(), 1); - assert_eq!(scheduler.workloads.get("Systems"), Some(&(0..2))); - assert_eq!(scheduler.default, 0..2); - - let mut scheduler = Scheduler::default(); - <(System2, System1)>::into_workload("Systems", &mut scheduler); - assert_eq!(scheduler.systems.len(), 2); - assert_eq!(scheduler.batch.len(), 2); - assert_eq!(&*scheduler.batch[0], &[0]); - assert_eq!(&*scheduler.batch[1], &[1]); - assert_eq!(scheduler.workloads.len(), 1); - assert_eq!(scheduler.workloads.get("Systems"), Some(&(0..2))); - assert_eq!(scheduler.default, 0..2); -} - -#[cfg(feature = "non_send")] -#[test] -fn non_send() { - struct NonSend(*const ()); - unsafe impl Sync for NonSend {} - - struct Sys1; - impl<'a> System<'a> for Sys1 { - type Data = (crate::NonSend<&'a NonSend>,); - fn run(_: >::View) {} - } - struct Sys2; - impl<'a> System<'a> for Sys2 { - type Data = (crate::NonSend<&'a mut NonSend>,); - fn run(_: >::View) {} - } - - struct Sys3; - impl<'a> System<'a> for Sys3 { - type Data = (&'a usize,); - fn run(_: >::View) {} - } - - struct Sys4; - impl<'a> System<'a> for Sys4 { - type Data = (&'a mut usize,); - fn run(_: >::View) {} - } - - let mut scheduler = Scheduler::default(); - <(Sys1, Sys1)>::into_workload("Test", &mut scheduler); - assert_eq!(scheduler.systems.len(), 1); - assert_eq!(scheduler.batch.len(), 2); - assert_eq!(&*scheduler.batch[0], &[0]); - assert_eq!(&*scheduler.batch[1], &[0]); - assert_eq!(scheduler.workloads.len(), 1); - assert_eq!(scheduler.workloads.get("Test"), Some(&(0..2))); - assert_eq!(scheduler.default, 0..2); - - let mut scheduler = Scheduler::default(); - <(Sys1, Sys2)>::into_workload("Test", &mut scheduler); - assert_eq!(scheduler.systems.len(), 2); - assert_eq!(scheduler.batch.len(), 2); - assert_eq!(&*scheduler.batch[0], &[0]); - assert_eq!(&*scheduler.batch[1], &[1]); - assert_eq!(scheduler.workloads.len(), 1); - assert_eq!(scheduler.workloads.get("Test"), Some(&(0..2))); - assert_eq!(scheduler.default, 0..2); - - let mut scheduler = Scheduler::default(); - <(Sys2, Sys1)>::into_workload("Test", &mut scheduler); - assert_eq!(scheduler.systems.len(), 2); - assert_eq!(scheduler.batch.len(), 2); - assert_eq!(&*scheduler.batch[0], &[0]); - assert_eq!(&*scheduler.batch[1], &[1]); - assert_eq!(scheduler.workloads.len(), 1); - assert_eq!(scheduler.workloads.get("Test"), Some(&(0..2))); - assert_eq!(scheduler.default, 0..2); - - let mut scheduler = Scheduler::default(); - <(Sys1, Sys2)>::into_workload("Test", &mut scheduler); - assert_eq!(scheduler.systems.len(), 2); - assert_eq!(scheduler.batch.len(), 2); - assert_eq!(&*scheduler.batch[0], &[0]); - assert_eq!(&*scheduler.batch[1], &[1]); - assert_eq!(scheduler.workloads.len(), 1); - assert_eq!(scheduler.workloads.get("Test"), Some(&(0..2))); - assert_eq!(scheduler.default, 0..2); - - let mut scheduler = Scheduler::default(); - <(Sys1, Sys2)>::into_workload("Test", &mut scheduler); - assert_eq!(scheduler.systems.len(), 2); - assert_eq!(scheduler.batch.len(), 2); - assert_eq!(&*scheduler.batch[0], &[0]); - assert_eq!(&*scheduler.batch[1], &[1]); - assert_eq!(scheduler.workloads.len(), 1); - assert_eq!(scheduler.workloads.get("Test"), Some(&(0..2))); - assert_eq!(scheduler.default, 0..2); -} - -#[test] -fn fake_borrow() { - use crate::run::FakeBorrow; - - struct System1; - impl<'a> System<'a> for System1 { - type Data = (&'a usize,); - fn run(_: >::View) {} - } - struct System2; - impl<'a> System<'a> for System2 { - type Data = (&'a usize,); - fn run(_: >::View) {} - } - - let mut scheduler = Scheduler::default(); - <(System1, FakeBorrow, System2)>::into_workload("Systems", &mut scheduler); - assert_eq!(scheduler.systems.len(), 3); - assert_eq!(scheduler.batch.len(), 3); - assert_eq!(&*scheduler.batch[0], &[0]); - assert_eq!(&*scheduler.batch[1], &[1]); - assert_eq!(&*scheduler.batch[2], &[2]); - assert_eq!(scheduler.workloads.len(), 1); - assert_eq!(scheduler.workloads.get("Systems"), Some(&(0..3))); - assert_eq!(scheduler.default, 0..3); -} diff --git a/tests/add_component.rs b/tests/add_component.rs index c49fd8f1..a990bb70 100644 --- a/tests/add_component.rs +++ b/tests/add_component.rs @@ -1,10 +1,10 @@ -use shipyard::prelude::*; +use shipyard::*; #[test] fn no_pack() { let world = World::new(); let (mut entities, mut usizes, mut u32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); let entity1 = entities.add_entity((), ()); entities.add_component((&mut usizes, &mut u32s), (0, 1), entity1); @@ -16,7 +16,7 @@ fn no_pack() { fn tight() { let world = World::new(); let (mut entities, mut usizes, mut u32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut usizes, &mut u32s).tight_pack(); let entity1 = entities.add_entity((), ()); @@ -32,7 +32,7 @@ fn tight() { fn loose_add_component() { let world = World::new(); let (mut entities, mut usizes, mut u32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut usizes, &mut u32s).loose_pack(); let entity1 = entities.add_entity((), ()); @@ -48,7 +48,7 @@ fn loose_add_component() { fn tight_loose_add_component() { let world = World::new(); let (mut entities, mut usizes, mut u64s, mut u32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u64, &mut u32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut, ViewMut)>(); (&mut usizes, &mut u64s).tight_pack(); LoosePack::<(u32,)>::loose_pack((&mut u32s, &mut usizes, &mut u64s)); @@ -67,7 +67,7 @@ fn tight_loose_add_component() { #[test] fn update() { let world = World::new(); - let (mut entities, mut usizes) = world.borrow::<(EntitiesMut, &mut usize)>(); + let (mut entities, mut usizes) = world.borrow::<(EntitiesViewMut, ViewMut)>(); usizes.update_pack(); let e0 = entities.add_entity((), ()); @@ -92,7 +92,7 @@ fn update() { fn not_enough_to_tightly_pack() { let world = World::new(); let (mut entities, mut usizes, mut u32s, mut f32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u32, &mut f32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut, ViewMut)>(); (&mut usizes, &mut u32s).tight_pack(); entities.add_entity(&mut u32s, 0); @@ -111,7 +111,7 @@ fn not_enough_to_tightly_pack() { fn not_enough_to_loosely_pack() { let world = World::new(); let (mut entities, mut usizes, mut u32s, mut f32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u32, &mut f32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut, ViewMut)>(); (&mut usizes, &mut u32s).loose_pack(); entities.add_entity(&mut u32s, 0); diff --git a/tests/add_entity.rs b/tests/add_entity.rs index 8ef78eb2..887b0449 100644 --- a/tests/add_entity.rs +++ b/tests/add_entity.rs @@ -1,13 +1,13 @@ -use shipyard::prelude::*; +use shipyard::*; #[test] fn no_pack() { let world = World::default(); - world.run::(|mut entities| { + world.run(|mut entities: EntitiesViewMut| { entities.add_entity((), ()); }); - world.run::<(EntitiesMut, &mut usize, &mut u32), _, _>( - |(mut entities, mut usizes, mut u32s)| { + world.run( + |(mut entities, mut usizes, mut u32s): (EntitiesViewMut, ViewMut, ViewMut)| { let entity1 = entities.add_entity((&mut usizes, &mut u32s), (0, 1)); assert_eq!((&usizes, &u32s).get(entity1).unwrap(), (&0, &1)); }, @@ -18,7 +18,7 @@ fn no_pack() { fn tight() { let world = World::new(); let (mut entities, mut usizes, mut u32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut usizes, &mut u32s).tight_pack(); let entity1 = entities.add_entity((&mut usizes, &mut u32s), (0, 1)); @@ -29,7 +29,7 @@ fn tight() { fn loose() { let world = World::new(); let (mut entities, mut usizes, mut u32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut usizes, &mut u32s).loose_pack(); let entity1 = entities.add_entity((&mut usizes, &mut u32s), (0, 1)); @@ -40,7 +40,7 @@ fn loose() { fn tight_loose() { let world = World::new(); let (mut entities, mut usizes, mut u64s, mut u32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u64, &mut u32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut, ViewMut)>(); (&mut usizes, &mut u64s).tight_pack(); LoosePack::<(u32,)>::loose_pack((&mut u32s, &mut usizes, &mut u64s)); @@ -51,7 +51,7 @@ fn tight_loose() { #[test] fn update() { let world = World::new(); - let (mut entities, mut usizes) = world.borrow::<(EntitiesMut, &mut usize)>(); + let (mut entities, mut usizes) = world.borrow::<(EntitiesViewMut, ViewMut)>(); usizes.update_pack(); let entity = entities.add_entity(&mut usizes, 0); assert_eq!(usizes.inserted().len(), 1); @@ -61,7 +61,7 @@ fn update() { #[test] fn cleared_update() { let world = World::new(); - let (mut entities, mut usizes) = world.borrow::<(EntitiesMut, &mut usize)>(); + let (mut entities, mut usizes) = world.borrow::<(EntitiesViewMut, ViewMut)>(); usizes.update_pack(); let entity1 = entities.add_entity(&mut usizes, 1); usizes.clear_inserted_and_modified(); @@ -74,7 +74,7 @@ fn cleared_update() { #[test] fn modified_update() { let world = World::new(); - let (mut entities, mut usizes) = world.borrow::<(EntitiesMut, &mut usize)>(); + let (mut entities, mut usizes) = world.borrow::<(EntitiesViewMut, ViewMut)>(); usizes.update_pack(); let entity1 = entities.add_entity(&mut usizes, 1); usizes.clear_inserted_and_modified(); @@ -90,7 +90,7 @@ fn not_all_tight() { let world = World::new(); let (mut entities, mut u32s, mut u16s, mut f32s) = - world.borrow::<(EntitiesMut, &mut u32, &mut u16, &mut f32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut, ViewMut)>(); (&mut u32s, &mut u16s).tight_pack(); @@ -105,7 +105,7 @@ fn not_all_loose() { let world = World::new(); let (mut entities, mut u32s, mut u16s, mut f32s) = - world.borrow::<(EntitiesMut, &mut u32, &mut u16, &mut f32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut, ViewMut)>(); (&mut u32s, &mut u16s).loose_pack(); diff --git a/tests/book/hierarchy.rs b/tests/book/hierarchy.rs index 9f010ee3..24e6f361 100644 --- a/tests/book/hierarchy.rs +++ b/tests/book/hierarchy.rs @@ -1,4 +1,4 @@ -use shipyard::prelude::*; +use shipyard::*; struct Parent { num_children: usize, diff --git a/tests/book/mod.rs b/tests/book/mod.rs index c3d7d7c0..3ca4bfe0 100644 --- a/tests/book/mod.rs +++ b/tests/book/mod.rs @@ -15,7 +15,7 @@ mod systems; mod world; mod world_insides; -use shipyard::prelude::*; +use shipyard::*; struct Empty; diff --git a/tests/book/packs.rs b/tests/book/packs.rs index 2f28138d..f80630ad 100644 --- a/tests/book/packs.rs +++ b/tests/book/packs.rs @@ -1,4 +1,4 @@ -use shipyard::prelude::*; +use shipyard::*; #[test] fn tight() { diff --git a/tests/book/syntactic_peculiarities.rs b/tests/book/syntactic_peculiarities.rs index afdee816..3bd8c694 100644 --- a/tests/book/syntactic_peculiarities.rs +++ b/tests/book/syntactic_peculiarities.rs @@ -1,4 +1,4 @@ -use shipyard::prelude::*; +use shipyard::*; #[system(RefMut)] fn run(ref mut usizes: &mut usize) { diff --git a/tests/book/world_insides.rs b/tests/book/world_insides.rs index 9a043bad..8d9cc092 100644 --- a/tests/book/world_insides.rs +++ b/tests/book/world_insides.rs @@ -1,4 +1,4 @@ -use shipyard::prelude::*; +use shipyard::*; #[test] fn test1() { diff --git a/tests/borrow/mod.rs b/tests/borrow/mod.rs index fd559e07..f189c135 100644 --- a/tests/borrow/mod.rs +++ b/tests/borrow/mod.rs @@ -1,13 +1,13 @@ #[cfg(feature = "non_send")] use core::any::type_name; use shipyard::error; -use shipyard::prelude::*; +use shipyard::*; #[test] fn simple_borrow() { let world = World::new(); - let u32s = world.borrow::<&u32>(); + let u32s = world.borrow::>(); assert_eq!(u32s.len(), 0); } @@ -15,8 +15,8 @@ fn simple_borrow() { fn all_storages_simple_borrow() { let world = World::new(); - let all_storages = world.borrow::(); - let u32s = all_storages.borrow::<&u32>(); + let all_storages = world.borrow::(); + let u32s = all_storages.borrow::>(); assert_eq!(u32s.len(), 0); } @@ -24,9 +24,9 @@ fn all_storages_simple_borrow() { fn invalid_borrow() { let world = World::new(); - let _u32s = world.borrow::<&mut u32>(); + let _u32s = world.borrow::>(); assert_eq!( - world.try_borrow::<&mut u32>().err(), + world.try_borrow::>().err(), Some(error::GetStorage::StorageBorrow(( core::any::type_name::(), error::Borrow::Unique @@ -38,10 +38,10 @@ fn invalid_borrow() { fn all_storages_invalid_borrow() { let world = World::new(); - let all_storages = world.borrow::(); - let _u32s = all_storages.borrow::<&mut u32>(); + let all_storages = world.borrow::(); + let _u32s = all_storages.borrow::>(); assert_eq!( - all_storages.try_borrow::<&mut u32>().err(), + all_storages.try_borrow::>().err(), Some(error::GetStorage::StorageBorrow(( core::any::type_name::(), error::Borrow::Unique @@ -53,19 +53,19 @@ fn all_storages_invalid_borrow() { fn double_borrow() { let world = World::new(); - let u32s = world.borrow::<&mut u32>(); + let u32s = world.borrow::>(); drop(u32s); - world.borrow::<&mut u32>(); + world.borrow::>(); } #[test] fn all_storages_double_borrow() { let world = World::new(); - let all_storages = world.borrow::(); - let u32s = all_storages.borrow::<&mut u32>(); + let all_storages = world.borrow::(); + let u32s = all_storages.borrow::>(); drop(u32s); - all_storages.borrow::<&mut u32>(); + all_storages.borrow::>(); } #[test] @@ -79,7 +79,7 @@ fn non_send_storage_in_other_thread() { rayon::join( || { assert_eq!( - world.try_borrow::>().err(), + world.try_borrow::>>().err(), Some(error::GetStorage::StorageBorrow(( type_name::(), error::Borrow::WrongThread @@ -99,7 +99,9 @@ fn non_send_sync_storage_in_other_thread() { rayon::join( || { assert_eq!( - world.try_borrow::>().err(), + world + .try_borrow::>>() + .err(), Some(error::GetStorage::StorageBorrow(( type_name::(), error::Borrow::WrongThread diff --git a/tests/clear.rs b/tests/clear.rs index da5ae8f6..0383c633 100644 --- a/tests/clear.rs +++ b/tests/clear.rs @@ -1,21 +1,21 @@ use core::any::type_name; use shipyard::error; -use shipyard::prelude::*; +use shipyard::*; #[test] fn no_pack() { let world = World::new(); - let (mut entities, mut u32s) = world.borrow::<(EntitiesMut, &mut u32)>(); + let (mut entities, mut u32s) = world.borrow::<(EntitiesViewMut, ViewMut)>(); entities.add_entity(&mut u32s, 0); entities.add_entity(&mut u32s, 1); entities.add_entity(&mut u32s, 2); drop((entities, u32s)); - world.borrow::().clear(); + world.borrow::().clear(); - let (mut entities, mut u32s) = world.borrow::<(EntitiesMut, &mut u32)>(); + let (mut entities, mut u32s) = world.borrow::<(EntitiesViewMut, ViewMut)>(); assert_eq!(u32s.len(), 0); let entity0 = entities.add_entity(&mut u32s, 3); @@ -45,18 +45,18 @@ fn no_pack() { fn tight() { let world = World::new(); let (mut entities, mut usizes, mut u32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut usizes, &mut u32s).tight_pack(); let entity1 = entities.add_entity((&mut usizes, &mut u32s), (0usize, 1u32)); let entity2 = entities.add_entity((&mut usizes, &mut u32s), (2usize, 3u32)); drop((entities, usizes, u32s)); - let mut all_storages = world.borrow::(); + let mut all_storages = world.borrow::(); all_storages.clear(); drop(all_storages); - let (usizes, u32s) = world.borrow::<(&usize, &u32)>(); + let (usizes, u32s) = world.borrow::<(View, View)>(); assert_eq!( (&usizes).get(entity1), @@ -96,18 +96,18 @@ fn tight() { fn delete_loose() { let world = World::new(); let (mut entities, mut usizes, mut u32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut usizes, &mut u32s).loose_pack(); let entity1 = entities.add_entity((&mut usizes, &mut u32s), (0usize, 1u32)); let entity2 = entities.add_entity((&mut usizes, &mut u32s), (2usize, 3u32)); drop((entities, usizes, u32s)); - world.run::(|mut all_storages| { + world.run(|mut all_storages: AllStoragesViewMut| { all_storages.clear(); }); - world.run::<(&usize, &u32), _, _>(|(usizes, u32s)| { + world.run(|(usizes, u32s): (View, View)| { assert_eq!( (&usizes).get(entity1), Err(error::MissingComponent { @@ -146,7 +146,7 @@ fn delete_loose() { fn delete_tight_loose() { let world = World::new(); let (mut entities, mut usizes, mut u64s, mut u32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u64, &mut u32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut, ViewMut)>(); (&mut usizes, &mut u64s).tight_pack(); LoosePack::<(u32,)>::loose_pack((&mut u32s, &mut usizes, &mut u64s)); @@ -154,78 +154,80 @@ fn delete_tight_loose() { let entity2 = entities.add_entity((&mut usizes, &mut u64s, &mut u32s), (3, 4, 5)); drop((entities, usizes, u64s, u32s)); - world.run::(|mut all_storages| { + world.run(|mut all_storages: AllStoragesViewMut| { all_storages.clear(); }); - world.run::<(&usize, &u64, &u32), _, _>(|(usizes, u64s, u32s)| { - assert_eq!( - (&usizes).get(entity1), - Err(error::MissingComponent { - id: entity1, - name: type_name::(), - }) - ); - assert_eq!( - (&u64s).get(entity1), - Err(error::MissingComponent { - id: entity1, - name: type_name::(), - }) - ); - assert_eq!( - (&u32s).get(entity1), - Err(error::MissingComponent { - id: entity1, - name: type_name::(), - }) - ); - assert_eq!( - usizes.get(entity2), - Err(error::MissingComponent { - id: entity2, - name: type_name::(), - }) - ); - assert_eq!( - u64s.get(entity2), - Err(error::MissingComponent { - id: entity2, - name: type_name::(), - }) - ); - assert_eq!( - u32s.get(entity2), - Err(error::MissingComponent { - id: entity2, - name: type_name::(), - }) - ); - let mut tight_iter = (&usizes, &u64s).iter(); - assert_eq!(tight_iter.next(), None); - let mut loose_iter = (&usizes, &u64s, &u32s).iter(); - assert_eq!(loose_iter.next(), None); - assert_eq!(usizes.len(), 0); - assert_eq!(u64s.len(), 0); - assert_eq!(u32s.len(), 0); - }); + world.run( + |(usizes, u64s, u32s): (View, View, View)| { + assert_eq!( + (&usizes).get(entity1), + Err(error::MissingComponent { + id: entity1, + name: type_name::(), + }) + ); + assert_eq!( + (&u64s).get(entity1), + Err(error::MissingComponent { + id: entity1, + name: type_name::(), + }) + ); + assert_eq!( + (&u32s).get(entity1), + Err(error::MissingComponent { + id: entity1, + name: type_name::(), + }) + ); + assert_eq!( + usizes.get(entity2), + Err(error::MissingComponent { + id: entity2, + name: type_name::(), + }) + ); + assert_eq!( + u64s.get(entity2), + Err(error::MissingComponent { + id: entity2, + name: type_name::(), + }) + ); + assert_eq!( + u32s.get(entity2), + Err(error::MissingComponent { + id: entity2, + name: type_name::(), + }) + ); + let mut tight_iter = (&usizes, &u64s).iter(); + assert_eq!(tight_iter.next(), None); + let mut loose_iter = (&usizes, &u64s, &u32s).iter(); + assert_eq!(loose_iter.next(), None); + assert_eq!(usizes.len(), 0); + assert_eq!(u64s.len(), 0); + assert_eq!(u32s.len(), 0); + }, + ); } #[test] fn update() { let world = World::new(); - let (mut entities, mut usizes) = world.borrow::<(EntitiesMut, &mut usize)>(); + let (mut entities, mut usizes) = world.borrow::<(EntitiesViewMut, ViewMut)>(); usizes.update_pack(); let entity1 = entities.add_entity(&mut usizes, 0); let entity2 = entities.add_entity(&mut usizes, 2); drop((entities, usizes)); - let mut all_storages = world.borrow::(); + let mut all_storages = world.borrow::(); all_storages.clear(); drop(all_storages); - let mut usizes = world.borrow::<&mut usize>(); + let mut usizes = world.borrow::>(); assert_eq!( (&usizes).get(entity1), Err(error::MissingComponent { diff --git a/tests/delete_component.rs b/tests/delete_component.rs index 90825d0a..dd55f64b 100644 --- a/tests/delete_component.rs +++ b/tests/delete_component.rs @@ -1,13 +1,13 @@ use core::any::type_name; use shipyard::error; -use shipyard::internal::iterators; -use shipyard::prelude::*; +use shipyard::iterators; +use shipyard::*; #[test] fn no_pack() { let world = World::new(); let (mut entities, mut usizes, mut u32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); let entity1 = entities.add_entity((&mut usizes, &mut u32s), (0usize, 1u32)); let entity2 = entities.add_entity((&mut usizes, &mut u32s), (2usize, 3u32)); @@ -28,7 +28,7 @@ fn no_pack() { fn tight() { let world = World::new(); let (mut entities, mut usizes, mut u32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut usizes, &mut u32s).tight_pack(); let entity1 = entities.add_entity((&mut usizes, &mut u32s), (0usize, 1u32)); @@ -57,7 +57,7 @@ fn tight() { fn loose() { let world = World::new(); let (mut entities, mut usizes, mut u32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut usizes, &mut u32s).loose_pack(); let entity1 = entities.add_entity((&mut usizes, &mut u32s), (0usize, 1u32)); @@ -82,7 +82,7 @@ fn loose() { fn tight_loose() { let world = World::new(); let (mut entities, mut usizes, mut u64s, mut u32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u64, &mut u32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut, ViewMut)>(); (&mut usizes, &mut u64s).tight_pack(); LoosePack::<(u32,)>::loose_pack((&mut u32s, &mut usizes, &mut u64s)); @@ -115,7 +115,7 @@ fn tight_loose() { #[test] fn update() { let world = World::new(); - let (mut entities, mut usizes) = world.borrow::<(EntitiesMut, &mut usize)>(); + let (mut entities, mut usizes) = world.borrow::<(EntitiesViewMut, ViewMut)>(); usizes.update_pack(); @@ -141,8 +141,8 @@ fn update() { fn strip() { let world = World::new(); - let (entity1, entity2) = world.run::<(EntitiesMut, &mut usize, &mut u32), _, _>( - |(mut entities, mut usizes, mut u32s)| { + let (entity1, entity2) = world.run( + |(mut entities, mut usizes, mut u32s): (EntitiesViewMut, ViewMut, ViewMut)| { ( entities.add_entity((&mut usizes, &mut u32s), (0usize, 1u32)), entities.add_entity((&mut usizes, &mut u32s), (2usize, 3u32)), @@ -150,11 +150,11 @@ fn strip() { }, ); - world.run::(|mut all_storages| { + world.run(|mut all_storages: AllStoragesViewMut| { all_storages.strip(entity1); }); - world.run::<(&mut usize, &mut u32), _, _>(|(mut usizes, mut u32s)| { + world.run(|(mut usizes, mut u32s): (ViewMut, ViewMut)| { assert_eq!( (&mut usizes).get(entity1), Err(error::MissingComponent { @@ -173,7 +173,7 @@ fn strip() { assert_eq!(u32s.get(entity2), Ok(&3)); }); - world.run::(|mut all_storages| { + world.run(|mut all_storages: AllStoragesViewMut| { assert!(all_storages.delete(entity1)); }); } diff --git a/tests/delete_entity.rs b/tests/delete_entity.rs index 55928aba..b9caeaf4 100644 --- a/tests/delete_entity.rs +++ b/tests/delete_entity.rs @@ -1,23 +1,23 @@ use core::any::type_name; use shipyard::error; -use shipyard::prelude::*; +use shipyard::*; #[test] fn no_pack() { let world = World::new(); let (mut entities, mut usizes, mut u32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); let entity1 = entities.add_entity((&mut usizes, &mut u32s), (0usize, 1u32)); let entity2 = entities.add_entity((&mut usizes, &mut u32s), (2usize, 3u32)); drop((entities, usizes, u32s)); - let mut all_storages = world.borrow::(); + let mut all_storages = world.borrow::(); assert!(all_storages.delete(entity1)); assert!(!all_storages.delete(entity1)); drop(all_storages); - let (usizes, u32s) = world.borrow::<(&usize, &u32)>(); + let (usizes, u32s) = world.borrow::<(View, View)>(); assert_eq!( (&usizes).get(entity1), Err(error::MissingComponent { @@ -40,19 +40,19 @@ fn no_pack() { fn tight() { let world = World::new(); let (mut entities, mut usizes, mut u32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut usizes, &mut u32s).tight_pack(); let entity1 = entities.add_entity((&mut usizes, &mut u32s), (0usize, 1u32)); let entity2 = entities.add_entity((&mut usizes, &mut u32s), (2usize, 3u32)); drop((entities, usizes, u32s)); - let mut all_storages = world.borrow::(); + let mut all_storages = world.borrow::(); assert!(all_storages.delete(entity1)); assert!(!all_storages.delete(entity1)); drop(all_storages); - let (usizes, u32s) = world.borrow::<(&usize, &u32)>(); + let (usizes, u32s) = world.borrow::<(View, View)>(); assert_eq!( (&usizes).get(entity1), @@ -79,19 +79,19 @@ fn tight() { fn delete_loose() { let world = World::new(); let (mut entities, mut usizes, mut u32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut usizes, &mut u32s).loose_pack(); let entity1 = entities.add_entity((&mut usizes, &mut u32s), (0usize, 1u32)); let entity2 = entities.add_entity((&mut usizes, &mut u32s), (2usize, 3u32)); drop((entities, usizes, u32s)); - world.run::(|mut all_storages| { + world.run(|mut all_storages: AllStoragesViewMut| { assert!(all_storages.delete(entity1)); assert!(!all_storages.delete(entity1)); }); - world.run::<(&usize, &u32), _, _>(|(usizes, u32s)| { + world.run(|(usizes, u32s): (View, View)| { assert_eq!( (&usizes).get(entity1), Err(error::MissingComponent { @@ -118,7 +118,7 @@ fn delete_loose() { fn delete_tight_loose() { let world = World::new(); let (mut entities, mut usizes, mut u64s, mut u32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u64, &mut u32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut, ViewMut)>(); (&mut usizes, &mut u64s).tight_pack(); LoosePack::<(u32,)>::loose_pack((&mut u32s, &mut usizes, &mut u64s)); @@ -126,61 +126,63 @@ fn delete_tight_loose() { let entity2 = entities.add_entity((&mut usizes, &mut u64s, &mut u32s), (3, 4, 5)); drop((entities, usizes, u64s, u32s)); - world.run::(|mut all_storages| { + world.run(|mut all_storages: AllStoragesViewMut| { assert!(all_storages.delete(entity1)); assert!(!all_storages.delete(entity1)); }); - world.run::<(&usize, &u64, &u32), _, _>(|(usizes, u64s, u32s)| { - assert_eq!( - (&usizes).get(entity1), - Err(error::MissingComponent { - id: entity1, - name: type_name::(), - }) - ); - assert_eq!( - (&u64s).get(entity1), - Err(error::MissingComponent { - id: entity1, - name: type_name::(), - }) - ); - assert_eq!( - (&u32s).get(entity1), - Err(error::MissingComponent { - id: entity1, - name: type_name::(), - }) - ); - assert_eq!(usizes.get(entity2), Ok(&3)); - assert_eq!(u64s.get(entity2), Ok(&4)); - assert_eq!(u32s.get(entity2), Ok(&5)); - let mut tight_iter = (&usizes, &u64s).iter(); - assert_eq!(tight_iter.next(), Some((&3, &4))); - assert_eq!(tight_iter.next(), None); - let mut loose_iter = (&usizes, &u64s, &u32s).iter(); - assert_eq!(loose_iter.next(), Some((&3, &4, &5))); - assert_eq!(loose_iter.next(), None); - }); + world.run( + |(usizes, u64s, u32s): (View, View, View)| { + assert_eq!( + (&usizes).get(entity1), + Err(error::MissingComponent { + id: entity1, + name: type_name::(), + }) + ); + assert_eq!( + (&u64s).get(entity1), + Err(error::MissingComponent { + id: entity1, + name: type_name::(), + }) + ); + assert_eq!( + (&u32s).get(entity1), + Err(error::MissingComponent { + id: entity1, + name: type_name::(), + }) + ); + assert_eq!(usizes.get(entity2), Ok(&3)); + assert_eq!(u64s.get(entity2), Ok(&4)); + assert_eq!(u32s.get(entity2), Ok(&5)); + let mut tight_iter = (&usizes, &u64s).iter(); + assert_eq!(tight_iter.next(), Some((&3, &4))); + assert_eq!(tight_iter.next(), None); + let mut loose_iter = (&usizes, &u64s, &u32s).iter(); + assert_eq!(loose_iter.next(), Some((&3, &4, &5))); + assert_eq!(loose_iter.next(), None); + }, + ); } #[test] fn update() { let world = World::new(); - let (mut entities, mut usizes) = world.borrow::<(EntitiesMut, &mut usize)>(); + let (mut entities, mut usizes) = world.borrow::<(EntitiesViewMut, ViewMut)>(); usizes.update_pack(); let entity1 = entities.add_entity(&mut usizes, 0); let entity2 = entities.add_entity(&mut usizes, 2); drop((entities, usizes)); - let mut all_storages = world.borrow::(); + let mut all_storages = world.borrow::(); assert!(all_storages.delete(entity1)); assert!(!all_storages.delete(entity1)); drop(all_storages); - let mut usizes = world.borrow::<&mut usize>(); + let mut usizes = world.borrow::>(); assert_eq!( (&usizes).get(entity1), Err(error::MissingComponent { diff --git a/tests/derive/all_storages.rs b/tests/derive/all_storages.rs index f79d7add..d8bcfb8b 100644 --- a/tests/derive/all_storages.rs +++ b/tests/derive/all_storages.rs @@ -1,4 +1,4 @@ -use shipyard::prelude::*; +use shipyard::*; #[system(Test1)] fn run(_: AllStorages, _: &mut i32) {} diff --git a/tests/derive/all_storages_threadpool.rs b/tests/derive/all_storages_threadpool.rs index 3cabe8c2..a2a0c76f 100644 --- a/tests/derive/all_storages_threadpool.rs +++ b/tests/derive/all_storages_threadpool.rs @@ -1,4 +1,4 @@ -use shipyard::prelude::*; +use shipyard::*; #[system(All)] fn run(_: AllStorages, _: ThreadPool) {} diff --git a/tests/derive/double_borrow.rs b/tests/derive/double_borrow.rs index 3b5fccf6..74e29d35 100644 --- a/tests/derive/double_borrow.rs +++ b/tests/derive/double_borrow.rs @@ -1,4 +1,4 @@ -use shipyard::prelude::*; +use shipyard::*; #[system(Double)] fn run(_: &u32, _: &mut u32) {} diff --git a/tests/derive/double_borrow_non_send.rs b/tests/derive/double_borrow_non_send.rs index 651074e6..ba891672 100644 --- a/tests/derive/double_borrow_non_send.rs +++ b/tests/derive/double_borrow_non_send.rs @@ -1,4 +1,4 @@ -use shipyard::prelude::*; +use shipyard::*; struct NonSendStruct(core::marker::PhantomData<*const ()>); diff --git a/tests/derive/double_borrow_non_send_sync.rs b/tests/derive/double_borrow_non_send_sync.rs index 24b1d468..71ff37b8 100644 --- a/tests/derive/double_borrow_non_send_sync.rs +++ b/tests/derive/double_borrow_non_send_sync.rs @@ -1,4 +1,4 @@ -use shipyard::prelude::*; +use shipyard::*; struct NonSendSyncStruct(core::marker::PhantomData<*const ()>); diff --git a/tests/derive/double_borrow_non_sync.rs b/tests/derive/double_borrow_non_sync.rs index 84ab1071..ddf33043 100644 --- a/tests/derive/double_borrow_non_sync.rs +++ b/tests/derive/double_borrow_non_sync.rs @@ -1,4 +1,4 @@ -use shipyard::prelude::*; +use shipyard::*; struct NonSyncStruct(core::marker::PhantomData<*const ()>); diff --git a/tests/derive/entities.rs b/tests/derive/entities.rs index b06d2e23..64e6d129 100644 --- a/tests/derive/entities.rs +++ b/tests/derive/entities.rs @@ -1,4 +1,4 @@ -use shipyard::prelude::*; +use shipyard::*; #[system(Test1)] fn run(_: Entities, _: EntitiesMut) {} diff --git a/tests/derive/generic_lifetime.rs b/tests/derive/generic_lifetime.rs index 95ba28d9..67cd1bd6 100644 --- a/tests/derive/generic_lifetime.rs +++ b/tests/derive/generic_lifetime.rs @@ -1,4 +1,4 @@ -use shipyard::prelude::*; +use shipyard::*; #[system(Test)] fn run<'a>() {} diff --git a/tests/derive/generic_type.rs b/tests/derive/generic_type.rs index 1ac465cd..ad28f39b 100644 --- a/tests/derive/generic_type.rs +++ b/tests/derive/generic_type.rs @@ -1,4 +1,4 @@ -use shipyard::prelude::*; +use shipyard::*; #[system(Test)] fn run() {} diff --git a/tests/derive/good.rs b/tests/derive/good.rs index 730af7f0..270c7529 100644 --- a/tests/derive/good.rs +++ b/tests/derive/good.rs @@ -1,4 +1,4 @@ -use shipyard::prelude::*; +use shipyard::*; #[system(Test1)] fn run(_: &usize, _: &mut i32, _: &Entities, _: Unique<&u32>, _: Entities) {} diff --git a/tests/derive/good_non_send.rs b/tests/derive/good_non_send.rs index b777d1a2..4ba9fe0b 100644 --- a/tests/derive/good_non_send.rs +++ b/tests/derive/good_non_send.rs @@ -1,4 +1,4 @@ -use shipyard::prelude::*; +use shipyard::*; struct NonSendStruct(core::marker::PhantomData<*const ()>); diff --git a/tests/derive/good_non_send_sync.rs b/tests/derive/good_non_send_sync.rs index 38444c96..f2a5b10a 100644 --- a/tests/derive/good_non_send_sync.rs +++ b/tests/derive/good_non_send_sync.rs @@ -1,4 +1,4 @@ -use shipyard::prelude::*; +use shipyard::*; struct NonSendSyncStruct(core::marker::PhantomData<*const ()>); diff --git a/tests/derive/good_non_sync.rs b/tests/derive/good_non_sync.rs index 227b70a1..0231a90d 100644 --- a/tests/derive/good_non_sync.rs +++ b/tests/derive/good_non_sync.rs @@ -1,4 +1,4 @@ -use shipyard::prelude::*; +use shipyard::*; struct NonSyncStruct(core::marker::PhantomData<*const ()>); diff --git a/tests/derive/good_parallel.rs b/tests/derive/good_parallel.rs index 7a9520ec..415977a0 100644 --- a/tests/derive/good_parallel.rs +++ b/tests/derive/good_parallel.rs @@ -1,4 +1,4 @@ -use shipyard::prelude::*; +use shipyard::*; #[system(Test)] fn run(_: ThreadPool, _: &ThreadPool) {} diff --git a/tests/derive/not_entities.rs b/tests/derive/not_entities.rs index 3cd588f7..217e937b 100644 --- a/tests/derive/not_entities.rs +++ b/tests/derive/not_entities.rs @@ -1,4 +1,4 @@ -use shipyard::prelude::*; +use shipyard::*; #[system(Test)] fn run(_: Not) {} diff --git a/tests/derive/not_run.rs b/tests/derive/not_run.rs index 3a1331c2..8c39d845 100644 --- a/tests/derive/not_run.rs +++ b/tests/derive/not_run.rs @@ -1,4 +1,4 @@ -use shipyard::prelude::*; +use shipyard::*; #[system(Test)] fn test() {} diff --git a/tests/derive/return_nothing.rs b/tests/derive/return_nothing.rs index 136f269f..5b9ac58e 100644 --- a/tests/derive/return_nothing.rs +++ b/tests/derive/return_nothing.rs @@ -1,5 +1,5 @@ // import it specifically to catch import issue with the proc macro -use shipyard::prelude::system; +use shipyard::system; #[system(Test)] fn run(_: &usize) -> () {} diff --git a/tests/derive/return_something.rs b/tests/derive/return_something.rs index 35737de9..efdda7cd 100644 --- a/tests/derive/return_something.rs +++ b/tests/derive/return_something.rs @@ -1,4 +1,4 @@ -use shipyard::prelude::*; +use shipyard::*; #[system(Test)] fn run() -> usize { 0 } diff --git a/tests/derive/unique_entities.rs b/tests/derive/unique_entities.rs index 5cd3336a..c084e256 100644 --- a/tests/derive/unique_entities.rs +++ b/tests/derive/unique_entities.rs @@ -1,4 +1,4 @@ -use shipyard::prelude::*; +use shipyard::*; #[system(Test)] fn run(_: Unique) {} diff --git a/tests/derive/where.rs b/tests/derive/where.rs index 6aadb4d3..d6ac63b2 100644 --- a/tests/derive/where.rs +++ b/tests/derive/where.rs @@ -1,4 +1,4 @@ -use shipyard::prelude::*; +use shipyard::*; #[system(Test)] fn run(_: &usize) where usize: Debug {} diff --git a/tests/derive/wrong_type.rs b/tests/derive/wrong_type.rs index 00232245..ea8c6380 100644 --- a/tests/derive/wrong_type.rs +++ b/tests/derive/wrong_type.rs @@ -1,4 +1,4 @@ -use shipyard::prelude::*; +use shipyard::*; #[system(Test)] fn run(_: fn()) {} diff --git a/tests/get.rs b/tests/get.rs index 64689eaf..7065e5e1 100644 --- a/tests/get.rs +++ b/tests/get.rs @@ -1,10 +1,11 @@ -use shipyard::prelude::*; +use shipyard::*; #[test] fn non_packed() { let world = World::new(); - let (mut entities, mut u32s, mut i16s) = world.borrow::<(EntitiesMut, &mut u32, &mut i16)>(); + let (mut entities, mut u32s, mut i16s) = + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); let entity0 = entities.add_entity((&mut u32s, &mut i16s), (0, 10)); let entity1 = entities.add_entity(&mut u32s, 1); let entity2 = entities.add_entity((&mut u32s, &mut i16s), (2, 12)); @@ -34,7 +35,8 @@ fn non_packed() { fn tight() { let world = World::new(); - let (mut entities, mut u32s, mut i16s) = world.borrow::<(EntitiesMut, &mut u32, &mut i16)>(); + let (mut entities, mut u32s, mut i16s) = + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut u32s, &mut i16s).tight_pack(); let entity0 = entities.add_entity((&mut u32s, &mut i16s), (0, 10)); let entity1 = entities.add_entity(&mut u32s, 1); @@ -65,7 +67,8 @@ fn tight() { fn loose() { let world = World::new(); - let (mut entities, mut u32s, mut i16s) = world.borrow::<(EntitiesMut, &mut u32, &mut i16)>(); + let (mut entities, mut u32s, mut i16s) = + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut u32s, &mut i16s).loose_pack(); let entity0 = entities.add_entity((&mut u32s, &mut i16s), (0, 10)); let entity1 = entities.add_entity(&mut u32s, 1); @@ -96,7 +99,8 @@ fn loose() { fn update() { let world = World::new(); - let (mut entities, mut u32s, mut i16s) = world.borrow::<(EntitiesMut, &mut u32, &mut i16)>(); + let (mut entities, mut u32s, mut i16s) = + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); u32s.update_pack(); i16s.update_pack(); let entity0 = entities.add_entity((&mut u32s, &mut i16s), (0, 10)); @@ -127,7 +131,7 @@ fn update() { #[test] fn off_by_one() { let world = World::new(); - let (mut entities, mut u32s) = world.borrow::<(EntitiesMut, &mut usize)>(); + let (mut entities, mut u32s) = world.borrow::<(EntitiesViewMut, ViewMut)>(); let entity0 = entities.add_entity(&mut u32s, 0); let entity1 = entities.add_entity(&mut u32s, 1); let entity2 = entities.add_entity(&mut u32s, 2); diff --git a/tests/iteration/loose.rs b/tests/iteration/loose.rs index c0d89970..a415ad56 100644 --- a/tests/iteration/loose.rs +++ b/tests/iteration/loose.rs @@ -1,9 +1,10 @@ -use shipyard::prelude::*; +use shipyard::*; #[test] fn basic() { let world = World::new(); - let (mut entities, mut u32s, mut i16s) = world.borrow::<(EntitiesMut, &mut u32, &mut i16)>(); + let (mut entities, mut u32s, mut i16s) = + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut u32s, &mut i16s).loose_pack(); entities.add_entity((&mut u32s, &mut i16s), (0, 10)); @@ -66,7 +67,8 @@ fn basic() { #[test] fn with_id() { let world = World::new(); - let (mut entities, mut u32s, mut i16s) = world.borrow::<(EntitiesMut, &mut u32, &mut i16)>(); + let (mut entities, mut u32s, mut i16s) = + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut u32s, &mut i16s).loose_pack(); let key0 = entities.add_entity((&mut u32s, &mut i16s), (0, 10)); @@ -127,7 +129,8 @@ fn with_id() { #[test] fn map() { let world = World::new(); - let (mut entities, mut u32s, mut i16s) = world.borrow::<(EntitiesMut, &mut u32, &mut i16)>(); + let (mut entities, mut u32s, mut i16s) = + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut u32s, &mut i16s).loose_pack(); entities.add_entity((&mut u32s, &mut i16s), (0, 10)); @@ -188,7 +191,8 @@ fn map() { #[test] fn filter() { let world = World::new(); - let (mut entities, mut u32s, mut i16s) = world.borrow::<(EntitiesMut, &mut u32, &mut i16)>(); + let (mut entities, mut u32s, mut i16s) = + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut u32s, &mut i16s).loose_pack(); entities.add_entity((&mut u32s, &mut i16s), (0, 10)); @@ -235,7 +239,8 @@ fn filter() { #[test] fn enumerate_map_filter_with_id() { let world = World::new(); - let (mut entities, mut u32s, mut i16s) = world.borrow::<(EntitiesMut, &mut u32, &mut i16)>(); + let (mut entities, mut u32s, mut i16s) = + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut u32s, &mut i16s).loose_pack(); @@ -311,7 +316,8 @@ fn enumerate_map_filter_with_id() { #[test] fn enumerate_filter_map_with_id() { let world = World::new(); - let (mut entities, mut u32s, mut i16s) = world.borrow::<(EntitiesMut, &mut u32, &mut i16)>(); + let (mut entities, mut u32s, mut i16s) = + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut u32s, &mut i16s).loose_pack(); @@ -387,7 +393,8 @@ fn enumerate_filter_map_with_id() { #[test] fn off_by_one() { let world = World::new(); - let (mut entities, mut u32s, mut i16s) = world.borrow::<(EntitiesMut, &mut u32, &mut i16)>(); + let (mut entities, mut u32s, mut i16s) = + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut u32s, &mut i16s).loose_pack(); entities.add_entity((&mut u32s, &mut i16s), (0, 10)); diff --git a/tests/iteration/non_packed.rs b/tests/iteration/non_packed.rs index d0253b64..6d362715 100644 --- a/tests/iteration/non_packed.rs +++ b/tests/iteration/non_packed.rs @@ -1,18 +1,20 @@ -use shipyard::prelude::*; +use shipyard::*; #[test] fn basic() { let world = World::new(); - world.run::<(EntitiesMut, &mut u32, &mut i16), _, _>(|(mut entities, mut u32s, mut i16s)| { - entities.add_entity((&mut u32s, &mut i16s), (0, 10)); - entities.add_entity(&mut u32s, 1); - entities.add_entity((&mut u32s, &mut i16s), (2, 12)); - entities.add_entity(&mut i16s, 13); - entities.add_entity((&mut u32s, &mut i16s), (4, 14)); - }); + world.run( + |(mut entities, mut u32s, mut i16s): (EntitiesViewMut, ViewMut, ViewMut)| { + entities.add_entity((&mut u32s, &mut i16s), (0, 10)); + entities.add_entity(&mut u32s, 1); + entities.add_entity((&mut u32s, &mut i16s), (2, 12)); + entities.add_entity(&mut i16s, 13); + entities.add_entity((&mut u32s, &mut i16s), (4, 14)); + }, + ); - world.run::<&u32, _, _>(|u32s| { + world.run(|u32s: View| { let mut iter = u32s.iter(); assert_eq!(iter.size_hint(), (4, Some(4))); assert_eq!(iter.next().unwrap(), &0); @@ -21,7 +23,7 @@ fn basic() { assert_eq!(iter.next().unwrap(), &4); assert!(iter.next().is_none()); }); - world.run::<&mut u32, _, _>(|u32s| { + world.run(|u32s: ViewMut| { let mut iter = u32s.iter(); assert_eq!(iter.next().unwrap(), &mut 0); assert_eq!(iter.next().unwrap(), &mut 1); @@ -30,7 +32,7 @@ fn basic() { assert!(iter.next().is_none()); }); - world.run::<&i16, _, _>(|i16s| { + world.run(|i16s: View| { let mut iter = i16s.iter(); assert_eq!(iter.next().unwrap(), &10); assert_eq!(iter.next().unwrap(), &12); @@ -38,7 +40,7 @@ fn basic() { assert_eq!(iter.next().unwrap(), &14); assert!(iter.next().is_none()); }); - world.run::<&mut i16, _, _>(|i16s| { + world.run(|i16s: ViewMut| { let mut iter = i16s.iter(); assert_eq!(iter.next().unwrap(), &mut 10); assert_eq!(iter.next().unwrap(), &mut 12); @@ -47,7 +49,7 @@ fn basic() { assert!(iter.next().is_none()); }); - world.run::<(&u32, &i16), _, _>(|(u32s, i16s)| { + world.run(|(u32s, i16s): (View, View)| { let mut iter = (&u32s, &i16s).iter(); assert_eq!(iter.size_hint(), (0, Some(4))); assert_eq!(iter.next().unwrap(), (&0, &10)); @@ -55,7 +57,7 @@ fn basic() { assert_eq!(iter.next().unwrap(), (&4, &14)); assert!(iter.next().is_none()); }); - world.run::<(&mut u32, &mut i16), _, _>(|(mut u32s, mut i16s)| { + world.run(|(mut u32s, mut i16s): (ViewMut, ViewMut)| { let mut iter = (&mut u32s, &mut i16s).iter(); assert_eq!(iter.next().unwrap(), (&mut 0, &mut 10)); assert_eq!(iter.next().unwrap(), (&mut 2, &mut 12)); @@ -63,14 +65,14 @@ fn basic() { assert!(iter.next().is_none()); }); - world.run::<(&i16, &u32), _, _>(|(i16s, u32s)| { + world.run(|(i16s, u32s): (View, View)| { let mut iter = (&i16s, &u32s).iter(); assert_eq!(iter.next().unwrap(), (&10, &0)); assert_eq!(iter.next().unwrap(), (&12, &2)); assert_eq!(iter.next().unwrap(), (&14, &4)); assert!(iter.next().is_none()); }); - world.run::<(&mut i16, &mut u32), _, _>(|(mut i16s, mut u32s)| { + world.run(|(mut i16s, mut u32s): (ViewMut, ViewMut)| { let mut iter = (&mut i16s, &mut u32s).iter(); assert_eq!(iter.next().unwrap(), (&mut 10, &mut 0)); assert_eq!(iter.next().unwrap(), (&mut 12, &mut 2)); @@ -83,8 +85,8 @@ fn basic() { fn with_id() { let world = World::new(); - let (key0, key1, key2, key3, key4) = world.run::<(EntitiesMut, &mut u32, &mut i16), _, _>( - |(mut entities, mut u32s, mut i16s)| { + let (key0, key1, key2, key3, key4) = world.run( + |(mut entities, mut u32s, mut i16s): (EntitiesViewMut, ViewMut, ViewMut)| { ( entities.add_entity((&mut u32s, &mut i16s), (0, 10)), entities.add_entity(&mut u32s, 1), @@ -95,7 +97,7 @@ fn with_id() { }, ); - world.run::<&u32, _, _>(|u32s| { + world.run(|u32s: View| { let mut iter = u32s.iter().with_id(); assert_eq!(iter.next().unwrap(), (key0, &0)); assert_eq!(iter.next().unwrap(), (key1, &1)); @@ -103,7 +105,7 @@ fn with_id() { assert_eq!(iter.next().unwrap(), (key4, &4)); assert!(iter.next().is_none()); }); - world.run::<&mut u32, _, _>(|mut u32s| { + world.run(|mut u32s: ViewMut| { let mut iter = (&mut u32s).iter().with_id(); assert_eq!(iter.next().unwrap(), (key0, &mut 0)); assert_eq!(iter.next().unwrap(), (key1, &mut 1)); @@ -112,7 +114,7 @@ fn with_id() { assert!(iter.next().is_none()); }); - world.run::<&i16, _, _>(|i16s| { + world.run(|i16s: View| { let mut iter = i16s.iter().with_id(); assert_eq!(iter.next().unwrap(), (key0, &10)); assert_eq!(iter.next().unwrap(), (key2, &12)); @@ -120,7 +122,7 @@ fn with_id() { assert_eq!(iter.next().unwrap(), (key4, &14)); assert!(iter.next().is_none()); }); - world.run::<&mut i16, _, _>(|mut i16s| { + world.run(|mut i16s: ViewMut| { let mut iter = (&mut i16s).iter().with_id(); assert_eq!(iter.next().unwrap(), (key0, &mut 10)); assert_eq!(iter.next().unwrap(), (key2, &mut 12)); @@ -129,14 +131,14 @@ fn with_id() { assert!(iter.next().is_none()); }); - world.run::<(&u32, &i16), _, _>(|(u32s, i16s)| { + world.run(|(u32s, i16s): (View, View)| { let mut iter = (&u32s, &i16s).iter().with_id(); assert_eq!(iter.next().unwrap(), (key0, (&0, &10))); assert_eq!(iter.next().unwrap(), (key2, (&2, &12))); assert_eq!(iter.next().unwrap(), (key4, (&4, &14))); assert!(iter.next().is_none()); }); - world.run::<(&mut u32, &mut i16), _, _>(|(mut u32s, mut i16s)| { + world.run(|(mut u32s, mut i16s): (ViewMut, ViewMut)| { let mut iter = (&mut u32s, &mut i16s).iter().with_id(); assert_eq!(iter.next().unwrap(), (key0, (&mut 0, &mut 10))); assert_eq!(iter.next().unwrap(), (key2, (&mut 2, &mut 12))); @@ -144,14 +146,14 @@ fn with_id() { assert!(iter.next().is_none()); }); - world.run::<(&i16, &u32), _, _>(|(i16s, u32s)| { + world.run(|(i16s, u32s): (View, View)| { let mut iter = (&i16s, &u32s).iter().with_id(); assert_eq!(iter.next().unwrap(), (key0, (&10, &0))); assert_eq!(iter.next().unwrap(), (key2, (&12, &2))); assert_eq!(iter.next().unwrap(), (key4, (&14, &4))); assert!(iter.next().is_none()); }); - world.run::<(&mut i16, &mut u32), _, _>(|(mut i16s, mut u32s)| { + world.run(|(mut i16s, mut u32s): (ViewMut, ViewMut)| { let mut iter = (&mut i16s, &mut u32s).iter().with_id(); assert_eq!(iter.next().unwrap(), (key0, (&mut 10, &mut 0))); assert_eq!(iter.next().unwrap(), (key2, (&mut 12, &mut 2))); @@ -164,15 +166,17 @@ fn with_id() { fn map() { let world = World::new(); - world.run::<(EntitiesMut, &mut u32, &mut i16), _, _>(|(mut entities, mut u32s, mut i16s)| { - entities.add_entity((&mut u32s, &mut i16s), (0, 10)); - entities.add_entity(&mut u32s, 1); - entities.add_entity((&mut u32s, &mut i16s), (2, 12)); - entities.add_entity(&mut i16s, 13); - entities.add_entity((&mut u32s, &mut i16s), (4, 14)); - }); + world.run( + |(mut entities, mut u32s, mut i16s): (EntitiesViewMut, ViewMut, ViewMut)| { + entities.add_entity((&mut u32s, &mut i16s), (0, 10)); + entities.add_entity(&mut u32s, 1); + entities.add_entity((&mut u32s, &mut i16s), (2, 12)); + entities.add_entity(&mut i16s, 13); + entities.add_entity((&mut u32s, &mut i16s), (4, 14)); + }, + ); - world.run::<&u32, _, _>(|u32s| { + world.run(|u32s: View| { let mut iter = u32s.iter().map(Clone::clone); assert_eq!(iter.next().unwrap(), 0); assert_eq!(iter.next().unwrap(), 1); @@ -180,7 +184,7 @@ fn map() { assert_eq!(iter.next().unwrap(), 4); assert!(iter.next().is_none()); }); - world.run::<&mut u32, _, _>(|u32s| { + world.run(|u32s: ViewMut| { let mut iter = u32s.iter().map(|x| *x); assert_eq!(iter.next().unwrap(), 0); assert_eq!(iter.next().unwrap(), 1); @@ -189,7 +193,7 @@ fn map() { assert!(iter.next().is_none()); }); - world.run::<&i16, _, _>(|i16s| { + world.run(|i16s: View| { let mut iter = i16s.iter().map(Clone::clone); assert_eq!(iter.next().unwrap(), 10); assert_eq!(iter.next().unwrap(), 12); @@ -197,7 +201,7 @@ fn map() { assert_eq!(iter.next().unwrap(), 14); assert!(iter.next().is_none()); }); - world.run::<&mut i16, _, _>(|i16s| { + world.run(|i16s: ViewMut| { let mut iter = i16s.iter().map(|x| *x); assert_eq!(iter.next().unwrap(), 10); assert_eq!(iter.next().unwrap(), 12); @@ -206,14 +210,14 @@ fn map() { assert!(iter.next().is_none()); }); - world.run::<(&u32, &i16), _, _>(|(u32s, i16s)| { + world.run(|(u32s, i16s): (View, View)| { let mut iter = (&u32s, &i16s).iter().map(|(x, y)| (*x, *y)); assert_eq!(iter.next().unwrap(), (0, 10)); assert_eq!(iter.next().unwrap(), (2, 12)); assert_eq!(iter.next().unwrap(), (4, 14)); assert!(iter.next().is_none()); }); - world.run::<(&mut u32, &mut i16), _, _>(|(mut u32s, mut i16s)| { + world.run(|(mut u32s, mut i16s): (ViewMut, ViewMut)| { let mut iter = (&mut u32s, &mut i16s).iter().map(|(x, y)| (*x, *y)); assert_eq!(iter.next().unwrap(), (0, 10)); assert_eq!(iter.next().unwrap(), (2, 12)); @@ -221,14 +225,14 @@ fn map() { assert!(iter.next().is_none()); }); - world.run::<(&i16, &u32), _, _>(|(i16s, u32s)| { + world.run(|(i16s, u32s): (View, View)| { let mut iter = (&i16s, &u32s).iter().map(|(x, y)| (*x, *y)); assert_eq!(iter.next().unwrap(), (10, 0)); assert_eq!(iter.next().unwrap(), (12, 2)); assert_eq!(iter.next().unwrap(), (14, 4)); assert!(iter.next().is_none()); }); - world.run::<(&mut i16, &mut u32), _, _>(|(mut i16s, mut u32s)| { + world.run(|(mut i16s, mut u32s): (ViewMut, ViewMut)| { let mut iter = (&mut i16s, &mut u32s).iter().map(|(x, y)| (*x, *y)); assert_eq!(iter.next().unwrap(), (10, 0)); assert_eq!(iter.next().unwrap(), (12, 2)); @@ -241,15 +245,17 @@ fn map() { fn filter() { let world = World::new(); - world.run::<(EntitiesMut, &mut u32, &mut i16), _, _>(|(mut entities, mut u32s, mut i16s)| { - entities.add_entity((&mut u32s, &mut i16s), (0, 10)); - entities.add_entity(&mut u32s, 1); - entities.add_entity((&mut u32s, &mut i16s), (2, 12)); - entities.add_entity(&mut i16s, 13); - entities.add_entity((&mut u32s, &mut i16s), (4, 14)); - }); + world.run( + |(mut entities, mut u32s, mut i16s): (EntitiesViewMut, ViewMut, ViewMut)| { + entities.add_entity((&mut u32s, &mut i16s), (0, 10)); + entities.add_entity(&mut u32s, 1); + entities.add_entity((&mut u32s, &mut i16s), (2, 12)); + entities.add_entity(&mut i16s, 13); + entities.add_entity((&mut u32s, &mut i16s), (4, 14)); + }, + ); - world.run::<&u32, _, _>(|u32s| { + world.run(|u32s: View| { let mut iter = u32s.iter().filter(|x| **x % 2 == 0); assert_eq!(iter.size_hint(), (0, Some(4))); assert_eq!(iter.next().unwrap(), &0); @@ -257,43 +263,43 @@ fn filter() { assert_eq!(iter.next().unwrap(), &4); assert!(iter.next().is_none()); }); - world.run::<&mut u32, _, _>(|u32s| { + world.run(|u32s: ViewMut| { let mut iter = u32s.iter().filter(|x| **x % 2 != 0); assert_eq!(iter.next().unwrap(), &mut 1); assert!(iter.next().is_none()); }); - world.run::<&i16, _, _>(|i16s| { + world.run(|i16s: View| { let mut iter = i16s.iter().filter(|x| **x % 2 == 0); assert_eq!(iter.next().unwrap(), &10); assert_eq!(iter.next().unwrap(), &12); assert_eq!(iter.next().unwrap(), &14); assert!(iter.next().is_none()); }); - world.run::<&mut i16, _, _>(|i16s| { + world.run(|i16s: ViewMut| { let mut iter = i16s.iter().filter(|x| **x % 2 != 0); assert_eq!(iter.next().unwrap(), &mut 13); assert!(iter.next().is_none()); }); - world.run::<(&u32, &i16), _, _>(|(u32s, i16s)| { + world.run(|(u32s, i16s): (View, View)| { let mut iter = (&u32s, &i16s).iter().filter(|(_, y)| **y % 5 == 0); assert_eq!(iter.next().unwrap(), (&0, &10)); assert!(iter.next().is_none()); }); - world.run::<(&mut u32, &mut i16), _, _>(|(mut u32s, mut i16s)| { + world.run(|(mut u32s, mut i16s): (ViewMut, ViewMut)| { let mut iter = (&mut u32s, &mut i16s).iter().filter(|(_, y)| **y % 5 != 0); assert_eq!(iter.next().unwrap(), (&mut 2, &mut 12)); assert_eq!(iter.next().unwrap(), (&mut 4, &mut 14)); assert!(iter.next().is_none()); }); - world.run::<(&i16, &u32), _, _>(|(i16s, u32s)| { + world.run(|(i16s, u32s): (View, View)| { let mut iter = (&i16s, &u32s).iter().filter(|(x, _)| **x % 5 == 0); assert_eq!(iter.next().unwrap(), (&10, &0)); assert!(iter.next().is_none()); }); - world.run::<(&mut i16, &mut u32), _, _>(|(mut i16s, mut u32s)| { + world.run(|(mut i16s, mut u32s): (ViewMut, ViewMut)| { let mut iter = (&mut i16s, &mut u32s).iter().filter(|(x, _)| **x % 5 != 0); assert_eq!(iter.next().unwrap(), (&mut 12, &mut 2)); assert_eq!(iter.next().unwrap(), (&mut 14, &mut 4)); @@ -305,8 +311,8 @@ fn filter() { fn enumerate_map_filter_with_id() { let world = World::new(); - let (key0, key1, key2, key3, key4) = world.run::<(EntitiesMut, &mut u32, &mut i16), _, _>( - |(mut entities, mut u32s, mut i16s)| { + let (key0, key1, key2, key3, key4) = world.run( + |(mut entities, mut u32s, mut i16s): (EntitiesViewMut, ViewMut, ViewMut)| { ( entities.add_entity((&mut u32s, &mut i16s), (0, 10)), entities.add_entity(&mut u32s, 1), @@ -317,7 +323,7 @@ fn enumerate_map_filter_with_id() { }, ); - world.run::<&u32, _, _>(|u32s| { + world.run(|u32s: View| { let mut iter = u32s .iter() .enumerate() @@ -330,7 +336,7 @@ fn enumerate_map_filter_with_id() { assert_eq!(iter.next().unwrap(), (key4, (9, &4))); assert!(iter.next().is_none()); }); - world.run::<&mut u32, _, _>(|mut u32s| { + world.run(|mut u32s: ViewMut| { let mut iter = (&mut u32s) .iter() .enumerate() @@ -342,7 +348,7 @@ fn enumerate_map_filter_with_id() { assert!(iter.next().is_none()); }); - world.run::<&i16, _, _>(|i16s| { + world.run(|i16s: View| { let mut iter = i16s .iter() .enumerate() @@ -355,7 +361,7 @@ fn enumerate_map_filter_with_id() { assert_eq!(iter.next().unwrap(), (key4, (9, &14))); assert!(iter.next().is_none()); }); - world.run::<&mut i16, _, _>(|mut i16s| { + world.run(|mut i16s: ViewMut| { let mut iter = (&mut i16s) .iter() .enumerate() @@ -367,7 +373,7 @@ fn enumerate_map_filter_with_id() { assert!(iter.next().is_none()); }); - world.run::<(&u32, &i16), _, _>(|(u32s, i16s)| { + world.run(|(u32s, i16s): (View, View)| { let mut iter = (&u32s, &i16s) .iter() .enumerate() @@ -379,7 +385,7 @@ fn enumerate_map_filter_with_id() { assert_eq!(iter.next().unwrap(), (key4, (6, (&4, &14)))); assert!(iter.next().is_none()); }); - world.run::<(&mut i16, &mut u32), _, _>(|(mut i16s, mut u32s)| { + world.run(|(mut i16s, mut u32s): (ViewMut, ViewMut)| { let mut iter = (&mut i16s, &mut u32s) .iter() .enumerate() @@ -396,8 +402,8 @@ fn enumerate_map_filter_with_id() { fn enumerate_filter_map_with_id() { let world = World::new(); - let (key0, key1, key2, key3, key4) = world.run::<(EntitiesMut, &mut u32, &mut i16), _, _>( - |(mut entities, mut u32s, mut i16s)| { + let (key0, key1, key2, key3, key4) = world.run( + |(mut entities, mut u32s, mut i16s): (EntitiesViewMut, ViewMut, ViewMut)| { ( entities.add_entity((&mut u32s, &mut i16s), (0, 10)), entities.add_entity(&mut u32s, 1), @@ -408,7 +414,7 @@ fn enumerate_filter_map_with_id() { }, ); - world.run::<&u32, _, _>(|u32s| { + world.run(|u32s: View| { let mut iter = u32s .iter() .enumerate() @@ -421,7 +427,7 @@ fn enumerate_filter_map_with_id() { assert_eq!(iter.next().unwrap(), (key4, (9, &4))); assert!(iter.next().is_none()); }); - world.run::<&mut u32, _, _>(|mut u32s| { + world.run(|mut u32s: ViewMut| { let mut iter = (&mut u32s) .iter() .enumerate() @@ -433,7 +439,7 @@ fn enumerate_filter_map_with_id() { assert!(iter.next().is_none()); }); - world.run::<&i16, _, _>(|i16s| { + world.run(|i16s: View| { let mut iter = i16s .iter() .enumerate() @@ -446,7 +452,7 @@ fn enumerate_filter_map_with_id() { assert_eq!(iter.next().unwrap(), (key4, (9, &14))); assert!(iter.next().is_none()); }); - world.run::<&mut i16, _, _>(|mut i16s| { + world.run(|mut i16s: ViewMut| { let mut iter = (&mut i16s) .iter() .enumerate() @@ -458,7 +464,7 @@ fn enumerate_filter_map_with_id() { assert!(iter.next().is_none()); }); - world.run::<(&u32, &i16), _, _>(|(u32s, i16s)| { + world.run(|(u32s, i16s): (View, View)| { let mut iter = (&u32s, &i16s) .iter() .enumerate() @@ -470,7 +476,7 @@ fn enumerate_filter_map_with_id() { assert_eq!(iter.next().unwrap(), (key4, (6, (&4, &14)))); assert!(iter.next().is_none()); }); - world.run::<(&mut i16, &mut u32), _, _>(|(mut i16s, mut u32s)| { + world.run(|(mut i16s, mut u32s): (ViewMut, ViewMut)| { let mut iter = (&mut i16s, &mut u32s) .iter() .enumerate() @@ -487,7 +493,8 @@ fn enumerate_filter_map_with_id() { fn off_by_one() { let world = World::new(); - let (mut entities, mut u32s, mut i16s) = world.borrow::<(EntitiesMut, &mut u32, &mut i16)>(); + let (mut entities, mut u32s, mut i16s) = + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); entities.add_entity((&mut u32s, &mut i16s), (0, 10)); entities.add_entity(&mut u32s, 1); entities.add_entity((&mut u32s, &mut i16s), (2, 12)); diff --git a/tests/iteration/tight/multiple.rs b/tests/iteration/tight/multiple.rs index a13fa749..e6622bed 100644 --- a/tests/iteration/tight/multiple.rs +++ b/tests/iteration/tight/multiple.rs @@ -1,9 +1,10 @@ -use shipyard::prelude::*; +use shipyard::*; #[test] fn basic() { let world = World::new(); - let (mut entities, mut u32s, mut i16s) = world.borrow::<(EntitiesMut, &mut u32, &mut i16)>(); + let (mut entities, mut u32s, mut i16s) = + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut u32s, &mut i16s).tight_pack(); entities.add_entity((&mut u32s, &mut i16s), (0, 10)); @@ -66,7 +67,8 @@ fn basic() { #[test] fn with_id() { let world = World::new(); - let (mut entities, mut u32s, mut i16s) = world.borrow::<(EntitiesMut, &mut u32, &mut i16)>(); + let (mut entities, mut u32s, mut i16s) = + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut u32s, &mut i16s).tight_pack(); let key0 = entities.add_entity((&mut u32s, &mut i16s), (0, 10)); @@ -127,7 +129,8 @@ fn with_id() { #[test] fn map() { let world = World::new(); - let (mut entities, mut u32s, mut i16s) = world.borrow::<(EntitiesMut, &mut u32, &mut i16)>(); + let (mut entities, mut u32s, mut i16s) = + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut u32s, &mut i16s).tight_pack(); entities.add_entity((&mut u32s, &mut i16s), (0, 10)); @@ -188,7 +191,8 @@ fn map() { #[test] fn filter() { let world = World::new(); - let (mut entities, mut u32s, mut i16s) = world.borrow::<(EntitiesMut, &mut u32, &mut i16)>(); + let (mut entities, mut u32s, mut i16s) = + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut u32s, &mut i16s).tight_pack(); entities.add_entity((&mut u32s, &mut i16s), (0, 10)); @@ -236,7 +240,8 @@ fn filter() { #[test] fn enumerate_map_filter_with_id() { let world = World::new(); - let (mut entities, mut u32s, mut i16s) = world.borrow::<(EntitiesMut, &mut u32, &mut i16)>(); + let (mut entities, mut u32s, mut i16s) = + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut u32s, &mut i16s).tight_pack(); let key0 = entities.add_entity((&mut u32s, &mut i16s), (0, 10)); @@ -311,7 +316,8 @@ fn enumerate_map_filter_with_id() { #[test] fn enumerate_filter_map_with_id() { let world = World::new(); - let (mut entities, mut u32s, mut i16s) = world.borrow::<(EntitiesMut, &mut u32, &mut i16)>(); + let (mut entities, mut u32s, mut i16s) = + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut u32s, &mut i16s).tight_pack(); let key0 = entities.add_entity((&mut u32s, &mut i16s), (0, 10)); @@ -387,7 +393,8 @@ fn enumerate_filter_map_with_id() { fn off_by_one() { let world = World::new(); - let (mut entities, mut u32s, mut i16s) = world.borrow::<(EntitiesMut, &mut u32, &mut i16)>(); + let (mut entities, mut u32s, mut i16s) = + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut u32s, &mut i16s).tight_pack(); entities.add_entity((&mut u32s, &mut i16s), (0, 10)); diff --git a/tests/iteration/tight/single.rs b/tests/iteration/tight/single.rs index 34145914..df62f58e 100644 --- a/tests/iteration/tight/single.rs +++ b/tests/iteration/tight/single.rs @@ -1,22 +1,24 @@ -use shipyard::prelude::*; +use shipyard::*; #[test] fn basic() { let world = World::new(); - world.run::<(EntitiesMut, &mut u32), _, _>(|(mut entities, mut u32s)| { - entities.add_entity(&mut u32s, 0); - entities.add_entity(&mut u32s, 1); - entities.add_entity(&mut u32s, 2); - }); + world.run( + |(mut entities, mut u32s): (EntitiesViewMut, ViewMut)| { + entities.add_entity(&mut u32s, 0); + entities.add_entity(&mut u32s, 1); + entities.add_entity(&mut u32s, 2); + }, + ); let mut vec = Vec::new(); - world.run::<&u32, _, _>(|u32s| { + world.run(|u32s: View| { let iter = u32s.iter(); assert_eq!(iter.size_hint(), (3, Some(3))); iter.for_each(|&x| vec.push(x)); }); - world.run::<&mut u32, _, _>(|mut u32s| { + world.run(|mut u32s: ViewMut| { (&mut u32s).iter().for_each(|&mut x| vec.push(x)); }); @@ -27,20 +29,21 @@ fn basic() { fn with_id() { let world = World::new(); - let (key0, key1, key2) = - world.run::<(EntitiesMut, &mut u32), _, _>(|(mut entities, mut u32s)| { + let (key0, key1, key2) = world.run( + |(mut entities, mut u32s): (EntitiesViewMut, ViewMut)| { ( entities.add_entity(&mut u32s, 0), entities.add_entity(&mut u32s, 1), entities.add_entity(&mut u32s, 2), ) - }); + }, + ); let mut vec = Vec::new(); - world.run::<&u32, _, _>(|u32s| { + world.run(|u32s: View| { u32s.iter().with_id().for_each(|(id, &x)| vec.push((id, x))); }); - world.run::<&mut u32, _, _>(|mut u32s| { + world.run(|mut u32s: ViewMut| { (&mut u32s) .iter() .with_id() @@ -64,17 +67,19 @@ fn with_id() { fn map() { let world = World::new(); - world.run::<(EntitiesMut, &mut u32), _, _>(|(mut entities, mut u32s)| { - entities.add_entity(&mut u32s, 0); - entities.add_entity(&mut u32s, 1); - entities.add_entity(&mut u32s, 2); - }); + world.run( + |(mut entities, mut u32s): (EntitiesViewMut, ViewMut)| { + entities.add_entity(&mut u32s, 0); + entities.add_entity(&mut u32s, 1); + entities.add_entity(&mut u32s, 2); + }, + ); let mut vec = Vec::new(); - world.run::<&u32, _, _>(|u32s| { + world.run(|u32s: View| { u32s.iter().map(|x| *x + 10).for_each(|x| vec.push(x)); }); - world.run::<&mut u32, _, _>(|mut u32s| { + world.run(|mut u32s: ViewMut| { (&mut u32s).iter().map(|x| *x + 1).for_each(|x| vec.push(x)); }); @@ -85,19 +90,21 @@ fn map() { fn filter() { let world = World::new(); - world.run::<(EntitiesMut, &mut u32), _, _>(|(mut entities, mut u32s)| { - entities.add_entity(&mut u32s, 0); - entities.add_entity(&mut u32s, 1); - entities.add_entity(&mut u32s, 2); - }); + world.run( + |(mut entities, mut u32s): (EntitiesViewMut, ViewMut)| { + entities.add_entity(&mut u32s, 0); + entities.add_entity(&mut u32s, 1); + entities.add_entity(&mut u32s, 2); + }, + ); let mut vec = Vec::new(); - world.run::<&u32, _, _>(|u32s| { + world.run(|u32s: View| { let iter = u32s.iter(); assert_eq!(iter.size_hint(), (3, Some(3))); iter.filter(|&&x| x % 2 == 0).for_each(|&x| vec.push(x)); }); - world.run::<&mut u32, _, _>(|mut u32s| { + world.run(|mut u32s: ViewMut| { (&mut u32s) .iter() .filter(|&&mut x| x % 2 != 0) @@ -111,17 +118,19 @@ fn filter() { fn enumerate_map_filter_with_id() { let world = World::new(); - let (key0, _, key2) = world.run::<(EntitiesMut, &mut u32), _, _>(|(mut entities, mut u32s)| { - let result = ( - entities.add_entity(&mut u32s, 10), - entities.add_entity(&mut u32s, 11), - entities.add_entity(&mut u32s, 12), - ); - result - }); + let (key0, _, key2) = world.run( + |(mut entities, mut u32s): (EntitiesViewMut, ViewMut)| { + let result = ( + entities.add_entity(&mut u32s, 10), + entities.add_entity(&mut u32s, 11), + entities.add_entity(&mut u32s, 12), + ); + result + }, + ); let mut vec = Vec::new(); - world.run::<&mut u32, _, _>(|mut u32s| { + world.run(|mut u32s: ViewMut| { (&mut u32s) .iter() .enumerate() @@ -138,17 +147,19 @@ fn enumerate_map_filter_with_id() { fn enumerate_filter_map_with_id() { let world = World::new(); - let (key0, _, key2) = world.run::<(EntitiesMut, &mut u32), _, _>(|(mut entities, mut u32s)| { - let result = ( - entities.add_entity(&mut u32s, 10), - entities.add_entity(&mut u32s, 11), - entities.add_entity(&mut u32s, 12), - ); - result - }); + let (key0, _, key2) = world.run( + |(mut entities, mut u32s): (EntitiesViewMut, ViewMut)| { + let result = ( + entities.add_entity(&mut u32s, 10), + entities.add_entity(&mut u32s, 11), + entities.add_entity(&mut u32s, 12), + ); + result + }, + ); let mut vec = Vec::new(); - world.run::<&mut u32, _, _>(|mut u32s| { + world.run(|mut u32s: ViewMut| { (&mut u32s) .iter() .enumerate() @@ -165,7 +176,7 @@ fn enumerate_filter_map_with_id() { fn off_by_one() { let world = World::new(); - let (mut entities, mut u32s) = world.borrow::<(EntitiesMut, &mut u32)>(); + let (mut entities, mut u32s) = world.borrow::<(EntitiesViewMut, ViewMut)>(); entities.add_entity(&mut u32s, 0); entities.add_entity(&mut u32s, 1); diff --git a/tests/iteration/update/multiple.rs b/tests/iteration/update/multiple.rs index f96687ca..860100dc 100644 --- a/tests/iteration/update/multiple.rs +++ b/tests/iteration/update/multiple.rs @@ -1,9 +1,10 @@ -use shipyard::prelude::*; +use shipyard::*; #[test] fn basic() { let world = World::new(); - let (mut entities, mut u32s, mut i16s) = world.borrow::<(EntitiesMut, &mut u32, &mut i16)>(); + let (mut entities, mut u32s, mut i16s) = + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); u32s.update_pack(); i16s.update_pack(); @@ -31,7 +32,7 @@ fn basic() { assert_eq!(i16s.inserted_or_modified().len(), 0); drop((u32s, i16s)); - world.run::<&u32, _, _>(|u32s| { + world.run(|u32s: View| { let mut iter = (&u32s).iter(); assert_eq!(iter.size_hint(), (4, Some(4))); assert_eq!(iter.next().unwrap(), &0); @@ -44,7 +45,7 @@ fn basic() { assert_eq!(u32s.modified().len(), 0); assert_eq!(u32s.inserted_or_modified().len(), 0); }); - world.run::<&mut u32, _, _>(|mut u32s| { + world.run(|mut u32s: ViewMut| { let mut iter = (&mut u32s).iter(); assert_eq!(iter.next().unwrap(), &mut 0); assert_eq!(iter.next().unwrap(), &mut 1); @@ -66,7 +67,7 @@ fn basic() { u32s.clear_modified(); }); - world.run::<&i16, _, _>(|i16s| { + world.run(|i16s: View| { let mut iter = (&i16s).iter(); assert_eq!(iter.next().unwrap(), &10); assert_eq!(iter.next().unwrap(), &12); @@ -80,7 +81,7 @@ fn basic() { assert!(i16s.modified().iter().next().is_none()); }); - world.run::<&mut i16, _, _>(|mut i16s| { + world.run(|mut i16s: ViewMut| { let mut iter = (&mut i16s).iter(); assert_eq!(iter.next().unwrap(), &mut 10); assert_eq!(iter.next().unwrap(), &mut 12); @@ -102,7 +103,7 @@ fn basic() { i16s.clear_modified(); }); - world.run::<(&u32, &i16), _, _>(|(u32s, i16s)| { + world.run(|(u32s, i16s): (View, View)| { let mut iter = (&u32s, &i16s).iter(); assert_eq!(iter.size_hint(), (0, Some(4))); assert_eq!(iter.next().unwrap(), (&0, &10)); @@ -120,7 +121,7 @@ fn basic() { assert!(u32s.modified().iter().next().is_none()); assert!(i16s.modified().iter().next().is_none()); }); - world.run::<(&mut u32, &mut i16), _, _>(|(mut u32s, mut i16s)| { + world.run(|(mut u32s, mut i16s): (ViewMut, ViewMut)| { let mut iter = (&mut u32s, &mut i16s).iter(); assert_eq!(iter.next().unwrap(), (&mut 0, &mut 10)); assert_eq!(iter.next().unwrap(), (&mut 2, &mut 12)); @@ -149,7 +150,7 @@ fn basic() { i16s.clear_modified(); }); - world.run::<(&i16, &u32), _, _>(|(i16s, u32s)| { + world.run(|(i16s, u32s): (View, View)| { let mut iter = (&i16s, &u32s).iter(); assert_eq!(iter.next().unwrap(), (&10, &0)); assert_eq!(iter.next().unwrap(), (&12, &2)); @@ -166,7 +167,7 @@ fn basic() { assert!(i16s.modified().iter().next().is_none()); assert!(u32s.modified().iter().next().is_none()); }); - world.run::<(&mut i16, &mut u32), _, _>(|(mut i16s, mut u32s)| { + world.run(|(mut i16s, mut u32s): (ViewMut, ViewMut)| { let mut iter = (&mut i16s, &mut u32s).iter(); assert_eq!(iter.next().unwrap(), (&mut 10, &mut 0)); assert_eq!(iter.next().unwrap(), (&mut 12, &mut 2)); @@ -196,7 +197,8 @@ fn basic() { #[test] fn with_id() { let world = World::new(); - let (mut entities, mut u32s, mut i16s) = world.borrow::<(EntitiesMut, &mut u32, &mut i16)>(); + let (mut entities, mut u32s, mut i16s) = + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); u32s.update_pack(); i16s.update_pack(); @@ -209,7 +211,7 @@ fn with_id() { i16s.clear_inserted(); drop((u32s, i16s)); - world.run::<&u32, _, _>(|u32s| { + world.run(|u32s: View| { let mut iter = (&u32s).iter().with_id(); assert_eq!(iter.next().unwrap(), (key0, &0)); assert_eq!(iter.next().unwrap(), (key1, &1)); @@ -219,7 +221,7 @@ fn with_id() { assert!(u32s.modified().iter().next().is_none()); }); - world.run::<&mut u32, _, _>(|mut u32s| { + world.run(|mut u32s: ViewMut| { let mut iter = (&mut u32s).iter().with_id(); assert_eq!(iter.next().unwrap(), (key0, &mut 0)); assert_eq!(iter.next().unwrap(), (key1, &mut 1)); @@ -237,7 +239,7 @@ fn with_id() { u32s.clear_modified(); }); - world.run::<&i16, _, _>(|i16s| { + world.run(|i16s: View| { let mut iter = (&i16s).iter().with_id(); assert_eq!(iter.next().unwrap(), (key0, &10)); assert_eq!(iter.next().unwrap(), (key2, &12)); @@ -247,7 +249,7 @@ fn with_id() { assert!(i16s.modified().iter().next().is_none()); }); - world.run::<&mut i16, _, _>(|mut i16s| { + world.run(|mut i16s: ViewMut| { let mut iter = (&mut i16s).iter().with_id(); assert_eq!(iter.next().unwrap(), (key0, &mut 10)); assert_eq!(iter.next().unwrap(), (key2, &mut 12)); @@ -265,7 +267,7 @@ fn with_id() { i16s.clear_modified(); }); - world.run::<(&u32, &i16), _, _>(|(u32s, i16s)| { + world.run(|(u32s, i16s): (View, View)| { let mut iter = (&u32s, &i16s).iter().with_id(); assert_eq!(iter.next().unwrap(), (key0, (&0, &10))); assert_eq!(iter.next().unwrap(), (key2, (&2, &12))); @@ -275,7 +277,7 @@ fn with_id() { assert!(u32s.modified().iter().next().is_none()); assert!(i16s.modified().iter().next().is_none()); }); - world.run::<(&mut u32, &mut i16), _, _>(|(mut u32s, mut i16s)| { + world.run(|(mut u32s, mut i16s): (ViewMut, ViewMut)| { let mut iter = (&mut u32s, &mut i16s).iter().with_id(); assert_eq!(iter.next().unwrap(), (key0, (&mut 0, &mut 10))); assert_eq!(iter.next().unwrap(), (key2, (&mut 2, &mut 12))); @@ -297,7 +299,7 @@ fn with_id() { i16s.clear_modified(); }); - world.run::<(&i16, &u32), _, _>(|(i16s, u32s)| { + world.run(|(i16s, u32s): (View, View)| { let mut iter = (&i16s, &u32s).iter().with_id(); assert_eq!(iter.next().unwrap(), (key0, (&10, &0))); assert_eq!(iter.next().unwrap(), (key2, (&12, &2))); @@ -307,7 +309,7 @@ fn with_id() { assert!(i16s.modified().iter().next().is_none()); assert!(u32s.modified().iter().next().is_none()); }); - world.run::<(&mut i16, &mut u32), _, _>(|(mut i16s, mut u32s)| { + world.run(|(mut i16s, mut u32s): (ViewMut, ViewMut)| { let mut iter = (&mut i16s, &mut u32s).iter().with_id(); assert_eq!(iter.next().unwrap(), (key0, (&mut 10, &mut 0))); assert_eq!(iter.next().unwrap(), (key2, (&mut 12, &mut 2))); @@ -330,7 +332,8 @@ fn with_id() { #[test] fn map() { let world = World::new(); - let (mut entities, mut u32s, mut i16s) = world.borrow::<(EntitiesMut, &mut u32, &mut i16)>(); + let (mut entities, mut u32s, mut i16s) = + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); u32s.update_pack(); i16s.update_pack(); @@ -344,7 +347,7 @@ fn map() { i16s.clear_inserted(); drop((u32s, i16s)); - world.run::<&u32, _, _>(|u32s| { + world.run(|u32s: View| { let mut iter = (&u32s).iter().map(Clone::clone); assert_eq!(iter.next().unwrap(), 0); assert_eq!(iter.next().unwrap(), 1); @@ -354,7 +357,7 @@ fn map() { assert!(u32s.modified().iter().next().is_none()); }); - world.run::<&mut u32, _, _>(|mut u32s| { + world.run(|mut u32s: ViewMut| { let mut iter = (&mut u32s).iter().map(|x| *x); assert_eq!(iter.next().unwrap(), 0); assert_eq!(iter.next().unwrap(), 1); @@ -372,7 +375,7 @@ fn map() { u32s.clear_modified(); }); - world.run::<&i16, _, _>(|i16s| { + world.run(|i16s: View| { let mut iter = (&i16s).iter().map(Clone::clone); assert_eq!(iter.next().unwrap(), 10); assert_eq!(iter.next().unwrap(), 12); @@ -382,7 +385,7 @@ fn map() { assert!(i16s.modified().iter().next().is_none()); }); - world.run::<&mut i16, _, _>(|mut i16s| { + world.run(|mut i16s: ViewMut| { let mut iter = (&mut i16s).iter().map(|x| *x); assert_eq!(iter.next().unwrap(), 10); assert_eq!(iter.next().unwrap(), 12); @@ -400,7 +403,7 @@ fn map() { i16s.clear_modified(); }); - world.run::<(&u32, &i16), _, _>(|(u32s, i16s)| { + world.run(|(u32s, i16s): (View, View)| { let mut iter = (&u32s, &i16s).iter().map(|(x, y)| (*x, *y)); assert_eq!(iter.next().unwrap(), (0, 10)); assert_eq!(iter.next().unwrap(), (2, 12)); @@ -410,7 +413,7 @@ fn map() { assert!(u32s.modified().iter().next().is_none()); assert!(i16s.modified().iter().next().is_none()); }); - world.run::<(&mut u32, &mut i16), _, _>(|(mut u32s, mut i16s)| { + world.run(|(mut u32s, mut i16s): (ViewMut, ViewMut)| { let mut iter = (&mut u32s, &mut i16s).iter().map(|(x, y)| (*x, *y)); assert_eq!(iter.next().unwrap(), (0, 10)); assert_eq!(iter.next().unwrap(), (2, 12)); @@ -432,7 +435,7 @@ fn map() { i16s.clear_modified(); }); - world.run::<(&i16, &u32), _, _>(|(i16s, u32s)| { + world.run(|(i16s, u32s): (View, View)| { let mut iter = (&i16s, &u32s).iter().map(|(x, y)| (*x, *y)); assert_eq!(iter.next().unwrap(), (10, 0)); assert_eq!(iter.next().unwrap(), (12, 2)); @@ -442,7 +445,7 @@ fn map() { assert!(i16s.modified().iter().next().is_none()); assert!(u32s.modified().iter().next().is_none()); }); - world.run::<(&mut i16, &mut u32), _, _>(|(mut i16s, mut u32s)| { + world.run(|(mut i16s, mut u32s): (ViewMut, ViewMut)| { let mut iter = (&mut i16s, &mut u32s).iter().map(|(x, y)| (*x, *y)); assert_eq!(iter.next().unwrap(), (10, 0)); assert_eq!(iter.next().unwrap(), (12, 2)); @@ -465,7 +468,8 @@ fn map() { #[test] fn filter() { let world = World::new(); - let (mut entities, mut u32s, mut i16s) = world.borrow::<(EntitiesMut, &mut u32, &mut i16)>(); + let (mut entities, mut u32s, mut i16s) = + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); u32s.update_pack(); i16s.update_pack(); @@ -479,7 +483,7 @@ fn filter() { i16s.clear_inserted(); drop((u32s, i16s)); - world.run::<&u32, _, _>(|u32s| { + world.run(|u32s: View| { let mut iter = (&u32s).iter().filter(|x| **x % 2 == 0); assert_eq!(iter.size_hint(), (0, Some(4))); assert_eq!(iter.next().unwrap(), &0); @@ -489,7 +493,7 @@ fn filter() { assert!(u32s.modified().iter().next().is_none()); }); - world.run::<&mut u32, _, _>(|mut u32s| { + world.run(|mut u32s: ViewMut| { let mut iter = (&mut u32s).iter().filter(|x| **x % 2 != 0); assert_eq!(iter.next().unwrap(), &mut 1); assert!(iter.next().is_none()); @@ -501,7 +505,7 @@ fn filter() { u32s.clear_modified(); }); - world.run::<&i16, _, _>(|i16s| { + world.run(|i16s: View| { let mut iter = (&i16s).iter().filter(|x| **x % 2 == 0); assert_eq!(iter.next().unwrap(), &10); assert_eq!(iter.next().unwrap(), &12); @@ -510,7 +514,7 @@ fn filter() { assert!(i16s.modified().iter().next().is_none()); }); - world.run::<&mut i16, _, _>(|mut i16s| { + world.run(|mut i16s: ViewMut| { let mut iter = (&mut i16s).iter().filter(|x| **x % 2 != 0); assert_eq!(iter.next().unwrap(), &mut 13); assert!(iter.next().is_none()); @@ -522,7 +526,7 @@ fn filter() { i16s.clear_modified(); }); - world.run::<(&u32, &i16), _, _>(|(u32s, i16s)| { + world.run(|(u32s, i16s): (View, View)| { let mut iter = (&u32s, &i16s).iter().filter(|(_, y)| **y % 5 == 0); assert_eq!(iter.next().unwrap(), (&0, &10)); assert!(iter.next().is_none()); @@ -530,7 +534,7 @@ fn filter() { assert!(u32s.modified().iter().next().is_none()); assert!(i16s.modified().iter().next().is_none()); }); - world.run::<(&mut u32, &mut i16), _, _>(|(mut u32s, mut i16s)| { + world.run(|(mut u32s, mut i16s): (ViewMut, ViewMut)| { let mut iter = (&mut u32s, &mut i16s).iter().filter(|(_, y)| **y % 5 != 0); assert_eq!(iter.next().unwrap(), (&mut 4, &mut 14)); assert_eq!(iter.next().unwrap(), (&mut 2, &mut 12)); @@ -549,7 +553,7 @@ fn filter() { i16s.clear_modified(); }); - world.run::<(&i16, &u32), _, _>(|(i16s, u32s)| { + world.run(|(i16s, u32s): (View, View)| { let mut iter = (&i16s, &u32s).iter().filter(|(x, _)| **x % 5 == 0); assert_eq!(iter.next().unwrap(), (&10, &0)); assert!(iter.next().is_none()); @@ -557,7 +561,7 @@ fn filter() { assert!(i16s.modified().iter().next().is_none()); assert!(u32s.modified().iter().next().is_none()); }); - world.run::<(&mut i16, &mut u32), _, _>(|(mut i16s, mut u32s)| { + world.run(|(mut i16s, mut u32s): (ViewMut, ViewMut)| { let mut iter = (&mut i16s, &mut u32s).iter().filter(|(x, _)| **x % 5 != 0); assert_eq!(iter.next().unwrap(), (&mut 14, &mut 4)); assert_eq!(iter.next().unwrap(), (&mut 12, &mut 2)); @@ -577,7 +581,8 @@ fn filter() { #[test] fn enumerate_map_filter_with_id() { let world = World::new(); - let (mut entities, mut u32s, mut i16s) = world.borrow::<(EntitiesMut, &mut u32, &mut i16)>(); + let (mut entities, mut u32s, mut i16s) = + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); u32s.update_pack(); i16s.update_pack(); @@ -590,7 +595,7 @@ fn enumerate_map_filter_with_id() { i16s.clear_inserted(); drop((u32s, i16s)); - world.run::<&u32, _, _>(|u32s| { + world.run(|u32s: View| { let mut iter = (&u32s) .iter() .enumerate() @@ -605,7 +610,7 @@ fn enumerate_map_filter_with_id() { assert!(u32s.modified().iter().next().is_none()); }); - world.run::<&mut u32, _, _>(|mut u32s| { + world.run(|mut u32s: ViewMut| { let mut iter = (&mut u32s) .iter() .enumerate() @@ -626,7 +631,7 @@ fn enumerate_map_filter_with_id() { u32s.clear_modified(); }); - world.run::<&i16, _, _>(|i16s| { + world.run(|i16s: View| { let mut iter = (&i16s) .iter() .enumerate() @@ -641,7 +646,7 @@ fn enumerate_map_filter_with_id() { assert!(i16s.modified().iter().next().is_none()); }); - world.run::<&mut i16, _, _>(|mut i16s| { + world.run(|mut i16s: ViewMut| { let mut iter = (&mut i16s) .iter() .enumerate() @@ -662,7 +667,7 @@ fn enumerate_map_filter_with_id() { i16s.clear_modified(); }); - world.run::<(&u32, &i16), _, _>(|(u32s, i16s)| { + world.run(|(u32s, i16s): (View, View)| { let mut iter = (&u32s, &i16s) .iter() .enumerate() @@ -677,7 +682,7 @@ fn enumerate_map_filter_with_id() { assert!(u32s.modified().iter().next().is_none()); assert!(i16s.modified().iter().next().is_none()); }); - world.run::<(&mut i16, &mut u32), _, _>(|(mut i16s, mut u32s)| { + world.run(|(mut u32s, mut i16s): (ViewMut, ViewMut)| { let mut iter = (&mut i16s, &mut u32s) .iter() .enumerate() @@ -707,7 +712,8 @@ fn enumerate_map_filter_with_id() { #[test] fn enumerate_filter_map_with_id() { let world = World::new(); - let (mut entities, mut u32s, mut i16s) = world.borrow::<(EntitiesMut, &mut u32, &mut i16)>(); + let (mut entities, mut u32s, mut i16s) = + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); u32s.update_pack(); i16s.update_pack(); @@ -720,7 +726,7 @@ fn enumerate_filter_map_with_id() { i16s.clear_inserted(); drop((u32s, i16s)); - world.run::<&u32, _, _>(|u32s| { + world.run(|u32s: View| { let mut iter = (&u32s) .iter() .enumerate() @@ -735,7 +741,7 @@ fn enumerate_filter_map_with_id() { assert!(u32s.modified().iter().next().is_none()); }); - world.run::<&mut u32, _, _>(|mut u32s| { + world.run(|mut u32s: ViewMut| { let mut iter = (&mut u32s) .iter() .enumerate() @@ -753,7 +759,7 @@ fn enumerate_filter_map_with_id() { u32s.clear_modified(); }); - world.run::<&i16, _, _>(|i16s| { + world.run(|i16s: View| { let mut iter = (&i16s) .iter() .enumerate() @@ -768,7 +774,7 @@ fn enumerate_filter_map_with_id() { assert!(i16s.modified().iter().next().is_none()); }); - world.run::<&mut i16, _, _>(|mut i16s| { + world.run(|mut i16s: ViewMut| { let mut iter = (&mut i16s) .iter() .enumerate() @@ -786,7 +792,7 @@ fn enumerate_filter_map_with_id() { i16s.clear_modified(); }); - world.run::<(&u32, &i16), _, _>(|(u32s, i16s)| { + world.run(|(u32s, i16s): (View, View)| { let mut iter = (&u32s, &i16s) .iter() .enumerate() @@ -801,7 +807,7 @@ fn enumerate_filter_map_with_id() { assert!(u32s.modified().iter().next().is_none()); assert!(i16s.modified().iter().next().is_none()); }); - world.run::<(&mut i16, &mut u32), _, _>(|(mut i16s, mut u32s)| { + world.run(|(mut i16s, mut u32s): (ViewMut, ViewMut)| { let mut iter = (&mut i16s, &mut u32s) .iter() .enumerate() diff --git a/tests/iteration/update/par_single.rs b/tests/iteration/update/par_single.rs index 4d16f3bd..07ff0b99 100644 --- a/tests/iteration/update/par_single.rs +++ b/tests/iteration/update/par_single.rs @@ -1,10 +1,10 @@ use rayon::prelude::*; -use shipyard::prelude::*; +use shipyard::*; #[test] fn filter() { let world = World::new(); - let (mut entities, mut u32s) = world.borrow::<(EntitiesMut, &mut u32)>(); + let (mut entities, mut u32s) = world.borrow::<(EntitiesViewMut, ViewMut)>(); u32s.update_pack(); entities.add_entity(&mut u32s, 0); diff --git a/tests/iteration/update/single.rs b/tests/iteration/update/single.rs index 6d49b2eb..3c0208b0 100644 --- a/tests/iteration/update/single.rs +++ b/tests/iteration/update/single.rs @@ -1,9 +1,9 @@ -use shipyard::prelude::*; +use shipyard::*; #[test] fn basic() { let world = World::new(); - let (mut entities, mut u32s) = world.borrow::<(EntitiesMut, &mut u32)>(); + let (mut entities, mut u32s) = world.borrow::<(EntitiesViewMut, ViewMut)>(); u32s.update_pack(); entities.add_entity(&mut u32s, 0); @@ -22,7 +22,7 @@ fn basic() { drop(u32s); let mut vec = Vec::new(); - world.run::<&u32, _, _>(|u32s| { + world.run(|u32s: View| { let iter = u32s.iter(); assert_eq!(iter.size_hint(), (3, Some(3))); iter.for_each(|&x| vec.push(x)); @@ -31,7 +31,7 @@ fn basic() { assert_eq!(u32s.modified().len(), 0); assert_eq!(u32s.inserted_or_modified().len(), 0); }); - world.run::<&mut u32, _, _>(|mut u32s| { + world.run(|mut u32s: ViewMut| { (&mut u32s).iter().for_each(|&mut x| vec.push(x)); u32s.modified().iter().for_each(|&x| vec.push(x)); (&mut u32s).iter().for_each(|_| {}); @@ -47,7 +47,7 @@ fn basic() { #[test] fn with_id() { let world = World::new(); - let (mut entities, mut u32s) = world.borrow::<(EntitiesMut, &mut u32)>(); + let (mut entities, mut u32s) = world.borrow::<(EntitiesViewMut, ViewMut)>(); u32s.update_pack(); let key0 = entities.add_entity(&mut u32s, 0); @@ -57,10 +57,10 @@ fn with_id() { drop(u32s); let mut vec = Vec::new(); - world.run::<&u32, _, _>(|u32s| { + world.run(|u32s: View| { u32s.iter().with_id().for_each(|(id, &x)| vec.push((id, x))); }); - world.run::<&mut u32, _, _>(|mut u32s| { + world.run(|mut u32s: ViewMut| { (&mut u32s) .iter() .with_id() @@ -90,7 +90,7 @@ fn with_id() { #[test] fn map() { let world = World::new(); - let (mut entities, mut u32s) = world.borrow::<(EntitiesMut, &mut u32)>(); + let (mut entities, mut u32s) = world.borrow::<(EntitiesViewMut, ViewMut)>(); u32s.update_pack(); entities.add_entity(&mut u32s, 0); @@ -100,10 +100,10 @@ fn map() { drop(u32s); let mut vec = Vec::new(); - world.run::<&u32, _, _>(|u32s| { + world.run(|u32s: View| { u32s.iter().map(|x| *x + 10).for_each(|x| vec.push(x)); }); - world.run::<&mut u32, _, _>(|mut u32s| { + world.run(|mut u32s: ViewMut| { (&mut u32s).iter().map(|x| *x + 1).for_each(|x| vec.push(x)); u32s.modified().iter().for_each(|&x| vec.push(x)); }); @@ -114,7 +114,7 @@ fn map() { #[test] fn filter() { let world = World::new(); - let (mut entities, mut u32s) = world.borrow::<(EntitiesMut, &mut u32)>(); + let (mut entities, mut u32s) = world.borrow::<(EntitiesViewMut, ViewMut)>(); u32s.update_pack(); entities.add_entity(&mut u32s, 0); @@ -140,7 +140,7 @@ fn filter() { #[test] fn enumerate_map_filter_with_id() { let world = World::new(); - let (mut entities, mut u32s) = world.borrow::<(EntitiesMut, &mut u32)>(); + let (mut entities, mut u32s) = world.borrow::<(EntitiesViewMut, ViewMut)>(); u32s.update_pack(); let key0 = entities.add_entity(&mut u32s, 10); @@ -151,7 +151,7 @@ fn enumerate_map_filter_with_id() { drop(u32s); let mut vec = Vec::new(); let mut modified = Vec::new(); - world.run::<&mut u32, _, _>(|mut u32s| { + world.run(|mut u32s: ViewMut| { (&mut u32s) .iter() .enumerate() @@ -169,7 +169,7 @@ fn enumerate_map_filter_with_id() { #[test] fn enumerate_filter_map_with_id() { let world = World::new(); - let (mut entities, mut u32s) = world.borrow::<(EntitiesMut, &mut u32)>(); + let (mut entities, mut u32s) = world.borrow::<(EntitiesViewMut, ViewMut)>(); u32s.update_pack(); let key0 = entities.add_entity(&mut u32s, 10); @@ -180,7 +180,7 @@ fn enumerate_filter_map_with_id() { drop(u32s); let mut vec = Vec::new(); let mut modified = Vec::new(); - world.run::<&mut u32, _, _>(|mut u32s| { + world.run(|mut u32s: ViewMut| { (&mut u32s) .iter() .enumerate() diff --git a/tests/key.rs b/tests/key.rs index 7d90428e..d5569d48 100644 --- a/tests/key.rs +++ b/tests/key.rs @@ -1,26 +1,29 @@ -use shipyard::prelude::*; +use shipyard::*; #[test] fn key_equality() { let world = World::default(); //create 3 entities - let (e0, e1, e2) = - world.run::<(EntitiesMut, &mut usize), _, _>(|(mut entities, mut usizes)| { + let (e0, e1, e2) = world.run( + |(mut entities, mut usizes): (EntitiesViewMut, ViewMut)| { ( entities.add_entity(&mut usizes, 0), entities.add_entity(&mut usizes, 1), entities.add_entity(&mut usizes, 2), ) - }); + }, + ); //add a component to e1 - world.run::<(EntitiesMut, &mut u32), _, _>(|(ref mut entities, ref mut u32s)| { - entities.add_component(u32s, 42, e1); - }); + world.run( + |(ref mut entities, ref mut u32s): (EntitiesViewMut, ViewMut)| { + entities.add_component(u32s, 42, e1); + }, + ); //confirm that the entity keys have not changed for usizes storage - world.run::<&usize, _, _>(|usizes| { + world.run(|usizes: View| { //sanity check assert_eq!((&usizes).iter().with_id().count(), 3); @@ -39,7 +42,7 @@ fn key_equality() { //confirm that the entity id for (usize) is the same as (usize, u32) //in other words that the entity itself did not somehow change from adding a component - world.run::<(&usize, &u32), _, _>(|(usizes, u32s)| { + world.run(|(usizes, u32s): (View, View)| { //sanity check assert_eq!((&usizes, &u32s).iter().with_id().count(), 1); diff --git a/tests/lib.rs b/tests/lib.rs index 2e9615eb..5db64fb3 100644 --- a/tests/lib.rs +++ b/tests/lib.rs @@ -1,4 +1,4 @@ -mod book; +//mod book; mod borrow; mod iteration; #[cfg(feature = "serde")] @@ -8,14 +8,14 @@ mod workload; use shipyard::error; #[cfg(feature = "parallel")] -use shipyard::internal::iterators; -use shipyard::prelude::*; +use shipyard::iterators; +use shipyard::*; #[test] fn run() { let world = World::new(); - world.run::<(EntitiesMut, &mut usize, &mut u32), _, _>( - |(mut entities, mut usizes, mut u32s)| { + world.run( + |(mut entities, mut usizes, mut u32s): (EntitiesViewMut, ViewMut, ViewMut)| { entities.add_entity((&mut usizes, &mut u32s), (0usize, 1u32)); entities.add_entity((&mut usizes, &mut u32s), (2usize, 3u32)); @@ -55,7 +55,7 @@ fn run() { #[test] fn thread_pool() { let world = World::new(); - world.run::<(ThreadPool,), _, _>(|(thread_pool,)| { + world.run(|thread_pool: ThreadPoolView| { use rayon::prelude::*; let vec = vec![0, 1, 2, 3]; @@ -67,28 +67,24 @@ fn thread_pool() { #[test] fn system() { - struct System1; - impl<'a> System<'a> for System1 { - type Data = (&'a mut usize, &'a u32); - fn run((mut usizes, u32s): ::View) { - (&mut usizes, &u32s).iter().for_each(|(x, y)| { - *x += *y as usize; - }); - } + fn system1((mut usizes, u32s): (ViewMut, View)) { + (&mut usizes, &u32s).iter().for_each(|(x, y)| { + *x += *y as usize; + }); } let world = World::new(); - world.run::<(EntitiesMut, &mut usize, &mut u32), _, _>( - |(mut entities, mut usizes, mut u32s)| { + world.run( + |(mut entities, mut usizes, mut u32s): (EntitiesViewMut, ViewMut, ViewMut)| { entities.add_entity((&mut usizes, &mut u32s), (0usize, 1u32)); entities.add_entity((&mut usizes, &mut u32s), (2usize, 3u32)); }, ); - world.add_workload::("sys1"); + world.add_workload("").with_system(system!(system1)).build(); world.run_default(); - world.run::<(&usize,), _, _>(|(usizes,)| { + world.run(|usizes: View| { let mut iter = usizes.iter(); assert_eq!(iter.next(), Some(&1)); assert_eq!(iter.next(), Some(&5)); @@ -98,37 +94,34 @@ fn system() { #[test] fn systems() { - struct System1; - impl<'a> System<'a> for System1 { - type Data = (&'a mut usize, &'a u32); - fn run((mut usizes, u32s): ::View) { - (&mut usizes, &u32s).iter().for_each(|(x, y)| { - *x += *y as usize; - }); - } + fn system1((mut usizes, u32s): (ViewMut, View)) { + (&mut usizes, &u32s).iter().for_each(|(x, y)| { + *x += *y as usize; + }); } - struct System2; - impl<'a> System<'a> for System2 { - type Data = (&'a mut usize,); - fn run((mut usizes,): ::View) { - (&mut usizes,).iter().for_each(|x| { - *x += 1; - }); - } + + fn system2(mut usizes: ViewMut) { + (&mut usizes,).iter().for_each(|x| { + *x += 1; + }); } let world = World::new(); - world.run::<(EntitiesMut, &mut usize, &mut u32), _, _>( - |(mut entities, mut usizes, mut u32s)| { + world.run( + |(mut entities, mut usizes, mut u32s): (EntitiesViewMut, ViewMut, ViewMut)| { entities.add_entity((&mut usizes, &mut u32s), (0usize, 1u32)); entities.add_entity((&mut usizes, &mut u32s), (2usize, 3u32)); }, ); - world.add_workload::<(System1, System2), _>("sys1"); + world + .add_workload("") + .with_system(system!(system1)) + .with_system(system!(system2)) + .build(); world.run_default(); - world.run::<(&usize,), _, _>(|(usizes,)| { + world.run(|usizes: View| { let mut iter = usizes.iter(); assert_eq!(iter.next(), Some(&2)); assert_eq!(iter.next(), Some(&6)); @@ -144,14 +137,14 @@ fn simple_parallel_sum() { let world = World::new(); - world.run::<(EntitiesMut, &mut usize, &mut u32), _, _>( - |(mut entities, mut usizes, mut u32s)| { + world.run( + |(mut entities, mut usizes, mut u32s): (EntitiesViewMut, ViewMut, ViewMut)| { entities.add_entity((&mut usizes, &mut u32s), (1usize, 2u32)); entities.add_entity((&mut usizes, &mut u32s), (3usize, 4u32)); }, ); - world.run::<(&mut usize, ThreadPool), _, _>(|(usizes, thread_pool)| { + world.run(|(usizes, thread_pool): (ViewMut, ThreadPoolView)| { thread_pool.install(|| { let sum: usize = (&usizes,).par_iter().cloned().sum(); assert_eq!(sum, 4); @@ -168,32 +161,34 @@ fn tight_parallel_iterator() { let world = World::new(); - world.run::<(EntitiesMut, &mut usize, &mut u32), _, _>( - |(mut entities, mut usizes, mut u32s)| { + world.run( + |(mut entities, mut usizes, mut u32s): (EntitiesViewMut, ViewMut, ViewMut)| { (&mut usizes, &mut u32s).tight_pack(); entities.add_entity((&mut usizes, &mut u32s), (0usize, 1u32)); entities.add_entity((&mut usizes, &mut u32s), (2usize, 3u32)); }, ); - world.run::<(&mut usize, &u32, ThreadPool), _, _>(|(mut usizes, u32s, thread_pool)| { - let counter = std::sync::atomic::AtomicUsize::new(0); - thread_pool.install(|| { - if let ParIter2::Tight(iter) = (&mut usizes, &u32s).par_iter() { - iter.for_each(|(x, y)| { - counter.fetch_add(1, std::sync::atomic::Ordering::SeqCst); - *x += *y as usize; - }); - } else { - panic!() - } - }); - assert_eq!(counter.load(std::sync::atomic::Ordering::SeqCst), 2); - let mut iter = (&mut usizes).iter(); - assert_eq!(iter.next(), Some(&mut 1)); - assert_eq!(iter.next(), Some(&mut 5)); - assert_eq!(iter.next(), None); - }); + world.run( + |(mut usizes, u32s, thread_pool): (ViewMut, View, ThreadPoolView)| { + let counter = std::sync::atomic::AtomicUsize::new(0); + thread_pool.install(|| { + if let ParIter2::Tight(iter) = (&mut usizes, &u32s).par_iter() { + iter.for_each(|(x, y)| { + counter.fetch_add(1, std::sync::atomic::Ordering::SeqCst); + *x += *y as usize; + }); + } else { + panic!() + } + }); + assert_eq!(counter.load(std::sync::atomic::Ordering::SeqCst), 2); + let mut iter = (&mut usizes).iter(); + assert_eq!(iter.next(), Some(&mut 1)); + assert_eq!(iter.next(), Some(&mut 5)); + assert_eq!(iter.next(), None); + }, + ); } #[cfg(feature = "parallel")] @@ -204,27 +199,29 @@ fn parallel_iterator() { let world = World::new(); - world.run::<(EntitiesMut, &mut usize, &mut u32), _, _>( - |(mut entities, mut usizes, mut u32s)| { + world.run( + |(mut entities, mut usizes, mut u32s): (EntitiesViewMut, ViewMut, ViewMut)| { entities.add_entity((&mut usizes, &mut u32s), (0usize, 1u32)); entities.add_entity((&mut usizes, &mut u32s), (2usize, 3u32)); }, ); - world.run::<(&mut usize, &u32, ThreadPool), _, _>(|(mut usizes, u32s, thread_pool)| { - let counter = std::sync::atomic::AtomicUsize::new(0); - thread_pool.install(|| { - (&mut usizes, &u32s).par_iter().for_each(|(x, y)| { - counter.fetch_add(1, std::sync::atomic::Ordering::SeqCst); - *x += *y as usize; + world.run( + |(mut usizes, u32s, thread_pool): (ViewMut, View, ThreadPoolView)| { + let counter = std::sync::atomic::AtomicUsize::new(0); + thread_pool.install(|| { + (&mut usizes, &u32s).par_iter().for_each(|(x, y)| { + counter.fetch_add(1, std::sync::atomic::Ordering::SeqCst); + *x += *y as usize; + }); }); - }); - assert_eq!(counter.load(std::sync::atomic::Ordering::SeqCst), 2); - let mut iter = (&mut usizes).iter(); - assert_eq!(iter.next(), Some(&mut 1)); - assert_eq!(iter.next(), Some(&mut 5)); - assert_eq!(iter.next(), None); - }); + assert_eq!(counter.load(std::sync::atomic::Ordering::SeqCst), 2); + let mut iter = (&mut usizes).iter(); + assert_eq!(iter.next(), Some(&mut 1)); + assert_eq!(iter.next(), Some(&mut 5)); + assert_eq!(iter.next(), None); + }, + ); } #[cfg(feature = "parallel")] @@ -236,48 +233,46 @@ fn loose_parallel_iterator() { let world = World::new(); - world.run::<(EntitiesMut, &mut usize, &mut u32), _, _>( - |(mut entities, mut usizes, mut u32s)| { + world.run( + |(mut entities, mut usizes, mut u32s): (EntitiesViewMut, ViewMut, ViewMut)| { LoosePack::<(usize,)>::loose_pack((&mut usizes, &mut u32s)); entities.add_entity((&mut usizes, &mut u32s), (0usize, 1u32)); entities.add_entity((&mut usizes, &mut u32s), (2usize, 3u32)); }, ); - world.run::<(&mut usize, &u32, ThreadPool), _, _>(|(mut usizes, u32s, thread_pool)| { - let counter = std::sync::atomic::AtomicUsize::new(0); - thread_pool.install(|| { - if let ParIter2::Loose(iter) = (&mut usizes, &u32s).par_iter() { - iter.for_each(|(x, y)| { - counter.fetch_add(1, std::sync::atomic::Ordering::SeqCst); - *x += *y as usize; - }); - } else { - panic!() - } - }); - assert_eq!(counter.load(std::sync::atomic::Ordering::SeqCst), 2); - let mut iter = (&mut usizes).iter(); - assert_eq!(iter.next(), Some(&mut 1)); - assert_eq!(iter.next(), Some(&mut 5)); - assert_eq!(iter.next(), None); - }); + world.run( + |(mut usizes, u32s, thread_pool): (ViewMut, View, ThreadPoolView)| { + let counter = std::sync::atomic::AtomicUsize::new(0); + thread_pool.install(|| { + if let ParIter2::Loose(iter) = (&mut usizes, &u32s).par_iter() { + iter.for_each(|(x, y)| { + counter.fetch_add(1, std::sync::atomic::Ordering::SeqCst); + *x += *y as usize; + }); + } else { + panic!() + } + }); + assert_eq!(counter.load(std::sync::atomic::Ordering::SeqCst), 2); + let mut iter = (&mut usizes).iter(); + assert_eq!(iter.next(), Some(&mut 1)); + assert_eq!(iter.next(), Some(&mut 5)); + assert_eq!(iter.next(), None); + }, + ); } #[cfg(feature = "parallel")] #[cfg_attr(miri, ignore)] #[test] fn two_workloads() { - struct System1; - impl<'a> System<'a> for System1 { - type Data = (&'a usize,); - fn run(_: ::View) { - std::thread::sleep(std::time::Duration::from_millis(200)); - } + fn system1(_: View) { + std::thread::sleep(std::time::Duration::from_millis(200)); } let world = World::new(); - world.add_workload::<(System1,), _>("default"); + world.add_workload("").with_system(system!(system1)).build(); rayon::scope(|s| { s.spawn(|_| world.run_default()); @@ -289,19 +284,15 @@ fn two_workloads() { #[cfg_attr(miri, ignore)] #[test] #[should_panic( - expected = "Result::unwrap()` on an `Err` value: Cannot mutably borrow usize storage while it's already borrowed." + expected = "called `Result::unwrap()` on an `Err` value: System lib::two_bad_workloads::system1 failed: Cannot mutably borrow usize storage while it\'s already borrowed." )] fn two_bad_workloads() { - struct System1; - impl<'a> System<'a> for System1 { - type Data = (&'a mut usize,); - fn run(_: ::View) { - std::thread::sleep(std::time::Duration::from_millis(200)); - } + fn system1(_: ViewMut) { + std::thread::sleep(std::time::Duration::from_millis(200)); } let world = World::new(); - world.add_workload::<(System1,), _>("default"); + world.add_workload("").with_system(system!(system1)).build(); rayon::scope(|s| { s.spawn(|_| world.run_default()); @@ -315,23 +306,22 @@ fn add_component_with_old_key() { let entity = { let (mut entities, mut usizes, mut u32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); entities.add_entity((&mut usizes, &mut u32s), (0usize, 1u32)) }; - world.run::(|mut all_storages| { + world.run(|mut all_storages: AllStoragesViewMut| { all_storages.delete(entity); }); - { - let (entities, mut usizes, mut u32s) = world.borrow::<(Entities, &mut usize, &mut u32)>(); - assert_eq!( - entities.try_add_component((&mut usizes, &mut u32s), (1, 2), entity), - Err(error::AddComponent::EntityIsNotAlive) - ); - } + let (entities, mut usizes, mut u32s) = + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); + assert_eq!( + entities.try_add_component((&mut usizes, &mut u32s), (1, 2), entity), + Err(error::AddComponent::EntityIsNotAlive) + ); } - +/* #[cfg_attr(miri, ignore)] #[cfg(feature = "proc")] #[test] @@ -374,7 +364,7 @@ fn derive() { t.compile_fail("tests/derive/double_borrow_non_send_sync.rs"); } } - +*/ #[cfg(feature = "parallel")] #[cfg_attr(miri, ignore)] #[test] @@ -383,33 +373,35 @@ fn par_update_pack() { let world = World::new(); - world.run::<(EntitiesMut, &mut usize), _, _>(|(mut entities, mut usizes)| { - usizes.update_pack(); - entities.add_entity(&mut usizes, 0); - entities.add_entity(&mut usizes, 1); - entities.add_entity(&mut usizes, 2); - entities.add_entity(&mut usizes, 3); + world.run( + |(mut entities, mut usizes): (EntitiesViewMut, ViewMut)| { + usizes.update_pack(); + entities.add_entity(&mut usizes, 0); + entities.add_entity(&mut usizes, 1); + entities.add_entity(&mut usizes, 2); + entities.add_entity(&mut usizes, 3); - usizes.clear_inserted(); + usizes.clear_inserted(); - (&usizes).par_iter().sum::(); + (&usizes).par_iter().sum::(); - assert_eq!(usizes.modified().len(), 0); + assert_eq!(usizes.modified().len(), 0); - (&mut usizes).par_iter().for_each(|i| { - *i += 1; - }); + (&mut usizes).par_iter().for_each(|i| { + *i += 1; + }); - let mut iter = usizes.inserted().iter(); - assert_eq!(iter.next(), None); + let mut iter = usizes.inserted().iter(); + assert_eq!(iter.next(), None); - let mut iter = usizes.modified_mut().iter(); - assert_eq!(iter.next(), Some(&mut 1)); - assert_eq!(iter.next(), Some(&mut 2)); - assert_eq!(iter.next(), Some(&mut 3)); - assert_eq!(iter.next(), Some(&mut 4)); - assert_eq!(iter.next(), None); - }); + let mut iter = usizes.modified_mut().iter(); + assert_eq!(iter.next(), Some(&mut 1)); + assert_eq!(iter.next(), Some(&mut 2)); + assert_eq!(iter.next(), Some(&mut 3)); + assert_eq!(iter.next(), Some(&mut 4)); + assert_eq!(iter.next(), None); + }, + ); } #[cfg(feature = "parallel")] @@ -421,8 +413,8 @@ fn par_multiple_update_pack() { let world = World::new(); - world.run::<(EntitiesMut, &mut usize, &mut u32), _, _>( - |(mut entities, mut usizes, mut u32s)| { + world.run( + |(mut entities, mut usizes, mut u32s): (EntitiesViewMut, ViewMut, ViewMut)| { u32s.update_pack(); entities.add_entity((&mut usizes, &mut u32s), (0usize, 1u32)); entities.add_entity(&mut usizes, 2usize); @@ -435,7 +427,7 @@ fn par_multiple_update_pack() { }, ); - world.run::<(&mut usize, &mut u32), _, _>(|(mut usizes, mut u32s)| { + world.run(|(mut usizes, mut u32s): (ViewMut, ViewMut)| { if let ParIter2::NonPacked(iter) = (&usizes, &u32s).par_iter() { iter.for_each(|_| {}); } else { @@ -476,31 +468,33 @@ fn par_update_filter() { let world = World::new(); - world.run::<(EntitiesMut, &mut usize), _, _>(|(mut entities, mut usizes)| { - usizes.update_pack(); - entities.add_entity(&mut usizes, 0); - entities.add_entity(&mut usizes, 1); - entities.add_entity(&mut usizes, 2); - entities.add_entity(&mut usizes, 3); - - usizes.clear_inserted(); - - (&mut usizes) - .par_iter() - .filter(|x| **x % 2 == 0) - .for_each(|i| { - *i += 1; - }); + world.run( + |(mut entities, mut usizes): (EntitiesViewMut, ViewMut)| { + usizes.update_pack(); + entities.add_entity(&mut usizes, 0); + entities.add_entity(&mut usizes, 1); + entities.add_entity(&mut usizes, 2); + entities.add_entity(&mut usizes, 3); + + usizes.clear_inserted(); + + (&mut usizes) + .par_iter() + .filter(|x| **x % 2 == 0) + .for_each(|i| { + *i += 1; + }); - let mut iter = usizes.inserted().iter(); - assert_eq!(iter.next(), None); + let mut iter = usizes.inserted().iter(); + assert_eq!(iter.next(), None); - let mut modified: Vec<_> = usizes.modified().iter().collect(); - modified.sort_unstable(); - assert_eq!(modified, vec![&1, &1, &3, &3]); + let mut modified: Vec<_> = usizes.modified().iter().collect(); + modified.sort_unstable(); + assert_eq!(modified, vec![&1, &1, &3, &3]); - let mut iter: Vec<_> = (&usizes).iter().collect(); - iter.sort_unstable(); - assert_eq!(iter, vec![&1, &1, &3, &3]); - }); + let mut iter: Vec<_> = (&usizes).iter().collect(); + iter.sort_unstable(); + assert_eq!(iter, vec![&1, &1, &3, &3]); + }, + ); } diff --git a/tests/pack.rs b/tests/pack.rs index d4ca5e61..ba3d08d1 100644 --- a/tests/pack.rs +++ b/tests/pack.rs @@ -1,4 +1,4 @@ -use shipyard::prelude::*; +use shipyard::*; #[test] fn pack() { @@ -6,7 +6,7 @@ fn pack() { let world = World::new(); let (mut usizes, mut u64s, mut u32s, mut u16s) = - world.borrow::<(&mut usize, &mut u64, &mut u32, &mut u16)>(); + world.borrow::<(ViewMut, ViewMut, ViewMut, ViewMut)>(); (&mut usizes, &mut u64s).tight_pack(); diff --git a/tests/remove.rs b/tests/remove.rs index f68855f3..5f0d1a07 100644 --- a/tests/remove.rs +++ b/tests/remove.rs @@ -1,13 +1,13 @@ use core::any::type_name; use shipyard::error; -use shipyard::internal::iterators; -use shipyard::prelude::*; +use shipyard::iterators; +use shipyard::*; #[test] fn no_pack() { let world = World::new(); let (mut entities, mut usizes, mut u32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); let entity1 = entities.add_entity((&mut usizes, &mut u32s), (0usize, 1u32)); let entity2 = entities.add_entity((&mut usizes, &mut u32s), (2usize, 3u32)); @@ -29,7 +29,7 @@ fn no_pack() { fn tight() { let world = World::new(); let (mut entities, mut usizes, mut u32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut usizes, &mut u32s).tight_pack(); let entity1 = entities.add_entity((&mut usizes, &mut u32s), (0usize, 1u32)); @@ -59,7 +59,7 @@ fn tight() { fn loose() { let world = World::new(); let (mut entities, mut usizes, mut u32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut usizes, &mut u32s).loose_pack(); let entity1 = entities.add_entity((&mut usizes, &mut u32s), (0usize, 1u32)); @@ -85,7 +85,7 @@ fn loose() { fn tight_loose() { let world = World::new(); let (mut entities, mut usizes, mut u64s, mut u32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u64, &mut u32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut, ViewMut)>(); (&mut usizes, &mut u64s).tight_pack(); LoosePack::<(u32,)>::loose_pack((&mut u32s, &mut usizes, &mut u64s)); @@ -119,7 +119,7 @@ fn tight_loose() { #[test] fn update() { let world = World::new(); - let (mut entities, mut usizes) = world.borrow::<(EntitiesMut, &mut usize)>(); + let (mut entities, mut usizes) = world.borrow::<(EntitiesViewMut, ViewMut)>(); usizes.update_pack(); @@ -145,18 +145,18 @@ fn update() { fn old_key() { let world = World::new(); - let entity = world.run::<(EntitiesMut, &mut usize, &mut u32), _, _>( - |(mut entities, mut usizes, mut u32s)| { + let entity = world.run( + |(mut entities, mut usizes, mut u32s): (EntitiesViewMut, ViewMut, ViewMut)| { entities.add_entity((&mut usizes, &mut u32s), (0usize, 1u32)) }, ); - world.run::(|mut all_storages| { + world.run(|mut all_storages: AllStoragesViewMut| { all_storages.delete(entity); }); - world.run::<(EntitiesMut, &mut usize, &mut u32), _, _>( - |(mut entities, mut usizes, mut u32s)| { + world.run( + |(mut entities, mut usizes, mut u32s): (EntitiesViewMut, ViewMut, ViewMut)| { entities.add_entity((&mut usizes, &mut u32s), (2usize, 3u32)); let (old_usize, old_u32) = Remove::<(usize, u32)>::remove((&mut usizes, &mut u32s), entity); @@ -169,8 +169,8 @@ fn old_key() { fn newer_key() { let world = World::new(); - world.run::<(EntitiesMut, &mut usize, &mut u32), _, _>( - |(mut entities, mut usizes, mut u32s)| { + world.run( + |(mut entities, mut usizes, mut u32s): (EntitiesViewMut, ViewMut, ViewMut)| { let entity = entities.add_entity((&mut usizes, &mut u32s), (0usize, 1u32)); entities.delete_unchecked(entity); diff --git a/tests/serde/entity_id.rs b/tests/serde/entity_id.rs index 2d868366..e39cc29d 100644 --- a/tests/serde/entity_id.rs +++ b/tests/serde/entity_id.rs @@ -1,34 +1,38 @@ -use shipyard::prelude::*; +use shipyard::*; #[test] fn entity_id_serde() { let world = World::default(); //create and check a couple entities - let (entity_id0, _) = world.run::<(EntitiesMut, &mut u32), _, _>(|(mut entities, mut u32s)| { - let entity_id0 = entities.add_entity(&mut u32s, 0); - check_roundtrip(entity_id0, "[0,0]"); + let (entity_id0, _) = world.run( + |(mut entities, mut u32s): (EntitiesViewMut, ViewMut)| { + let entity_id0 = entities.add_entity(&mut u32s, 0); + check_roundtrip(entity_id0, "[0,0]"); - let entity_id1 = entities.add_entity(&mut u32s, 1); - check_roundtrip(entity_id1, "[1,0]"); + let entity_id1 = entities.add_entity(&mut u32s, 1); + check_roundtrip(entity_id1, "[1,0]"); - (entity_id0, entity_id1) - }); + (entity_id0, entity_id1) + }, + ); //delete the first entity - world.run::(|mut all_storages| { + world.run(|mut all_storages: AllStoragesViewMut| { assert!(all_storages.delete(entity_id0)); }); //add 2 more - world.run::<(EntitiesMut, &mut u32), _, _>(|(mut entities, mut u32s)| { - let entity_id2 = entities.add_entity(&mut u32s, 2); - //version was bumped - check_roundtrip(entity_id2, "[0,1]"); - - let entity_id3 = entities.add_entity(&mut u32s, 1); - check_roundtrip(entity_id3, "[2,0]"); - }); + world.run( + |(mut entities, mut u32s): (EntitiesViewMut, ViewMut)| { + let entity_id2 = entities.add_entity(&mut u32s, 2); + //version was bumped + check_roundtrip(entity_id2, "[0,1]"); + + let entity_id3 = entities.add_entity(&mut u32s, 1); + check_roundtrip(entity_id3, "[2,0]"); + }, + ); } fn check_roundtrip(entity_id: EntityId, expected: &str) { diff --git a/tests/sort.rs b/tests/sort.rs index d7860739..55877656 100644 --- a/tests/sort.rs +++ b/tests/sort.rs @@ -1,33 +1,35 @@ use shipyard::error; -use shipyard::internal::iterators; -use shipyard::prelude::*; +use shipyard::iterators; +use shipyard::*; #[test] fn simple_sort() { let world = World::new(); - world.run::<(EntitiesMut, &mut usize), _, _>(|(mut entities, mut usizes)| { - entities.add_entity(&mut usizes, 5); - entities.add_entity(&mut usizes, 2); - entities.add_entity(&mut usizes, 4); - entities.add_entity(&mut usizes, 3); - entities.add_entity(&mut usizes, 1); - - usizes.sort().unstable(Ord::cmp); - - let mut prev = 0; - (&mut usizes).iter().for_each(|&mut x| { - assert!(prev <= x); - prev = x; - }); - }); + world.run( + |(mut entities, mut usizes): (EntitiesViewMut, ViewMut)| { + entities.add_entity(&mut usizes, 5); + entities.add_entity(&mut usizes, 2); + entities.add_entity(&mut usizes, 4); + entities.add_entity(&mut usizes, 3); + entities.add_entity(&mut usizes, 1); + + usizes.sort().unstable(Ord::cmp); + + let mut prev = 0; + (&mut usizes).iter().for_each(|&mut x| { + assert!(prev <= x); + prev = x; + }); + }, + ); } #[test] fn tight_sort() { let world = World::new(); let (mut entities, mut usizes, mut u32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut usizes, &mut u32s).tight_pack(); entities.add_entity((&mut usizes, &mut u32s), (10usize, 3u32)); @@ -52,7 +54,7 @@ fn tight_sort() { fn loose_sort() { let world = World::new(); let (mut entities, mut usizes, mut u32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut)>(); (&mut usizes, &mut u32s).loose_pack(); @@ -78,7 +80,7 @@ fn loose_sort() { fn tight_loose_sort() { let world = World::new(); let (mut entities, mut usizes, mut u64s, mut u32s) = - world.borrow::<(EntitiesMut, &mut usize, &mut u64, &mut u32)>(); + world.borrow::<(EntitiesViewMut, ViewMut, ViewMut, ViewMut)>(); (&mut usizes, &mut u64s).tight_pack(); LoosePack::<(u32,)>::loose_pack((&mut u32s, &mut usizes, &mut u64s)); @@ -117,7 +119,7 @@ fn tight_loose_sort() { #[test] fn tight_sort_missing_storage() { let world = World::new(); - let (mut usizes, mut u64s) = world.borrow::<(&mut usize, &mut u64)>(); + let (mut usizes, mut u64s) = world.borrow::<(ViewMut, ViewMut)>(); (&mut usizes, &mut u64s).tight_pack(); assert_eq!( @@ -129,7 +131,7 @@ fn tight_sort_missing_storage() { #[test] fn loose_sort_missing_storage() { let world = World::new(); - let (mut usizes, mut u64s) = world.borrow::<(&mut usize, &mut u64)>(); + let (mut usizes, mut u64s) = world.borrow::<(ViewMut, ViewMut)>(); (&mut usizes, &mut u64s).loose_pack(); assert_eq!( @@ -141,7 +143,8 @@ fn loose_sort_missing_storage() { #[test] fn tight_sort_too_many_storages() { let world = World::new(); - let (mut usizes, mut u64s, mut u32s) = world.borrow::<(&mut usize, &mut u64, &mut u32)>(); + let (mut usizes, mut u64s, mut u32s) = + world.borrow::<(ViewMut, ViewMut, ViewMut)>(); (&mut usizes, &mut u64s).tight_pack(); assert_eq!( @@ -158,7 +161,7 @@ fn tight_sort_too_many_storages() { #[test] fn update_sort() { let world = World::new(); - let mut usizes = world.borrow::<&mut usize>(); + let mut usizes = world.borrow::>(); usizes.update_pack(); assert_eq!( diff --git a/tests/static_view.rs b/tests/static_view.rs index 4f471af9..0e487265 100644 --- a/tests/static_view.rs +++ b/tests/static_view.rs @@ -1,6 +1,6 @@ use core::any::type_name; use shipyard::error; -use shipyard::prelude::*; +use shipyard::*; #[test] fn returned() { @@ -9,16 +9,19 @@ fn returned() { unsafe { WORLD = Some(World::new()) }; let _view: ViewMut<'static, usize> = - unsafe { WORLD.as_ref().unwrap() }.run::<&mut usize, _, _>(|usizes| usizes); - assert_eq!( - unsafe { WORLD.as_ref().unwrap() } - .try_run::<&mut usize, _, _>(|usizes| usizes) - .err(), - Some(error::GetStorage::StorageBorrow(( - type_name::(), - error::Borrow::Unique - ))) - ); + unsafe { WORLD.as_ref().unwrap() }.run(|usizes: ViewMut| usizes); + match unsafe { WORLD.as_ref().unwrap() } + .try_run(|usizes: ViewMut| usizes) + .err() + { + Some(error::Run::GetStorage(get_storage)) => { + assert_eq!( + get_storage, + error::GetStorage::StorageBorrow((type_name::(), error::Borrow::Unique)) + ); + } + _ => panic!(), + } } #[test] @@ -28,15 +31,18 @@ fn taken_from_run() { unsafe { WORLD = Some(World::new()) }; let mut view = None; - unsafe { WORLD.as_ref().unwrap() }.run::<&mut usize, _, _>(|usizes| view = Some(usizes)); + unsafe { WORLD.as_ref().unwrap() }.run(|usizes: ViewMut| view = Some(usizes)); let mut view = None; - assert_eq!( - unsafe { WORLD.as_ref().unwrap() } - .try_run::<&mut usize, _, _>(|usizes| view = Some(usizes)) - .err(), - Some(error::GetStorage::StorageBorrow(( - type_name::(), - error::Borrow::Unique - ))) - ); + match unsafe { WORLD.as_ref().unwrap() } + .try_run(|usizes: ViewMut| view = Some(usizes)) + .err() + { + Some(error::Run::GetStorage(get_storage)) => { + assert_eq!( + get_storage, + error::GetStorage::StorageBorrow((type_name::(), error::Borrow::Unique)) + ); + } + _ => panic!(), + } } diff --git a/tests/unique.rs b/tests/unique.rs index a582612f..64aa01e8 100644 --- a/tests/unique.rs +++ b/tests/unique.rs @@ -1,16 +1,16 @@ use core::any::type_name; use shipyard::error; -use shipyard::prelude::*; +use shipyard::*; #[test] fn unique_storage() { let world = World::default(); world.add_unique(0usize); - world.run::, _, _>(|mut x| { + world.run(|mut x: UniqueViewMut| { *x += 1; }); - world.run::, _, _>(|x| { + world.run(|x: UniqueView| { assert_eq!(*x, 1); }); } @@ -19,20 +19,21 @@ fn unique_storage() { fn not_unique_storage() { let world = World::new(); - assert_eq!( - world.try_run::, _, _>(|_| {}).err(), - Some(error::GetStorage::NonUnique(( - type_name::(), - error::Borrow::Shared - ))) - ); - assert_eq!( - world.try_run::, _, _>(|_| {}).err(), - Some(error::GetStorage::NonUnique(( - type_name::(), - error::Borrow::Unique - ))) - ); + match world.try_run(|_: UniqueView| {}).err() { + Some(error::Run::GetStorage(get_storage)) => assert_eq!( + get_storage, + error::GetStorage::NonUnique((type_name::(), error::Borrow::Shared)) + ), + _ => panic!(), + } + + match world.try_run(|_: UniqueViewMut| {}).err() { + Some(error::Run::GetStorage(get_storage)) => assert_eq!( + get_storage, + error::GetStorage::NonUnique((type_name::(), error::Borrow::Unique)) + ), + _ => panic!(), + } } #[cfg(feature = "non_send")] @@ -50,10 +51,10 @@ fn non_send() { _phantom: core::marker::PhantomData, }); - world.run::>, _, _>(|mut x| { + world.run(|mut x: NonSend>| { x.value += 1; }); - world.run::>, _, _>(|x| { + world.run(|x: NonSend>| { assert_eq!(x.value, 1); }); } @@ -73,10 +74,10 @@ fn non_sync() { _phantom: core::marker::PhantomData, }); - world.run::>, _, _>(|mut x| { + world.run(|mut x: NonSync>| { x.value += 1; }); - world.run::>, _, _>(|x| { + world.run(|x: NonSync>| { assert_eq!(x.value, 1); }); } @@ -95,10 +96,10 @@ fn non_send_sync() { _phantom: core::marker::PhantomData, }); - world.run::>, _, _>(|mut x| { + world.run(|mut x: NonSendSync>| { x.value += 1; }); - world.run::>, _, _>(|x| { + world.run(|x: NonSendSync>| { assert_eq!(x.value, 1); }); } diff --git a/tests/window.rs b/tests/window.rs index e22350d3..1c800758 100644 --- a/tests/window.rs +++ b/tests/window.rs @@ -1,11 +1,11 @@ use shipyard::error; -use shipyard::prelude::*; +use shipyard::*; #[test] fn empty_inserted_in_modified() { let world = World::new(); - let mut usizes = world.borrow::<&mut usize>(); + let mut usizes = world.borrow::>(); usizes.update_pack(); let modified = usizes.modified(); modified.inserted(); @@ -15,7 +15,7 @@ fn empty_inserted_in_modified() { fn inserted_in_inserted() { let world = World::new(); - let (mut entities, mut usizes) = world.borrow::<(EntitiesMut, &mut usize)>(); + let (mut entities, mut usizes) = world.borrow::<(EntitiesViewMut, ViewMut)>(); usizes.update_pack(); entities.add_entity(&mut usizes, 0); let inserted = usizes.inserted(); @@ -26,7 +26,7 @@ fn inserted_in_inserted() { fn inserted_in_modified() { let world = World::new(); - let (mut entities, mut usizes) = world.borrow::<(EntitiesMut, &mut usize)>(); + let (mut entities, mut usizes) = world.borrow::<(EntitiesViewMut, ViewMut)>(); usizes.update_pack(); entities.add_entity(&mut usizes, 0); let modified = usizes.modified(); @@ -40,7 +40,7 @@ fn inserted_in_modified() { fn inserted_in_inserted_or_modified() { let world = World::new(); - let (mut entities, mut usizes) = world.borrow::<(EntitiesMut, &mut usize)>(); + let (mut entities, mut usizes) = world.borrow::<(EntitiesViewMut, ViewMut)>(); usizes.update_pack(); entities.add_entity(&mut usizes, 0); let inserted_or_modified = usizes.inserted_or_modified(); @@ -51,7 +51,7 @@ fn inserted_in_inserted_or_modified() { fn empty_modified_in_inserted() { let world = World::new(); - let mut usizes = world.borrow::<&mut usize>(); + let mut usizes = world.borrow::>(); usizes.update_pack(); let inserted = usizes.inserted(); inserted.modified(); @@ -61,7 +61,7 @@ fn empty_modified_in_inserted() { fn modified_in_modified() { let world = World::new(); - let (mut entities, mut usizes) = world.borrow::<(EntitiesMut, &mut usize)>(); + let (mut entities, mut usizes) = world.borrow::<(EntitiesViewMut, ViewMut)>(); usizes.update_pack(); entities.add_entity(&mut usizes, 0); usizes.clear_inserted(); @@ -74,7 +74,7 @@ fn modified_in_modified() { fn modified_in_inserted() { let world = World::new(); - let (mut entities, mut usizes) = world.borrow::<(EntitiesMut, &mut usize)>(); + let (mut entities, mut usizes) = world.borrow::<(EntitiesViewMut, ViewMut)>(); usizes.update_pack(); entities.add_entity(&mut usizes, 0); usizes.clear_inserted(); @@ -90,7 +90,7 @@ fn modified_in_inserted() { fn modified_in_inserted_or_modified() { let world = World::new(); - let (mut entities, mut usizes) = world.borrow::<(EntitiesMut, &mut usize)>(); + let (mut entities, mut usizes) = world.borrow::<(EntitiesViewMut, ViewMut)>(); usizes.update_pack(); entities.add_entity(&mut usizes, 0); usizes.clear_inserted(); @@ -103,7 +103,7 @@ fn modified_in_inserted_or_modified() { fn empty_inserted_or_modified_in_inserted() { let world = World::new(); - let mut usizes = world.borrow::<&mut usize>(); + let mut usizes = world.borrow::>(); usizes.update_pack(); let inserted = usizes.inserted(); inserted.inserted_or_modified(); @@ -113,7 +113,7 @@ fn empty_inserted_or_modified_in_inserted() { fn empty_inserted_or_modified_in_modified() { let world = World::new(); - let mut usizes = world.borrow::<&mut usize>(); + let mut usizes = world.borrow::>(); usizes.update_pack(); let modified = usizes.modified(); modified.inserted_or_modified(); @@ -123,7 +123,7 @@ fn empty_inserted_or_modified_in_modified() { fn inserted_or_modified_in_inserted_or_modified() { let world = World::new(); - let (mut entities, mut usizes) = world.borrow::<(EntitiesMut, &mut usize)>(); + let (mut entities, mut usizes) = world.borrow::<(EntitiesViewMut, ViewMut)>(); usizes.update_pack(); entities.add_entity(&mut usizes, 0); let inserted_or_modified = usizes.inserted_or_modified(); @@ -139,7 +139,7 @@ fn inserted_or_modified_in_inserted_or_modified() { fn inserted_or_modified_in_inserted() { let world = World::new(); - let (mut entities, mut usizes) = world.borrow::<(EntitiesMut, &mut usize)>(); + let (mut entities, mut usizes) = world.borrow::<(EntitiesViewMut, ViewMut)>(); usizes.update_pack(); entities.add_entity(&mut usizes, 0); usizes.clear_inserted(); @@ -155,7 +155,7 @@ fn inserted_or_modified_in_inserted() { fn inserted_or_modified_in_modified() { let world = World::new(); - let (mut entities, mut usizes) = world.borrow::<(EntitiesMut, &mut usize)>(); + let (mut entities, mut usizes) = world.borrow::<(EntitiesViewMut, ViewMut)>(); usizes.update_pack(); entities.add_entity(&mut usizes, 0); let modified = usizes.modified(); diff --git a/tests/workload/function.rs b/tests/workload/function.rs index b5ce4c12..1f3a5e06 100644 --- a/tests/workload/function.rs +++ b/tests/workload/function.rs @@ -1,4 +1,4 @@ -use shipyard::prelude::*; +use shipyard::*; #[test] fn basic() { diff --git a/tests/workload/mod.rs b/tests/workload/mod.rs index 65e3b469..4bc69817 100644 --- a/tests/workload/mod.rs +++ b/tests/workload/mod.rs @@ -1,3 +1 @@ -// WIP -//mod function; mod non_send_non_sync; diff --git a/tests/workload/non_send_non_sync.rs b/tests/workload/non_send_non_sync.rs index 189bce52..8869ef4a 100644 --- a/tests/workload/non_send_non_sync.rs +++ b/tests/workload/non_send_non_sync.rs @@ -1,4 +1,4 @@ -/*use shipyard::prelude::*; +/*use shipyard::*; use std::cell::RefCell; use std::rc::Rc;