#bevy-plugin #bevy #gamedev #place #projects #seldom

seldom_fn_plugin

允许使用Rust函数替换Bevy插件

6个版本 (破坏性更新)

0.6.0 2024年2月18日
0.5.0 2023年11月12日
0.4.0 2023年7月15日
0.3.0 2023年3月12日
0.1.0 2022年8月31日

#803游戏开发

Download history 99/week @ 2024-04-07 141/week @ 2024-04-14 136/week @ 2024-04-21 139/week @ 2024-04-28 152/week @ 2024-05-05 167/week @ 2024-05-12 189/week @ 2024-05-19 200/week @ 2024-05-26 190/week @ 2024-06-02 129/week @ 2024-06-09 166/week @ 2024-06-16 158/week @ 2024-06-23 45/week @ 2024-06-30 69/week @ 2024-07-07 145/week @ 2024-07-14 141/week @ 2024-07-21

每月414次下载
2 个Crate中使用(通过 foxtrot

MIT/Apache

7KB

seldom_fn_plugin

Crates.io MIT/Apache 2.0 Crates.io

seldom_fn_plugin 允许在不牺牲构建器模式的情况下,使用Rust函数替换Bevy插件。这提高了插件密集型应用程序的易用性,同时保持了模块化并避免了某些 .clone() 的使用。

我建议不要在公共API中使用 fn_plugin 替换Bevy插件。在这种情况下,最好与Bevy生态系统保持一致。然而,您可以公开两者,只需让Bevy插件添加 fn_plugin

此Crate的代码只有10行,不包括文档和空白,因此您只需将代码复制到您的项目中即可避免添加依赖。尽管其长度有限,我还是决定发布它,原因有几个。首先,我想看到人们使用这种模式。其次,我在许多Bevy项目中工作,并希望减少代码的重复。最后,我打算发布更多Crate,因此熟悉这个过程没有坏处。

用法

# Replace * with your desired version

[dependencies]
seldom_fn_plugin = "*"

请参阅下面的示例以了解示例用法。

兼容性

Bevy seldom_fn_plugin
0.13 0.6
0.12 0.5
0.11 0.4
0.10 0.3
0.9 0.2
0.8 0.1

示例

以下是示例用法

use bevy::prelude::*;
use seldom_fn_plugin::FnPluginExt;

fn say_hi() {
    println!("hi");
}

fn my_plugin(app: &mut App) {
    app.add_system(say_hi);
}

fn main() {
    App::new().fn_plugin(my_plugin).run();
}

以下是从我开发的游戏和其他Crate中的示例

之前

pub struct ControlsPlugin;

impl Plugin for ControlsPlugin {
    fn build(&self, app: &mut App) {
        app.init_resource::<Controls>();
    }
}

之后

pub fn controls_plugin(app: &mut App) {
    app.init_resource::<Controls>();
}

之前

pub(crate) struct AssetPlugin;

impl Plugin for AssetPlugin {
    fn build(&self, app: &mut App) {
        app.add_plugin(PxAssetPlugin::<PxSpriteData>::default())
            .add_plugin(PxAssetPlugin::<PxTilesetData>::default())
            .add_plugin(PxAssetPlugin::<PxTypefaceData>::default())
            .add_plugin(PxAssetPlugin::<PxFilterData>::default());
    }
}

struct PxAssetPlugin<D: PxAssetData>(PhantomData<D>);

impl<D: PxAssetData> Plugin for PxAssetPlugin<D> {
    fn build(&self, app: &mut App) {
        app.add_asset::<PxAsset<D>>()
            .init_resource::<LoadingAssets<D>>()
            .add_system(D::load.in_set(PxSet::LoadAssets));
    }
}

impl<D: PxAssetData> Default for PxAssetPlugin<D> {
    fn default() -> Self {
        Self(default())
    }
}

之后(避免了一个讨厌的 PhantomData

pub(crate) fn asset_plugin(app: &mut App) {
    app.fn_plugin(px_asset_plugin::<PxSpriteData>)
        .fn_plugin(px_asset_plugin::<PxTilesetData>)
        .fn_plugin(px_asset_plugin::<PxTypefaceData>)
        .fn_plugin(px_asset_plugin::<PxFilterData>);
}

fn px_asset_plugin<D: PxAssetData>(app: &mut App) {
    app.add_asset::<PxAsset<D>>()
        .init_resource::<LoadingAssets<D>>()
        .add_system(D::load.in_set(PxSet::LoadAssets));
}

之前

pub(crate) struct CollisionPlugin<G: PxCollisionGroup> {
    listeners: HashMap<G, HashSet<G>>,
    resolvers: HashMap<G, HashSet<G>>,
}

impl<G: PxCollisionGroup> Plugin for CollisionPlugin<G> {
    fn build(&self, app: &mut App) {
        app.add_event::<PxCollision>().add_system(detect_collisions(
            self.listeners.clone(),
            self.resolvers.clone(),
        ));
    }
}

impl<G: PxCollisionGroup> CollisionPlugin<G> {
    pub(crate) fn new(
        listeners: HashMap<G, HashSet<G>>,
        resolvers: HashMap<G, HashSet<G>>,
    ) -> Self {
        Self {
            listeners,
            resolvers,
        }
    }
}

之后(避免了一些 .clone()

pub(crate) fn collision_plugin<G: PxCollisionGroup>(
    listeners: HashMap<G, HashSet<G>>,
    resolvers: HashMap<G, HashSet<G>>,
) -> impl FnOnce(&mut App) {
    |app| {
        app.add_event::<PxCollision>()
            .add_system(detect_collisions(listeners, resolvers));
    }
}

许可证

seldom_fn_plugin 可根据您的选择在MIT和Apache 2.0下双重许可。

依赖项

~19–46MB
~726K SLoC