diff --git a/Cargo.toml b/Cargo.toml index d05f6226c..8df0ac0d8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -86,6 +86,12 @@ required-features = ["common"] name = "saveload" required-features = ["serde"] +[[example]] +name = "system_derive_simple" + +[[example]] +name = "system_derive_with_components" + [[bench]] name = "benches_main" harness = false diff --git a/benches/storage_sparse.rs b/benches/storage_sparse.rs index 5c59132f4..97f996759 100644 --- a/benches/storage_sparse.rs +++ b/benches/storage_sparse.rs @@ -83,14 +83,15 @@ macro_rules! gap { c.bench_function( &format!("sparse insert {}/{}", $sparsity, stringify!($storage)), |b| insert(b), - ).bench_function( - &format!("sparse remove {}/{}", $sparsity, stringify!($storage)), - |b| remove(b), - ) - .bench_function( - &format!("sparse get {}/{}", $sparsity, stringify!($storage)), - |b| get(b), - ); + ) + .bench_function( + &format!("sparse remove {}/{}", $sparsity, stringify!($storage)), + |b| remove(b), + ) + .bench_function( + &format!("sparse get {}/{}", $sparsity, stringify!($storage)), + |b| get(b), + ); } } }; diff --git a/examples/cluster_bomb.rs b/examples/cluster_bomb.rs index a3bd697a9..b6fe0236a 100644 --- a/examples/cluster_bomb.rs +++ b/examples/cluster_bomb.rs @@ -2,8 +2,8 @@ extern crate rand; extern crate rayon; extern crate specs; -use rand::Rng; use rand::distributions::{Distribution, Range}; +use rand::Rng; use rayon::iter::ParallelIterator; diff --git a/examples/full.rs b/examples/full.rs index d9d66d297..c60a80379 100644 --- a/examples/full.rs +++ b/examples/full.rs @@ -168,7 +168,11 @@ impl<'a> System<'a> for SysStoreMax { struct JoinParallel; impl<'a> System<'a> for JoinParallel { - type SystemData = (ReadStorage<'a, CompBool>, ReadStorage<'a, CompInt>, WriteStorage<'a, CompFloat>); + type SystemData = ( + ReadStorage<'a, CompBool>, + ReadStorage<'a, CompInt>, + WriteStorage<'a, CompFloat>, + ); fn run(&mut self, (comp_bool, comp_int, mut comp_float): Self::SystemData) { use rayon::prelude::*; @@ -239,7 +243,8 @@ fn main() { .with(CompBool(false)) .build(); // build() returns an entity, we will use it later to perform a deletion - let e = w.create_entity() + let e = w + .create_entity() .with(CompInt(9)) .with(CompBool(true)) .build(); diff --git a/examples/ordered_track.rs b/examples/ordered_track.rs index 0145e003a..0bb18b356 100644 --- a/examples/ordered_track.rs +++ b/examples/ordered_track.rs @@ -41,9 +41,9 @@ impl<'a> System<'a> for SysA { ComponentEvent::Modified(id) => { let entity = entities.entity(*id); if let Some(component) = tracked.get(entity) { - // This is safe because it can only occur after an `Inserted` event, not a + // This is safe because it can only occur after an `Inserted` event, not a // `Removed` event. - *self.cache.get_mut(id).unwrap() = (entity, component.0); + *self.cache.get_mut(id).unwrap() = (entity, component.0); println!("{:?} was changed to {:?}", entity, component.0); } else { println!( diff --git a/examples/saveload.rs b/examples/saveload.rs index 54448b50a..c0750638a 100644 --- a/examples/saveload.rs +++ b/examples/saveload.rs @@ -7,7 +7,9 @@ use std::fmt; use specs::error::NoError; use specs::prelude::*; -use specs::saveload::{DeserializeComponents, MarkedBuilder, SerializeComponents, U64Marker, U64MarkerAllocator}; +use specs::saveload::{ + DeserializeComponents, MarkedBuilder, SerializeComponents, U64Marker, U64MarkerAllocator, +}; // This is an example of how the serialized data of two entities might look on disk. // @@ -82,7 +84,7 @@ impl From for Combined { } } -// This cannot be called. +// This cannot be called. impl From for Combined { fn from(e: NoError) -> Self { match e {} @@ -142,11 +144,11 @@ fn main() { let mut ser = ron::ser::Serializer::new(Some(Default::default()), true); // For serialization we use the [`SerializeComponents`](struct.SerializeComponents.html)-trait's `serialize` function. - // It takes two generic parameters: + // It takes two generic parameters: // * An unbound type -> `NoError` (However, the serialize function expects it to be bound by the `Display`-trait) // * A type implementing the `Marker`-trait -> [U64Marker](struct.U64Marker.html) (a convenient, predefined marker) // - // The first parameter resembles the `.join()` syntax from other specs-systems, + // The first parameter resembles the `.join()` syntax from other specs-systems, // every component that should be serialized has to be put inside a tuple. // // The second and third parameters are just the entity-storage and marker-storage, which get `.join()`ed internally. @@ -157,7 +159,8 @@ fn main() { &ents, &markers, &mut ser, - ).unwrap_or_else(|e| eprintln!("Error: {}", e)); + ) + .unwrap_or_else(|e| eprintln!("Error: {}", e)); // TODO: Specs should return an error which combines serialization // and component errors. @@ -167,7 +170,7 @@ fn main() { } } - // Running the system results in a print to the standard output channel, in `.ron`-format, + // Running the system results in a print to the standard output channel, in `.ron`-format, // showing how the serialized dummy entities look like. Serialize.run_now(&world.res); @@ -189,7 +192,7 @@ fn main() { fn run(&mut self, (ent, mut alloc, pos, mass, mut markers): Self::SystemData) { // The `const ENTITIES: &str` at the top of this file was formatted according to the `.ron`-specs, - // therefore we need a `.ron`-deserializer. + // therefore we need a `.ron`-deserializer. // Others can be used, as long as they implement the `serde::de::Deserializer`-trait. use ron::de::Deserializer; @@ -206,7 +209,8 @@ fn main() { &mut markers, &mut alloc, &mut de, - ).unwrap_or_else(|e| eprintln!("Error: {}", e)); + ) + .unwrap_or_else(|e| eprintln!("Error: {}", e)); } } } diff --git a/examples/system_derive_simple.rs b/examples/system_derive_simple.rs new file mode 100644 index 000000000..2270f6608 --- /dev/null +++ b/examples/system_derive_simple.rs @@ -0,0 +1,22 @@ +extern crate specs; +#[macro_use] +extern crate specs_derive; + +use specs::prelude::*; + +#[specs_system(SysPrint)] +fn sys_print() { + println!("Yo! I'm SysPrint"); +} + +fn main() { + let mut world = World::new(); + + // Create a dispatcher with the generated system. + let mut dispatcher = DispatcherBuilder::new().with(SysPrint, "sys_print", &[]).build(); + + dispatcher.setup(&mut world.res); + + // This dispatches all the systems in parallel (but blocking). + dispatcher.dispatch(&world.res); +} diff --git a/examples/system_derive_with_components.rs b/examples/system_derive_with_components.rs new file mode 100644 index 000000000..b57c3b8cc --- /dev/null +++ b/examples/system_derive_with_components.rs @@ -0,0 +1,70 @@ +extern crate specs; +#[macro_use] +extern crate specs_derive; + +use specs::prelude::*; + +// A component contains data which is associated with an entity. + +#[derive(Debug)] +struct Vel(f32); + +impl Component for Vel { + type Storage = VecStorage; +} + +#[derive(Debug)] +struct Pos(f32); + +impl Component for Pos { + type Storage = VecStorage; +} + +/// Increments entities' position by their velocity. +/// +/// The function parameters are the resources required for execution. +#[specs_system(SysA)] +fn sys_a(mut pos: WriteStorage, vel: ReadStorage) { + for (pos, vel) in (&mut pos, &vel).join() { + pos.0 += vel.0; + } +} + +#[specs_system(SysPrint)] +fn sys_print(entities: Entities, pos: ReadStorage, vel: ReadStorage) { + for (e, pos, vel) in (&entities, &pos, &vel).join() { + println!("{:?}: Pos: {:?} Vel: {:?}", e, pos, vel); + } +} + +fn main() { + // The `World` is our + // container for components + // and other resources. + + let mut world = World::new(); + + // This builds a dispatcher. + // The third parameter of `add` specifies + // logical dependencies on other systems. + // Since we only have one, we don't depend on anything. + // See the `full` example for dependencies. + let mut dispatcher = DispatcherBuilder::new() + .with(SysA, "sys_a", &[]) + .with(SysPrint, "sys_print", &["sys_a"]) + .build(); + + // setup() must be called before creating any entity, it will register + // all Components and Resources that Systems depend on + dispatcher.setup(&mut world.res); + + // An entity may or may not contain some component. + + world.create_entity().with(Vel(2.0)).with(Pos(0.0)).build(); + world.create_entity().with(Vel(4.0)).with(Pos(1.6)).build(); + world.create_entity().with(Vel(1.5)).with(Pos(5.4)).build(); + + // This dispatches all the systems in parallel (but blocking). + dispatcher.dispatch(&world.res); + dispatcher.dispatch(&world.res); +} diff --git a/specs-derive/src/impl_saveload.rs b/specs-derive/src/impl_saveload.rs index 002263f77..907b00816 100644 --- a/specs-derive/src/impl_saveload.rs +++ b/specs-derive/src/impl_saveload.rs @@ -4,8 +4,11 @@ // NOTE: All examples given in the documentation below are "cleaned up" into readable Rust, // so it doesn't give an entirely accurate view of what's actually generated. -use syn::{DataEnum, DataStruct, DeriveInput, Field, Generics, Ident, Type, GenericParam, WhereClause, WherePredicate}; use proc_macro2::{Span, TokenStream}; +use syn::{ + DataEnum, DataStruct, DeriveInput, Field, GenericParam, Generics, Ident, Type, WhereClause, + WherePredicate, +}; /// Handy collection since tuples got unwieldy and /// unclear in purpose @@ -24,25 +27,25 @@ pub fn impl_saveload(ast: &mut DeriveInput) -> TokenStream { add_where_clauses( &mut ast.generics.where_clause, &ast.generics.params, - |ty| parse_quote!(#ty: ConvertSaveload + ConvertSaveload) + |ty| parse_quote!(#ty: ConvertSaveload + ConvertSaveload), ); add_where_clauses( &mut ast.generics.where_clause, &ast.generics.params, - |ty| parse_quote!(<#ty as ConvertSaveload>::Data: ::serde::Serialize + ::serde::de::DeserializeOwned + Clone) + |ty| parse_quote!(<#ty as ConvertSaveload>::Data: ::serde::Serialize + ::serde::de::DeserializeOwned + Clone), ); add_where_clauses( &mut ast.generics.where_clause, &ast.generics.params, - |ty| parse_quote!(<#ty as ConvertSaveload>::Data: ::serde::Serialize + ::serde::de::DeserializeOwned + Clone) + |ty| parse_quote!(<#ty as ConvertSaveload>::Data: ::serde::Serialize + ::serde::de::DeserializeOwned + Clone), ); add_where_clause( &mut ast.generics.where_clause, - parse_quote!(MA: ::serde::Serialize + ::serde::de::DeserializeOwned + Marker) + parse_quote!(MA: ::serde::Serialize + ::serde::de::DeserializeOwned + Marker), ); add_where_clause( &mut ast.generics.where_clause, - parse_quote!(for <'deser> MA: ::serde::Deserialize<'deser>) + parse_quote!(for <'deser> MA: ::serde::Deserialize<'deser>), ); let derive = match ast.data { @@ -400,13 +403,12 @@ fn saveload_enum(data: &DataEnum, name: &Ident, generics: &Generics) -> Saveload /// Adds where clause for each type parameter fn add_where_clauses<'a, F, I>(where_clause: &mut Option, generics: I, mut clause: F) - where F: FnMut(Ident) -> WherePredicate, - I: IntoIterator, +where + F: FnMut(Ident) -> WherePredicate, + I: IntoIterator, { use syn::GenericParam; - let preds = &mut where_clause - .get_or_insert(parse_quote!(where)) - .predicates; + let preds = &mut where_clause.get_or_insert(parse_quote!(where)).predicates; for generic in generics { if let GenericParam::Type(ty_param) = generic { let ty_param = ty_param.ident.clone(); @@ -441,7 +443,9 @@ fn replace_entity_type(ty: &mut Type) { Type::TraitObject(_) => {} Type::ImplTrait(_) => {} - Type::Slice(_) => panic!("Slices are unsupported, use owned types like Vecs or Arrays instead"), + Type::Slice(_) => { + panic!("Slices are unsupported, use owned types like Vecs or Arrays instead") + } Type::Reference(_) => panic!("References are unsupported"), Type::Ptr(_) => panic!("Raw pointer types are unsupported"), Type::BareFn(_) => panic!("Function types are unsupported"), diff --git a/specs-derive/src/impl_specs_system.rs b/specs-derive/src/impl_specs_system.rs new file mode 100644 index 000000000..5f4655e10 --- /dev/null +++ b/specs-derive/src/impl_specs_system.rs @@ -0,0 +1,119 @@ +use proc_macro2::TokenStream; +use syn::punctuated::Pair; +use syn::{ + ArgCaptured, AttributeArgs, FnArg, GenericArgument, ItemFn, Meta, NestedMeta, Path, + PathArguments, ReturnType, Type, TypePath, +}; + +/// The main entrypoint, sets things up and delegates to the +/// type we're deriving on. +pub fn impl_specs_system(args: AttributeArgs, input: ItemFn) -> TokenStream { + let system_name = if args.len() == 1 { + match args.into_iter().next().unwrap() { + NestedMeta::Meta(Meta::Word(name)) => name, + arg @ _ => panic!( + "Expected an identifier for a struct name such as `MyStruct`, found: `{:?}`.", + arg + ), + } + } else { + panic!( + "Expected exactly one argument to `specs_system` attribute, found: `{:?}`", + args + ) + }; + + let decl = input.decl; + if let ReturnType::Type(_, ty) = decl.output { + panic!( + "System function must have default `()` return type, found: `{:?}`", + ty + ); + } + + let system_lifetime: GenericArgument = parse_quote!('a);; + + let (system_data_names, system_data_types) = decl + .inputs + .iter() + // Filter the function parameter types + .filter_map(|fn_arg| match fn_arg { + FnArg::SelfRef(..) | FnArg::SelfValue(..) => { + panic!("System function must not have a `self` parameter.") + } + FnArg::Captured(ArgCaptured { pat, ty, .. }) => Some((pat, ty)), + FnArg::Ignored(_ty) => unimplemented!(), + _ => None, + }) + // Prepend lifetime parameter + .fold( + ( + Vec::with_capacity(decl.inputs.len()), + Vec::with_capacity(decl.inputs.len()), + ), + |(mut names, mut types), (pat, ty)| { + let mut ty = ty.clone(); + + { + let segments = match ty { + Type::Path(TypePath { + path: + Path { + ref mut segments, .. + }, + .. + }) => segments, + Type::Tuple(_) => unimplemented!(), // TODO: recurse + _ => panic!("Unexpected type, expected Path and Tuple, found: {:?}", &ty), + }; + + let last_segment = segments + .last_mut() + .expect("Expected path to contain last segment."); + + let segment = match last_segment { + Pair::End(segment) => segment, + _ => unreachable!(), + }; + + let amended_arguments = { + let arguments = &segment.arguments; + match arguments { + PathArguments::None => { + let lifetime_generic_arg = parse_quote!(< #system_lifetime >); + PathArguments::AngleBracketed(lifetime_generic_arg) + } + PathArguments::AngleBracketed(ref generic_args) => { + let mut generic_args = generic_args.clone(); + generic_args.args.insert(0, system_lifetime.clone()); + PathArguments::AngleBracketed(generic_args) + } + PathArguments::Parenthesized(_) => { + panic!("Unexpected type argument for SystemData.") + } + } + }; + + segment.arguments = amended_arguments; + } + + names.push(pat); + types.push(ty); + + (names, types) + }, + ); + + let block = input.block; + + quote! { + struct #system_name; + + impl<'a> System<'a> for #system_name { + type SystemData = (#(#system_data_types),*); + + fn run(&mut self, (#(#system_data_names),*): Self::SystemData) + #block + } + } +} diff --git a/specs-derive/src/lib.rs b/specs-derive/src/lib.rs index feb632f5b..1879e273c 100644 --- a/specs-derive/src/lib.rs +++ b/specs-derive/src/lib.rs @@ -13,9 +13,13 @@ extern crate quote; extern crate syn; use proc_macro::TokenStream; -use syn::{DeriveInput, Path, parse::{Parse, ParseStream, Result}}; +use syn::{ + parse::{Parse, ParseStream, Result}, + AttributeArgs, DeriveInput, ItemFn, Path, +}; mod impl_saveload; +mod impl_specs_system; /// Custom derive macro for the `Component` trait. /// @@ -45,7 +49,7 @@ impl Parse for StorageAttribute { let _parenthesized_token = parenthesized!(content in input); Ok(StorageAttribute { - storage: content.parse()? + storage: content.parse()?, }) } } @@ -73,14 +77,14 @@ fn impl_component(ast: &DeriveInput) -> proc_macro2::TokenStream { } /// Custom derive macro for the `ConvertSaveload` trait. -/// +/// /// Requires `Entity`, `ConvertSaveload`, `Marker` and `NoError` to be in a scope. /// /// ## Example /// /// ```rust,ignore /// use specs::{Entity, saveload::{ConvertSaveload, Marker}, error::NoError}; -/// +/// /// #[derive(ConvertSaveload)] /// struct Target(Entity); /// ``` @@ -92,3 +96,26 @@ pub fn saveload(input: TokenStream) -> TokenStream { let gen = impl_saveload(&mut ast); gen.into() } + +/// Custom derive macro for the `ConvertSaveload` trait. +/// +/// Requires `System`, and `SystemData` to be in scope. +/// +/// ## Example +/// +/// ```rust,ignore +/// use specs::{System, SystemData}; +/// +/// #[specs_system(SimpleSystem)] +/// fn run(); +/// ``` +#[proc_macro_attribute] +pub fn specs_system(args: TokenStream, input: TokenStream) -> TokenStream { + use impl_specs_system::impl_specs_system; + + let args = parse_macro_input!(args as AttributeArgs); + let input = parse_macro_input!(input as ItemFn); + + let gen = impl_specs_system(args, input); + gen.into() +} diff --git a/specs-derive/tests/saveload.rs b/specs-derive/tests/saveload.rs index f6eea65ec..d05256d73 100644 --- a/specs-derive/tests/saveload.rs +++ b/specs-derive/tests/saveload.rs @@ -5,7 +5,11 @@ extern crate specs as spocs; #[macro_use] extern crate specs_derive; -use spocs::{Entity, saveload::{ConvertSaveload, Marker}, error::NoError}; +use spocs::{ + error::NoError, + saveload::{ConvertSaveload, Marker}, + Entity, +}; #[derive(ConvertSaveload)] struct OneFieldNamed { @@ -50,8 +54,8 @@ impl EntityLike for Entity {} mod tests { use super::*; - use spocs::{Builder, World}; use spocs::saveload::{ConvertSaveload, U64Marker}; + use spocs::{Builder, World}; #[test] fn type_check() { diff --git a/src/common.rs b/src/common.rs index 9882d08be..c0b2ba733 100644 --- a/src/common.rs +++ b/src/common.rs @@ -147,7 +147,8 @@ impl Errors { &mut stderr, "Exiting program because of {} errors...", errors.len() - ).unwrap(); + ) + .unwrap(); for (ind, error) in errors.drain(..).enumerate() { let error = error.as_ref(); @@ -256,9 +257,9 @@ mod test { use std::error::Error; use std::fmt::{Display, Formatter, Result as FmtResult}; - use futures::Poll; use futures::future::{result, Future, FutureResult}; use futures::task; + use futures::Poll; use common::{BoxedErr, Errors, Merge}; use shred::DispatcherBuilder; diff --git a/src/join/mod.rs b/src/join/mod.rs index f0e5488cc..2813786a1 100644 --- a/src/join/mod.rs +++ b/src/join/mod.rs @@ -3,9 +3,9 @@ use std; use hibitset::{BitIter, BitSetAll, BitSetAnd, BitSetLike}; +use shred::{Fetch, FetchMut, Read, ReadExpect, Resource, Write, WriteExpect}; use std::ops::{Deref, DerefMut}; use tuple_utils::Split; -use shred::{Fetch, FetchMut, Read, ReadExpect, Resource, Write, WriteExpect}; use world::{Entities, Entity, Index}; @@ -13,7 +13,7 @@ use world::{Entities, Entity, Index}; mod par_join; #[cfg(feature = "parallel")] -pub use self::par_join::{ParJoin, JoinParIter}; +pub use self::par_join::{JoinParIter, ParJoin}; /// `BitAnd` is a helper method to & bitsets together resulting in a tree. pub trait BitAnd { diff --git a/src/join/par_join.rs b/src/join/par_join.rs index 719fa634b..900377cc8 100644 --- a/src/join/par_join.rs +++ b/src/join/par_join.rs @@ -1,12 +1,10 @@ - use std::cell::UnsafeCell; use hibitset::{BitProducer, BitSetLike}; +use join::Join; use rayon::iter::plumbing::{bridge_unindexed, Folder, UnindexedConsumer, UnindexedProducer}; use rayon::iter::ParallelIterator; -use join::Join; - /// The purpose of the `ParJoin` trait is to provide a way /// to access multiple storages in parallel at the same time with @@ -115,4 +113,4 @@ where folder.consume_iter(iter) } -} \ No newline at end of file +} diff --git a/src/lib.rs b/src/lib.rs index 0880c69f1..3477c67c0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -192,8 +192,8 @@ extern crate fnv; extern crate hibitset; #[macro_use] extern crate log; -extern crate nonzero_signed; extern crate mopa; +extern crate nonzero_signed; #[cfg(feature = "parallel")] extern crate rayon; extern crate shrev; @@ -226,14 +226,18 @@ pub use hibitset::BitSet; pub use join::Join; #[cfg(feature = "parallel")] pub use join::ParJoin; -pub use shred::{Accessor, Dispatcher, DispatcherBuilder, Read, ReadExpect, Resources, RunNow, - StaticAccessor, System, SystemData, Write, WriteExpect}; +pub use shred::{ + Accessor, Dispatcher, DispatcherBuilder, Read, ReadExpect, Resources, RunNow, StaticAccessor, + System, SystemData, Write, WriteExpect, +}; pub use shrev::ReaderId; #[cfg(feature = "parallel")] pub use shred::AsyncDispatcher; pub use changeset::ChangeSet; -pub use storage::{DenseVecStorage, FlaggedStorage, HashMapStorage, NullStorage, ReadStorage, Storage, Tracked, VecStorage, - WriteStorage}; +pub use storage::{ + DenseVecStorage, FlaggedStorage, HashMapStorage, NullStorage, ReadStorage, Storage, Tracked, + VecStorage, WriteStorage, +}; pub use world::{Builder, Component, Entities, Entity, EntityBuilder, LazyUpdate, World}; diff --git a/src/prelude.rs b/src/prelude.rs index ca237428f..cf35f0c0f 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -6,8 +6,10 @@ pub use hibitset::BitSet; pub use join::Join; #[cfg(feature = "parallel")] pub use join::ParJoin; -pub use shred::{Accessor, Dispatcher, DispatcherBuilder, Read, ReadExpect, Resources, RunNow, - StaticAccessor, System, SystemData, Write, WriteExpect}; +pub use shred::{ + Accessor, Dispatcher, DispatcherBuilder, Read, ReadExpect, Resources, RunNow, StaticAccessor, + System, SystemData, Write, WriteExpect, +}; pub use shrev::ReaderId; #[cfg(feature = "parallel")] @@ -17,7 +19,7 @@ pub use shred::AsyncDispatcher; pub use changeset::ChangeSet; pub use storage::{ - DenseVecStorage, FlaggedStorage, HashMapStorage, NullStorage, ReadStorage, Storage, Tracked, - VecStorage, WriteStorage, ComponentEvent, + ComponentEvent, DenseVecStorage, FlaggedStorage, HashMapStorage, NullStorage, ReadStorage, + Storage, Tracked, VecStorage, WriteStorage, }; pub use world::{Builder, Component, Entities, Entity, EntityBuilder, LazyUpdate, World}; diff --git a/src/saveload/de.rs b/src/saveload/de.rs index 41bfdfcb9..97a3060f6 100644 --- a/src/saveload/de.rs +++ b/src/saveload/de.rs @@ -5,11 +5,11 @@ use serde::de::{ self, Deserialize, DeserializeOwned, DeserializeSeed, Deserializer, SeqAccess, Visitor, }; +use super::ConvertSaveload; use saveload::marker::{Marker, MarkerAllocator}; use saveload::EntityData; use storage::{GenericWriteStorage, WriteStorage}; use world::{Component, EntitiesRes, Entity}; -use super::ConvertSaveload; /// A trait which allows to deserialize entities and their components. pub trait DeserializeComponents diff --git a/src/saveload/marker.rs b/src/saveload/marker.rs index 0b5d63107..5987b06a3 100644 --- a/src/saveload/marker.rs +++ b/src/saveload/marker.rs @@ -80,7 +80,7 @@ impl<'a> MarkedBuilder for LazyBuilder<'a> { /// added to the `World`. fn marked(self) -> Self where - M: Marker + M: Marker, { let entity = self.entity; self.lazy.exec(move |world| { diff --git a/src/saveload/mod.rs b/src/saveload/mod.rs index c9175449c..3850865f9 100644 --- a/src/saveload/mod.rs +++ b/src/saveload/mod.rs @@ -23,7 +23,7 @@ //! see the docs for the `Marker` trait. //! -use serde::{Serialize, de::DeserializeOwned}; +use serde::{de::DeserializeOwned, Serialize}; use error::NoError; use world::Entity; @@ -34,9 +34,9 @@ mod ser; #[cfg(test)] mod tests; -pub use self::de::{DeserializeComponents}; +pub use self::de::DeserializeComponents; pub use self::marker::{MarkedBuilder, Marker, MarkerAllocator, U64Marker, U64MarkerAllocator}; -pub use self::ser::{SerializeComponents}; +pub use self::ser::SerializeComponents; /// A struct used for deserializing entity data. #[derive(Serialize, Deserialize)] @@ -47,7 +47,6 @@ pub struct EntityData { pub components: D, } - /// Converts a data type (usually a [`Component`]) into its serializable form /// and back to actual data from it's deserialized form. /// diff --git a/src/saveload/ser.rs b/src/saveload/ser.rs index 2cab8a796..67b91c72e 100644 --- a/src/saveload/ser.rs +++ b/src/saveload/ser.rs @@ -2,12 +2,12 @@ use std::fmt::Display; use serde::ser::{self, Serialize, SerializeSeq, Serializer}; +use super::ConvertSaveload; use join::Join; use saveload::marker::{Marker, MarkerAllocator}; use saveload::EntityData; use storage::{GenericReadStorage, ReadStorage, WriteStorage}; use world::{Component, EntitiesRes, Entity}; -use super::ConvertSaveload; /// A trait which allows to serialize entities and their components. pub trait SerializeComponents diff --git a/src/saveload/tests.rs b/src/saveload/tests.rs index aa115f934..20ab4c91d 100644 --- a/src/saveload/tests.rs +++ b/src/saveload/tests.rs @@ -62,7 +62,8 @@ mod marker_test { &ents, &markers, &mut ser, - ).unwrap(); + ) + .unwrap(); }, ); @@ -92,7 +93,8 @@ mod marker_test { &mut markers, &mut alloc, &mut de, - ).unwrap(); + ) + .unwrap(); }, ); diff --git a/src/storage/restrict.rs b/src/storage/restrict.rs index 547cc8db2..33b6e3d98 100644 --- a/src/storage/restrict.rs +++ b/src/storage/restrict.rs @@ -86,8 +86,7 @@ where C: Component, S: BorrowMut + 'rf, B: Borrow + 'rf, -{ -} +{} #[cfg(feature = "parallel")] unsafe impl<'rf, 'st: 'rf, C, S, B, Restrict> ParJoin @@ -97,8 +96,7 @@ where S: Borrow + 'rf, B: Borrow + 'rf, Restrict: ImmutableAliasing, -{ -} +{} impl<'rf, 'st: 'rf, C, S, B, Restrict> Join for &'rf RestrictedStorage<'rf, 'st, C, S, B, Restrict> where diff --git a/src/storage/tests.rs b/src/storage/tests.rs index 1205307f4..a429dda72 100644 --- a/src/storage/tests.rs +++ b/src/storage/tests.rs @@ -793,7 +793,6 @@ mod test { comp.0 += 1; } - { inserted.clear(); modified.clear(); diff --git a/src/storage/track.rs b/src/storage/track.rs index e3f666458..740285855 100644 --- a/src/storage/track.rs +++ b/src/storage/track.rs @@ -65,4 +65,3 @@ where self.channel_mut().single_write(event); } } - diff --git a/src/world/lazy.rs b/src/world/lazy.rs index f6a7eca7f..1a5fed707 100644 --- a/src/world/lazy.rs +++ b/src/world/lazy.rs @@ -25,7 +25,7 @@ pub struct LazyBuilder<'a> { impl<'a> Builder for LazyBuilder<'a> { /// Inserts a component using [`LazyUpdate`]. /// - /// If a component was already associated with the entity, it will + /// If a component was already associated with the entity, it will /// overwrite the previous component. fn with(self, component: C) -> Self where @@ -33,7 +33,11 @@ impl<'a> Builder for LazyBuilder<'a> { { let entity = self.entity; self.lazy.exec(move |world| { - if world.write_storage::().insert(entity, component).is_err() { + if world + .write_storage::() + .insert(entity, component) + .is_err() + { warn!( "Lazy insert of component failed because {:?} was dead.", entity @@ -81,7 +85,7 @@ where #[derive(Derivative)] #[derivative(Default)] pub struct LazyUpdate { - #[derivative(Default(value="Some(Default::default())"))] + #[derivative(Default(value = "Some(Default::default())"))] queue: Option>>, } @@ -258,7 +262,11 @@ impl LazyUpdate { where F: FnOnce(&World) + 'static + Send + Sync, { - self.queue.as_ref().unwrap().0.push(Box::new(|w: &mut World| f(w))); + self.queue + .as_ref() + .unwrap() + .0 + .push(Box::new(|w: &mut World| f(w))); } /// Lazily executes a closure with mutable world access. diff --git a/src/world/mod.rs b/src/world/mod.rs index 3688d3297..76a3b3f88 100644 --- a/src/world/mod.rs +++ b/src/world/mod.rs @@ -1,8 +1,9 @@ //! Entities, resources, components, and general world management. pub use self::comp::Component; -pub use self::entity::{CreateIterAtomic, Entities, EntitiesRes, Entity, EntityResBuilder, - Generation, Index}; +pub use self::entity::{ + CreateIterAtomic, Entities, EntitiesRes, Entity, EntityResBuilder, Generation, Index, +}; pub use self::lazy::{LazyBuilder, LazyUpdate}; use self::entity::Allocator; @@ -41,7 +42,7 @@ impl<'a> Iterator for CreateIter<'a> { pub trait Builder { /// Appends a component and associates it with the entity. /// - /// If a component was already associated with the entity, it should + /// If a component was already associated with the entity, it should /// overwrite the previous component. /// /// # Panics @@ -100,7 +101,7 @@ pub struct EntityBuilder<'a> { impl<'a> Builder for EntityBuilder<'a> { /// Inserts a component for this entity. /// - /// If a component was already associated with the entity, it will + /// If a component was already associated with the entity, it will /// overwrite the previous component. #[inline] fn with(self, c: T) -> Self { @@ -575,7 +576,9 @@ impl World { } /// Adds the given bundle of resources/components. - #[deprecated(note="Please read the book's chapter on setup: https://slide-rs.github.io/specs/07_setup.html")] + #[deprecated( + note = "Please read the book's chapter on setup: https://slide-rs.github.io/specs/07_setup.html" + )] pub fn add_bundle(&mut self, bundle: B) where B: Bundle, @@ -614,7 +617,9 @@ impl Default for World { } /// Trait used to bundle up resources/components for easy registration with `World`. -#[deprecated(note="Please read the book's chapter on setup: https://slide-rs.github.io/specs/07_setup.html")] +#[deprecated( + note = "Please read the book's chapter on setup: https://slide-rs.github.io/specs/07_setup.html" +)] pub trait Bundle { /// Add resources/components to `world`. fn add_to_world(self, world: &mut World); diff --git a/tests/tests.rs b/tests/tests.rs index 71d74d27e..469491b42 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -333,8 +333,8 @@ fn join_two_components() { #[test] fn par_join_two_components() { - use std::sync::Mutex; use std::sync::atomic::{AtomicBool, Ordering}; + use std::sync::Mutex; let mut world = create_world(); world .create_entity()