Skip to content

Commit

Permalink
Add ApplicationHandler trait
Browse files Browse the repository at this point in the history
  • Loading branch information
madsmtm committed Aug 30, 2023
1 parent 4b71aa5 commit 406a723
Show file tree
Hide file tree
Showing 8 changed files with 538 additions and 156 deletions.
222 changes: 136 additions & 86 deletions examples/control_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,119 +8,169 @@ use web_time as time;

use simple_logger::SimpleLogger;
use winit::{
event::{ElementState, Event, KeyEvent, WindowEvent},
event::{ElementState, KeyEvent, WindowEvent},
event_loop::EventLoop,
keyboard::Key,
window::WindowBuilder,
window::{Window, WindowBuilder},
ApplicationHandler,
};

#[path = "util/fill.rs"]
mod fill;

const WAIT_TIME: time::Duration = time::Duration::from_millis(100);
const POLL_SLEEP_TIME: time::Duration = time::Duration::from_millis(100);

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Mode {
Wait,
WaitUntil,
Poll,
}

const WAIT_TIME: time::Duration = time::Duration::from_millis(100);
const POLL_SLEEP_TIME: time::Duration = time::Duration::from_millis(100);
#[derive(Debug)]
struct App {
mode: Mode,
request_redraw: bool,
wait_cancelled: bool,
close_requested: bool,
window: Window,
}

fn main() -> Result<(), impl std::error::Error> {
SimpleLogger::new().init().unwrap();
impl ApplicationHandler for App {
type Suspended = Self;

println!("Press '1' to switch to Wait mode.");
println!("Press '2' to switch to WaitUntil mode.");
println!("Press '3' to switch to Poll mode.");
println!("Press 'R' to toggle request_redraw() calls.");
println!("Press 'Esc' to close the window.");
fn resume(
suspended: Self::Suspended,
_elwt: &winit::event_loop::EventLoopWindowTarget,
) -> Self {
suspended
}

let event_loop = EventLoop::new().unwrap();
let window = WindowBuilder::new()
.with_title("Press 1, 2, 3 to change control flow mode. Press R to toggle redraw requests.")
.build(&event_loop)
.unwrap();

let mut mode = Mode::Wait;
let mut request_redraw = false;
let mut wait_cancelled = false;
let mut close_requested = false;

event_loop.run(move |event, elwt| {
use winit::event::StartCause;
fn suspend(self) -> Self::Suspended {
self
}

fn window_event(
&mut self,
_elwt: &winit::event_loop::EventLoopWindowTarget,
_window_id: winit::window::WindowId,
event: WindowEvent,
) {
println!("{event:?}");
match event {
Event::NewEvents(start_cause) => {
wait_cancelled = match start_cause {
StartCause::WaitCancelled { .. } => mode == Mode::WaitUntil,
_ => false,
}
WindowEvent::CloseRequested => {
self.close_requested = true;
}
Event::WindowEvent { event, .. } => match event {
WindowEvent::CloseRequested => {
close_requested = true;
WindowEvent::KeyboardInput {
event:
KeyEvent {
logical_key: key,
state: ElementState::Pressed,
..
},
..
} => match key.as_ref() {
// WARNING: Consider using `key_without_modifers()` if available on your platform.
// See the `key_binding` example
Key::Character("1") => {
self.mode = Mode::Wait;
println!("\nmode: {:?}\n", self.mode);
}
Key::Character("2") => {
self.mode = Mode::WaitUntil;
println!("\nmode: {:?}\n", self.mode);
}
Key::Character("3") => {
self.mode = Mode::Poll;
println!("\nmode: {:?}\n", self.mode);
}
WindowEvent::KeyboardInput {
event:
KeyEvent {
logical_key: key,
state: ElementState::Pressed,
..
},
..
} => match key.as_ref() {
// WARNING: Consider using `key_without_modifers()` if available on your platform.
// See the `key_binding` example
Key::Character("1") => {
mode = Mode::Wait;
println!("\nmode: {mode:?}\n");
}
Key::Character("2") => {
mode = Mode::WaitUntil;
println!("\nmode: {mode:?}\n");
}
Key::Character("3") => {
mode = Mode::Poll;
println!("\nmode: {mode:?}\n");
}
Key::Character("r") => {
request_redraw = !request_redraw;
println!("\nrequest_redraw: {request_redraw}\n");
}
Key::Escape => {
close_requested = true;
}
_ => (),
},
WindowEvent::RedrawRequested => {
fill::fill_window(&window);
Key::Character("r") => {
self.request_redraw = !self.request_redraw;
println!("\nrequest_redraw: {}\n", self.request_redraw);
}
Key::Escape => {
self.close_requested = true;
}
_ => (),
},
Event::AboutToWait => {
if request_redraw && !wait_cancelled && !close_requested {
window.request_redraw();
}
WindowEvent::RedrawRequested => {
fill::fill_window(&self.window);
}
_ => (),
}
}

match mode {
Mode::Wait => elwt.set_wait(),
Mode::WaitUntil => {
if !wait_cancelled {
elwt.set_wait_until(time::Instant::now() + WAIT_TIME);
}
}
Mode::Poll => {
thread::sleep(POLL_SLEEP_TIME);
elwt.set_poll();
}
};

if close_requested {
elwt.exit();
fn start_wait_cancelled(
&mut self,
_elwt: &winit::event_loop::EventLoopWindowTarget<()>,
_start: time::Instant,
_requested_resume: Option<time::Instant>,
) {
self.wait_cancelled = self.mode == Mode::WaitUntil;
}

fn start_resume_time_reached(
&mut self,
_elwt: &winit::event_loop::EventLoopWindowTarget<()>,
_start: time::Instant,
_requested_resume: time::Instant,
) {
self.wait_cancelled = false;
}

fn start_poll(&mut self, _elwt: &winit::event_loop::EventLoopWindowTarget<()>) {
self.wait_cancelled = false;
}

fn about_to_wait(&mut self, elwt: &winit::event_loop::EventLoopWindowTarget) {
if self.request_redraw && !self.wait_cancelled && !self.close_requested {
self.window.request_redraw();
}

match self.mode {
Mode::Wait => elwt.set_wait(),
Mode::WaitUntil => {
if !self.wait_cancelled {
elwt.set_wait_until(time::Instant::now() + WAIT_TIME);
}
}
_ => (),
Mode::Poll => {
thread::sleep(POLL_SLEEP_TIME);
elwt.set_poll();
}
};

if self.close_requested {
elwt.exit();
}
}
}

fn main() -> Result<(), impl std::error::Error> {
SimpleLogger::new().init().unwrap();

println!("Press '1' to switch to Wait mode.");
println!("Press '2' to switch to WaitUntil mode.");
println!("Press '3' to switch to Poll mode.");
println!("Press 'R' to toggle request_redraw() calls.");
println!("Press 'Esc' to close the window.");

let event_loop = EventLoop::new().unwrap();
event_loop.run_with::<App>(|elwt| {
let window = WindowBuilder::new()
.with_title(
"Press 1, 2, 3 to change control flow mode. Press R to toggle redraw requests.",
)
.build(elwt)
.unwrap();

App {
window,
mode: Mode::Wait,
request_redraw: false,
wait_cancelled: false,
close_requested: false,
}
})
}
116 changes: 74 additions & 42 deletions examples/multiwindow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,64 +4,96 @@ use std::collections::HashMap;

use simple_logger::SimpleLogger;
use winit::{
event::{ElementState, Event, KeyEvent, WindowEvent},
event::{ElementState, KeyEvent, WindowEvent},
event_loop::EventLoop,
keyboard::Key,
window::Window,
window::{Window, WindowId},
ApplicationHandler,
};

#[path = "util/fill.rs"]
mod fill;

fn main() -> Result<(), impl std::error::Error> {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new().unwrap();
#[derive(Debug)]
struct App {
windows: HashMap<WindowId, Window>,
}

let mut windows = HashMap::new();
for _ in 0..3 {
let window = Window::new(&event_loop).unwrap();
println!("Opened a new window: {:?}", window.id());
windows.insert(window.id(), window);
}
impl ApplicationHandler for App {
type Suspended = Self;

println!("Press N to open a new window.");
fn resume(
suspended: Self::Suspended,
_elwt: &winit::event_loop::EventLoopWindowTarget,
) -> Self {
suspended
}

event_loop.run(move |event, elwt| {
elwt.set_wait();
fn suspend(self) -> Self::Suspended {
self
}

if let Event::WindowEvent { event, window_id } = event {
match event {
WindowEvent::CloseRequested => {
println!("Window {window_id:?} has received the signal to close");
fn window_event(
&mut self,
elwt: &winit::event_loop::EventLoopWindowTarget,
window_id: winit::window::WindowId,
event: WindowEvent,
) {
match event {
WindowEvent::CloseRequested => {
println!("Window {window_id:?} has received the signal to close");

// This drops the window, causing it to close.
windows.remove(&window_id);
// This drops the window, causing it to close.
self.windows.remove(&window_id);

if windows.is_empty() {
elwt.exit();
}
if self.windows.is_empty() {
elwt.exit();
}
WindowEvent::KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
logical_key: Key::Character(c),
..
},
is_synthetic: false,
..
} if matches!(c.as_ref(), "n" | "N") => {
let window = Window::new(elwt).unwrap();
println!("Opened a new window: {:?}", window.id());
windows.insert(window.id(), window);
}
WindowEvent::RedrawRequested => {
if let Some(window) = windows.get(&window_id) {
fill::fill_window(window);
}
}
WindowEvent::KeyboardInput {
event:
KeyEvent {
state: ElementState::Pressed,
logical_key: Key::Character(c),
..
},
is_synthetic: false,
..
} if matches!(c.as_ref(), "n" | "N") => {
let window = Window::new(elwt).unwrap();
println!("Opened a new window: {:?}", window.id());
self.windows.insert(window.id(), window);
}
WindowEvent::RedrawRequested => {
if let Some(window) = self.windows.get(&window_id) {
fill::fill_window(window);
}
_ => (),
}
_ => (),
}
}

fn about_to_wait(&mut self, _elwt: &winit::event_loop::EventLoopWindowTarget) {
// self.window.request_redraw();
}
}

fn main() -> Result<(), impl std::error::Error> {
SimpleLogger::new().init().unwrap();
let event_loop = EventLoop::new().unwrap();

println!("Press N to open a new window.");

event_loop.run_with::<App>(|elwt| {
elwt.set_wait();

let mut windows = HashMap::new();
for _ in 0..3 {
let window = Window::new(elwt).unwrap();
println!("Opened a new window: {:?}", window.id());
windows.insert(window.id(), window);
}

App { windows }
})
}
Loading

0 comments on commit 406a723

Please sign in to comment.