control_flow/
control_flow.rs1#![allow(clippy::single_match)]
2
3use std::thread;
4#[cfg(not(web_platform))]
5use std::time;
6
7use ::tracing::{info, warn};
8#[cfg(web_platform)]
9use web_time as time;
10
11use rio_window::application::ApplicationHandler;
12use rio_window::event::{ElementState, KeyEvent, StartCause, WindowEvent};
13use rio_window::event_loop::{ActiveEventLoop, ControlFlow, EventLoop};
14use rio_window::keyboard::{Key, NamedKey};
15use rio_window::window::{Window, WindowId};
16
17#[path = "util/fill.rs"]
18mod fill;
19#[path = "util/tracing.rs"]
20mod tracing;
21
22const WAIT_TIME: time::Duration = time::Duration::from_millis(100);
23const POLL_SLEEP_TIME: time::Duration = time::Duration::from_millis(100);
24
25#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
26enum Mode {
27 #[default]
28 Wait,
29 WaitUntil,
30 Poll,
31}
32
33fn main() -> Result<(), impl std::error::Error> {
34 #[cfg(web_platform)]
35 console_error_panic_hook::set_once();
36
37 tracing::init();
38
39 info!("Press '1' to switch to Wait mode.");
40 info!("Press '2' to switch to WaitUntil mode.");
41 info!("Press '3' to switch to Poll mode.");
42 info!("Press 'R' to toggle request_redraw() calls.");
43 info!("Press 'Esc' to close the window.");
44
45 let event_loop = EventLoop::new().unwrap();
46
47 let mut app = ControlFlowDemo::default();
48 event_loop.run_app(&mut app)
49}
50
51#[derive(Default)]
52struct ControlFlowDemo {
53 mode: Mode,
54 request_redraw: bool,
55 wait_cancelled: bool,
56 close_requested: bool,
57 window: Option<Window>,
58}
59
60impl ApplicationHandler for ControlFlowDemo {
61 fn new_events(&mut self, _event_loop: &ActiveEventLoop, cause: StartCause) {
62 info!("new_events: {cause:?}");
63
64 self.wait_cancelled = match cause {
65 StartCause::WaitCancelled { .. } => self.mode == Mode::WaitUntil,
66 _ => false,
67 }
68 }
69
70 fn resumed(&mut self, event_loop: &ActiveEventLoop) {
71 let window_attributes = Window::default_attributes().with_title(
72 "Press 1, 2, 3 to change control flow mode. Press R to toggle redraw requests.",
73 );
74 self.window = Some(event_loop.create_window(window_attributes).unwrap());
75 }
76
77 fn window_event(
78 &mut self,
79 _event_loop: &ActiveEventLoop,
80 _window_id: WindowId,
81 event: WindowEvent,
82 ) {
83 info!("{event:?}");
84
85 match event {
86 WindowEvent::CloseRequested => {
87 self.close_requested = true;
88 }
89 WindowEvent::KeyboardInput {
90 event:
91 KeyEvent {
92 logical_key: key,
93 state: ElementState::Pressed,
94 ..
95 },
96 ..
97 } => match key.as_ref() {
98 Key::Character("1") => {
101 self.mode = Mode::Wait;
102 warn!("mode: {:?}", self.mode);
103 }
104 Key::Character("2") => {
105 self.mode = Mode::WaitUntil;
106 warn!("mode: {:?}", self.mode);
107 }
108 Key::Character("3") => {
109 self.mode = Mode::Poll;
110 warn!("mode: {:?}", self.mode);
111 }
112 Key::Character("r") => {
113 self.request_redraw = !self.request_redraw;
114 warn!("request_redraw: {}", self.request_redraw);
115 }
116 Key::Named(NamedKey::Escape) => {
117 self.close_requested = true;
118 }
119 _ => (),
120 },
121 WindowEvent::RedrawRequested => {
122 let window = self.window.as_ref().unwrap();
123 window.pre_present_notify();
124 fill::fill_window(window);
125 }
126 _ => (),
127 }
128 }
129
130 fn about_to_wait(&mut self, event_loop: &ActiveEventLoop) {
131 if self.request_redraw && !self.wait_cancelled && !self.close_requested {
132 self.window.as_ref().unwrap().request_redraw();
133 }
134
135 match self.mode {
136 Mode::Wait => event_loop.set_control_flow(ControlFlow::Wait),
137 Mode::WaitUntil => {
138 if !self.wait_cancelled {
139 event_loop.set_control_flow(ControlFlow::WaitUntil(
140 time::Instant::now() + WAIT_TIME,
141 ));
142 }
143 }
144 Mode::Poll => {
145 thread::sleep(POLL_SLEEP_TIME);
146 event_loop.set_control_flow(ControlFlow::Poll);
147 }
148 };
149
150 if self.close_requested {
151 event_loop.exit();
152 }
153 }
154}