Skip to content

Commit

Permalink
Fix bevy_picking plugin suffixes (#16082)
Browse files Browse the repository at this point in the history
# Objective

- `MeshPickingBackend` and `SpritePickingBackend` do not have the
`Plugin` suffix
- `DefaultPickingPlugins` is masquerading as a `Plugin` when in reality
it should be a `PluginGroup`
- Fixes #16081.

## Solution

- Rename some structures:

|Original Name|New Name|
|-|-|
|`MeshPickingBackend`|`MeshPickingPlugin`|
|`MeshPickingBackendSettings`|`MeshPickingSettings`|
|`SpritePickingBackend`|`SpritePickingPlugin`|
|`UiPickingBackendPlugin`|`UiPickingPlugin`|

- Make `DefaultPickingPlugins` a `PluginGroup`.
- Because `DefaultPickingPlugins` is within the `DefaultPlugins` plugin
group, I also added support for nested plugin groups to the
`plugin_group!` macro.

## Testing

- I used ripgrep to ensure all references were properly renamed.
- For the `plugin_group!` macro, I used `cargo expand` to manually
inspect the expansion of `DefaultPlugins`.

---

## Migration Guide

> [!NOTE]
>
> All 3 of the changed structures were added after 0.14, so this does
not need to be included in the 0.14 to 0.15 migration guide.

- `MeshPickingBackend` is now named `MeshPickingPlugin`.
- `MeshPickingBackendSettings` is now named `MeshPickingSettings`.
- `SpritePickingBackend` is now named `SpritePickingPlugin`.
- `UiPickingBackendPlugin` is now named `UiPickingPlugin`.
- `DefaultPickingPlugins` is now a a `PluginGroup` instead of a
`Plugin`.
  • Loading branch information
BD103 authored Oct 25, 2024
1 parent 611ba8b commit 7c59317
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 31 deletions.
39 changes: 39 additions & 0 deletions crates/bevy_app/src/plugin_group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,17 @@ use core::any::TypeId;
/// # impl Plugin for WebCompatibilityPlugin { fn build(&self, _: &mut App) {} }
/// # }
/// #
/// # mod audio {
/// # use bevy_app::*;
/// # #[derive(Default)]
/// # pub struct AudioPlugins;
/// # impl PluginGroup for AudioPlugins {
/// # fn build(self) -> PluginGroupBuilder {
/// # PluginGroupBuilder::start::<Self>()
/// # }
/// # }
/// # }
/// #
/// # mod internal {
/// # use bevy_app::*;
/// # #[derive(Default)]
Expand Down Expand Up @@ -75,6 +86,10 @@ use core::any::TypeId;
/// // generation, in which case you must wrap it in `#[custom()]`.
/// #[custom(cfg(target_arch = "wasm32"))]
/// web:::WebCompatibilityPlugin,
/// // You can nest `PluginGroup`s within other `PluginGroup`s, you just need the
/// // `#[plugin_group]` attribute.
/// #[plugin_group]
/// audio:::AudioPlugins,
/// // You can hide plugins from documentation. Due to macro limitations, hidden plugins
/// // must be last.
/// #[doc(hidden)]
Expand All @@ -94,6 +109,14 @@ macro_rules! plugin_group {
$(#[custom($plugin_meta:meta)])*
$($plugin_path:ident::)* : $plugin_name:ident
),*
$(
$(,)?$(
#[plugin_group]
$(#[cfg(feature = $plugin_group_feature:literal)])?
$(#[custom($plugin_group_meta:meta)])*
$($plugin_group_path:ident::)* : $plugin_group_name:ident
),+
)?
$(
$(,)?$(
#[doc(hidden)]
Expand All @@ -113,6 +136,10 @@ macro_rules! plugin_group {
" - [`", stringify!($plugin_name), "`](" $(, stringify!($plugin_path), "::")*, stringify!($plugin_name), ")"
$(, " - with feature `", $plugin_feature, "`")?
)])*
$($(#[doc = concat!(
" - [`", stringify!($plugin_group_name), "`](" $(, stringify!($plugin_group_path), "::")*, stringify!($plugin_group_name), ")"
$(, " - with feature `", $plugin_group_feature, "`")?
)]),+)?
$(
///
$(#[doc = $post_doc])+
Expand All @@ -135,6 +162,18 @@ macro_rules! plugin_group {
group = group.add(<$($plugin_path::)*$plugin_name>::default());
}
)*
$($(
$(#[cfg(feature = $plugin_group_feature)])?
$(#[$plugin_group_meta])*
{
const _: () = {
const fn check_default<T: Default>() {}
check_default::<$($plugin_group_path::)*$plugin_group_name>();
};

group = group.add_group(<$($plugin_group_path::)*$plugin_group_name>::default());
}
)+)?
$($(
$(#[cfg(feature = $hidden_plugin_feature)])?
$(#[$hidden_plugin_meta])*
Expand Down
5 changes: 3 additions & 2 deletions crates/bevy_internal/src/default_plugins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,13 @@ plugin_group! {
bevy_gizmos:::GizmoPlugin,
#[cfg(feature = "bevy_state")]
bevy_state::app:::StatesPlugin,
#[cfg(feature = "bevy_picking")]
bevy_picking:::DefaultPickingPlugins,
#[cfg(feature = "bevy_dev_tools")]
bevy_dev_tools:::DevToolsPlugin,
#[cfg(feature = "bevy_ci_testing")]
bevy_dev_tools::ci_testing:::CiTestingPlugin,
#[plugin_group]
#[cfg(feature = "bevy_picking")]
bevy_picking:::DefaultPickingPlugins,
#[doc(hidden)]
:IgnoreAmbiguitiesPlugin,
}
Expand Down
31 changes: 21 additions & 10 deletions crates/bevy_picking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ pub mod input;
pub mod mesh_picking;
pub mod pointer;

use bevy_app::prelude::*;
use bevy_app::{prelude::*, PluginGroupBuilder};
use bevy_ecs::prelude::*;
use bevy_reflect::prelude::*;

Expand All @@ -172,7 +172,7 @@ pub mod prelude {
#[doc(hidden)]
pub use crate::mesh_picking::{
ray_cast::{MeshRayCast, RayCastBackfaces, RayCastSettings, RayCastVisibility},
MeshPickingBackend, MeshPickingBackendSettings, RayCastPickable,
MeshPickingPlugin, MeshPickingSettings, RayCastPickable,
};
#[doc(hidden)]
pub use crate::{
Expand Down Expand Up @@ -275,15 +275,26 @@ pub enum PickSet {
#[derive(Default)]
pub struct DefaultPickingPlugins;

impl Plugin for DefaultPickingPlugins {
fn build(&self, app: &mut App) {
app.add_plugins((
input::PointerInputPlugin::default(),
PickingPlugin::default(),
InteractionPlugin,
));
impl PluginGroup for DefaultPickingPlugins {
fn build(self) -> PluginGroupBuilder {
#[cfg_attr(
not(feature = "bevy_mesh"),
expect(
unused_mut,
reason = "Group is not mutated when `bevy_mesh` is not enabled."
)
)]
let mut group = PluginGroupBuilder::start::<Self>()
.add(input::PointerInputPlugin::default())
.add(PickingPlugin::default())
.add(InteractionPlugin);

#[cfg(feature = "bevy_mesh")]
app.add_plugins(mesh_picking::MeshPickingBackend);
{
group = group.add(mesh_picking::MeshPickingPlugin);
};

group
}
}

Expand Down
24 changes: 12 additions & 12 deletions crates/bevy_picking/src/mesh_picking/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! By default, all meshes are pickable. Picking can be disabled for individual entities
//! by adding [`PickingBehavior::IGNORE`].
//!
//! To make mesh picking entirely opt-in, set [`MeshPickingBackendSettings::require_markers`]
//! To make mesh picking entirely opt-in, set [`MeshPickingSettings::require_markers`]
//! to `true` and add a [`RayCastPickable`] component to the desired camera and target entities.
//!
//! To manually perform mesh ray casts independent of picking, use the [`MeshRayCast`] system parameter.
Expand All @@ -21,10 +21,10 @@ use bevy_reflect::prelude::*;
use bevy_render::{prelude::*, view::RenderLayers};
use ray_cast::{MeshRayCast, RayCastSettings, RayCastVisibility, SimplifiedMesh};

/// Runtime settings for the [`MeshPickingBackend`].
/// Runtime settings for the [`MeshPickingPlugin`].
#[derive(Resource, Reflect)]
#[reflect(Resource, Default)]
pub struct MeshPickingBackendSettings {
pub struct MeshPickingSettings {
/// When set to `true` ray casting will only happen between cameras and entities marked with
/// [`RayCastPickable`]. `false` by default.
///
Expand All @@ -40,7 +40,7 @@ pub struct MeshPickingBackendSettings {
pub ray_cast_visibility: RayCastVisibility,
}

impl Default for MeshPickingBackendSettings {
impl Default for MeshPickingSettings {
fn default() -> Self {
Self {
require_markers: false,
Expand All @@ -49,28 +49,28 @@ impl Default for MeshPickingBackendSettings {
}
}

/// An optional component that marks cameras and target entities that should be used in the [`MeshPickingBackend`].
/// Only needed if [`MeshPickingBackendSettings::require_markers`] is set to `true`, and ignored otherwise.
/// An optional component that marks cameras and target entities that should be used in the [`MeshPickingPlugin`].
/// Only needed if [`MeshPickingSettings::require_markers`] is set to `true`, and ignored otherwise.
#[derive(Debug, Clone, Default, Component, Reflect)]
#[reflect(Component, Default)]
pub struct RayCastPickable;

/// Adds the mesh picking backend to your app.
#[derive(Clone, Default)]
pub struct MeshPickingBackend;
pub struct MeshPickingPlugin;

impl Plugin for MeshPickingBackend {
impl Plugin for MeshPickingPlugin {
fn build(&self, app: &mut App) {
app.init_resource::<MeshPickingBackendSettings>()
.register_type::<(RayCastPickable, MeshPickingBackendSettings, SimplifiedMesh)>()
app.init_resource::<MeshPickingSettings>()
.register_type::<(RayCastPickable, MeshPickingSettings, SimplifiedMesh)>()
.add_systems(PreUpdate, update_hits.in_set(PickSet::Backend));
}
}

/// Casts rays into the scene using [`MeshPickingBackendSettings`] and sends [`PointerHits`] events.
/// Casts rays into the scene using [`MeshPickingSettings`] and sends [`PointerHits`] events.
#[allow(clippy::too_many_arguments)]
pub fn update_hits(
backend_settings: Res<MeshPickingBackendSettings>,
backend_settings: Res<MeshPickingSettings>,
ray_map: Res<RayMap>,
picking_cameras: Query<(&Camera, Option<&RayCastPickable>, Option<&RenderLayers>)>,
pickables: Query<&PickingBehavior>,
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_sprite/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ impl Plugin for SpritePlugin {
);

#[cfg(feature = "bevy_sprite_picking_backend")]
app.add_plugins(picking_backend::SpritePickingBackend);
app.add_plugins(picking_backend::SpritePickingPlugin);

if let Some(render_app) = app.get_sub_app_mut(RenderApp) {
render_app
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_sprite/src/picking_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ use bevy_transform::prelude::*;
use bevy_window::PrimaryWindow;

#[derive(Clone)]
pub struct SpritePickingBackend;
pub struct SpritePickingPlugin;

impl Plugin for SpritePickingBackend {
impl Plugin for SpritePickingPlugin {
fn build(&self, app: &mut App) {
app.add_systems(PreUpdate, sprite_picking.in_set(PickSet::Backend));
}
Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ impl Plugin for UiPlugin {
build_text_interop(app);

#[cfg(feature = "bevy_ui_picking_backend")]
app.add_plugins(picking_backend::UiPickingBackendPlugin);
app.add_plugins(picking_backend::UiPickingPlugin);

if !self.enable_rendering {
return;
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_ui/src/picking_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ use bevy_picking::backend::prelude::*;

/// A plugin that adds picking support for UI nodes.
#[derive(Clone)]
pub struct UiPickingBackendPlugin;
impl Plugin for UiPickingBackendPlugin {
pub struct UiPickingPlugin;
impl Plugin for UiPickingPlugin {
fn build(&self, app: &mut App) {
app.add_systems(PreUpdate, ui_picking.in_set(PickSet::Backend));
}
Expand Down
2 changes: 1 addition & 1 deletion examples/picking/mesh_picking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! By default, all meshes are pickable. Picking can be disabled for individual entities
//! by adding [`PickingBehavior::IGNORE`].
//!
//! If you want mesh picking to be entirely opt-in, you can set [`MeshPickingBackendSettings::require_markers`]
//! If you want mesh picking to be entirely opt-in, you can set [`MeshPickingSettings::require_markers`]
//! to `true` and add a [`RayCastPickable`] component to the desired camera and target entities.

use std::f32::consts::PI;
Expand Down

0 comments on commit 7c59317

Please sign in to comment.