 512b7463a3
			
		
	
	
		512b7463a3
		
			
		
	
	
	
	
		
			
			# Objective Make bevy_utils less of a compilation bottleneck. Tackle #11478. ## Solution * Move all of the directly reexported dependencies and move them to where they're actually used. * Remove the UUID utilities that have gone unused since `TypePath` took over for `TypeUuid`. * There was also a extraneous bytemuck dependency on `bevy_core` that has not been used for a long time (since `encase` became the primary way to prepare GPU buffers). * Remove the `all_tuples` macro reexport from bevy_ecs since it's accessible from `bevy_utils`. --- ## Changelog Removed: Many of the reexports from bevy_utils (petgraph, uuid, nonmax, smallvec, and thiserror). Removed: bevy_core's reexports of bytemuck. ## Migration Guide bevy_utils' reexports of petgraph, uuid, nonmax, smallvec, and thiserror have been removed. bevy_core' reexports of bytemuck's types has been removed. Add them as dependencies in your own crate instead.
		
			
				
	
	
		
			168 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			168 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| use downcast_rs::{impl_downcast, Downcast};
 | |
| 
 | |
| use crate::App;
 | |
| use std::any::Any;
 | |
| 
 | |
| /// A collection of Bevy app logic and configuration.
 | |
| ///
 | |
| /// Plugins configure an [`App`]. When an [`App`] registers a plugin,
 | |
| /// the plugin's [`Plugin::build`] function is run. By default, a plugin
 | |
| /// can only be added once to an [`App`].
 | |
| ///
 | |
| /// If the plugin may need to be added twice or more, the function [`is_unique()`](Self::is_unique)
 | |
| /// should be overridden to return `false`. Plugins are considered duplicate if they have the same
 | |
| /// [`name()`](Self::name). The default `name()` implementation returns the type name, which means
 | |
| /// generic plugins with different type parameters will not be considered duplicates.
 | |
| ///
 | |
| /// ## Lifecycle of a plugin
 | |
| ///
 | |
| /// When adding a plugin to an [`App`]:
 | |
| /// * the app calls [`Plugin::build`] immediately, and register the plugin
 | |
| /// * once the app started, it will wait for all registered [`Plugin::ready`] to return `true`
 | |
| /// * it will then call all registered [`Plugin::finish`]
 | |
| /// * and call all registered [`Plugin::cleanup`]
 | |
| ///
 | |
| /// ## Defining a plugin.
 | |
| ///
 | |
| /// Most plugins are simply functions that add configuration to an [`App`].
 | |
| ///
 | |
| /// ```
 | |
| /// # use bevy_app::{App, Update};
 | |
| /// App::new().add_plugins(my_plugin).run();
 | |
| ///
 | |
| /// // This function implements `Plugin`, along with every other `fn(&mut App)`.
 | |
| /// pub fn my_plugin(app: &mut App) {
 | |
| ///     app.add_systems(Update, hello_world);
 | |
| /// }
 | |
| /// # fn hello_world() {}
 | |
| /// ```
 | |
| ///
 | |
| /// For more advanced use cases, the `Plugin` trait can be implemented manually for a type.
 | |
| ///
 | |
| /// ```
 | |
| /// # use bevy_app::*;
 | |
| /// pub struct AccessibilityPlugin {
 | |
| ///     pub flicker_damping: bool,
 | |
| ///     // ...
 | |
| /// }
 | |
| ///
 | |
| /// impl Plugin for AccessibilityPlugin {
 | |
| ///     fn build(&self, app: &mut App) {
 | |
| ///         if self.flicker_damping {
 | |
| ///             app.add_systems(PostUpdate, damp_flickering);
 | |
| ///         }
 | |
| ///     }
 | |
| /// }
 | |
| /// # fn damp_flickering() {}
 | |
| /// ````
 | |
| pub trait Plugin: Downcast + Any + Send + Sync {
 | |
|     /// Configures the [`App`] to which this plugin is added.
 | |
|     fn build(&self, app: &mut App);
 | |
| 
 | |
|     /// Has the plugin finished its setup? This can be useful for plugins that need something
 | |
|     /// asynchronous to happen before they can finish their setup, like the initialization of a renderer.
 | |
|     /// Once the plugin is ready, [`finish`](Plugin::finish) should be called.
 | |
|     fn ready(&self, _app: &App) -> bool {
 | |
|         true
 | |
|     }
 | |
| 
 | |
|     /// Finish adding this plugin to the [`App`], once all plugins registered are ready. This can
 | |
|     /// be useful for plugins that depends on another plugin asynchronous setup, like the renderer.
 | |
|     fn finish(&self, _app: &mut App) {
 | |
|         // do nothing
 | |
|     }
 | |
| 
 | |
|     /// Runs after all plugins are built and finished, but before the app schedule is executed.
 | |
|     /// This can be useful if you have some resource that other plugins need during their build step,
 | |
|     /// but after build you want to remove it and send it to another thread.
 | |
|     fn cleanup(&self, _app: &mut App) {
 | |
|         // do nothing
 | |
|     }
 | |
| 
 | |
|     /// Configures a name for the [`Plugin`] which is primarily used for checking plugin
 | |
|     /// uniqueness and debugging.
 | |
|     fn name(&self) -> &str {
 | |
|         std::any::type_name::<Self>()
 | |
|     }
 | |
| 
 | |
|     /// If the plugin can be meaningfully instantiated several times in an [`App`],
 | |
|     /// override this method to return `false`.
 | |
|     fn is_unique(&self) -> bool {
 | |
|         true
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl_downcast!(Plugin);
 | |
| 
 | |
| impl<T: Fn(&mut App) + Send + Sync + 'static> Plugin for T {
 | |
|     fn build(&self, app: &mut App) {
 | |
|         self(app);
 | |
|     }
 | |
| }
 | |
| 
 | |
| /// A type representing an unsafe function that returns a mutable pointer to a [`Plugin`].
 | |
| /// It is used for dynamically loading plugins.
 | |
| ///
 | |
| /// See `bevy_dynamic_plugin/src/loader.rs#dynamically_load_plugin`.
 | |
| pub type CreatePlugin = unsafe fn() -> *mut dyn Plugin;
 | |
| 
 | |
| /// Types that represent a set of [`Plugin`]s.
 | |
| ///
 | |
| /// This is implemented for all types which implement [`Plugin`],
 | |
| /// [`PluginGroup`](super::PluginGroup), and tuples over [`Plugins`].
 | |
| pub trait Plugins<Marker>: sealed::Plugins<Marker> {}
 | |
| 
 | |
| impl<Marker, T> Plugins<Marker> for T where T: sealed::Plugins<Marker> {}
 | |
| 
 | |
| mod sealed {
 | |
|     use bevy_utils::all_tuples;
 | |
| 
 | |
|     use crate::{App, AppError, Plugin, PluginGroup};
 | |
| 
 | |
|     pub trait Plugins<Marker> {
 | |
|         fn add_to_app(self, app: &mut App);
 | |
|     }
 | |
| 
 | |
|     pub struct PluginMarker;
 | |
|     pub struct PluginGroupMarker;
 | |
|     pub struct PluginsTupleMarker;
 | |
| 
 | |
|     impl<P: Plugin> Plugins<PluginMarker> for P {
 | |
|         #[track_caller]
 | |
|         fn add_to_app(self, app: &mut App) {
 | |
|             if let Err(AppError::DuplicatePlugin { plugin_name }) =
 | |
|                 app.add_boxed_plugin(Box::new(self))
 | |
|             {
 | |
|                 panic!(
 | |
|                     "Error adding plugin {plugin_name}: : plugin was already added in application"
 | |
|                 )
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     impl<P: PluginGroup> Plugins<PluginGroupMarker> for P {
 | |
|         #[track_caller]
 | |
|         fn add_to_app(self, app: &mut App) {
 | |
|             self.build().finish(app);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     macro_rules! impl_plugins_tuples {
 | |
|         ($(($param: ident, $plugins: ident)),*) => {
 | |
|             impl<$($param, $plugins),*> Plugins<(PluginsTupleMarker, $($param,)*)> for ($($plugins,)*)
 | |
|             where
 | |
|                 $($plugins: Plugins<$param>),*
 | |
|             {
 | |
|                 #[allow(non_snake_case, unused_variables)]
 | |
|                 #[track_caller]
 | |
|                 fn add_to_app(self, app: &mut App) {
 | |
|                     let ($($plugins,)*) = self;
 | |
|                     $($plugins.add_to_app(app);)*
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     all_tuples!(impl_plugins_tuples, 0, 15, P, S);
 | |
| }
 |