bevy_winit/
winit_config.rs

1use bevy_ecs::system::Resource;
2use bevy_utils::Duration;
3
4/// Settings for the [`WinitPlugin`](super::WinitPlugin).
5#[derive(Debug, Resource, Clone)]
6pub struct WinitSettings {
7    /// Determines how frequently the application can update when it has focus.
8    pub focused_mode: UpdateMode,
9    /// Determines how frequently the application can update when it's out of focus.
10    pub unfocused_mode: UpdateMode,
11}
12
13impl WinitSettings {
14    /// Default settings for games.
15    ///
16    /// [`Continuous`](UpdateMode::Continuous) if windows have focus,
17    /// [`reactive_low_power`](UpdateMode::reactive_low_power) otherwise.
18    pub fn game() -> Self {
19        WinitSettings {
20            focused_mode: UpdateMode::Continuous,
21            unfocused_mode: UpdateMode::reactive_low_power(Duration::from_secs_f64(1.0 / 60.0)), /* 60Hz, */
22        }
23    }
24
25    /// Default settings for desktop applications.
26    ///
27    /// [`Reactive`](UpdateMode::Reactive) if windows have focus,
28    /// [`reactive_low_power`](UpdateMode::reactive_low_power) otherwise.
29    ///
30    /// Use the [`EventLoopProxy`](crate::EventLoopProxy) to request a redraw from outside bevy.
31    pub fn desktop_app() -> Self {
32        WinitSettings {
33            focused_mode: UpdateMode::reactive(Duration::from_secs(5)),
34            unfocused_mode: UpdateMode::reactive_low_power(Duration::from_secs(60)),
35        }
36    }
37
38    /// Default settings for mobile.
39    ///
40    /// [`Reactive`](UpdateMode::Reactive) if windows have focus,
41    /// [`reactive_low_power`](UpdateMode::reactive_low_power) otherwise.
42    ///
43    /// Use the [`EventLoopProxy`](crate::EventLoopProxy) to request a redraw from outside bevy.
44    pub fn mobile() -> Self {
45        WinitSettings {
46            focused_mode: UpdateMode::reactive(Duration::from_secs_f32(1.0 / 60.0)),
47            unfocused_mode: UpdateMode::reactive_low_power(Duration::from_secs(1)),
48        }
49    }
50
51    /// Returns the current [`UpdateMode`].
52    ///
53    /// **Note:** The output depends on whether the window has focus or not.
54    pub fn update_mode(&self, focused: bool) -> UpdateMode {
55        match focused {
56            true => self.focused_mode,
57            false => self.unfocused_mode,
58        }
59    }
60}
61
62impl Default for WinitSettings {
63    fn default() -> Self {
64        WinitSettings::game()
65    }
66}
67
68/// Determines how frequently an [`App`](bevy_app::App) should update.
69///
70/// **Note:** This setting is independent of VSync. VSync is controlled by a window's
71/// [`PresentMode`](bevy_window::PresentMode) setting. If an app can update faster than the refresh
72/// rate, but VSync is enabled, the update rate will be indirectly limited by the renderer.
73#[derive(Debug, Clone, Copy, PartialEq)]
74pub enum UpdateMode {
75    /// The [`App`](bevy_app::App) will update over and over, as fast as it possibly can, until an
76    /// [`AppExit`](bevy_app::AppExit) event appears.
77    Continuous,
78    /// The [`App`](bevy_app::App) will update in response to the following, until an
79    /// [`AppExit`](bevy_app::AppExit) event appears:
80    /// - `wait` time has elapsed since the previous update
81    /// - a redraw has been requested by [`RequestRedraw`](bevy_window::RequestRedraw)
82    /// - new [window](`winit::event::WindowEvent`), [raw input](`winit::event::DeviceEvent`), or custom
83    ///     events have appeared
84    /// - a redraw has been requested with the [`EventLoopProxy`](crate::EventLoopProxy)
85    Reactive {
86        /// The approximate time from the start of one update to the next.
87        ///
88        /// **Note:** This has no upper limit.
89        /// The [`App`](bevy_app::App) will wait indefinitely if you set this to [`Duration::MAX`].
90        wait: Duration,
91        /// Reacts to device events, that will wake up the loop if it's in a wait state
92        react_to_device_events: bool,
93        /// Reacts to user events, that will wake up the loop if it's in a wait state
94        react_to_user_events: bool,
95        /// Reacts to window events, that will wake up the loop if it's in a wait state
96        react_to_window_events: bool,
97    },
98}
99
100impl UpdateMode {
101    /// Reactive mode, will update the app for any kind of event
102    pub fn reactive(wait: Duration) -> Self {
103        Self::Reactive {
104            wait,
105            react_to_device_events: true,
106            react_to_user_events: true,
107            react_to_window_events: true,
108        }
109    }
110
111    /// Low power mode
112    ///
113    /// Unlike [`Reactive`](`UpdateMode::reactive()`), this will ignore events that
114    /// don't come from interacting with a window, like [`MouseMotion`](winit::event::DeviceEvent::MouseMotion).
115    /// Use this if, for example, you only want your app to update when the mouse cursor is
116    /// moving over a window, not just moving in general. This can greatly reduce power consumption.
117    pub fn reactive_low_power(wait: Duration) -> Self {
118        Self::Reactive {
119            wait,
120            react_to_device_events: false,
121            react_to_user_events: true,
122            react_to_window_events: true,
123        }
124    }
125}