From ddce22b61429036400c64ce20f4264cf82813a13 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 27 Apr 2022 19:08:11 +0000 Subject: [PATCH] Decouple some dependencies (#3886) # Objective Reduce from scratch build time. ## Solution Reduce the size of the critical path by removing dependencies between crates where not necessary. For `cargo check --no-default-features` this reduced build time from ~51s to ~45s. For some commits I am not completely sure if the tradeoff between build time reduction and convenience caused by the commit is acceptable. If not, I can drop them. --- crates/bevy_derive/src/enum_variant_meta.rs | 9 +-- crates/bevy_derive/src/lib.rs | 3 +- crates/bevy_derive/src/modules.rs | 1 - crates/bevy_ecs/Cargo.toml | 1 - crates/bevy_ecs/src/entity/map_entities.rs | 17 +++++- crates/bevy_ecs/src/query/state.rs | 23 ++++++-- crates/bevy_ecs/src/schedule/state.rs | 31 ++++++++-- crates/bevy_ecs/src/system/query.rs | 56 +++++++++++++++---- crates/bevy_macro_utils/Cargo.toml | 2 +- crates/bevy_macro_utils/src/lib.rs | 36 +++++++++--- .../bevy_reflect_derive/Cargo.toml | 2 +- .../bevy_render/src/mesh/mesh/conversions.rs | 1 - crates/bevy_render/src/mesh/mesh/mod.rs | 3 +- crates/bevy_utils/Cargo.toml | 3 +- crates/bevy_utils/src/enum_variant_meta.rs | 6 -- crates/bevy_utils/src/lib.rs | 4 +- 16 files changed, 138 insertions(+), 60 deletions(-) delete mode 100644 crates/bevy_derive/src/modules.rs delete mode 100644 crates/bevy_utils/src/enum_variant_meta.rs diff --git a/crates/bevy_derive/src/enum_variant_meta.rs b/crates/bevy_derive/src/enum_variant_meta.rs index 415c6f291c..afe400b09a 100644 --- a/crates/bevy_derive/src/enum_variant_meta.rs +++ b/crates/bevy_derive/src/enum_variant_meta.rs @@ -1,4 +1,3 @@ -use bevy_macro_utils::BevyManifest; use proc_macro::{Span, TokenStream}; use quote::quote; use syn::{parse_macro_input, Data, DeriveInput}; @@ -14,8 +13,6 @@ pub fn derive_enum_variant_meta(input: TokenStream) -> TokenStream { } }; - let bevy_util_path = BevyManifest::default().get_path(crate::modules::BEVY_UTILS); - let generics = ast.generics; let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); @@ -25,13 +22,13 @@ pub fn derive_enum_variant_meta(input: TokenStream) -> TokenStream { let indices = 0..names.len(); TokenStream::from(quote! { - impl #impl_generics #bevy_util_path::EnumVariantMeta for #struct_name #ty_generics #where_clause { - fn enum_variant_index(&self) -> usize { + impl #impl_generics #struct_name #ty_generics #where_clause { + pub fn enum_variant_index(&self) -> usize { match self { #(#struct_name::#idents {..} => #indices,)* } } - fn enum_variant_name(&self) -> &'static str { + pub fn enum_variant_name(&self) -> &'static str { static variants: &[&str] = &[ #(#names,)* ]; diff --git a/crates/bevy_derive/src/lib.rs b/crates/bevy_derive/src/lib.rs index 929eaf67b7..3c43776ef9 100644 --- a/crates/bevy_derive/src/lib.rs +++ b/crates/bevy_derive/src/lib.rs @@ -4,13 +4,12 @@ mod app_plugin; mod bevy_main; mod derefs; mod enum_variant_meta; -mod modules; use bevy_macro_utils::{derive_label, BevyManifest}; use proc_macro::TokenStream; use quote::format_ident; -/// Generates a dynamic plugin entry point function for the given `Plugin` type. +/// Generates a dynamic plugin entry point function for the given `Plugin` type. #[proc_macro_derive(DynamicPlugin)] pub fn derive_dynamic_plugin(input: TokenStream) -> TokenStream { app_plugin::derive_dynamic_plugin(input) diff --git a/crates/bevy_derive/src/modules.rs b/crates/bevy_derive/src/modules.rs deleted file mode 100644 index 14d68e7051..0000000000 --- a/crates/bevy_derive/src/modules.rs +++ /dev/null @@ -1 +0,0 @@ -pub const BEVY_UTILS: &str = "bevy_utils"; diff --git a/crates/bevy_ecs/Cargo.toml b/crates/bevy_ecs/Cargo.toml index ebbdcf2a28..c7a76ac02b 100644 --- a/crates/bevy_ecs/Cargo.toml +++ b/crates/bevy_ecs/Cargo.toml @@ -22,7 +22,6 @@ bevy_ecs_macros = { path = "macros", version = "0.8.0-dev" } async-channel = "1.4" fixedbitset = "0.4" fxhash = "0.2" -thiserror = "1.0" downcast-rs = "1.2" serde = "1" diff --git a/crates/bevy_ecs/src/entity/map_entities.rs b/crates/bevy_ecs/src/entity/map_entities.rs index 00080bd0ed..a4b9ea9f97 100644 --- a/crates/bevy_ecs/src/entity/map_entities.rs +++ b/crates/bevy_ecs/src/entity/map_entities.rs @@ -1,13 +1,24 @@ use crate::entity::Entity; use bevy_utils::{Entry, HashMap}; -use thiserror::Error; +use std::fmt; -#[derive(Error, Debug)] +#[derive(Debug)] pub enum MapEntitiesError { - #[error("the given entity does not exist in the map")] EntityNotFound(Entity), } +impl std::error::Error for MapEntitiesError {} + +impl fmt::Display for MapEntitiesError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + MapEntitiesError::EntityNotFound(_) => { + write!(f, "the given entity does not exist in the map") + } + } + } +} + pub trait MapEntities { fn map_entities(&mut self, entity_map: &EntityMap) -> Result<(), MapEntitiesError>; } diff --git a/crates/bevy_ecs/src/query/state.rs b/crates/bevy_ecs/src/query/state.rs index 5956e69564..e369fd7f64 100644 --- a/crates/bevy_ecs/src/query/state.rs +++ b/crates/bevy_ecs/src/query/state.rs @@ -12,7 +12,7 @@ use crate::{ }; use bevy_tasks::TaskPool; use fixedbitset::FixedBitSet; -use thiserror::Error; +use std::fmt; /// Provides scoped access to a [`World`] state according to a given [`WorldQuery`] and query filter. pub struct QueryState @@ -936,16 +936,29 @@ where /// An error that occurs when retrieving a specific [`Entity`]'s query result. // TODO: return the type_name as part of this error -#[derive(Error, Debug, PartialEq, Clone, Copy)] +#[derive(Debug, PartialEq, Clone, Copy)] pub enum QueryEntityError { - #[error("The given entity does not have the requested component.")] QueryDoesNotMatch(Entity), - #[error("The requested entity does not exist.")] NoSuchEntity(Entity), - #[error("The entity was requested mutably more than once.")] AliasedMutability(Entity), } +impl std::error::Error for QueryEntityError {} + +impl fmt::Display for QueryEntityError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + QueryEntityError::QueryDoesNotMatch(_) => { + write!(f, "The given entity does not have the requested component.") + } + QueryEntityError::NoSuchEntity(_) => write!(f, "The requested entity does not exist."), + QueryEntityError::AliasedMutability(_) => { + write!(f, "The entity was requested mutably more than once.") + } + } + } +} + #[cfg(test)] mod tests { use crate::{prelude::*, query::QueryEntityError}; diff --git a/crates/bevy_ecs/src/schedule/state.rs b/crates/bevy_ecs/src/schedule/state.rs index 3b4c894a8c..3c9ddb3752 100644 --- a/crates/bevy_ecs/src/schedule/state.rs +++ b/crates/bevy_ecs/src/schedule/state.rs @@ -5,8 +5,11 @@ use crate::{ }, system::{In, IntoChainSystem, Local, Res, ResMut}, }; -use std::{any::TypeId, fmt::Debug, hash::Hash}; -use thiserror::Error; +use std::{ + any::TypeId, + fmt::{self, Debug}, + hash::Hash, +}; pub trait StateData: Send + Sync + Clone + Eq + Debug + Hash + 'static {} impl StateData for T where T: Send + Sync + Clone + Eq + Debug + Hash + 'static {} @@ -399,16 +402,32 @@ where } } -#[derive(Debug, Error)] +#[derive(Debug)] pub enum StateError { - #[error("Attempted to change the state to the current state.")] AlreadyInState, - #[error("Attempted to queue a state change, but there was already a state queued.")] StateAlreadyQueued, - #[error("Attempted to queue a pop, but there is nothing to pop.")] StackEmpty, } +impl std::error::Error for StateError {} + +impl fmt::Display for StateError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + StateError::AlreadyInState => { + write!(f, "Attempted to change the state to the current state.") + } + StateError::StateAlreadyQueued => write!( + f, + "Attempted to queue a state change, but there was already a state queued." + ), + StateError::StackEmpty => { + write!(f, "Attempted to queue a pop, but there is nothing to pop.") + } + } + } +} + fn should_run_adapter(In(cmp_result): In, state: Res>) -> ShouldRun { if state.end_next_loop { return ShouldRun::No; diff --git a/crates/bevy_ecs/src/system/query.rs b/crates/bevy_ecs/src/system/query.rs index 304fd5c403..5eccd95d9c 100644 --- a/crates/bevy_ecs/src/system/query.rs +++ b/crates/bevy_ecs/src/system/query.rs @@ -9,7 +9,6 @@ use crate::{ }; use bevy_tasks::TaskPool; use std::{any::TypeId, fmt::Debug}; -use thiserror::Error; /// Provides scoped access to components in a [`World`]. /// @@ -670,7 +669,7 @@ where /// for (targeting_entity, targets, origin) in targeting_query.iter(){ /// // We can use "destructuring" to unpack the results nicely /// let [target_1, target_2, target_3] = targets_query.many(targets.0); - /// + /// /// assert!(target_1.distance(origin) <= 5); /// assert!(target_2.distance(origin) <= 5); /// assert!(target_3.distance(origin) <= 5); @@ -779,10 +778,10 @@ where /// for spring in spring_query.iter(){ /// // We can use "destructuring" to unpack our query items nicely /// let [(position_1, mut force_1), (position_2, mut force_2)] = mass_query.many_mut(spring.connected_entities); - /// + /// /// force_1.x += spring.strength * (position_1.x - position_2.x); /// force_1.y += spring.strength * (position_1.y - position_2.y); - /// + /// /// // Silence borrow-checker: I have split your mutable borrow! /// force_2.x += spring.strength * (position_2.x - position_1.x); /// force_2.y += spring.strength * (position_2.y - position_1.y); @@ -1157,28 +1156,61 @@ where } /// An error that occurs when retrieving a specific [`Entity`]'s component from a [`Query`] -#[derive(Error, Debug)] +#[derive(Debug)] pub enum QueryComponentError { - #[error("This query does not have read access to the requested component.")] MissingReadAccess, - #[error("This query does not have write access to the requested component.")] MissingWriteAccess, - #[error("The given entity does not have the requested component.")] MissingComponent, - #[error("The requested entity does not exist.")] NoSuchEntity, } +impl std::error::Error for QueryComponentError {} + +impl std::fmt::Display for QueryComponentError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + QueryComponentError::MissingReadAccess => { + write!( + f, + "This query does not have read access to the requested component." + ) + } + QueryComponentError::MissingWriteAccess => { + write!( + f, + "This query does not have write access to the requested component." + ) + } + QueryComponentError::MissingComponent => { + write!(f, "The given entity does not have the requested component.") + } + QueryComponentError::NoSuchEntity => { + write!(f, "The requested entity does not exist.") + } + } + } +} + /// An error that occurs when evaluating a [`Query`] as a single expected resulted via /// [`Query::single`] or [`Query::single_mut`]. -#[derive(Debug, Error)] +#[derive(Debug)] pub enum QuerySingleError { - #[error("No entities fit the query {0}")] NoEntities(&'static str), - #[error("Multiple entities fit the query {0}!")] MultipleEntities(&'static str), } +impl std::error::Error for QuerySingleError {} + +impl std::fmt::Display for QuerySingleError { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + QuerySingleError::NoEntities(query) => write!(f, "No entities fit the query {}", query), + QuerySingleError::MultipleEntities(query) => { + write!(f, "Multiple entities fit the query {}!", query) + } + } + } +} impl<'w, 's, Q: WorldQuery, F: WorldQuery> Query<'w, 's, Q, F> where F::Fetch: FilterFetch, diff --git a/crates/bevy_macro_utils/Cargo.toml b/crates/bevy_macro_utils/Cargo.toml index 5372bab50b..c5a19e5c2f 100644 --- a/crates/bevy_macro_utils/Cargo.toml +++ b/crates/bevy_macro_utils/Cargo.toml @@ -9,6 +9,6 @@ license = "MIT OR Apache-2.0" keywords = ["bevy"] [dependencies] -cargo-manifest = "0.2.6" +toml = "0.5.8" syn = "1.0" quote = "1.0" diff --git a/crates/bevy_macro_utils/src/lib.rs b/crates/bevy_macro_utils/src/lib.rs index 4f360a3bd3..4883999039 100644 --- a/crates/bevy_macro_utils/src/lib.rs +++ b/crates/bevy_macro_utils/src/lib.rs @@ -8,13 +8,13 @@ pub use attrs::*; pub use shape::*; pub use symbol::*; -use cargo_manifest::{DepsSet, Manifest}; use proc_macro::TokenStream; use quote::quote; use std::{env, path::PathBuf}; +use toml::{map::Map, Value}; pub struct BevyManifest { - manifest: Manifest, + manifest: Map, } impl Default for BevyManifest { @@ -24,7 +24,8 @@ impl Default for BevyManifest { .map(PathBuf::from) .map(|mut path| { path.push("Cargo.toml"); - Manifest::from_path(path).unwrap() + let manifest = std::fs::read_to_string(path).unwrap(); + toml::from_str(&manifest).unwrap() }) .unwrap(), } @@ -36,13 +37,24 @@ impl BevyManifest { const BEVY: &str = "bevy"; const BEVY_INTERNAL: &str = "bevy_internal"; - let find_in_deps = |deps: &DepsSet| -> Option { + fn dep_package(dep: &Value) -> Option<&str> { + if dep.as_str().is_some() { + None + } else { + dep.as_table() + .unwrap() + .get("package") + .map(|name| name.as_str().unwrap()) + } + } + + let find_in_deps = |deps: &Map| -> Option { let package = if let Some(dep) = deps.get(name) { - return Some(Self::parse_str(dep.package().unwrap_or(name))); + return Some(Self::parse_str(dep_package(dep).unwrap_or(name))); } else if let Some(dep) = deps.get(BEVY) { - dep.package().unwrap_or(BEVY) + dep_package(dep).unwrap_or(BEVY) } else if let Some(dep) = deps.get(BEVY_INTERNAL) { - dep.package().unwrap_or(BEVY_INTERNAL) + dep_package(dep).unwrap_or(BEVY_INTERNAL) } else { return None; }; @@ -54,8 +66,14 @@ impl BevyManifest { Some(path) }; - let deps = self.manifest.dependencies.as_ref(); - let deps_dev = self.manifest.dev_dependencies.as_ref(); + let deps = self + .manifest + .get("dependencies") + .map(|deps| deps.as_table().unwrap()); + let deps_dev = self + .manifest + .get("dev-dependencies") + .map(|deps| deps.as_table().unwrap()); deps.and_then(find_in_deps) .or_else(|| deps_dev.and_then(find_in_deps)) diff --git a/crates/bevy_reflect/bevy_reflect_derive/Cargo.toml b/crates/bevy_reflect/bevy_reflect_derive/Cargo.toml index 0cd2722d70..3663af55af 100644 --- a/crates/bevy_reflect/bevy_reflect_derive/Cargo.toml +++ b/crates/bevy_reflect/bevy_reflect_derive/Cargo.toml @@ -17,4 +17,4 @@ bevy_macro_utils = { path = "../../bevy_macro_utils", version = "0.8.0-dev" } syn = { version = "1.0", features = ["full"] } proc-macro2 = "1.0" quote = "1.0" -uuid = { version = "0.8", features = ["v4", "serde"] } +uuid = { version = "0.8", features = ["v4"] } diff --git a/crates/bevy_render/src/mesh/mesh/conversions.rs b/crates/bevy_render/src/mesh/mesh/conversions.rs index a49edbe1ce..6270389432 100644 --- a/crates/bevy_render/src/mesh/mesh/conversions.rs +++ b/crates/bevy_render/src/mesh/mesh/conversions.rs @@ -25,7 +25,6 @@ //! ``` use crate::mesh::VertexAttributeValues; -use bevy_utils::EnumVariantMeta; use thiserror::Error; #[derive(Debug, Clone, Error)] diff --git a/crates/bevy_render/src/mesh/mesh/mod.rs b/crates/bevy_render/src/mesh/mesh/mod.rs index 73488a60af..5618ebba20 100644 --- a/crates/bevy_render/src/mesh/mesh/mod.rs +++ b/crates/bevy_render/src/mesh/mesh/mod.rs @@ -9,10 +9,11 @@ use crate::{ renderer::RenderDevice, }; use bevy_core::cast_slice; +use bevy_derive::EnumVariantMeta; use bevy_ecs::system::{lifetimeless::SRes, SystemParamItem}; use bevy_math::*; use bevy_reflect::TypeUuid; -use bevy_utils::{EnumVariantMeta, Hashed}; +use bevy_utils::Hashed; use std::{collections::BTreeMap, hash::Hash}; use thiserror::Error; use wgpu::{ diff --git a/crates/bevy_utils/Cargo.toml b/crates/bevy_utils/Cargo.toml index 9d02349b1f..6262d70812 100644 --- a/crates/bevy_utils/Cargo.toml +++ b/crates/bevy_utils/Cargo.toml @@ -9,9 +9,8 @@ license = "MIT OR Apache-2.0" keywords = ["bevy"] [dependencies] -bevy_derive = { path = "../bevy_derive", version = "0.8.0-dev" } ahash = "0.7.0" -tracing = { version = "0.1" } +tracing = { version = "0.1", default-features = false, features = ["std"] } instant = { version = "0.1", features = ["wasm-bindgen"] } uuid = { version = "0.8", features = ["v4", "serde"] } hashbrown = { version = "0.11", features = ["serde"] } diff --git a/crates/bevy_utils/src/enum_variant_meta.rs b/crates/bevy_utils/src/enum_variant_meta.rs deleted file mode 100644 index fa55230e59..0000000000 --- a/crates/bevy_utils/src/enum_variant_meta.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub use bevy_derive::EnumVariantMeta; - -pub trait EnumVariantMeta { - fn enum_variant_index(&self) -> usize; - fn enum_variant_name(&self) -> &'static str; -} diff --git a/crates/bevy_utils/src/lib.rs b/crates/bevy_utils/src/lib.rs index 92eed886f8..0f425be909 100644 --- a/crates/bevy_utils/src/lib.rs +++ b/crates/bevy_utils/src/lib.rs @@ -6,12 +6,10 @@ pub mod futures; pub mod label; mod default; -mod enum_variant_meta; mod float_ord; pub use ahash::AHasher; pub use default::default; -pub use enum_variant_meta::*; pub use float_ord::*; pub use hashbrown; pub use instant::{Duration, Instant}; @@ -201,7 +199,7 @@ pub type PreHashMap = hashbrown::HashMap, V, PassHash>; pub trait PreHashMapExt { /// Tries to get or insert the value for the given `key` using the pre-computed hash first. /// If the [`PreHashMap`] does not already contain the `key`, it will clone it and insert - /// the value returned by `func`. + /// the value returned by `func`. fn get_or_insert_with V>(&mut self, key: &Hashed, func: F) -> &mut V; }