Replace Option<Instant> with RedrawRequest enum
This commit is contained in:
parent
502c9bfbf6
commit
e2ddef7438
8 changed files with 84 additions and 31 deletions
|
|
@ -270,6 +270,7 @@ async fn run_instance<A, E, C>(
|
||||||
redraw_pending = matches!(
|
redraw_pending = matches!(
|
||||||
start_cause,
|
start_cause,
|
||||||
event::StartCause::Init
|
event::StartCause::Init
|
||||||
|
| event::StartCause::Poll
|
||||||
| event::StartCause::ResumeTimeReached { .. }
|
| event::StartCause::ResumeTimeReached { .. }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -379,8 +380,15 @@ async fn run_instance<A, E, C>(
|
||||||
|
|
||||||
let _ = control_sender.start_send(match interface_state {
|
let _ = control_sender.start_send(match interface_state {
|
||||||
user_interface::State::Updated {
|
user_interface::State::Updated {
|
||||||
redraw_requested_at: Some(at),
|
redraw_request: Some(redraw_request),
|
||||||
} => ControlFlow::WaitUntil(at),
|
} => match redraw_request {
|
||||||
|
crate::window::RedrawRequest::NextFrame => {
|
||||||
|
ControlFlow::Poll
|
||||||
|
}
|
||||||
|
crate::window::RedrawRequest::At(at) => {
|
||||||
|
ControlFlow::WaitUntil(at)
|
||||||
|
}
|
||||||
|
},
|
||||||
_ => ControlFlow::Wait,
|
_ => ControlFlow::Wait,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use std::time::Instant;
|
use crate::window;
|
||||||
|
|
||||||
/// A connection to the state of a shell.
|
/// A connection to the state of a shell.
|
||||||
///
|
///
|
||||||
|
|
@ -9,7 +9,7 @@ use std::time::Instant;
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Shell<'a, Message> {
|
pub struct Shell<'a, Message> {
|
||||||
messages: &'a mut Vec<Message>,
|
messages: &'a mut Vec<Message>,
|
||||||
redraw_requested_at: Option<Instant>,
|
redraw_request: Option<window::RedrawRequest>,
|
||||||
is_layout_invalid: bool,
|
is_layout_invalid: bool,
|
||||||
are_widgets_invalid: bool,
|
are_widgets_invalid: bool,
|
||||||
}
|
}
|
||||||
|
|
@ -19,7 +19,7 @@ impl<'a, Message> Shell<'a, Message> {
|
||||||
pub fn new(messages: &'a mut Vec<Message>) -> Self {
|
pub fn new(messages: &'a mut Vec<Message>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
messages,
|
messages,
|
||||||
redraw_requested_at: None,
|
redraw_request: None,
|
||||||
is_layout_invalid: false,
|
is_layout_invalid: false,
|
||||||
are_widgets_invalid: false,
|
are_widgets_invalid: false,
|
||||||
}
|
}
|
||||||
|
|
@ -31,21 +31,21 @@ impl<'a, Message> Shell<'a, Message> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Requests a new frame to be drawn at the given [`Instant`].
|
/// Requests a new frame to be drawn at the given [`Instant`].
|
||||||
pub fn request_redraw(&mut self, at: Instant) {
|
pub fn request_redraw(&mut self, request: window::RedrawRequest) {
|
||||||
match self.redraw_requested_at {
|
match self.redraw_request {
|
||||||
None => {
|
None => {
|
||||||
self.redraw_requested_at = Some(at);
|
self.redraw_request = Some(request);
|
||||||
}
|
}
|
||||||
Some(current) if at < current => {
|
Some(current) if request < current => {
|
||||||
self.redraw_requested_at = Some(at);
|
self.redraw_request = Some(request);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the requested [`Instant`] a redraw should happen, if any.
|
/// Returns the requested [`Instant`] a redraw should happen, if any.
|
||||||
pub fn redraw_requested_at(&self) -> Option<Instant> {
|
pub fn redraw_request(&self) -> Option<window::RedrawRequest> {
|
||||||
self.redraw_requested_at
|
self.redraw_request
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns whether the current layout is invalid or not.
|
/// Returns whether the current layout is invalid or not.
|
||||||
|
|
@ -90,7 +90,7 @@ impl<'a, Message> Shell<'a, Message> {
|
||||||
pub fn merge<B>(&mut self, other: Shell<'_, B>, f: impl Fn(B) -> Message) {
|
pub fn merge<B>(&mut self, other: Shell<'_, B>, f: impl Fn(B) -> Message) {
|
||||||
self.messages.extend(other.messages.drain(..).map(f));
|
self.messages.extend(other.messages.drain(..).map(f));
|
||||||
|
|
||||||
if let Some(at) = other.redraw_requested_at {
|
if let Some(at) = other.redraw_request {
|
||||||
self.request_redraw(at);
|
self.request_redraw(at);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,9 @@ use crate::layout;
|
||||||
use crate::mouse;
|
use crate::mouse;
|
||||||
use crate::renderer;
|
use crate::renderer;
|
||||||
use crate::widget;
|
use crate::widget;
|
||||||
|
use crate::window;
|
||||||
use crate::{Clipboard, Element, Layout, Point, Rectangle, Shell, Size};
|
use crate::{Clipboard, Element, Layout, Point, Rectangle, Shell, Size};
|
||||||
|
|
||||||
use std::time::Instant;
|
|
||||||
|
|
||||||
/// A set of interactive graphical elements with a specific [`Layout`].
|
/// A set of interactive graphical elements with a specific [`Layout`].
|
||||||
///
|
///
|
||||||
/// It can be updated and drawn.
|
/// It can be updated and drawn.
|
||||||
|
|
@ -191,7 +190,7 @@ where
|
||||||
use std::mem::ManuallyDrop;
|
use std::mem::ManuallyDrop;
|
||||||
|
|
||||||
let mut outdated = false;
|
let mut outdated = false;
|
||||||
let mut redraw_requested_at = None;
|
let mut redraw_request = None;
|
||||||
|
|
||||||
let mut manual_overlay =
|
let mut manual_overlay =
|
||||||
ManuallyDrop::new(self.root.as_widget_mut().overlay(
|
ManuallyDrop::new(self.root.as_widget_mut().overlay(
|
||||||
|
|
@ -221,12 +220,12 @@ where
|
||||||
|
|
||||||
event_statuses.push(event_status);
|
event_statuses.push(event_status);
|
||||||
|
|
||||||
match (redraw_requested_at, shell.redraw_requested_at()) {
|
match (redraw_request, shell.redraw_request()) {
|
||||||
(None, Some(at)) => {
|
(None, Some(at)) => {
|
||||||
redraw_requested_at = Some(at);
|
redraw_request = Some(at);
|
||||||
}
|
}
|
||||||
(Some(current), Some(new)) if new < current => {
|
(Some(current), Some(new)) if new < current => {
|
||||||
redraw_requested_at = Some(new);
|
redraw_request = Some(new);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
@ -303,12 +302,12 @@ where
|
||||||
self.overlay = None;
|
self.overlay = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
match (redraw_requested_at, shell.redraw_requested_at()) {
|
match (redraw_request, shell.redraw_request()) {
|
||||||
(None, Some(at)) => {
|
(None, Some(at)) => {
|
||||||
redraw_requested_at = Some(at);
|
redraw_request = Some(at);
|
||||||
}
|
}
|
||||||
(Some(current), Some(new)) if new < current => {
|
(Some(current), Some(new)) if new < current => {
|
||||||
redraw_requested_at = Some(new);
|
redraw_request = Some(new);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
@ -334,9 +333,7 @@ where
|
||||||
if outdated {
|
if outdated {
|
||||||
State::Outdated
|
State::Outdated
|
||||||
} else {
|
} else {
|
||||||
State::Updated {
|
State::Updated { redraw_request }
|
||||||
redraw_requested_at,
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
event_statuses,
|
event_statuses,
|
||||||
)
|
)
|
||||||
|
|
@ -594,6 +591,6 @@ pub enum State {
|
||||||
/// rebuilding.
|
/// rebuilding.
|
||||||
Updated {
|
Updated {
|
||||||
/// The [`Instant`] when a redraw should be performed.
|
/// The [`Instant`] when a redraw should be performed.
|
||||||
redraw_requested_at: Option<Instant>,
|
redraw_request: Option<window::RedrawRequest>,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -793,9 +793,9 @@ where
|
||||||
- (now - focus.updated_at).as_millis()
|
- (now - focus.updated_at).as_millis()
|
||||||
% CURSOR_BLINK_INTERVAL_MILLIS;
|
% CURSOR_BLINK_INTERVAL_MILLIS;
|
||||||
|
|
||||||
shell.request_redraw(
|
shell.request_redraw(window::RedrawRequest::At(
|
||||||
now + Duration::from_millis(millis_until_redraw as u64),
|
now + Duration::from_millis(millis_until_redraw as u64),
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,13 @@
|
||||||
mod action;
|
mod action;
|
||||||
mod event;
|
mod event;
|
||||||
mod mode;
|
mod mode;
|
||||||
|
mod redraw_request;
|
||||||
mod user_attention;
|
mod user_attention;
|
||||||
|
|
||||||
pub use action::Action;
|
pub use action::Action;
|
||||||
pub use event::Event;
|
pub use event::Event;
|
||||||
pub use mode::Mode;
|
pub use mode::Mode;
|
||||||
|
pub use redraw_request::RedrawRequest;
|
||||||
pub use user_attention::UserAttention;
|
pub use user_attention::UserAttention;
|
||||||
|
|
||||||
use crate::subscription::{self, Subscription};
|
use crate::subscription::{self, Subscription};
|
||||||
|
|
|
||||||
38
native/src/window/redraw_request.rs
Normal file
38
native/src/window/redraw_request.rs
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
|
/// A request to redraw a window.
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub enum RedrawRequest {
|
||||||
|
/// Redraw the next frame.
|
||||||
|
NextFrame,
|
||||||
|
|
||||||
|
/// Redraw at the given time.
|
||||||
|
At(Instant),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ordering() {
|
||||||
|
let now = Instant::now();
|
||||||
|
let later = now + Duration::from_millis(10);
|
||||||
|
|
||||||
|
assert_eq!(RedrawRequest::NextFrame, RedrawRequest::NextFrame);
|
||||||
|
assert_eq!(RedrawRequest::At(now), RedrawRequest::At(now));
|
||||||
|
|
||||||
|
assert!(RedrawRequest::NextFrame < RedrawRequest::At(now));
|
||||||
|
assert!(RedrawRequest::At(now) > RedrawRequest::NextFrame);
|
||||||
|
assert!(RedrawRequest::At(now) < RedrawRequest::At(later));
|
||||||
|
assert!(RedrawRequest::At(later) > RedrawRequest::At(now));
|
||||||
|
|
||||||
|
assert!(RedrawRequest::NextFrame <= RedrawRequest::NextFrame);
|
||||||
|
assert!(RedrawRequest::NextFrame <= RedrawRequest::At(now));
|
||||||
|
assert!(RedrawRequest::At(now) >= RedrawRequest::NextFrame);
|
||||||
|
assert!(RedrawRequest::At(now) <= RedrawRequest::At(now));
|
||||||
|
assert!(RedrawRequest::At(now) <= RedrawRequest::At(later));
|
||||||
|
assert!(RedrawRequest::At(later) >= RedrawRequest::At(now));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -332,6 +332,7 @@ async fn run_instance<A, E, C>(
|
||||||
redraw_pending = matches!(
|
redraw_pending = matches!(
|
||||||
start_cause,
|
start_cause,
|
||||||
event::StartCause::Init
|
event::StartCause::Init
|
||||||
|
| event::StartCause::Poll
|
||||||
| event::StartCause::ResumeTimeReached { .. }
|
| event::StartCause::ResumeTimeReached { .. }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -440,8 +441,15 @@ async fn run_instance<A, E, C>(
|
||||||
|
|
||||||
let _ = control_sender.start_send(match interface_state {
|
let _ = control_sender.start_send(match interface_state {
|
||||||
user_interface::State::Updated {
|
user_interface::State::Updated {
|
||||||
redraw_requested_at: Some(at),
|
redraw_request: Some(redraw_request),
|
||||||
} => ControlFlow::WaitUntil(at),
|
} => match redraw_request {
|
||||||
|
crate::window::RedrawRequest::NextFrame => {
|
||||||
|
ControlFlow::Poll
|
||||||
|
}
|
||||||
|
crate::window::RedrawRequest::At(at) => {
|
||||||
|
ControlFlow::WaitUntil(at)
|
||||||
|
}
|
||||||
|
},
|
||||||
_ => ControlFlow::Wait,
|
_ => ControlFlow::Wait,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
use crate::command::{self, Command};
|
use crate::command::{self, Command};
|
||||||
use iced_native::window;
|
use iced_native::window;
|
||||||
|
|
||||||
pub use window::{frames, Event, Mode, UserAttention};
|
pub use window::{frames, Event, Mode, RedrawRequest, UserAttention};
|
||||||
|
|
||||||
/// Closes the current window and exits the application.
|
/// Closes the current window and exits the application.
|
||||||
pub fn close<Message>() -> Command<Message> {
|
pub fn close<Message>() -> Command<Message> {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue