bevy_winit/
winit_config.rs

1use bevy_ecs::resource::Resource;
2use core::time::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    /// The application will update as fast possible.
52    ///
53    /// Uses [`Continuous`](UpdateMode::Continuous) regardless of whether windows have focus.
54    pub fn continuous() -> Self {
55        WinitSettings {
56            focused_mode: UpdateMode::Continuous,
57            unfocused_mode: UpdateMode::Continuous,
58        }
59    }
60
61    /// Returns the current [`UpdateMode`].
62    ///
63    /// **Note:** The output depends on whether the window has focus or not.
64    pub fn update_mode(&self, focused: bool) -> UpdateMode {
65        match focused {
66            true => self.focused_mode,
67            false => self.unfocused_mode,
68        }
69    }
70}
71
72impl Default for WinitSettings {
73    fn default() -> Self {
74        WinitSettings::game()
75    }
76}
77
78/// Determines how frequently an [`App`](bevy_app::App) should update.
79///
80/// **Note:** This setting is independent of VSync. VSync is controlled by a window's
81/// [`PresentMode`](bevy_window::PresentMode) setting. If an app can update faster than the refresh
82/// rate, but VSync is enabled, the update rate will be indirectly limited by the renderer.
83#[derive(Debug, Clone, Copy, PartialEq)]
84pub enum UpdateMode {
85    /// The [`App`](bevy_app::App) will update over and over, as fast as it possibly can, until an
86    /// [`AppExit`](bevy_app::AppExit) event appears.
87    Continuous,
88    /// The [`App`](bevy_app::App) will update in response to the following, until an
89    /// [`AppExit`](bevy_app::AppExit) event appears:
90    /// - `wait` time has elapsed since the previous update
91    /// - a redraw has been requested by [`RequestRedraw`](bevy_window::RequestRedraw)
92    /// - new [window](`winit::event::WindowEvent`), [raw input](`winit::event::DeviceEvent`), or custom
93    ///   events have appeared
94    /// - a redraw has been requested with the [`EventLoopProxy`](crate::EventLoopProxy)
95    Reactive {
96        /// The approximate time from the start of one update to the next.
97        ///
98        /// **Note:** This has no upper limit.
99        /// The [`App`](bevy_app::App) will wait indefinitely if you set this to [`Duration::MAX`].
100        wait: Duration,
101        /// Reacts to device events, that will wake up the loop if it's in a wait state
102        react_to_device_events: bool,
103        /// Reacts to user events, that will wake up the loop if it's in a wait state
104        react_to_user_events: bool,
105        /// Reacts to window events, that will wake up the loop if it's in a wait state
106        react_to_window_events: bool,
107    },
108}
109
110impl UpdateMode {
111    /// Reactive mode, will update the app for any kind of event
112    pub fn reactive(wait: Duration) -> Self {
113        Self::Reactive {
114            wait,
115            react_to_device_events: true,
116            react_to_user_events: true,
117            react_to_window_events: true,
118        }
119    }
120
121    /// Low power mode
122    ///
123    /// Unlike [`Reactive`](`UpdateMode::reactive()`), this will ignore events that
124    /// don't come from interacting with a window, like [`MouseMotion`](winit::event::DeviceEvent::MouseMotion).
125    /// Use this if, for example, you only want your app to update when the mouse cursor is
126    /// moving over a window, not just moving in general. This can greatly reduce power consumption.
127    pub fn reactive_low_power(wait: Duration) -> Self {
128        Self::Reactive {
129            wait,
130            react_to_device_events: false,
131            react_to_user_events: true,
132            react_to_window_events: true,
133        }
134    }
135}