control_flow/
control_flow.rs

1#![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 winit::application::ApplicationHandler;
12use winit::event::{ElementState, KeyEvent, StartCause, WindowEvent};
13use winit::event_loop::{ActiveEventLoop, ControlFlow, EventLoop};
14use winit::keyboard::{Key, NamedKey};
15use winit::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: KeyEvent { logical_key: key, state: ElementState::Pressed, .. },
91                ..
92            } => match key.as_ref() {
93                // WARNING: Consider using `key_without_modifiers()` if available on your platform.
94                // See the `key_binding` example
95                Key::Character("1") => {
96                    self.mode = Mode::Wait;
97                    warn!("mode: {:?}", self.mode);
98                },
99                Key::Character("2") => {
100                    self.mode = Mode::WaitUntil;
101                    warn!("mode: {:?}", self.mode);
102                },
103                Key::Character("3") => {
104                    self.mode = Mode::Poll;
105                    warn!("mode: {:?}", self.mode);
106                },
107                Key::Character("r") => {
108                    self.request_redraw = !self.request_redraw;
109                    warn!("request_redraw: {}", self.request_redraw);
110                },
111                Key::Named(NamedKey::Escape) => {
112                    self.close_requested = true;
113                },
114                _ => (),
115            },
116            WindowEvent::RedrawRequested => {
117                let window = self.window.as_ref().unwrap();
118                window.pre_present_notify();
119                fill::fill_window(window);
120            },
121            _ => (),
122        }
123    }
124
125    fn about_to_wait(&mut self, event_loop: &ActiveEventLoop) {
126        if self.request_redraw && !self.wait_cancelled && !self.close_requested {
127            self.window.as_ref().unwrap().request_redraw();
128        }
129
130        match self.mode {
131            Mode::Wait => event_loop.set_control_flow(ControlFlow::Wait),
132            Mode::WaitUntil => {
133                if !self.wait_cancelled {
134                    event_loop
135                        .set_control_flow(ControlFlow::WaitUntil(time::Instant::now() + WAIT_TIME));
136                }
137            },
138            Mode::Poll => {
139                thread::sleep(POLL_SLEEP_TIME);
140                event_loop.set_control_flow(ControlFlow::Poll);
141            },
142        };
143
144        if self.close_requested {
145            event_loop.exit();
146        }
147    }
148}