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}