mirror of
https://github.com/bevyengine/bevy
synced 2024-11-13 00:17:27 +00:00
Inverse bevy_render bevy_winit dependency and move cursor to bevy_winit (#15649)
# Objective - `bevy_render` should not depend on `bevy_winit` - Fixes #15565 ## Solution - `bevy_render` no longer depends on `bevy_winit` - The following is behind the `custom_cursor` feature - Move custom cursor code from `bevy_render` to `bevy_winit` behind the `custom_cursor` feature - `bevy_winit` now depends on `bevy_render` (for `Image` and `TextureFormat`) - `bevy_winit` now depends on `bevy_asset` (for `Assets`, `Handle` and `AssetId`) - `bevy_winit` now depends on `bytemuck` (already in tree) - Custom cursor code in `bevy_winit` reworked to use `AssetId` (other than that it is taken over 1:1) - Rework `bevy_winit` custom cursor interface visibility now that the logic is all contained in `bevy_winit` ## Testing - I ran the screenshot and window_settings examples - Tested on linux wayland so far --- ## Migration Guide `CursorIcon` and `CustomCursor` previously provided by `bevy::render::view::cursor` is now available from `bevy::winit`. A new feature `custom_cursor` enables this functionality (default feature).
This commit is contained in:
parent
4a23dc4216
commit
6edb78a8c3
12 changed files with 64 additions and 40 deletions
|
@ -132,6 +132,7 @@ default = [
|
|||
"webgl2",
|
||||
"sysinfo_plugin",
|
||||
"android-game-activity",
|
||||
"custom_cursor",
|
||||
]
|
||||
|
||||
# Provides an implementation for picking sprites
|
||||
|
@ -417,6 +418,9 @@ track_change_detection = ["bevy_internal/track_change_detection"]
|
|||
# Enable function reflection
|
||||
reflect_functions = ["bevy_internal/reflect_functions"]
|
||||
|
||||
# Enable winit custom cursor support
|
||||
custom_cursor = ["bevy_internal/custom_cursor"]
|
||||
|
||||
[dependencies]
|
||||
bevy_internal = { path = "crates/bevy_internal", version = "0.15.0-dev", default-features = false }
|
||||
|
||||
|
|
|
@ -223,6 +223,9 @@ reflect_functions = [
|
|||
"bevy_ecs/reflect_functions",
|
||||
]
|
||||
|
||||
# Enable winit custom cursor support
|
||||
custom_cursor = ["bevy_winit/custom_cursor"]
|
||||
|
||||
[dependencies]
|
||||
# bevy
|
||||
bevy_a11y = { path = "../bevy_a11y", version = "0.15.0-dev" }
|
||||
|
|
|
@ -66,7 +66,6 @@ bevy_render_macros = { path = "macros", version = "0.15.0-dev" }
|
|||
bevy_time = { path = "../bevy_time", version = "0.15.0-dev" }
|
||||
bevy_transform = { path = "../bevy_transform", version = "0.15.0-dev" }
|
||||
bevy_window = { path = "../bevy_window", version = "0.15.0-dev" }
|
||||
bevy_winit = { path = "../bevy_winit", version = "0.15.0-dev" }
|
||||
bevy_utils = { path = "../bevy_utils", version = "0.15.0-dev" }
|
||||
bevy_tasks = { path = "../bevy_tasks", version = "0.15.0-dev" }
|
||||
bevy_image = { path = "../bevy_image", version = "0.15.0-dev" }
|
||||
|
|
|
@ -15,12 +15,10 @@ use core::{
|
|||
num::NonZero,
|
||||
ops::{Deref, DerefMut},
|
||||
};
|
||||
use cursor::CursorPlugin;
|
||||
use wgpu::{
|
||||
SurfaceConfiguration, SurfaceTargetUnsafe, TextureFormat, TextureUsages, TextureViewDescriptor,
|
||||
};
|
||||
|
||||
pub mod cursor;
|
||||
pub mod screenshot;
|
||||
|
||||
use screenshot::{ScreenshotPlugin, ScreenshotToScreenPipeline};
|
||||
|
@ -29,7 +27,7 @@ pub struct WindowRenderPlugin;
|
|||
|
||||
impl Plugin for WindowRenderPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_plugins((ScreenshotPlugin, CursorPlugin));
|
||||
app.add_plugins(ScreenshotPlugin);
|
||||
|
||||
if let Some(render_app) = app.get_sub_app_mut(RenderApp) {
|
||||
render_app
|
||||
|
|
|
@ -18,6 +18,8 @@ serialize = ["serde", "bevy_input/serialize", "bevy_window/serialize"]
|
|||
android-native-activity = ["winit/android-native-activity"]
|
||||
android-game-activity = ["winit/android-game-activity"]
|
||||
|
||||
custom_cursor = ["bevy_image", "bevy_asset", "bytemuck", "wgpu-types"]
|
||||
|
||||
|
||||
[dependencies]
|
||||
# bevy
|
||||
|
@ -34,6 +36,10 @@ bevy_window = { path = "../bevy_window", version = "0.15.0-dev" }
|
|||
bevy_utils = { path = "../bevy_utils", version = "0.15.0-dev" }
|
||||
bevy_tasks = { path = "../bevy_tasks", version = "0.15.0-dev" }
|
||||
|
||||
# bevy optional
|
||||
bevy_asset = { path = "../bevy_asset", version = "0.15.0-dev", optional = true }
|
||||
bevy_image = { path = "../bevy_image", version = "0.15.0-dev", optional = true }
|
||||
|
||||
# other
|
||||
# feature rwh_06 refers to window_raw_handle@v0.6
|
||||
winit = { version = "0.30", default-features = false, features = ["rwh_06"] }
|
||||
|
@ -44,6 +50,8 @@ approx = { version = "0.5", default-features = false }
|
|||
cfg-if = "1.0"
|
||||
raw-window-handle = "0.6"
|
||||
serde = { version = "1.0", features = ["derive"], optional = true }
|
||||
bytemuck = { version = "1.5", optional = true }
|
||||
wgpu-types = { version = "22", optional = true }
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
wasm-bindgen = { version = "0.2" }
|
||||
|
|
|
@ -6,7 +6,9 @@ use bevy_input::{
|
|||
ButtonState,
|
||||
};
|
||||
use bevy_math::Vec2;
|
||||
use bevy_window::{EnabledButtons, SystemCursorIcon, WindowLevel, WindowTheme};
|
||||
#[cfg(feature = "custom_cursor")]
|
||||
use bevy_window::SystemCursorIcon;
|
||||
use bevy_window::{EnabledButtons, WindowLevel, WindowTheme};
|
||||
use winit::keyboard::{Key, NamedKey, NativeKey};
|
||||
|
||||
pub fn convert_keyboard_input(
|
||||
|
@ -628,6 +630,7 @@ pub fn convert_native_key(native_key: &NativeKey) -> bevy_input::keyboard::Nativ
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "custom_cursor")]
|
||||
/// Converts a [`SystemCursorIcon`] to a [`winit::window::CursorIcon`].
|
||||
pub fn convert_system_cursor_icon(cursor_icon: SystemCursorIcon) -> winit::window::CursorIcon {
|
||||
match cursor_icon {
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
//! Components to customize winit cursor
|
||||
|
||||
use crate::{
|
||||
converters::convert_system_cursor_icon,
|
||||
state::{CursorSource, CustomCursorCache, CustomCursorCacheKey, PendingCursor},
|
||||
WinitCustomCursor,
|
||||
};
|
||||
use bevy_app::{App, Last, Plugin};
|
||||
use bevy_asset::{AssetId, Assets, Handle};
|
||||
use bevy_asset::{Assets, Handle};
|
||||
use bevy_ecs::{
|
||||
change_detection::DetectChanges,
|
||||
component::Component,
|
||||
|
@ -10,18 +17,13 @@ use bevy_ecs::{
|
|||
system::{Commands, Local, Query, Res},
|
||||
world::{OnRemove, Ref},
|
||||
};
|
||||
use bevy_image::Image;
|
||||
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
|
||||
use bevy_utils::{tracing::warn, HashSet};
|
||||
use bevy_window::{SystemCursorIcon, Window};
|
||||
use bevy_winit::{
|
||||
convert_system_cursor_icon, CursorSource, CustomCursorCache, CustomCursorCacheKey,
|
||||
PendingCursor,
|
||||
};
|
||||
use wgpu::TextureFormat;
|
||||
use wgpu_types::TextureFormat;
|
||||
|
||||
use crate::prelude::Image;
|
||||
|
||||
pub struct CursorPlugin;
|
||||
pub(crate) struct CursorPlugin;
|
||||
|
||||
impl Plugin for CursorPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
|
@ -85,7 +87,7 @@ pub enum CustomCursor {
|
|||
},
|
||||
}
|
||||
|
||||
pub fn update_cursors(
|
||||
fn update_cursors(
|
||||
mut commands: Commands,
|
||||
windows: Query<(Entity, Ref<CursorIcon>), With<Window>>,
|
||||
cursor_cache: Res<CustomCursorCache>,
|
||||
|
@ -99,12 +101,7 @@ pub fn update_cursors(
|
|||
|
||||
let cursor_source = match cursor.as_ref() {
|
||||
CursorIcon::Custom(CustomCursor::Image { handle, hotspot }) => {
|
||||
let cache_key = match handle.id() {
|
||||
AssetId::Index { index, .. } => {
|
||||
CustomCursorCacheKey::AssetIndex(index.to_bits())
|
||||
}
|
||||
AssetId::Uuid { uuid } => CustomCursorCacheKey::AssetUuid(uuid.as_u128()),
|
||||
};
|
||||
let cache_key = CustomCursorCacheKey::Asset(handle.id());
|
||||
|
||||
if cursor_cache.0.contains_key(&cache_key) {
|
||||
CursorSource::CustomCached(cache_key)
|
||||
|
@ -123,7 +120,7 @@ pub fn update_cursors(
|
|||
|
||||
let width = image.texture_descriptor.size.width;
|
||||
let height = image.texture_descriptor.size.height;
|
||||
let source = match bevy_winit::WinitCustomCursor::from_rgba(
|
||||
let source = match WinitCustomCursor::from_rgba(
|
||||
rgba,
|
||||
width as u16,
|
||||
height as u16,
|
||||
|
@ -147,9 +144,8 @@ pub fn update_cursors(
|
|||
if cursor_cache.0.contains_key(&cache_key) {
|
||||
CursorSource::CustomCached(cache_key)
|
||||
} else {
|
||||
use bevy_winit::CustomCursorExtWebSys;
|
||||
let source =
|
||||
bevy_winit::WinitCustomCursor::from_url(url.clone(), hotspot.0, hotspot.1);
|
||||
use crate::CustomCursorExtWebSys;
|
||||
let source = WinitCustomCursor::from_url(url.clone(), hotspot.0, hotspot.1);
|
||||
CursorSource::Custom((cache_key, source))
|
||||
}
|
||||
}
|
||||
|
@ -165,7 +161,7 @@ pub fn update_cursors(
|
|||
}
|
||||
|
||||
/// Resets the cursor to the default icon when `CursorIcon` is removed.
|
||||
pub fn on_remove_cursor_icon(trigger: Trigger<OnRemove, CursorIcon>, mut commands: Commands) {
|
||||
fn on_remove_cursor_icon(trigger: Trigger<OnRemove, CursorIcon>, mut commands: Commands) {
|
||||
// Use `try_insert` to avoid panic if the window is being destroyed.
|
||||
commands
|
||||
.entity(trigger.entity())
|
|
@ -23,8 +23,6 @@ use bevy_a11y::AccessibilityRequested;
|
|||
use bevy_app::{App, Last, Plugin};
|
||||
use bevy_ecs::prelude::*;
|
||||
use bevy_window::{exit_on_all_closed, Window, WindowCreated};
|
||||
pub use converters::convert_system_cursor_icon;
|
||||
pub use state::{CursorSource, CustomCursorCache, CustomCursorCacheKey, PendingCursor};
|
||||
use system::{changed_windows, check_keyboard_focus_lost, despawn_windows};
|
||||
pub use system::{create_monitors, create_windows};
|
||||
#[cfg(all(target_family = "wasm", target_os = "unknown"))]
|
||||
|
@ -44,6 +42,8 @@ use crate::{
|
|||
|
||||
pub mod accessibility;
|
||||
mod converters;
|
||||
#[cfg(feature = "custom_cursor")]
|
||||
pub mod cursor;
|
||||
mod state;
|
||||
mod system;
|
||||
mod winit_config;
|
||||
|
@ -131,6 +131,8 @@ impl<T: Event> Plugin for WinitPlugin<T> {
|
|||
);
|
||||
|
||||
app.add_plugins(AccessKitPlugin);
|
||||
#[cfg(feature = "custom_cursor")]
|
||||
app.add_plugins(cursor::CursorPlugin);
|
||||
|
||||
let event_loop = event_loop_builder
|
||||
.build()
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use approx::relative_eq;
|
||||
use bevy_app::{App, AppExit, PluginsState};
|
||||
#[cfg(feature = "custom_cursor")]
|
||||
use bevy_asset::AssetId;
|
||||
use bevy_ecs::{
|
||||
change_detection::{DetectChanges, NonSendMut, Res},
|
||||
entity::Entity,
|
||||
|
@ -8,6 +10,8 @@ use bevy_ecs::{
|
|||
system::SystemState,
|
||||
world::FromWorld,
|
||||
};
|
||||
#[cfg(feature = "custom_cursor")]
|
||||
use bevy_image::Image;
|
||||
use bevy_input::{
|
||||
gestures::*,
|
||||
mouse::{MouseButtonInput, MouseMotion, MouseScrollUnit, MouseWheel},
|
||||
|
@ -16,7 +20,9 @@ use bevy_log::{error, trace, warn};
|
|||
use bevy_math::{ivec2, DVec2, Vec2};
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
use bevy_tasks::tick_global_task_pools_on_main_thread;
|
||||
use bevy_utils::{HashMap, Instant};
|
||||
#[cfg(feature = "custom_cursor")]
|
||||
use bevy_utils::HashMap;
|
||||
use bevy_utils::Instant;
|
||||
use core::marker::PhantomData;
|
||||
use winit::{
|
||||
application::ApplicationHandler,
|
||||
|
@ -88,6 +94,7 @@ struct WinitAppRunnerState<T: Event> {
|
|||
|
||||
impl<T: Event> WinitAppRunnerState<T> {
|
||||
fn new(mut app: App) -> Self {
|
||||
#[cfg(feature = "custom_cursor")]
|
||||
app.add_event::<T>().init_resource::<CustomCursorCache>();
|
||||
|
||||
let event_writer_system_state: SystemState<(
|
||||
|
@ -134,23 +141,25 @@ impl<T: Event> WinitAppRunnerState<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "custom_cursor")]
|
||||
/// Identifiers for custom cursors used in caching.
|
||||
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
|
||||
pub enum CustomCursorCacheKey {
|
||||
/// u64 is used instead of `AssetId`, because `bevy_asset` can't be imported here.
|
||||
AssetIndex(u64),
|
||||
/// u128 is used instead of `AssetId`, because `bevy_asset` can't be imported here.
|
||||
AssetUuid(u128),
|
||||
/// A URL to a cursor.
|
||||
/// An `AssetId` to a cursor.
|
||||
Asset(AssetId<Image>),
|
||||
#[cfg(all(target_family = "wasm", target_os = "unknown"))]
|
||||
/// An URL to a cursor.
|
||||
Url(String),
|
||||
}
|
||||
|
||||
#[cfg(feature = "custom_cursor")]
|
||||
/// Caches custom cursors. On many platforms, creating custom cursors is expensive, especially on
|
||||
/// the web.
|
||||
#[derive(Debug, Clone, Default, Resource)]
|
||||
pub struct CustomCursorCache(pub HashMap<CustomCursorCacheKey, winit::window::CustomCursor>);
|
||||
|
||||
/// A source for a cursor. Is created in `bevy_render` and consumed by the winit event loop.
|
||||
#[cfg(feature = "custom_cursor")]
|
||||
/// A source for a cursor. Consumed by the winit event loop.
|
||||
#[derive(Debug)]
|
||||
pub enum CursorSource {
|
||||
/// A custom cursor was identified to be cached, no reason to recreate it.
|
||||
|
@ -161,6 +170,7 @@ pub enum CursorSource {
|
|||
System(winit::window::CursorIcon),
|
||||
}
|
||||
|
||||
#[cfg(feature = "custom_cursor")]
|
||||
/// Component that indicates what cursor should be used for a window. Inserted
|
||||
/// automatically after changing `CursorIcon` and consumed by the winit event
|
||||
/// loop.
|
||||
|
@ -547,6 +557,7 @@ impl<T: Event> ApplicationHandler<T> for WinitAppRunnerState<T> {
|
|||
// This is a temporary solution, full solution is mentioned here: https://github.com/bevyengine/bevy/issues/1343#issuecomment-770091684
|
||||
if !self.ran_update_since_last_redraw || all_invisible {
|
||||
self.run_app_update();
|
||||
#[cfg(feature = "custom_cursor")]
|
||||
self.update_cursors(event_loop);
|
||||
self.ran_update_since_last_redraw = true;
|
||||
} else {
|
||||
|
@ -775,6 +786,7 @@ impl<T: Event> WinitAppRunnerState<T> {
|
|||
.send_batch(buffered_events);
|
||||
}
|
||||
|
||||
#[cfg(feature = "custom_cursor")]
|
||||
fn update_cursors(&mut self, event_loop: &ActiveEventLoop) {
|
||||
let mut windows_state: SystemState<(
|
||||
NonSendMut<WinitWindows>,
|
||||
|
|
|
@ -34,6 +34,7 @@ The default feature set enables most of the expected features of a game engine,
|
|||
|bevy_ui|A custom ECS-driven UI framework|
|
||||
|bevy_ui_picking_backend|Provides an implementation for picking ui|
|
||||
|bevy_winit|winit window and input backend|
|
||||
|custom_cursor|Enable winit custom cursor support|
|
||||
|default_font|Include a default font, containing only ASCII characters, at the cost of a 20kB binary size increase|
|
||||
|hdr|HDR image format support|
|
||||
|ktx2|KTX2 compressed texture support|
|
||||
|
|
|
@ -2,11 +2,9 @@
|
|||
|
||||
use bevy::{
|
||||
prelude::*,
|
||||
render::view::{
|
||||
cursor::CursorIcon,
|
||||
screenshot::{save_to_disk, Capturing, Screenshot},
|
||||
},
|
||||
render::view::screenshot::{save_to_disk, Capturing, Screenshot},
|
||||
window::SystemCursorIcon,
|
||||
winit::cursor::CursorIcon,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -5,8 +5,8 @@ use bevy::{
|
|||
core::FrameCount,
|
||||
diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},
|
||||
prelude::*,
|
||||
render::view::cursor::{CursorIcon, CustomCursor},
|
||||
window::{CursorGrabMode, PresentMode, SystemCursorIcon, WindowLevel, WindowTheme},
|
||||
winit::cursor::{CursorIcon, CustomCursor},
|
||||
};
|
||||
|
||||
fn main() {
|
||||
|
|
Loading…
Reference in a new issue