diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..7f3456a --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,3 @@ +# These are supported funding model platforms + +github: aevyrie diff --git a/Cargo.toml b/Cargo.toml index 10b607b..ffdd421 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bevy_framepace" -version = "0.14.1" +version = "0.15.0" edition = "2021" resolver = "2" description = "Frame pacing and frame limiting for Bevy" @@ -11,21 +11,39 @@ documentation = "https://docs.rs/bevy_framepace" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bevy = { version = "0.12", default-features = false, features = [ - "bevy_render", - "bevy_winit", -] } +bevy_app = "0.13" +bevy_ecs = "0.13" +bevy_diagnostic = "0.13" +bevy_log = "0.13" +bevy_render = "0.13" +bevy_reflect = "0.13" +bevy_time = "0.13" +bevy_utils = "0.13" +bevy_window = "0.13" +bevy_winit = "0.13" +# Non-bevy spin_sleep = "1.0" [features] -default = ["framepace_debug", "bevy/x11"] +default = ["framepace_debug", "bevy_winit/x11"] framepace_debug = [] [dev-dependencies] -bevy = { version = "0.12", default-features = false, features = [ +bevy = { version = "0.13", default-features = false, features = [ "bevy_gizmos", "bevy_text", "bevy_ui", "default_font", "multi-threaded", + "x11", ] } + +[[example]] +name = "demo" +path = "examples/demo.rs" +required-features = ["default"] + +[[example]] +name = "minimal" +path = "examples/minimal.rs" +required-features = ["default"] diff --git a/README.md b/README.md index 122a10d..2e0f0d2 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ I intend to track the `main` branch of Bevy. PRs supporting this are welcome! | bevy | bevy_framepace | | ---- | ------------------- | +| 0.13 | 0.15 | | 0.12 | 0.14 | | 0.11 | 0.13 | | 0.10 | 0.12 | diff --git a/examples/demo.rs b/examples/demo.rs index 4161003..64a9850 100644 --- a/examples/demo.rs +++ b/examples/demo.rs @@ -18,7 +18,7 @@ struct EnableText; fn toggle_plugin( mut settings: ResMut, - input: Res>, + input: Res>, ) { if input.just_pressed(KeyCode::Space) { use bevy_framepace::Limiter; diff --git a/src/debug.rs b/src/debug.rs index 84f4e52..13bcc46 100644 --- a/src/debug.rs +++ b/src/debug.rs @@ -1,9 +1,9 @@ //! Adds diagnostic logging and a cursor for debugging. -use bevy::{ - diagnostic::{Diagnostic, DiagnosticId, Diagnostics, RegisterDiagnostic}, - prelude::*, -}; +use bevy_app::prelude::*; +use bevy_diagnostic::{Diagnostic, DiagnosticPath, Diagnostics, RegisterDiagnostic}; +use bevy_ecs::prelude::*; +use bevy_time::prelude::*; /// Adds [`Diagnostics`] data from `bevy_framepace` pub struct DiagnosticsPlugin; @@ -12,24 +12,18 @@ impl Plugin for DiagnosticsPlugin { fn build(&self, app: &mut App) { app.add_systems(Update, Self::diagnostic_system); - app.register_diagnostic( - Diagnostic::new(Self::FRAMEPACE_FRAMETIME, "framepace::frametime", 128) - .with_suffix("ms"), - ); - app.register_diagnostic( - Diagnostic::new(Self::FRAMEPACE_OVERSLEEP, "framepace::oversleep", 128) - .with_suffix("µs"), - ); + app.register_diagnostic(Diagnostic::new(Self::FRAMEPACE_FRAMETIME).with_suffix("ms")); + app.register_diagnostic(Diagnostic::new(Self::FRAMEPACE_OVERSLEEP).with_suffix("µs")); } } impl DiagnosticsPlugin { - /// [`DiagnosticId`] for the frametime - pub const FRAMEPACE_FRAMETIME: DiagnosticId = - DiagnosticId::from_u128(8021378406439507683279787892187089153); - /// [`DiagnosticId`] for failures to meet frame time target - pub const FRAMEPACE_OVERSLEEP: DiagnosticId = - DiagnosticId::from_u128(978023490268634078905367093342937); + /// [`DiagnosticPath`] for the frametime + pub const FRAMEPACE_FRAMETIME: DiagnosticPath = + DiagnosticPath::const_new("framepace/frametime"); + /// [`DiagnosticPath`] for failures to meet frame time target + pub const FRAMEPACE_OVERSLEEP: DiagnosticPath = + DiagnosticPath::const_new("framepace/oversleep"); /// Updates diagnostic data from measurements pub fn diagnostic_system( @@ -44,7 +38,7 @@ impl DiagnosticsPlugin { let frametime_millis = stats.frametime.try_lock().unwrap().as_secs_f64() * 1_000_f64; let error_micros = stats.oversleep.try_lock().unwrap().as_secs_f64() * 1_000_000_f64; - diagnostics.add_measurement(Self::FRAMEPACE_FRAMETIME, || frametime_millis); - diagnostics.add_measurement(Self::FRAMEPACE_OVERSLEEP, || error_micros); + diagnostics.add_measurement(&Self::FRAMEPACE_FRAMETIME, || frametime_millis); + diagnostics.add_measurement(&Self::FRAMEPACE_OVERSLEEP, || error_micros); } } diff --git a/src/lib.rs b/src/lib.rs index fa65274..fdeb17b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -//! This is a [`bevy`] plugin that adds framepacing and framelimiting to improve input latency and +//! This is a `bevy` plugin that adds framepacing and framelimiting to improve input latency and //! power use. //! //! # How it works @@ -27,13 +27,18 @@ #![deny(missing_docs)] +use bevy_app::prelude::*; +use bevy_ecs::prelude::*; +use bevy_reflect::prelude::*; +use bevy_render::{Render, RenderApp, RenderSet}; +use bevy_utils::Instant; + #[cfg(not(target_arch = "wasm32"))] -use bevy::winit::WinitWindows; -use bevy::{ - prelude::*, - render::{pipelined_rendering::RenderExtractApp, RenderApp, RenderSet}, - utils::Instant, -}; +use bevy_render::pipelined_rendering::RenderExtractApp; +#[cfg(not(target_arch = "wasm32"))] +use bevy_window::prelude::*; +#[cfg(not(target_arch = "wasm32"))] +use bevy_winit::WinitWindows; use std::{ sync::{Arc, Mutex}, @@ -43,6 +48,12 @@ use std::{ #[cfg(feature = "framepace_debug")] pub mod debug; +/// Bevy does not export `RenderExtractApp` on wasm32, so we create a dummy label to ensure this +/// compiles on wasm32. +#[cfg(target_arch = "wasm32")] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, bevy_app::AppLabel)] +struct RenderExtractApp; + /// Adds framepacing and framelimiting functionality to your [`App`]. #[derive(Debug, Clone, Component)] pub struct FramepacePlugin; @@ -78,7 +89,7 @@ impl Plugin for FramepacePlugin { .insert_resource(limit) .insert_resource(stats) .add_systems( - bevy::render::Render, + Render, framerate_limiter .in_set(RenderSet::Cleanup) .after(World::clear_entities), @@ -115,6 +126,7 @@ struct FramepaceSettingsProxy { limiter: Arc>, } +#[cfg(not(target_arch = "wasm32"))] impl FramepaceSettingsProxy { fn is_enabled(&self) -> bool { self.limiter.try_lock().iter().any(|l| l.is_enabled()) @@ -199,7 +211,7 @@ fn get_display_refresh_rate( Limiter::Off => { #[cfg(feature = "framepace_debug")] if settings.is_changed() { - info!("Frame limiter disabled"); + bevy_log::info!("Frame limiter disabled"); } return; } @@ -208,7 +220,7 @@ fn get_display_refresh_rate( if let Ok(mut limit) = frame_limit.0.try_lock() { if new_frametime != *limit { #[cfg(feature = "framepace_debug")] - info!("Frametime limit changed to: {:?}", new_frametime); + bevy_log::info!("Frametime limit changed to: {:?}", new_frametime); *limit = new_frametime; } } @@ -249,6 +261,7 @@ pub struct FramePaceStats { /// `spin_sleep` sleeps as long as possible given the platform's sleep accuracy, and spins for the /// remainder. The dependency is however not WASM compatible, which is fine, because frame limiting /// should not be used in a browser; this would compete with the browser's frame limiter. +#[allow(unused_variables)] fn framerate_limiter( mut timer: ResMut, target_frametime: Res,