From 7352c4a2fbe92ca0049610cc847065c3322b16ed Mon Sep 17 00:00:00 2001 From: Thomas Schaller Date: Sun, 26 May 2019 09:28:27 +0200 Subject: [PATCH 01/27] Fix doc warning --- src/world/lazy.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/lazy.rs b/src/world/lazy.rs index 6ca09b2fc..4848d37a5 100644 --- a/src/world/lazy.rs +++ b/src/world/lazy.rs @@ -26,7 +26,7 @@ pub struct LazyBuilder<'a> { } impl<'a> Builder for LazyBuilder<'a> { - /// Inserts a component using [`LazyUpdate`]. + /// Inserts a component using [LazyUpdate]. /// /// If a component was already associated with the entity, it will /// overwrite the previous component. From 113a6f35d831368cf3d89a123f006271cf8b2997 Mon Sep 17 00:00:00 2001 From: Thomas Schaller Date: Sun, 26 May 2019 09:31:15 +0200 Subject: [PATCH 02/27] Formatting --- examples/saveload.rs | 3 ++- src/saveload/marker.rs | 7 ++++--- src/saveload/tests.rs | 4 ++-- tests/saveload.rs | 4 ++-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/examples/saveload.rs b/examples/saveload.rs index 4861ade33..5d876a46d 100644 --- a/examples/saveload.rs +++ b/examples/saveload.rs @@ -9,7 +9,8 @@ use specs::{ error::NoError, prelude::*, saveload::{ - DeserializeComponents, MarkedBuilder, SerializeComponents, SimpleMarker, SimpleMarkerAllocator, + DeserializeComponents, MarkedBuilder, SerializeComponents, SimpleMarker, + SimpleMarkerAllocator, }, }; diff --git a/src/saveload/marker.rs b/src/saveload/marker.rs index 7d5a5b3ea..27efa3688 100644 --- a/src/saveload/marker.rs +++ b/src/saveload/marker.rs @@ -363,7 +363,8 @@ pub trait MarkerAllocator: Resource { fn maintain(&mut self, _entities: &EntitiesRes, _storage: &ReadStorage); } -/// Basic marker implementation usable for saving and loading, uses `u64` as identifier +/// Basic marker implementation usable for saving and loading, uses `u64` as +/// identifier #[derive(Derivative, Serialize, Deserialize)] #[derivative(Clone, Copy, Debug, Hash, PartialEq, Eq)] #[repr(transparent)] @@ -404,8 +405,8 @@ impl Default for SimpleMarkerAllocator { } impl SimpleMarkerAllocator { - /// Create new `SimpleMarkerAllocator` which will yield `SimpleMarker`s starting - /// with `0` + /// Create new `SimpleMarkerAllocator` which will yield `SimpleMarker`s + /// starting with `0` pub fn new() -> Self { SimpleMarkerAllocator { index: 0, diff --git a/src/saveload/tests.rs b/src/saveload/tests.rs index bfcc2edaf..58da73300 100644 --- a/src/saveload/tests.rs +++ b/src/saveload/tests.rs @@ -158,8 +158,8 @@ mod marker_test { assert_markers_are_unique::(&mut world); } - /// Assert that the number of entities marked with `SimpleMarker` is equal to - /// `count` + /// Assert that the number of entities marked with `SimpleMarker` is equal + /// to `count` fn assert_marked_entity_count(world: &mut World, count: usize) { world.exec(|(ents, markers): (Entities, ReadStorage)| { let marked_entity_count = (&ents, &markers).join().count(); diff --git a/tests/saveload.rs b/tests/saveload.rs index 7a2ecde65..c51f29d35 100644 --- a/tests/saveload.rs +++ b/tests/saveload.rs @@ -11,13 +11,13 @@ extern crate specs_derive; #[cfg(feature = "serde")] mod tests { + #[cfg(feature = "uuid_entity")] + use spocs::saveload::UuidMarker; use spocs::{ error::NoError, saveload::{ConvertSaveload, Marker, SimpleMarker}, Builder, Entity, World, WorldExt, }; - #[cfg(feature = "uuid_entity")] - use spocs::saveload::UuidMarker; #[derive(ConvertSaveload)] struct OneFieldNamed { From b759518d13fcfa582a7b5c57f041ede1ee4cb1a4 Mon Sep 17 00:00:00 2001 From: Thomas Schaller Date: Sun, 23 Jun 2019 17:33:35 +0200 Subject: [PATCH 03/27] Remove methods from WorldExt moved over to shred See https://github.com/slide-rs/shred/pull/141 --- benches/parallel.rs | 2 +- examples/saveload.rs | 2 +- src/saveload/marker.rs | 8 +- src/saveload/tests.rs | 4 +- src/world/tests.rs | 2 +- src/world/world_ext.rs | 376 ++++------------------------------------- tests/tests.rs | 2 +- 7 files changed, 41 insertions(+), 355 deletions(-) diff --git a/benches/parallel.rs b/benches/parallel.rs index 3bc7c32b4..33ce60cb7 100644 --- a/benches/parallel.rs +++ b/benches/parallel.rs @@ -294,7 +294,7 @@ fn bench_parallel(b: &mut Bencher) { w.register::(); w.register::(); - w.add_resource(DeltaTime(0.02)); + w.insert(DeltaTime(0.02)); for x in -50i32..50i32 { for y in -50i32..50i32 { diff --git a/examples/saveload.rs b/examples/saveload.rs index 5d876a46d..f7c998d30 100644 --- a/examples/saveload.rs +++ b/examples/saveload.rs @@ -115,7 +115,7 @@ fn main() { // This predifined marker uses a `HashMap` to keep track of all // entities that should be (de)serializable, as well as which ids are // already in use. - world.add_resource(SimpleMarkerAllocator::::new()); + world.insert(SimpleMarkerAllocator::::new()); world .create_entity() diff --git a/src/saveload/marker.rs b/src/saveload/marker.rs index 27efa3688..1624cdf47 100644 --- a/src/saveload/marker.rs +++ b/src/saveload/marker.rs @@ -37,7 +37,7 @@ pub trait MarkedBuilder { /// /// let mut world = World::new(); /// world.register::>(); - /// world.add_resource(SimpleMarkerAllocator::::new()); + /// world.insert(SimpleMarkerAllocator::::new()); /// /// mark_entity(world.create_entity()); /// ``` @@ -73,7 +73,7 @@ impl<'a> MarkedBuilder for LazyBuilder<'a> { /// /// let mut world = World::new(); /// world.register::>(); - /// world.add_resource(SimpleMarkerAllocator::::new()); + /// world.insert(SimpleMarkerAllocator::::new()); /// /// # let lazy = world.read_resource::(); /// # let entities = world.entities(); @@ -118,7 +118,7 @@ impl<'a> EntityResBuilder<'a> { /// /// let mut world = World::new(); /// world.register::>(); - /// world.add_resource(SimpleMarkerAllocator::::new()); + /// world.insert(SimpleMarkerAllocator::::new()); /// /// let mut storage = world.write_storage::>(); /// let mut alloc = world.write_resource::>(); @@ -220,7 +220,7 @@ impl<'a> EntityResBuilder<'a> { /// let mut world = World::new(); /// world.register::(); /// -/// world.add_resource(NetNode { +/// world.insert(NetNode { /// range: 0..100, /// mapping: HashMap::new(), /// }); diff --git a/src/saveload/tests.rs b/src/saveload/tests.rs index 58da73300..27573561c 100644 --- a/src/saveload/tests.rs +++ b/src/saveload/tests.rs @@ -46,7 +46,7 @@ mod marker_test { { let mut world = World::new(); - world.add_resource(allocator.clone()); + world.insert(allocator.clone()); world.register::(); world.register::(); world.register::(); @@ -92,7 +92,7 @@ mod marker_test { // Throw the old world away and deserialize into a new world let mut world = World::new(); - world.add_resource(allocator); + world.insert(allocator); world.register::(); world.register::(); world.register::(); diff --git a/src/world/tests.rs b/src/world/tests.rs index 3990fbde8..aaf40f328 100644 --- a/src/world/tests.rs +++ b/src/world/tests.rs @@ -96,7 +96,7 @@ fn lazy_execution() { #[test] fn lazy_execution_order() { let mut world = World::new(); - world.add_resource(Vec::::new()); + world.insert(Vec::::new()); { let lazy = world.read_resource::(); lazy.exec(move |world| { diff --git a/src/world/world_ext.rs b/src/world/world_ext.rs index 4106dd3e2..8f8c33a40 100644 --- a/src/world/world_ext.rs +++ b/src/world/world_ext.rs @@ -11,14 +11,34 @@ use crate::{ }; use shred::{Fetch, FetchMut, MetaTable, Read, Resource, SystemData, World}; -/// This trait provides some extension methods to make working with -/// `shred::World` easier. +/// This trait provides some extension methods to make working with shred's [World] easier. /// /// Many methods take `&self` which works because everything /// is stored with **interior mutability**. In case you violate /// the borrowing rules of Rust (multiple reads xor one write), /// you will get a panic. /// +/// ## Difference between resources and components +/// +/// While components exist per [Entity], resources are like globals in the +/// `World`. Components are stored in component storages ([MaskedStorage]), which are resources +/// themselves. +/// +/// Everything that is `Any + Send + Sync` can be a resource. +/// +/// ## Built-in resources +/// +/// There are two built-in resources: +/// +/// * `LazyUpdate` and +/// * `EntitiesRes` +/// +/// Both of them should only be fetched immutably, which is why +/// the latter one has a type def for convenience: `Entities` which +/// is just `Fetch`. Both resources are special and need +/// to execute code at the end of the frame, which is done in +/// `World::maintain`. +/// /// ## Examples /// /// ``` @@ -33,7 +53,7 @@ use shred::{Fetch, FetchMut, MetaTable, Read, Resource, SystemData, World}; /// world.register::(); /// world.register::(); /// -/// world.add_resource(DeltaTime(0.02)); +/// world.insert(DeltaTime(0.02)); /// /// world /// .create_entity() @@ -119,116 +139,11 @@ pub trait WorldExt { F: FnOnce() -> T::Storage, T: Component; - /// Gets `SystemData` `T` from the `World`. - /// - /// # Examples - /// - /// ``` - /// # use specs::prelude::*; - /// # struct Pos; struct Vel; - /// # impl Component for Pos { type Storage = VecStorage; } - /// # impl Component for Vel { type Storage = VecStorage; } - /// - /// let mut world = World::new(); - /// world.register::(); - /// world.register::(); - /// let storages: (WriteStorage, ReadStorage) = world.system_data(); - /// ``` - /// - /// # Panics - /// - /// * Panics if `T` is already borrowed in an incompatible way. - fn system_data<'a, T>(&'a self) -> T - where - T: SystemData<'a>; - - /// Sets up system data `T` for fetching afterwards. - fn setup<'a, T: SystemData<'a>>(&mut self); - - /// Executes `f` once, right now with the specified system data. - /// - /// This sets up the system data `f` expects, fetches it and then - /// executes `f`. You can see this like a system that only runs once. - /// - /// This is especially useful if you either need a lot of system data or - /// you want to build an entity and for that you need to access resources - /// first - /// - just fetching the resources and building the entity would cause a - /// double borrow. - /// - /// **Calling this method is equivalent to:** - /// - /// ``` - /// # use specs::prelude::*; use specs::shred::ResourceId; - /// # struct MySystemData; impl MySystemData { fn do_something(&self) {} } - /// # impl<'a> SystemData<'a> for MySystemData { - /// # fn fetch(res: &World) -> Self { MySystemData } - /// # fn reads() -> Vec { vec![] } - /// # fn writes() -> Vec { vec![] } - /// # fn setup(res: &mut World) {} - /// # } - /// # let mut world = World::new(); - /// { - /// // note the extra scope - /// world.setup::(); - /// let my_data: MySystemData = world.system_data(); - /// my_data.do_something(); - /// } - /// ``` - /// - /// ## Examples - /// - /// ``` - /// # use specs::prelude::*; - /// let mut world = World::new(); - /// - /// struct MyComp; - /// - /// impl Component for MyComp { - /// type Storage = DenseVecStorage; - /// } - /// - /// #[derive(Default)] - /// struct MyRes { - /// field: i32, - /// } - /// - /// world.exec(|(mut my_res,): (Write,)| { - /// assert_eq!(my_res.field, 0); - /// my_res.field = 5; - /// }); - /// - /// assert_eq!(world.read_resource::().field, 5); - /// ``` - fn exec<'a, F, R, T>(&'a mut self, f: F) -> R - where - F: FnOnce(T) -> R, - T: SystemData<'a>; - /// Adds a resource to the world. /// /// If the resource already exists it will be overwritten. /// - /// ## Difference between resources and components - /// - /// While components exist per entity, resources are like globals in the - /// `World`. Components are stored in component storages, which are - /// resources themselves. - /// - /// Everything that is `Any + Send + Sync` can be a resource. - /// - /// ## Built-in resources - /// - /// There are two built-in resources: - /// - /// * `LazyUpdate` and - /// * `EntitiesRes` - /// - /// Both of them should only be fetched immutably, which is why - /// the latter one has a type def for convenience: `Entities` which - /// is just `Fetch`. Both resources are special and need - /// to execute code at the end of the frame, which is done in - /// `World::maintain`. + /// **DEPREACTED:** Use [World::insert] instead. /// /// ## Examples /// @@ -238,9 +153,10 @@ pub trait WorldExt { /// # let timer = (); /// # let server_con = (); /// let mut world = World::new(); - /// world.add_resource(timer); - /// world.add_resource(server_con); + /// world.insert(timer); + /// world.insert(server_con); /// ``` + #[deprecated(since = "0.15", note = "use `World::insert` instead")] fn add_resource(&mut self, res: T); /// Fetches a component storage for reading. @@ -377,38 +293,13 @@ pub trait WorldExt { impl WorldExt for World { fn new() -> Self { let mut world = World::default(); - world.add_resource(EntitiesRes::default()); - world.add_resource(MetaTable::::default()); - world.add_resource(LazyUpdate::default()); + world.insert(EntitiesRes::default()); + world.insert(MetaTable::::default()); + world.insert(LazyUpdate::default()); world } - /// Registers a new component, adding the component storage. - /// - /// Calls `register_with_storage` with `Default::default()`. - /// - /// Does nothing if the component was already - /// registered. - /// - /// ## Examples - /// - /// ``` - /// use specs::prelude::*; - /// - /// struct Pos { - /// x: f32, - /// y: f32, - /// } - /// - /// impl Component for Pos { - /// type Storage = DenseVecStorage; - /// } - /// - /// let mut world = World::new(); - /// world.register::(); - /// // Register all other components like this - /// ``` fn register(&mut self) where T::Storage: Default, @@ -416,9 +307,6 @@ impl WorldExt for World { self.register_with_storage::<_, T>(Default::default); } - /// Registers a new component with a given storage. - /// - /// Does nothing if the component was already registered. fn register_with_storage(&mut self, storage: F) where F: FnOnce() -> T::Storage, @@ -432,143 +320,8 @@ impl WorldExt for World { .register(&*self.fetch::>()); } - /// Gets `SystemData` `T` from the `World`. - /// - /// # Examples - /// - /// ``` - /// # use specs::prelude::*; - /// # struct Pos; struct Vel; - /// # impl Component for Pos { type Storage = VecStorage; } - /// # impl Component for Vel { type Storage = VecStorage; } - /// - /// let mut world = World::new(); - /// world.register::(); - /// world.register::(); - /// let storages: (WriteStorage, ReadStorage) = world.system_data(); - /// ``` - /// - /// # Panics - /// - /// * Panics if `T` is already borrowed in an incompatible way. - fn system_data<'a, T>(&'a self) -> T - where - T: SystemData<'a>, - { - SystemData::fetch(&self) - } - - /// Sets up system data `T` for fetching afterwards. - fn setup<'a, T: SystemData<'a>>(&mut self) { - T::setup(self); - } - - /// Executes `f` once, right now with the specified system data. - /// - /// This sets up the system data `f` expects, fetches it and then - /// executes `f`. You can see this like a system that only runs once. - /// - /// This is especially useful if you either need a lot of system data or - /// you want to build an entity and for that you need to access resources - /// first - /// - just fetching the resources and building the entity would cause a - /// double borrow. - /// - /// **Calling this method is equivalent to:** - /// - /// ``` - /// # use specs::prelude::*; use specs::shred::ResourceId; - /// # struct MySystemData; impl MySystemData { fn do_something(&self) {} } - /// # impl<'a> SystemData<'a> for MySystemData { - /// # fn fetch(res: &World) -> Self { MySystemData } - /// # fn reads() -> Vec { vec![] } - /// # fn writes() -> Vec { vec![] } - /// # fn setup(res: &mut World) {} - /// # } - /// # let mut world = World::new(); - /// { - /// // note the extra scope - /// world.setup::(); - /// let my_data: MySystemData = world.system_data(); - /// my_data.do_something(); - /// } - /// ``` - /// - /// ## Examples - /// - /// ``` - /// # use specs::prelude::*; - /// let mut world = World::new(); - /// - /// struct MyComp; - /// - /// impl Component for MyComp { - /// type Storage = DenseVecStorage; - /// } - /// - /// #[derive(Default)] - /// struct MyRes { - /// field: i32, - /// } - /// - /// world.exec(|(mut my_res,): (Write,)| { - /// assert_eq!(my_res.field, 0); - /// my_res.field = 5; - /// }); - /// - /// assert_eq!(world.read_resource::().field, 5); - /// ``` - fn exec<'a, F, R, T>(&'a mut self, f: F) -> R - where - F: FnOnce(T) -> R, - T: SystemData<'a>, - { - self.setup::(); - f(self.system_data()) - } - - /// Adds a resource to the world. - /// - /// If the resource already exists it will be overwritten. - /// - /// ## Difference between resources and components - /// - /// While components exist per entity, resources are like globals in the - /// `World`. Components are stored in component storages, which are - /// resources themselves. - /// - /// Everything that is `Any + Send + Sync` can be a resource. - /// - /// ## Built-in resources - /// - /// There are two built-in resources: - /// - /// * `LazyUpdate` and - /// * `EntitiesRes` - /// - /// Both of them should only be fetched immutably, which is why - /// the latter one has a type def for convenience: `Entities` which - /// is just `Fetch`. Both resources are special and need - /// to execute code at the end of the frame, which is done in - /// `World::maintain`. - /// - /// ## Examples - /// - /// ``` - /// use specs::prelude::*; - /// - /// # let timer = (); - /// # let server_con = (); - /// let mut world = World::new(); - /// world.add_resource(timer); - /// world.add_resource(server_con); - /// ``` fn add_resource(&mut self, res: T) { - if self.has_value::() { - *self.fetch_mut() = res; - } else { - self.insert(res); - } + self.insert(res); } fn read_component(&self) -> ReadStorage { @@ -579,57 +332,26 @@ impl WorldExt for World { self.system_data() } - /// Fetches a resource for reading. - /// - /// ## Panics - /// - /// Panics if it is already borrowed mutably. - /// Panics if the resource has not been added. fn read_resource(&self) -> Fetch { self.fetch() } - /// Fetches a resource for writing. - /// - /// # Panics - /// - /// Panics if it is already borrowed. - /// Panics if the resource has not been added. fn write_resource(&self) -> FetchMut { self.fetch_mut() } - /// Convenience method for fetching entities. - /// - /// Creation and deletion of entities with the `Entities` struct - /// are atomically, so the actual changes will be applied - /// with the next call to `maintain()`. fn entities(&self) -> Read { Read::fetch(&self) } - /// Convenience method for fetching entities. fn entities_mut(&self) -> FetchMut { self.write_resource() } - /// Allows building an entity with its components. - /// - /// This takes a mutable reference to the `World`, since no - /// component storage this builder accesses may be borrowed. - /// If it's necessary that you borrow a resource from the `World` - /// while this builder is alive, you can use `create_entity_unchecked`. fn create_entity(&mut self) -> EntityBuilder { self.create_entity_unchecked() } - /// Allows building an entity with its components. - /// - /// **You have to make sure that no component storage is borrowed - /// during the building!** - /// - /// This variant is only recommended if you need to borrow a resource - /// during the entity building. If possible, try to use `create_entity`. fn create_entity_unchecked(&self) -> EntityBuilder { let entity = self.entities_mut().alloc.allocate(); @@ -640,37 +362,20 @@ impl WorldExt for World { } } - /// Returns an iterator for entity creation. - /// This makes it easy to create a whole collection - /// of them. - /// - /// ## Examples - /// - /// ``` - /// use specs::prelude::*; - /// - /// let mut world = World::new(); - /// let five_entities: Vec<_> = world.create_iter().take(5).collect(); - /// # - /// # assert_eq!(five_entities.len(), 5); - /// ``` fn create_iter(&mut self) -> CreateIter { CreateIter(self.entities_mut()) } - /// Deletes an entity and its components. fn delete_entity(&mut self, entity: Entity) -> Result<(), WrongGeneration> { self.delete_entities(&[entity]) } - /// Deletes the specified entities and their components. fn delete_entities(&mut self, delete: &[Entity]) -> Result<(), WrongGeneration> { self.delete_components(delete); self.entities_mut().alloc.kill(delete) } - /// Deletes all entities and their components. fn delete_all(&mut self) { use crate::join::Join; @@ -682,20 +387,6 @@ impl WorldExt for World { ); } - /// Checks if an entity is alive. - /// Please note that atomically created or deleted entities - /// (the ones created / deleted with the `Entities` struct) - /// are not handled by this method. Therefore, you - /// should have called `maintain()` before using this - /// method. - /// - /// If you want to get this functionality before a `maintain()`, - /// you are most likely in a system; from there, just access the - /// `Entities` resource and call the `is_alive` method. - /// - /// # Panics - /// - /// Panics if generation is dead. fn is_alive(&self, e: Entity) -> bool { assert!(e.gen().is_alive(), "Generation is dead"); @@ -703,11 +394,6 @@ impl WorldExt for World { alloc.generation(e.id()) == Some(e.gen()) } - /// Merges in the appendix, recording all the dynamically created - /// and deleted entities into the persistent generations vector. - /// Also removes all the abandoned components. - /// - /// Additionally, `LazyUpdate` will be merged. fn maintain(&mut self) { let deleted = self.entities_mut().alloc.merge(); if !deleted.is_empty() { diff --git a/tests/tests.rs b/tests/tests.rs index 834958581..62cc0c2a3 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -253,7 +253,7 @@ fn stillborn_entities() { // Construct a bunch of entities let mut world = create_world(); - world.add_resource(Rand { values: Vec::new() }); + world.insert(Rand { values: Vec::new() }); for _ in 0..100 { world.create_entity().with(CompInt(rng.geni())).build(); From 16878d0878de46a31c5eb6087e60d72f9ae6f7f2 Mon Sep 17 00:00:00 2001 From: Thomas Schaller Date: Sun, 23 Jun 2019 17:38:21 +0200 Subject: [PATCH 04/27] Remove fnv in favour of hashbrown --- Cargo.toml | 2 +- src/lib.rs | 2 +- src/storage/storages.rs | 8 +++++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 082b7c221..058bf0c5c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ travis-ci = { repository = "slide-rs/specs" } [dependencies] crossbeam = "0.7.1" derivative = "1" -fnv = "1.0" +hashbrown = "0.5.0" hibitset = { version = "0.6.0", default-features = false } log = "0.4" mopa = "0.2" diff --git a/src/lib.rs b/src/lib.rs index 6a8b4067c..a12524d55 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -189,7 +189,7 @@ pub extern crate shred; extern crate crossbeam; #[macro_use] extern crate derivative; -extern crate fnv; +extern crate hashbrown; extern crate hibitset; #[macro_use] extern crate log; diff --git a/src/storage/storages.rs b/src/storage/storages.rs index 33c3d119b..39574cf5a 100644 --- a/src/storage/storages.rs +++ b/src/storage/storages.rs @@ -2,7 +2,7 @@ use std::collections::BTreeMap; -use fnv::FnvHashMap; +use hashbrown::HashMap; use hibitset::BitSetLike; use crate::{ @@ -42,10 +42,12 @@ impl UnprotectedStorage for BTreeStorage { unsafe impl DistinctStorage for BTreeStorage {} -/// HashMap-based storage. Best suited for rare components. +/// `HashMap`-based storage. Best suited for rare components. +/// +/// This uses the [hashbrown::HashMap] internally. #[derive(Derivative)] #[derivative(Default(bound = ""))] -pub struct HashMapStorage(FnvHashMap); +pub struct HashMapStorage(HashMap); impl UnprotectedStorage for HashMapStorage { unsafe fn clean(&mut self, _has: B) From 7ffb67a8dbb347057ca64a7e6228eab70606e5f2 Mon Sep 17 00:00:00 2001 From: Thomas Schaller Date: Sun, 23 Jun 2019 17:44:17 +0200 Subject: [PATCH 05/27] Reexport hibitset --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index a12524d55..cecf66a04 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -184,13 +184,13 @@ //! //! See the repository's examples directory for more examples. +pub extern crate hibitset; pub extern crate shred; extern crate crossbeam; #[macro_use] extern crate derivative; extern crate hashbrown; -extern crate hibitset; #[macro_use] extern crate log; extern crate mopa; From 2216f8562fc3063edb70c34e22e87a21806a47e0 Mon Sep 17 00:00:00 2001 From: Thomas Schaller Date: Sun, 23 Jun 2019 18:30:50 +0200 Subject: [PATCH 06/27] Formatting --- src/lib.rs | 6 +++--- src/world/world_ext.rs | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index cecf66a04..b0aa1208a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -217,9 +217,6 @@ pub mod prelude; pub mod storage; pub mod world; -pub use crate::join::Join; -#[cfg(feature = "parallel")] -pub use crate::join::ParJoin; pub use hibitset::BitSet; pub use shred::{ Accessor, Dispatcher, DispatcherBuilder, Read, ReadExpect, RunNow, StaticAccessor, System, @@ -230,8 +227,11 @@ pub use shrev::ReaderId; #[cfg(feature = "parallel")] pub use shred::AsyncDispatcher; +#[cfg(feature = "parallel")] +pub use crate::join::ParJoin; pub use crate::{ changeset::ChangeSet, + join::Join, storage::{ DenseVecStorage, FlaggedStorage, HashMapStorage, NullStorage, ReadStorage, Storage, Tracked, VecStorage, WriteStorage, diff --git a/src/world/world_ext.rs b/src/world/world_ext.rs index 8f8c33a40..a7a7e69e8 100644 --- a/src/world/world_ext.rs +++ b/src/world/world_ext.rs @@ -11,7 +11,8 @@ use crate::{ }; use shred::{Fetch, FetchMut, MetaTable, Read, Resource, SystemData, World}; -/// This trait provides some extension methods to make working with shred's [World] easier. +/// This trait provides some extension methods to make working with shred's +/// [World] easier. /// /// Many methods take `&self` which works because everything /// is stored with **interior mutability**. In case you violate @@ -21,8 +22,8 @@ use shred::{Fetch, FetchMut, MetaTable, Read, Resource, SystemData, World}; /// ## Difference between resources and components /// /// While components exist per [Entity], resources are like globals in the -/// `World`. Components are stored in component storages ([MaskedStorage]), which are resources -/// themselves. +/// `World`. Components are stored in component storages ([MaskedStorage]), +/// which are resources themselves. /// /// Everything that is `Any + Send + Sync` can be a resource. /// From 96161da23b686cb8d292399e2bc241070174f66e Mon Sep 17 00:00:00 2001 From: Thomas Schaller Date: Sun, 23 Jun 2019 18:32:16 +0200 Subject: [PATCH 07/27] Document and reexport public shrev dependency --- README.md | 1 + src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 17bd67b3f..9903513d0 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,7 @@ Please look into [the examples directory](examples) for more. | hibitset | [![hibitset](https://img.shields.io/crates/v/hibitset.svg)](https://crates.rs/crates/hibitset) | | rayon | [![rayon](https://img.shields.io/crates/v/rayon.svg)](https://crates.rs/crates/rayon) | | shred | [![shred](https://img.shields.io/crates/v/shred.svg)](https://crates.rs/crates/shred) | +| shrev | [![shrev](https://img.shields.io/crates/v/shrev.svg)](https://crates.rs/crates/shrev) | ## Contribution diff --git a/src/lib.rs b/src/lib.rs index b0aa1208a..62047d050 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -186,6 +186,7 @@ pub extern crate hibitset; pub extern crate shred; +pub extern crate shrev; extern crate crossbeam; #[macro_use] @@ -197,7 +198,6 @@ extern crate mopa; extern crate nonzero_signed; #[cfg(feature = "parallel")] extern crate rayon; -extern crate shrev; extern crate tuple_utils; #[cfg(feature = "uuid_entity")] pub extern crate uuid; From cc655009765f404275d036d642a4dececc801df1 Mon Sep 17 00:00:00 2001 From: Thomas Schaller Date: Sun, 23 Jun 2019 19:48:21 +0200 Subject: [PATCH 08/27] More reexports, bump shred to 0.9 * Reexport rayon * Reexport shred-derive macros * Reexport specs-derive macros --- Cargo.toml | 15 +++++++++------ examples/full.rs | 9 +++------ src/lib.rs | 7 +++++-- src/prelude.rs | 4 ++-- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 058bf0c5c..3ab0b006e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "specs" -version = "0.14.3" +version = "0.15.0" description = """ Specs is an Entity-Component-System library written in Rust. """ @@ -28,15 +28,15 @@ hashbrown = "0.5.0" hibitset = { version = "0.6.0", default-features = false } log = "0.4" mopa = "0.2" -shred = { version = "0.8.0", default-features = false } +shred = { version = "0.9.0", default-features = false } shrev = "1.0.0" -shred-derive = "0.6.0" tuple_utils = "0.3" -rayon = { version = "1.0.0", optional = true } nonzero_signed = "1.0.1" -uuid = { version = "0.7.4", optional = true, features = ["v4", "serde"] } +rayon = { version = "1.0.0", optional = true } serde = { version = "1.0", optional = true, features = ["serde_derive"] } +specs-derive = { version = "0.4.0", path = "specs-derive", optional = true } +uuid = { version = "0.7.4", optional = true, features = ["v4", "serde"] } [features] default = ["parallel"] @@ -46,8 +46,10 @@ uuid_entity = ["uuid", "serde"] stdweb = ["uuid/stdweb"] wasm-bindgen = ["uuid/wasm-bindgen"] +shred-derive = ["shred/shred-derive"] + [package.metadata.docs.rs] -features = ["parallel", "nightly", "uuid_entity"] +features = ["parallel", "saveload", "shred-derive", "specs-derive", "nightly", "uuid_entity"] [dev-dependencies] cgmath = { version = "0.17" } @@ -55,6 +57,7 @@ criterion = "0.2" ron = "0.5" rand = "0.6.1" serde_json = "1.0" +shred = { version = "0.9.0", features = ["shred-derive"] } specs-derive = { path = "specs-derive", version = "0.4.0" } [[example]] diff --git a/examples/full.rs b/examples/full.rs index 41a209c91..50489d38e 100644 --- a/examples/full.rs +++ b/examples/full.rs @@ -1,11 +1,8 @@ extern crate rayon; -extern crate shred; -#[macro_use] -extern crate shred_derive; extern crate specs; -use shred::ResourceId; -use specs::{prelude::*, storage::HashMapStorage, WorldExt}; +use specs::{prelude::*, storage::HashMapStorage}; + // -- Components -- // A component exists for 0..n // entities. @@ -174,7 +171,7 @@ impl<'a> System<'a> for JoinParallel { ); fn run(&mut self, (comp_bool, comp_int, mut comp_float): Self::SystemData) { - use rayon::prelude::*; + use specs::rayon::prelude::*; (&comp_bool, &comp_int, &mut comp_float) .par_join() // only iterate over entities with a `CompBool(true)` diff --git a/src/lib.rs b/src/lib.rs index 62047d050..8b2d46417 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -185,6 +185,8 @@ //! See the repository's examples directory for more examples. pub extern crate hibitset; +#[cfg(feature = "parallel")] +pub extern crate rayon; pub extern crate shred; pub extern crate shrev; @@ -196,8 +198,6 @@ extern crate hashbrown; extern crate log; extern crate mopa; extern crate nonzero_signed; -#[cfg(feature = "parallel")] -extern crate rayon; extern crate tuple_utils; #[cfg(feature = "uuid_entity")] pub extern crate uuid; @@ -227,6 +227,9 @@ pub use shrev::ReaderId; #[cfg(feature = "parallel")] pub use shred::AsyncDispatcher; +#[cfg(feature = "specs-derive")] +pub use specs_derive::{Component, ConvertSaveload}; + #[cfg(feature = "parallel")] pub use crate::join::ParJoin; pub use crate::{ diff --git a/src/prelude.rs b/src/prelude.rs index 8e329a471..250ed4e1a 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -7,8 +7,8 @@ pub use crate::join::Join; pub use crate::join::ParJoin; pub use hibitset::BitSet; pub use shred::{ - Accessor, Dispatcher, DispatcherBuilder, Read, ReadExpect, RunNow, StaticAccessor, System, - SystemData, World, Write, WriteExpect, + Accessor, Dispatcher, DispatcherBuilder, Read, ReadExpect, ResourceId, RunNow, StaticAccessor, + System, SystemData, World, Write, WriteExpect, }; pub use shrev::ReaderId; From 0a95736b84437d9fb8978f4db33a407ea997167d Mon Sep 17 00:00:00 2001 From: Thomas Schaller Date: Sun, 23 Jun 2019 19:50:42 +0200 Subject: [PATCH 09/27] Update CHANGELOG --- CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c600d37d2..17cd35ca3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,19 @@ +# 0.15.0 + +* Moved `World` to `shred`, added `WorldExt` trait for Specs functionality ([#550]) +* Implement `Join` on `BitSetLike` trait object ([#599]) +* Expose inner field of `AntiStorage` ([#603]) +* Remove `fnv` in favour of `hashbrown` ([#605]) +* Reexport `hibitset`, `rayon`, `shred` and `shrev` ([#605]) +* Reexport `shred_derive::SystemData` when `shred-derive` feature is enabled ([#605]) +* Reexport `specs_derive::{Component, ConvertSaveload}` when `specs-derive` feature is enabled +([#605]) + +[#550]: https://github.com/slide-rs/specs/pull/550 +[#599]: https://github.com/slide-rs/specs/pull/599 +[#603]: https://github.com/slide-rs/specs/pull/603 +[#605]: https://github.com/slide-rs/specs/pull/605 + # 0.14.2 * Add `Join`-able entries API to `Storage` ([#518]) From 5c02b760431d88f8f8629bbf173ee3f823f70008 Mon Sep 17 00:00:00 2001 From: Thomas Schaller Date: Sun, 23 Jun 2019 20:01:20 +0200 Subject: [PATCH 10/27] Remove all extern crate statements --- src/changeset.rs | 9 +++------ src/lib.rs | 14 -------------- src/prelude.rs | 4 ++-- src/saveload/marker.rs | 13 +++++-------- src/saveload/mod.rs | 2 +- src/saveload/uuid.rs | 1 + src/storage/mod.rs | 1 + src/storage/storages.rs | 1 + src/world/lazy.rs | 14 ++++++-------- 9 files changed, 20 insertions(+), 39 deletions(-) diff --git a/src/changeset.rs b/src/changeset.rs index ec920734f..2f749edf4 100644 --- a/src/changeset.rs +++ b/src/changeset.rs @@ -1,13 +1,10 @@ //! Provides a changeset that can be collected from an iterator. -use hibitset::BitSet; use std::{iter::FromIterator, ops::AddAssign}; -use crate::{ - join::Join, - storage::{DenseVecStorage, UnprotectedStorage}, - world::{Entity, Index}, -}; +use derivative::Derivative; + +use crate::{prelude::*, storage::UnprotectedStorage, world::Index}; /// Change set that can be collected from an iterator, and joined on for easy /// application to components. diff --git a/src/lib.rs b/src/lib.rs index 8b2d46417..e255b7dd7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -189,23 +189,9 @@ pub extern crate hibitset; pub extern crate rayon; pub extern crate shred; pub extern crate shrev; - -extern crate crossbeam; -#[macro_use] -extern crate derivative; -extern crate hashbrown; -#[macro_use] -extern crate log; -extern crate mopa; -extern crate nonzero_signed; -extern crate tuple_utils; #[cfg(feature = "uuid_entity")] pub extern crate uuid; -#[cfg(feature = "serde")] -#[macro_use] -extern crate serde; - #[cfg(feature = "serde")] pub mod saveload; diff --git a/src/prelude.rs b/src/prelude.rs index 250ed4e1a..eee349fd2 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -7,8 +7,8 @@ pub use crate::join::Join; pub use crate::join::ParJoin; pub use hibitset::BitSet; pub use shred::{ - Accessor, Dispatcher, DispatcherBuilder, Read, ReadExpect, ResourceId, RunNow, StaticAccessor, - System, SystemData, World, Write, WriteExpect, + Accessor, Dispatcher, DispatcherBuilder, Read, ReadExpect, Resource, ResourceId, RunNow, + StaticAccessor, System, SystemData, World, Write, WriteExpect, }; pub use shrev::ReaderId; diff --git a/src/saveload/marker.rs b/src/saveload/marker.rs index 1624cdf47..8abeefb6e 100644 --- a/src/saveload/marker.rs +++ b/src/saveload/marker.rs @@ -2,16 +2,13 @@ use std::{collections::HashMap, fmt::Debug, hash::Hash, marker::PhantomData}; +use derivative::Derivative; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; + use crate::{ - join::Join, - storage::{DenseVecStorage, ReadStorage, WriteStorage}, - world::{ - Component, EntitiesRes, Entity, EntityBuilder, EntityResBuilder, LazyBuilder, WorldExt, - }, + prelude::*, + world::{EntitiesRes, EntityResBuilder, LazyBuilder}, }; -use shred::Resource; - -use serde::{de::DeserializeOwned, ser::Serialize}; /// A common trait for `EntityBuilder` and `LazyBuilder` with a marker function, /// allowing either to be used. diff --git a/src/saveload/mod.rs b/src/saveload/mod.rs index 2f7f11571..b3b43526a 100644 --- a/src/saveload/mod.rs +++ b/src/saveload/mod.rs @@ -24,7 +24,7 @@ //! see the docs for the `Marker` trait. //! -use serde::{de::DeserializeOwned, Serialize}; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; use crate::{error::NoError, world::Entity}; diff --git a/src/saveload/uuid.rs b/src/saveload/uuid.rs index 901f91fda..7209ae2a2 100644 --- a/src/saveload/uuid.rs +++ b/src/saveload/uuid.rs @@ -1,5 +1,6 @@ use std::collections::HashMap; +use serde::{Deserialize, Serialize}; use uuid::Uuid; use crate::{ diff --git a/src/storage/mod.rs b/src/storage/mod.rs index c3ee392a2..245f9b77b 100644 --- a/src/storage/mod.rs +++ b/src/storage/mod.rs @@ -19,6 +19,7 @@ use std::{ ops::{Deref, DerefMut, Not}, }; +use derivative::Derivative; use hibitset::{BitSet, BitSetLike, BitSetNot}; use shred::{CastFrom, Fetch}; diff --git a/src/storage/storages.rs b/src/storage/storages.rs index 39574cf5a..e3793973e 100644 --- a/src/storage/storages.rs +++ b/src/storage/storages.rs @@ -2,6 +2,7 @@ use std::collections::BTreeMap; +use derivative::Derivative; use hashbrown::HashMap; use hibitset::BitSetLike; diff --git a/src/world/lazy.rs b/src/world/lazy.rs index 4848d37a5..1c408b548 100644 --- a/src/world/lazy.rs +++ b/src/world/lazy.rs @@ -1,9 +1,7 @@ -use crate::{ - storage::WriteStorage, - world::{Builder, Component, EntitiesRes, Entity}, -}; use crossbeam::queue::SegQueue; -use shred::{SystemData, World}; +use derivative::Derivative; + +use crate::{prelude::*, world::EntitiesRes}; struct Queue(SegQueue); @@ -38,7 +36,7 @@ impl<'a> Builder for LazyBuilder<'a> { self.lazy.exec(move |world| { let mut storage: WriteStorage = SystemData::fetch(world); if storage.insert(entity, component).is_err() { - warn!( + log::warn!( "Lazy insert of component failed because {:?} was dead.", entity ); @@ -147,7 +145,7 @@ impl LazyUpdate { self.exec(move |world| { let mut storage: WriteStorage = SystemData::fetch(world); if storage.insert(e, c).is_err() { - warn!("Lazy insert of component failed because {:?} was dead.", e); + log::warn!("Lazy insert of component failed because {:?} was dead.", e); } }); } @@ -187,7 +185,7 @@ impl LazyUpdate { let mut storage: WriteStorage = SystemData::fetch(world); for (e, c) in iter { if storage.insert(e, c).is_err() { - warn!("Lazy insert of component failed because {:?} was dead.", e); + log::warn!("Lazy insert of component failed because {:?} was dead.", e); } } }); From cf2dd7e0ac9ee317eb5c3d9829e1957dced378b4 Mon Sep 17 00:00:00 2001 From: Thomas Schaller Date: Sun, 23 Jun 2019 20:13:40 +0200 Subject: [PATCH 11/27] Update tutorials --- docs/tutorials/src/02_hello_world.md | 45 +++++++++++++++------------- docs/tutorials/src/03_dispatcher.md | 6 ++-- docs/tutorials/src/04_resources.md | 4 ++- docs/tutorials/src/06_system_data.md | 8 +++-- docs/tutorials/src/07_setup.md | 22 +++++++------- 5 files changed, 46 insertions(+), 39 deletions(-) diff --git a/docs/tutorials/src/02_hello_world.md b/docs/tutorials/src/02_hello_world.md index 6db9d0714..3f26d0106 100644 --- a/docs/tutorials/src/02_hello_world.md +++ b/docs/tutorials/src/02_hello_world.md @@ -2,18 +2,24 @@ ## Setting up -First of all, thanks for trying out `specs`. Let's -set it up first. Add the following line to your `Cargo.toml`: +First of all, thanks for trying out `specs`. +Before setting up the project, please make sure you're using the latest Rust version: -```toml -[dependencies] -specs = "0.14.0" +```bash +rustup update ``` -And add this to your crate root (`main.rs` or `lib.rs`): +Okay, now let's set up the project! -```rust,ignore -extern crate specs; +```bash +cargo new --bin my_game +``` + +Add the following line to your `Cargo.toml`: + +```toml +[dependencies] +specs = "0.14.0" ``` ## Components @@ -48,21 +54,16 @@ These will be our two component types. Optionally, the `specs-derive` crate provides a convenient custom `#[derive]` you can use to define component types more succinctly. -But first, you will need to add specs-derive to your crate +But first, you will need to enable the `specs-derive` feature: ```toml [dependencies] -specs = "0.14.0" -specs-derive = "0.4.0" +specs = { version = "0.15.0", features = ["specs-derive"] } ``` -Now you can use this: +Now you can do this: ```rust,ignore -extern crate specs; -#[macro_use] -extern crate specs_derive; - use specs::{Component, VecStorage}; #[derive(Component, Debug)] @@ -91,7 +92,7 @@ need to create a world in which to store all of our components. ## The `World` ```rust,ignore -use specs::{World, Builder}; +use specs::{World, WorldExt, Builder}; let mut world = World::new(); world.register::(); @@ -106,6 +107,10 @@ let ball = world.create_entity().with(Position { x: 4.0, y: 7.0 }).build(); Now you have an `Entity`, associated with a position. +> **Note:** `World` is a struct coming from `shred`, an important dependency of Specs. +> Whenever you call functions specific to Specs, you will need to import the `WorldExt` +> trait. + So far this is pretty boring. We just have some data, but we don't do anything with it. Let's change that! @@ -169,7 +174,7 @@ them. To execute the system, you can use `RunNow` like this: use specs::RunNow; let mut hello_world = HelloWorld; -hello_world.run_now(&world.res); +hello_world.run_now(&world); world.maintain(); ``` @@ -182,7 +187,7 @@ will record the changes in its internal data structure. Here the complete example of this chapter: ```rust,ignore -use specs::{Builder, Component, ReadStorage, System, VecStorage, World, RunNow}; +use specs::{Builder, Component, ReadStorage, System, VecStorage, World, WorldExt, RunNow}; #[derive(Debug)] struct Position { @@ -226,7 +231,7 @@ fn main() { world.create_entity().with(Position { x: 4.0, y: 7.0 }).build(); let mut hello_world = HelloWorld; - hello_world.run_now(&world.res); + hello_world.run_now(&world); world.maintain(); } ``` diff --git a/docs/tutorials/src/03_dispatcher.md b/docs/tutorials/src/03_dispatcher.md index 381b0d4c1..d948418e1 100644 --- a/docs/tutorials/src/03_dispatcher.md +++ b/docs/tutorials/src/03_dispatcher.md @@ -92,7 +92,7 @@ be executed after the dependency has finished. The final `HelloWorld` system pri Now to execute all the systems, just do ```rust,ignore -dispatcher.dispatch(&mut world.res); +dispatcher.dispatch(&mut world); ``` ## Full example code @@ -101,7 +101,7 @@ Here the code for this chapter: ```rust,ignore use specs::{Builder, Component, DispatcherBuilder, ReadStorage, - System, VecStorage, World, WriteStorage}; + System, VecStorage, World, WorldExt, WriteStorage}; #[derive(Debug)] struct Position { @@ -172,7 +172,7 @@ fn main() { .with(HelloWorld, "hello_updated", &["update_pos"]) .build(); - dispatcher.dispatch(&mut world.res); + dispatcher.dispatch(&mut world); world.maintain(); } ``` diff --git a/docs/tutorials/src/04_resources.md b/docs/tutorials/src/04_resources.md index 98b397588..c4fbd163f 100644 --- a/docs/tutorials/src/04_resources.md +++ b/docs/tutorials/src/04_resources.md @@ -21,12 +21,14 @@ struct DeltaTime(f32); Adding this resource to our world is pretty easy: ```rust,ignore -world.add_resource(DeltaTime(0.05)); // Let's use some start value +world.insert(DeltaTime(0.05)); // Let's use some start value ``` To update the delta time, just use ```rust,ignore +use specs::WorldExt; + let mut delta = world.write_resource::(); *delta = DeltaTime(0.04); ``` diff --git a/docs/tutorials/src/06_system_data.md b/docs/tutorials/src/06_system_data.md index 5ce05cb62..7e6228a78 100644 --- a/docs/tutorials/src/06_system_data.md +++ b/docs/tutorials/src/06_system_data.md @@ -91,9 +91,6 @@ more, you could even nest these tuples. However, at some point it becomes hard t That's why you can also create your own `SystemData` bundle using a struct: ```rust,ignore -extern crate shred; -#[macro_use] -extern crate shred_derive; extern crate specs; use specs::prelude::*; @@ -109,3 +106,8 @@ pub struct MySystemData<'a> { } ``` +Make sure to enable the `shred-derive` feature in your `Cargo.toml`: + +```toml +specs = { version = "*", features = ["shred-derive"] } +``` diff --git a/docs/tutorials/src/07_setup.md b/docs/tutorials/src/07_setup.md index a1fbb26c9..0d6241de0 100644 --- a/docs/tutorials/src/07_setup.md +++ b/docs/tutorials/src/07_setup.md @@ -26,6 +26,7 @@ through all `System`s in the graph, and call `setup` on each. Let's say you began by registering Components and Resources first: ```rust,ignore +use specs::prelude::*; struct Gravity; @@ -56,7 +57,7 @@ fn main() { .with(SimulationSystem, "simulation", &[]) .build(); - dispatcher.dispatch(&mut world.res); + dispatcher.dispatch(&mut world); world.maintain(); } @@ -71,13 +72,13 @@ fn main() { .with(SimulationSystem, "simulation", &[]) .build(); - dispatcher.setup(&mut world.res); + dispatcher.setup(&mut world); for _ in 0..5 { world.create_entity().with(Velocity).build(); } - dispatcher.dispatch(&mut world.res); + dispatcher.dispatch(&mut world); world.maintain(); } @@ -115,7 +116,7 @@ to create the `EventChannel` themselves and add it manually to the `World`. We can do better! ```rust,ignore -use specs::prelude::Resources; +use specs::prelude::*; #[derive(Default)] struct Sys { @@ -131,10 +132,9 @@ impl<'a> System<'a> for Sys { } } - fn setup(&mut self, res: &mut Resources) { - use specs::prelude::SystemData; - Self::SystemData::setup(res); - self.reader = Some(res.fetch_mut::>().register_reader()); + fn setup(&mut self, world: &mut World) { + Self::SystemData::setup(world); + self.reader = Some(world.fetch_mut::>().register_reader()); } } ``` @@ -142,10 +142,8 @@ impl<'a> System<'a> for Sys { This is much better; we can now use `setup` to fully initialize `Sys` without requiring our users to create and add resources manually to `World`! -**If we override the `setup` function on a `System`, it is vitally important that we -remember to add `Self::SystemData::setup(res);`, or setup will not be performed for -the `System`s `SystemData`.** This could cause panics during setup or during -the first dispatch. +**If we override the `setup` function on a `System`, it is vitally important that we remember to add `Self::SystemData::setup(world);`, or setup will not be performed for the `System`s `SystemData`.** +This could cause panics during setup or during the first dispatch. ## Setting up in bulk From 1b6424c08c42bad0ead3ffeac8cf25b4823ebabb Mon Sep 17 00:00:00 2001 From: Thomas Schaller Date: Fri, 28 Jun 2019 09:27:11 +0200 Subject: [PATCH 12/27] Bump rayon to 1.1 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 3ab0b006e..b1c664fe2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,7 @@ shrev = "1.0.0" tuple_utils = "0.3" nonzero_signed = "1.0.1" -rayon = { version = "1.0.0", optional = true } +rayon = { version = "1.1.0", optional = true } serde = { version = "1.0", optional = true, features = ["serde_derive"] } specs-derive = { version = "0.4.0", path = "specs-derive", optional = true } uuid = { version = "0.7.4", optional = true, features = ["v4", "serde"] } From c34bdac1031a50dbb86815e96d1ada0d4fe12465 Mon Sep 17 00:00:00 2001 From: Thomas Schaller Date: Fri, 28 Jun 2019 09:33:26 +0200 Subject: [PATCH 13/27] Change crossbeam to crossbeam-queue to reduce deps --- Cargo.toml | 2 +- src/world/lazy.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b1c664fe2..64b8820d1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ autobenches = false travis-ci = { repository = "slide-rs/specs" } [dependencies] -crossbeam = "0.7.1" +crossbeam-queue = "0.1" derivative = "1" hashbrown = "0.5.0" hibitset = { version = "0.6.0", default-features = false } diff --git a/src/world/lazy.rs b/src/world/lazy.rs index 1c408b548..7edf2a0d7 100644 --- a/src/world/lazy.rs +++ b/src/world/lazy.rs @@ -1,4 +1,4 @@ -use crossbeam::queue::SegQueue; +use crossbeam_queue::SegQueue; use derivative::Derivative; use crate::{prelude::*, world::EntitiesRes}; From 0f03eb23bd7f0f53c5853b0af3e4cefed2e62bb8 Mon Sep 17 00:00:00 2001 From: Thomas Schaller Date: Fri, 28 Jun 2019 09:35:50 +0200 Subject: [PATCH 14/27] Skip building dependency docs if failure occurs --- scripts/build-netlify.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/build-netlify.sh b/scripts/build-netlify.sh index f11b7b438..a159b9718 100755 --- a/scripts/build-netlify.sh +++ b/scripts/build-netlify.sh @@ -38,9 +38,11 @@ build_book reference build_book tutorials # Build API docs +FEATURES="parallel saveload shred-derive specs-derive nightly uuid_entity" + echo "Building Rust API docs..." cd "${WORKING_DIR}" -cargo doc --all --features "serde" +cargo doc --all --features "${FEATURES}" || cargo doc --all --features "${FEATURES}" --no-deps cp -R target/doc "${WORKING_DIR}/public/docs/api" echo "Done!" From 106a9744e9d49e4b4eb78e4e5e6762705ba90c84 Mon Sep 17 00:00:00 2001 From: Thomas Schaller Date: Fri, 28 Jun 2019 09:46:19 +0200 Subject: [PATCH 15/27] Bump patch versions --- Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 64b8820d1..41970b038 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,10 +25,10 @@ travis-ci = { repository = "slide-rs/specs" } crossbeam-queue = "0.1" derivative = "1" hashbrown = "0.5.0" -hibitset = { version = "0.6.0", default-features = false } +hibitset = { version = "0.6.1", default-features = false } log = "0.4" mopa = "0.2" -shred = { version = "0.9.0", default-features = false } +shred = { version = "0.9.1", default-features = false } shrev = "1.0.0" tuple_utils = "0.3" nonzero_signed = "1.0.1" From 103835793ece748cf8a70b292e92d41c876a6213 Mon Sep 17 00:00:00 2001 From: Thomas Schaller Date: Fri, 28 Jun 2019 09:58:38 +0200 Subject: [PATCH 16/27] Use "serde" feature ("saveload" does not exist) --- Cargo.toml | 2 +- scripts/build-netlify.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 41970b038..18d60d8ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,7 +49,7 @@ wasm-bindgen = ["uuid/wasm-bindgen"] shred-derive = ["shred/shred-derive"] [package.metadata.docs.rs] -features = ["parallel", "saveload", "shred-derive", "specs-derive", "nightly", "uuid_entity"] +features = ["parallel", "serde", "shred-derive", "specs-derive", "nightly", "uuid_entity"] [dev-dependencies] cgmath = { version = "0.17" } diff --git a/scripts/build-netlify.sh b/scripts/build-netlify.sh index a159b9718..39a2a5280 100755 --- a/scripts/build-netlify.sh +++ b/scripts/build-netlify.sh @@ -38,7 +38,7 @@ build_book reference build_book tutorials # Build API docs -FEATURES="parallel saveload shred-derive specs-derive nightly uuid_entity" +FEATURES="parallel serde shred-derive specs-derive nightly uuid_entity" echo "Building Rust API docs..." cd "${WORKING_DIR}" From 38ec503fd50d035e14ed9bc4488d48adc74f78cd Mon Sep 17 00:00:00 2001 From: Thomas Schaller Date: Fri, 28 Jun 2019 09:59:38 +0200 Subject: [PATCH 17/27] Fix typo --- src/world/world_ext.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/world/world_ext.rs b/src/world/world_ext.rs index a7a7e69e8..658e08479 100644 --- a/src/world/world_ext.rs +++ b/src/world/world_ext.rs @@ -144,7 +144,7 @@ pub trait WorldExt { /// /// If the resource already exists it will be overwritten. /// - /// **DEPREACTED:** Use [World::insert] instead. + /// **DEPRECATED:** Use [World::insert] instead. /// /// ## Examples /// From a7592fce51c33e0fb14b737c4026e31ccbb42154 Mon Sep 17 00:00:00 2001 From: Thomas Schaller Date: Fri, 28 Jun 2019 10:00:17 +0200 Subject: [PATCH 18/27] Update rustfmt options --- .rustfmt.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.rustfmt.toml b/.rustfmt.toml index d092e7eae..b6d4d4369 100644 --- a/.rustfmt.toml +++ b/.rustfmt.toml @@ -3,7 +3,7 @@ merge_imports = true reorder_impl_items = true use_field_init_shorthand = true use_try_shorthand = true -format_doc_comments = true +format_code_in_doc_comments = true wrap_comments = true edition = "2018" version = "Two" From 24259bd466ed3164769f24ca1be48ba030e9991d Mon Sep 17 00:00:00 2001 From: Thomas Schaller Date: Fri, 28 Jun 2019 11:16:35 +0200 Subject: [PATCH 19/27] Remove dyn, bump rand, tweak docs --- Cargo.toml | 2 +- src/error.rs | 8 ++++---- src/lib.rs | 12 +++++++----- src/storage/data.rs | 4 ++-- src/storage/mod.rs | 2 +- src/world/lazy.rs | 2 +- src/world/world_ext.rs | 10 +++++----- 7 files changed, 21 insertions(+), 19 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 18d60d8ad..49dfecd56 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,7 +55,7 @@ features = ["parallel", "serde", "shred-derive", "specs-derive", "nightly", "uui cgmath = { version = "0.17" } criterion = "0.2" ron = "0.5" -rand = "0.6.1" +rand = "0.7" serde_json = "1.0" shred = { version = "0.9.0", features = ["shred-derive"] } specs-derive = { path = "specs-derive", version = "0.4.0" } diff --git a/src/error.rs b/src/error.rs index 67a4d715e..4c0c7a486 100644 --- a/src/error.rs +++ b/src/error.rs @@ -12,7 +12,7 @@ use std::{ use crate::world::{Entity, Generation}; /// A boxed error implementing `Debug`, `Display` and `Error`. -pub struct BoxedErr(pub Box); +pub struct BoxedErr(pub Box); impl BoxedErr { /// Creates a new boxed error. @@ -24,8 +24,8 @@ impl BoxedErr { } } -impl AsRef for BoxedErr { - fn as_ref(&self) -> &(StdError + 'static) { +impl AsRef for BoxedErr { + fn as_ref(&self) -> &(dyn StdError + 'static) { self.0.as_ref() } } @@ -94,7 +94,7 @@ impl StdError for Error { "A Specs error" } - fn cause(&self) -> Option<&StdError> { + fn cause(&self) -> Option<&dyn StdError> { let e = match *self { Error::Custom(ref e) => e.as_ref(), Error::WrongGeneration(ref e) => e, diff --git a/src/lib.rs b/src/lib.rs index e255b7dd7..54b4c3bf3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,18 +40,20 @@ //! } //! ``` //! -//! Or alternatively, if you import the `specs-derive` crate, you can use a -//! custom `#[derive]` macro: +//! Or alternatively, if you enable the `specs-derive` feature, you can use a custom `#[derive]` +//! macro: //! //! ```rust //! # extern crate specs; -//! #[macro_use] -//! extern crate specs_derive; +//! # extern crate specs_derive; +//! # #[cfg(not(feature = "specs-derive"))] use specs_derive::Component; //! +//! # #[cfg(feature = "specs-derive")] +//! use specs::Component; //! use specs::prelude::*; //! //! #[derive(Component)] -//! #[storage(VecStorage)] +//! #[storage(VecStorage)] // default is `DenseVecStorage` //! struct MyComp; //! # fn main() {} //! ``` diff --git a/src/storage/data.rs b/src/storage/data.rs index 340992705..66ae8e4fd 100644 --- a/src/storage/data.rs +++ b/src/storage/data.rs @@ -127,7 +127,7 @@ where fn setup(res: &mut World) { res.entry::>() .or_insert_with(|| MaskedStorage::new(::unwrap_default())); - res.fetch_mut::>() + res.fetch_mut::>() .register(&*res.fetch::>()); } @@ -218,7 +218,7 @@ where fn setup(res: &mut World) { res.entry::>() .or_insert_with(|| MaskedStorage::new(::unwrap_default())); - res.fetch_mut::>() + res.fetch_mut::>() .register(&*res.fetch::>()); } diff --git a/src/storage/mod.rs b/src/storage/mod.rs index 245f9b77b..6155b4e56 100644 --- a/src/storage/mod.rs +++ b/src/storage/mod.rs @@ -77,7 +77,7 @@ pub trait AnyStorage { fn drop(&mut self, entities: &[Entity]); } -unsafe impl CastFrom for AnyStorage +unsafe impl CastFrom for dyn AnyStorage where T: AnyStorage + 'static, { diff --git a/src/world/lazy.rs b/src/world/lazy.rs index 7edf2a0d7..89ebaff08 100644 --- a/src/world/lazy.rs +++ b/src/world/lazy.rs @@ -84,7 +84,7 @@ where #[derivative(Default)] pub struct LazyUpdate { #[derivative(Default(value = "Some(Default::default())"))] - queue: Option>>, + queue: Option>>, } impl LazyUpdate { diff --git a/src/world/world_ext.rs b/src/world/world_ext.rs index 658e08479..5a40afb0b 100644 --- a/src/world/world_ext.rs +++ b/src/world/world_ext.rs @@ -295,7 +295,7 @@ impl WorldExt for World { fn new() -> Self { let mut world = World::default(); world.insert(EntitiesRes::default()); - world.insert(MetaTable::::default()); + world.insert(MetaTable::::default()); world.insert(LazyUpdate::default()); world @@ -315,9 +315,9 @@ impl WorldExt for World { { self.entry() .or_insert_with(move || MaskedStorage::::new(storage())); - self.entry::>() + self.entry::>() .or_insert_with(Default::default); - self.fetch_mut::>() + self.fetch_mut::>() .register(&*self.fetch::>()); } @@ -408,9 +408,9 @@ impl WorldExt for World { } fn delete_components(&mut self, delete: &[Entity]) { - self.entry::>() + self.entry::>() .or_insert_with(Default::default); - for storage in self.fetch_mut::>().iter_mut(&self) { + for storage in self.fetch_mut::>().iter_mut(&self) { storage.drop(delete); } } From a4df49431a8aa3d32ada518cdf9aa722ad1de89a Mon Sep 17 00:00:00 2001 From: Thomas Schaller Date: Fri, 28 Jun 2019 11:20:08 +0200 Subject: [PATCH 20/27] Clippy fixes --- src/saveload/uuid.rs | 12 ++++++------ src/storage/entry.rs | 2 +- src/storage/mod.rs | 3 +-- src/world/entity.rs | 10 +++++----- src/world/world_ext.rs | 2 +- 5 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/saveload/uuid.rs b/src/saveload/uuid.rs index 7209ae2a2..0860ec212 100644 --- a/src/saveload/uuid.rs +++ b/src/saveload/uuid.rs @@ -21,11 +21,11 @@ impl Component for UuidMarker { } impl Marker for UuidMarker { - type Allocator = UuidMarkerAllocator; type Identifier = Uuid; + type Allocator = UuidMarkerAllocator; fn id(&self) -> Uuid { - self.uuid().clone() + self.uuid() } } @@ -42,8 +42,8 @@ impl UuidMarker { } /// Get the current uuid. - pub fn uuid(&self) -> &Uuid { - &self.uuid + pub fn uuid(&self) -> Uuid { + self.uuid } } @@ -75,7 +75,7 @@ impl MarkerAllocator for UuidMarkerAllocator { } else { UuidMarker::new_random() }; - self.mapping.insert(marker.uuid().clone(), entity); + self.mapping.insert(marker.uuid(), entity); marker } @@ -88,7 +88,7 @@ impl MarkerAllocator for UuidMarkerAllocator { // FIXME: may be too slow self.mapping = (entities, storage) .join() - .map(|(e, m)| (m.uuid().clone(), e)) + .map(|(e, m)| (m.uuid(), e)) .collect(); } } diff --git a/src/storage/entry.rs b/src/storage/entry.rs index e90aee428..c7bc46eac 100644 --- a/src/storage/entry.rs +++ b/src/storage/entry.rs @@ -51,7 +51,7 @@ where .entities .alloc .generation(e.id()) - .unwrap_or(Generation::one()); + .unwrap_or_else(Generation::one); Err(WrongGeneration { action: "attempting to get an entry to a storage", actual_gen: gen, diff --git a/src/storage/mod.rs b/src/storage/mod.rs index 6155b4e56..a720820f6 100644 --- a/src/storage/mod.rs +++ b/src/storage/mod.rs @@ -59,8 +59,7 @@ impl<'a> Join for AntiStorage<'a> { } // SAFETY: No invariants to meet and no unsafe code. - unsafe fn get(_: &mut (), _: Index) -> () { - () + unsafe fn get(_: &mut (), _: Index) { } } diff --git a/src/world/entity.rs b/src/world/entity.rs index 7a8cd9be8..76d9abae1 100644 --- a/src/world/entity.rs +++ b/src/world/entity.rs @@ -102,7 +102,7 @@ impl Allocator { action: "delete", actual_gen: self.generations[e.id() as usize] .0 - .unwrap_or(Generation::one()), + .unwrap_or_else(Generation::one), entity: e, }) } @@ -112,7 +112,7 @@ impl Allocator { e.gen() == match self.generations.get(e.id() as usize) { Some(g) if !g.is_alive() && self.raised.contains(e.id()) => g.raised(), - Some(g) => g.0.unwrap_or(Generation::one()), + Some(g) => g.0.unwrap_or_else(Generation::one), None => Generation::one(), } } @@ -129,7 +129,7 @@ impl Allocator { pub fn entity(&self, id: Index) -> Entity { let gen = match self.generations.get(id as usize) { Some(g) if !g.is_alive() && self.raised.contains(id) => g.raised(), - Some(g) => g.0.unwrap_or(Generation::one()), + Some(g) => g.0.unwrap_or_else(Generation::one), None => Generation::one(), }; @@ -146,7 +146,7 @@ impl Allocator { let gen = self .generation(id) .map(|gen| if gen.is_alive() { gen } else { gen.raised() }) - .unwrap_or(Generation::one()); + .unwrap_or_else(Generation::one); Entity(id, gen) } @@ -327,7 +327,7 @@ impl<'a> Join for &'a EntitiesRes { .alloc .generation(idx) .map(|gen| if gen.is_alive() { gen } else { gen.raised() }) - .unwrap_or(Generation::one()); + .unwrap_or_else(Generation::one); Entity(idx, gen) } } diff --git a/src/world/world_ext.rs b/src/world/world_ext.rs index 5a40afb0b..fac60eb30 100644 --- a/src/world/world_ext.rs +++ b/src/world/world_ext.rs @@ -157,7 +157,7 @@ pub trait WorldExt { /// world.insert(timer); /// world.insert(server_con); /// ``` - #[deprecated(since = "0.15", note = "use `World::insert` instead")] + #[deprecated(since = "0.15.0", note = "use `World::insert` instead")] fn add_resource(&mut self, res: T); /// Fetches a component storage for reading. From b7368788fc662dcfec601b53d82057766eb80b2b Mon Sep 17 00:00:00 2001 From: Thomas Schaller Date: Fri, 28 Jun 2019 11:20:18 +0200 Subject: [PATCH 21/27] Formatting --- src/lib.rs | 7 +++---- src/saveload/uuid.rs | 2 +- src/storage/mod.rs | 3 +-- src/world/world_ext.rs | 5 ++++- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 54b4c3bf3..b27e6113d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,8 +40,8 @@ //! } //! ``` //! -//! Or alternatively, if you enable the `specs-derive` feature, you can use a custom `#[derive]` -//! macro: +//! Or alternatively, if you enable the `specs-derive` feature, you can use a +//! custom `#[derive]` macro: //! //! ```rust //! # extern crate specs; @@ -49,8 +49,7 @@ //! # #[cfg(not(feature = "specs-derive"))] use specs_derive::Component; //! //! # #[cfg(feature = "specs-derive")] -//! use specs::Component; -//! use specs::prelude::*; +//! use specs::{prelude::*, Component}; //! //! #[derive(Component)] //! #[storage(VecStorage)] // default is `DenseVecStorage` diff --git a/src/saveload/uuid.rs b/src/saveload/uuid.rs index 0860ec212..9dc0432b6 100644 --- a/src/saveload/uuid.rs +++ b/src/saveload/uuid.rs @@ -21,8 +21,8 @@ impl Component for UuidMarker { } impl Marker for UuidMarker { - type Identifier = Uuid; type Allocator = UuidMarkerAllocator; + type Identifier = Uuid; fn id(&self) -> Uuid { self.uuid() diff --git a/src/storage/mod.rs b/src/storage/mod.rs index a720820f6..d6ccc2887 100644 --- a/src/storage/mod.rs +++ b/src/storage/mod.rs @@ -59,8 +59,7 @@ impl<'a> Join for AntiStorage<'a> { } // SAFETY: No invariants to meet and no unsafe code. - unsafe fn get(_: &mut (), _: Index) { - } + unsafe fn get(_: &mut (), _: Index) {} } // SAFETY: Since `get` does not do any memory access, this is safe to implement. diff --git a/src/world/world_ext.rs b/src/world/world_ext.rs index fac60eb30..175e4021a 100644 --- a/src/world/world_ext.rs +++ b/src/world/world_ext.rs @@ -410,7 +410,10 @@ impl WorldExt for World { fn delete_components(&mut self, delete: &[Entity]) { self.entry::>() .or_insert_with(Default::default); - for storage in self.fetch_mut::>().iter_mut(&self) { + for storage in self + .fetch_mut::>() + .iter_mut(&self) + { storage.drop(delete); } } From 1e24ea4400d63de762420a043317624ebe8827b6 Mon Sep 17 00:00:00 2001 From: Thomas Schaller Date: Fri, 28 Jun 2019 11:23:42 +0200 Subject: [PATCH 22/27] Fix CHANGELOG --- CHANGELOG.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 17cd35ca3..a15a2eef8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,18 +1,20 @@ # 0.15.0 * Moved `World` to `shred`, added `WorldExt` trait for Specs functionality ([#550]) +* Add `UuidMarker` for UUID <-> `Entity` mappings ([#584]) * Implement `Join` on `BitSetLike` trait object ([#599]) * Expose inner field of `AntiStorage` ([#603]) -* Remove `fnv` in favour of `hashbrown` ([#605]) -* Reexport `hibitset`, `rayon`, `shred` and `shrev` ([#605]) -* Reexport `shred_derive::SystemData` when `shred-derive` feature is enabled ([#605]) +* Remove `fnv` in favour of `hashbrown` ([#606]) +* Reexport `hibitset`, `rayon`, `shred` and `shrev` ([#606]) +* Reexport `shred_derive::SystemData` when `shred-derive` feature is enabled ([#606]) * Reexport `specs_derive::{Component, ConvertSaveload}` when `specs-derive` feature is enabled -([#605]) +([#606]) [#550]: https://github.com/slide-rs/specs/pull/550 +[#584]: https://github.com/slide-rs/specs/pull/584 [#599]: https://github.com/slide-rs/specs/pull/599 [#603]: https://github.com/slide-rs/specs/pull/603 -[#605]: https://github.com/slide-rs/specs/pull/605 +[#606]: https://github.com/slide-rs/specs/pull/606 # 0.14.2 From 99e35149eff99993f20ef3ca67decdb843a1db85 Mon Sep 17 00:00:00 2001 From: Thomas Schaller Date: Fri, 28 Jun 2019 11:30:26 +0200 Subject: [PATCH 23/27] Fix doc code example in lib.rs --- src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib.rs b/src/lib.rs index b27e6113d..f1cf1da4b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -47,6 +47,7 @@ //! # extern crate specs; //! # extern crate specs_derive; //! # #[cfg(not(feature = "specs-derive"))] use specs_derive::Component; +//! # #[cfg(not(feature = "specs-derive"))] use specs::prelude::*; //! //! # #[cfg(feature = "specs-derive")] //! use specs::{prelude::*, Component}; From 6671a7c207665e8987b3168abcf6af8a2b46819c Mon Sep 17 00:00:00 2001 From: Thomas Schaller Date: Fri, 28 Jun 2019 11:51:39 +0200 Subject: [PATCH 24/27] Add PartialEq to ComponentEvent --- src/storage/track.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/storage/track.rs b/src/storage/track.rs index 2db97edd2..6f623b7a8 100644 --- a/src/storage/track.rs +++ b/src/storage/track.rs @@ -17,7 +17,7 @@ pub trait Tracked { fn channel_mut(&mut self) -> &mut EventChannel; } -#[derive(Debug, Copy, Clone)] +#[derive(Clone, Copy, Debug, Eq, PartialEq)] /// Component storage events received from a `FlaggedStorage` or any storage /// that implements `Tracked`. pub enum ComponentEvent { From 0c1f3aaa45ca344baed9dbb36f5e2577e75e7e34 Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Sat, 29 Jun 2019 09:33:11 +1200 Subject: [PATCH 25/27] Changed `world.res` to `world` in `README.md`. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9903513d0..147308fc6 100644 --- a/README.md +++ b/README.md @@ -105,10 +105,10 @@ fn main() { let mut dispatcher = DispatcherBuilder::new().with(SysA, "sys_a", &[]).build(); // This will call the `setup` function of every system. // In this example this has no effect since we already registered our components. - dispatcher.setup(&mut world.res); + dispatcher.setup(&mut world); // This dispatches all the systems in parallel (but blocking). - dispatcher.dispatch(&mut world.res); + dispatcher.dispatch(&mut world); } ``` From 8cde3394d695bffa094a31ed9dd3d939971a80f3 Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Sat, 29 Jun 2019 09:33:42 +1200 Subject: [PATCH 26/27] Use `0.15.0` in `02_hello_world.md`. --- docs/tutorials/src/02_hello_world.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/tutorials/src/02_hello_world.md b/docs/tutorials/src/02_hello_world.md index 3f26d0106..3f927f63a 100644 --- a/docs/tutorials/src/02_hello_world.md +++ b/docs/tutorials/src/02_hello_world.md @@ -13,13 +13,13 @@ Okay, now let's set up the project! ```bash cargo new --bin my_game -``` - +``` + Add the following line to your `Cargo.toml`: ```toml [dependencies] -specs = "0.14.0" +specs = "0.15.0" ``` ## Components @@ -52,7 +52,7 @@ impl Component for Velocity { These will be our two component types. Optionally, the `specs-derive` crate provides a convenient custom `#[derive]` you can use to define component types -more succinctly. +more succinctly. But first, you will need to enable the `specs-derive` feature: From 20d134bad1d62c81bf762e0e9985fb820029f02c Mon Sep 17 00:00:00 2001 From: Azriel Hoh Date: Sat, 29 Jun 2019 10:36:01 +1200 Subject: [PATCH 27/27] Use `world::insert` instead of `world::add_resource` in tutorials. --- CONTRIBUTING.md | 8 ++++---- docs/tutorials/src/04_resources.md | 2 +- docs/tutorials/src/07_setup.md | 4 ++-- docs/tutorials/src/10_rendering.md | 2 +- docs/tutorials/src/13_saveload.md | 6 +++--- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9d6a8e13a..992f731a5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -54,14 +54,14 @@ Number 1 is served by [`shred`](https://github.com/slide-rs/shred); it provides * `System`; this is the central interface for defining logic * `Dispatcher` and `DispatcherBuilder` - these are responsible for building a plan for how to run systems - (in parallel & sequentially) + (in parallel & sequentially) Additionally, `shred` also provides the central piece for number 2: -* `Resources`; everything that a `System` can access is stored inside +* `World`; everything that a `System` can access is stored inside. -Specs itself defines component storages (which are also stored inside the `Resources`). -For those, [`hibitset`](https://github.com/slide-rs/hibitset/) is used to +Specs itself defines component storages (which are also stored inside the `World`). +For those, [`hibitset`](https://github.com/slide-rs/hibitset/) is used to: * store the indices (= entity ids) with an existing component * allow efficient joining over sparse component storages diff --git a/docs/tutorials/src/04_resources.md b/docs/tutorials/src/04_resources.md index c4fbd163f..9b6a1def6 100644 --- a/docs/tutorials/src/04_resources.md +++ b/docs/tutorials/src/04_resources.md @@ -67,7 +67,7 @@ impl<'a> System<'a> for UpdatePos { ``` Note that all resources that a system accesses must be registered with -`world.add_resource(resource)` before that system is run, or you will get a +`world.insert(resource)` before that system is run, or you will get a panic. If the resource has a `Default` implementation, this step is usually done during `setup`, but again we will come back to this in a later chapter. diff --git a/docs/tutorials/src/07_setup.md b/docs/tutorials/src/07_setup.md index 0d6241de0..1bdc38a55 100644 --- a/docs/tutorials/src/07_setup.md +++ b/docs/tutorials/src/07_setup.md @@ -3,7 +3,7 @@ So far for all our component storages and resources, we've been adding them to the `World` manually. In Specs, this is not required if you use `setup`. This is a manually invoked stage that goes through `SystemData` -and calls `register`, `add_resource`, etc. for all (with some exceptions) +and calls `register`, `insert`, etc. for all (with some exceptions) components and resources found. The `setup` function can be found in the following locations: @@ -46,7 +46,7 @@ impl<'a> System<'a> for SimulationSystem { fn main() { let mut world = World::new(); - world.add_resource(Gravity); + world.insert(Gravity); world.register::(); for _ in 0..5 { diff --git a/docs/tutorials/src/10_rendering.md b/docs/tutorials/src/10_rendering.md index 84d35a471..4db8aae9a 100644 --- a/docs/tutorials/src/10_rendering.md +++ b/docs/tutorials/src/10_rendering.md @@ -37,7 +37,7 @@ This is what your code could look like: ```rust,ignore struct ResizeEvents(Vec<(u32, u32)>); -world.add_resource(ResizeEvents(Vec::new())); +world.insert(ResizeEvents(Vec::new())); while let Some(event) = window.poll_event() { match event { diff --git a/docs/tutorials/src/13_saveload.md b/docs/tutorials/src/13_saveload.md index 6604ba656..d68d34aab 100644 --- a/docs/tutorials/src/13_saveload.md +++ b/docs/tutorials/src/13_saveload.md @@ -28,10 +28,10 @@ fn main() { let mut world = World::new(); world.register::>(); - world.add_resource(SimpleMarkerAllocator::::default()); + world.insert(SimpleMarkerAllocator::::default()); world.register::>(); - world.add_resource(SimpleMarkerAllocator::::default()); + world.insert(SimpleMarkerAllocator::::default()); world .create_entity() @@ -96,7 +96,7 @@ fn main() { let mut world = World::new(); world.register::(); - world.add_resource(MyMarkerAllocator::default()); + world.insert(MyMarkerAllocator::default()); world .create_entity()