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 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                // WARNING: Consider using `key_without_modifiers()` if available on your platform.
99                // See the `key_binding` example
100                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}