bevy_fnplugins/
lib.rs

1/* Heavily based on the plugin.rs in bevy_app */
2#![allow(private_bounds)]
3
4use bevy::prelude::*;
5
6pub trait FnPluginsExt {
7    /// Extended App method that adds functions as plugins to the main bevy app. Useful for creating plugin hierarchies (```struct``` Plugins as base plugins and `fn` plugins as sub-plugins). This method is heavily inspired by bevy's ```App::add_plugins``` method.
8    /// ```
9    /// use bevy::prelude::*;
10    ///
11    /// fn main() {
12    ///     App::new().fn_plugins(example_plugin).run();
13    /// }
14    ///
15    /// fn example_plugin(app: &mut App) {
16    ///     println!("Hello from example_plugin!");
17    /// }
18    /// ```
19    fn fn_plugins<T>(&mut self, f: impl FnPlugins<T>) -> &mut Self;
20}
21
22impl FnPluginsExt for App {
23    fn fn_plugins<T>(&mut self, f: impl FnPlugins<T>) -> &mut Self {
24        f.add_to_app(self);
25        self
26    }
27}
28
29trait FnPlugins<Marker>: sealed::FnPlugins<Marker> {}
30
31impl<Marker, T> FnPlugins<Marker> for T where T: sealed::FnPlugins<Marker> {}
32
33mod sealed {
34    use bevy::ecs::all_tuples;
35    use bevy::prelude::*;
36
37    pub struct SingleFnMarker;
38    pub struct TupleFnMarker;
39
40    pub trait FnPlugins<Marker> {
41        fn add_to_app(self, app: &mut App);
42    }
43
44    impl<P: FnOnce(&mut App)> FnPlugins<SingleFnMarker> for P {
45        fn add_to_app(self, app: &mut App) {
46            self(app);
47        }
48    }
49
50    macro_rules! impl_fn_plugins {
51        ($(($param: ident, $plugins: ident)),*) => {
52            impl<$($param, $plugins),*> FnPlugins<(TupleFnMarker, $($param,)*)> for ($($plugins,)*)
53            where
54                $($plugins: FnPlugins<$param>),*
55            {
56                #[allow(non_snake_case, unused_variables)]
57                fn add_to_app(self, app: &mut App) {
58                    let ($($plugins,)*) = self;
59                    $($plugins.add_to_app(app);)*
60                }
61            }
62        }
63    }
64
65    all_tuples!(impl_fn_plugins, 0, 15, P, S);
66}