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}