From 9d5fc50b20eb6253c70b8339002545e23a01157f Mon Sep 17 00:00:00 2001 From: Alex Saveau Date: Thu, 2 Jun 2022 19:42:20 +0000 Subject: [PATCH] Fix crash when using Duration::MAX (#4900) # Objective If you set the `ReactiveLowPower` max wait to `Duration::MAX`, stuff panics. Fix that. ## Solution Wait forever if addition failed. --- crates/bevy_winit/src/lib.rs | 6 +++++- crates/bevy_winit/src/winit_config.rs | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index 676801fe2ad37a..40534dd8098ebe 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -591,7 +591,11 @@ pub fn winit_runner_with(mut app: App) { *control_flow = match winit_config.update_mode(focused) { Continuous => ControlFlow::Poll, Reactive { max_wait } | ReactiveLowPower { max_wait } => { - ControlFlow::WaitUntil(now + *max_wait) + if let Some(instant) = now.checked_add(*max_wait) { + ControlFlow::WaitUntil(instant) + } else { + ControlFlow::Wait + } } }; } diff --git a/crates/bevy_winit/src/winit_config.rs b/crates/bevy_winit/src/winit_config.rs index 0c93ee77b8c87e..9f40db04f2fc40 100644 --- a/crates/bevy_winit/src/winit_config.rs +++ b/crates/bevy_winit/src/winit_config.rs @@ -68,7 +68,12 @@ pub enum UpdateMode { /// Once the app has executed all bevy systems and reaches the end of the event loop, there is /// no way to force the app to wake and update again, unless a `winit` event (such as user /// input, or the window being resized) is received or the time limit is reached. - Reactive { max_wait: Duration }, + Reactive { + /// The maximum time to wait before the event loop runs again. + /// + /// Note that Bevy will wait indefinitely if the duration is too high (such as [`Duration::MAX`]). + max_wait: Duration, + }, /// The event loop will only update if there is a winit event from direct interaction with the /// window (e.g. mouseover), a redraw is requested, or the maximum wait time has elapsed. /// @@ -85,5 +90,10 @@ pub enum UpdateMode { /// window is not focused, to only re-draw your bevy app when the cursor is over the window, but /// not when the mouse moves somewhere else on the screen. This helps to significantly reduce /// power consumption by only updated the app when absolutely necessary. - ReactiveLowPower { max_wait: Duration }, + ReactiveLowPower { + /// The maximum time to wait before the event loop runs again. + /// + /// Note that Bevy will wait indefinitely if the duration is too high (such as [`Duration::MAX`]). + max_wait: Duration, + }, }