From f1c0a83cd305990d4fd9edc93ff615ea266ab8f5 Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Tue, 16 Nov 2021 23:13:40 +0000 Subject: [PATCH 1/4] Move SDL objects to TLS, allowing multiple windows to co-exist. --- src/window.rs | 48 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/src/window.rs b/src/window.rs index 9df01a4..7bc566d 100644 --- a/src/window.rs +++ b/src/window.rs @@ -1,7 +1,7 @@ use std::{fs::File, io::BufReader, ops::Deref}; #[cfg(feature = "with-sdl")] -use std::{thread, time::Duration}; +use std::{cell::RefCell, thread, time::Duration}; #[cfg(feature = "with-sdl")] use sdl2::{ @@ -11,6 +11,26 @@ use sdl2::{ render, }; +#[cfg(feature = "with-sdl")] +use once_cell::sync::Lazy; + +#[cfg(feature = "with-sdl")] +struct SdlContext { + video_subsystem: sdl2::VideoSubsystem, + event_pump: sdl2::EventPump, +} + +#[cfg(feature = "with-sdl")] +thread_local! { + static SDL: Lazy> = Lazy::new(|| { + let sdl_context = sdl2::init().unwrap(); + RefCell::new(SdlContext { + video_subsystem: sdl_context.video().unwrap(), + event_pump: sdl_context.event_pump().unwrap(), + }) + }); +} + use embedded_graphics::{pixelcolor::Rgb888, prelude::*}; use crate::{ @@ -216,7 +236,6 @@ impl Window { #[cfg(feature = "with-sdl")] struct SdlWindow { canvas: render::Canvas, - event_pump: sdl2::EventPump, } #[cfg(feature = "with-sdl")] @@ -229,21 +248,20 @@ impl SdlWindow { where C: PixelColor + Into, { - let sdl_context = sdl2::init().unwrap(); - let video_subsystem = sdl_context.video().unwrap(); - let size = output_settings.framebuffer_size(display); - let window = video_subsystem - .window(title, size.width, size.height) - .position_centered() - .build() - .unwrap(); + let window = SDL.with(|sdl| { + sdl.borrow_mut() + .video_subsystem + .window(title, size.width, size.height) + .position_centered() + .build() + .unwrap() + }); let canvas = window.into_canvas().build().unwrap(); - let event_pump = sdl_context.event_pump().unwrap(); - Self { canvas, event_pump } + Self { canvas } } pub fn update(&mut self, framebuffer: &OutputImage) { @@ -269,9 +287,9 @@ impl SdlWindow { output_settings: &OutputSettings, ) -> impl Iterator + '_ { let output_settings = output_settings.clone(); - self.event_pump - .poll_iter() - .filter_map(move |event| match event { + SDL.with(|sdl| sdl.borrow_mut().event_pump.poll_iter().collect::>()) + .into_iter() + .filter_map(move |event| match event { Event::Quit { .. } | Event::KeyDown { keycode: Some(Keycode::Escape), From 6f8b1e6322c7da474b3038282f9d3ce5d8f8268e Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Tue, 16 Nov 2021 23:13:53 +0000 Subject: [PATCH 2/4] Filter out mouse events from other windows. This requires updating sdl2 to use the `event.get_window_id()` method. Filtered events are discarded entirely. --- Cargo.toml | 8 ++++++-- src/window.rs | 27 ++++++++++++++++++--------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f775a10..8297f4b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,10 +25,14 @@ base64 = "0.13.0" embedded-graphics = "0.7.1" [dependencies.sdl2] -version = "0.32.2" +version = "0.35.1" +optional = true + +[dependencies.once_cell] +version = "1.8.0" optional = true [features] default = [ "with-sdl" ] fixed_point = [ "embedded-graphics/fixed_point" ] -with-sdl = [ "sdl2" ] +with-sdl = [ "sdl2", "once_cell" ] diff --git a/src/window.rs b/src/window.rs index 7bc566d..f5d9ba7 100644 --- a/src/window.rs +++ b/src/window.rs @@ -329,23 +329,32 @@ impl SdlWindow { } Event::MouseButtonUp { x, y, mouse_btn, .. - } => { - let point = output_settings.output_to_display(Point::new(x, y)); - Some(SimulatorEvent::MouseButtonUp { point, mouse_btn }) + } if event.get_window_id() == Some(self.canvas.window().id()) => { + match event.get_window_id() { + Some(id) if id == self.canvas.window().id() => { + let point = output_settings.output_to_display(Point::new(x, y)); + Some(SimulatorEvent::MouseButtonUp { point, mouse_btn }) + }, + _ => None, + } } Event::MouseButtonDown { x, y, mouse_btn, .. - } => { + } if event.get_window_id() == Some(self.canvas.window().id()) => { let point = output_settings.output_to_display(Point::new(x, y)); Some(SimulatorEvent::MouseButtonDown { point, mouse_btn }) } Event::MouseWheel { x, y, direction, .. - } => Some(SimulatorEvent::MouseWheel { - scroll_delta: Point::new(x, y), - direction, - }), - Event::MouseMotion { x, y, .. } => { + } if event.get_window_id() == Some(self.canvas.window().id()) => { + Some(SimulatorEvent::MouseWheel { + scroll_delta: Point::new(x, y), + direction, + }) + } + Event::MouseMotion { + x, y, .. + } if event.get_window_id() == Some(self.canvas.window().id()) => { let point = output_settings.output_to_display(Point::new(x, y)); Some(SimulatorEvent::MouseMove { point }) } From eb6b0165151dab1f8cdace9f8dc399b82e24a0d1 Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Fri, 3 Dec 2021 19:07:25 +0000 Subject: [PATCH 3/4] Run rustfmt --- src/window.rs | 143 ++++++++++++++++++++++++++------------------------ 1 file changed, 74 insertions(+), 69 deletions(-) diff --git a/src/window.rs b/src/window.rs index f5d9ba7..4f793a1 100644 --- a/src/window.rs +++ b/src/window.rs @@ -287,78 +287,83 @@ impl SdlWindow { output_settings: &OutputSettings, ) -> impl Iterator + '_ { let output_settings = output_settings.clone(); - SDL.with(|sdl| sdl.borrow_mut().event_pump.poll_iter().collect::>()) - .into_iter() - .filter_map(move |event| match event { - Event::Quit { .. } - | Event::KeyDown { - keycode: Some(Keycode::Escape), - .. - } => Some(SimulatorEvent::Quit), - Event::KeyDown { - keycode, - keymod, - repeat, - .. - } => { - if let Some(valid_keycode) = keycode { - Some(SimulatorEvent::KeyDown { - keycode: valid_keycode, - keymod, - repeat, - }) - } else { - None - } - } - Event::KeyUp { - keycode, - keymod, - repeat, - .. - } => { - if let Some(valid_keycode) = keycode { - Some(SimulatorEvent::KeyUp { - keycode: valid_keycode, - keymod, - repeat, - }) - } else { - None - } - } - Event::MouseButtonUp { - x, y, mouse_btn, .. - } if event.get_window_id() == Some(self.canvas.window().id()) => { - match event.get_window_id() { - Some(id) if id == self.canvas.window().id() => { - let point = output_settings.output_to_display(Point::new(x, y)); - Some(SimulatorEvent::MouseButtonUp { point, mouse_btn }) - }, - _ => None, - } - } - Event::MouseButtonDown { - x, y, mouse_btn, .. - } if event.get_window_id() == Some(self.canvas.window().id()) => { - let point = output_settings.output_to_display(Point::new(x, y)); - Some(SimulatorEvent::MouseButtonDown { point, mouse_btn }) + SDL.with(|sdl| { + sdl.borrow_mut() + .event_pump + .poll_iter() + .collect::>() + }) + .into_iter() + .filter_map(move |event| match event { + Event::Quit { .. } + | Event::KeyDown { + keycode: Some(Keycode::Escape), + .. + } => Some(SimulatorEvent::Quit), + Event::KeyDown { + keycode, + keymod, + repeat, + .. + } => { + if let Some(valid_keycode) = keycode { + Some(SimulatorEvent::KeyDown { + keycode: valid_keycode, + keymod, + repeat, + }) + } else { + None } - Event::MouseWheel { - x, y, direction, .. - } if event.get_window_id() == Some(self.canvas.window().id()) => { - Some(SimulatorEvent::MouseWheel { - scroll_delta: Point::new(x, y), - direction, + } + Event::KeyUp { + keycode, + keymod, + repeat, + .. + } => { + if let Some(valid_keycode) = keycode { + Some(SimulatorEvent::KeyUp { + keycode: valid_keycode, + keymod, + repeat, }) + } else { + None } - Event::MouseMotion { - x, y, .. - } if event.get_window_id() == Some(self.canvas.window().id()) => { - let point = output_settings.output_to_display(Point::new(x, y)); - Some(SimulatorEvent::MouseMove { point }) + } + Event::MouseButtonUp { + x, y, mouse_btn, .. + } if event.get_window_id() == Some(self.canvas.window().id()) => { + match event.get_window_id() { + Some(id) if id == self.canvas.window().id() => { + let point = output_settings.output_to_display(Point::new(x, y)); + Some(SimulatorEvent::MouseButtonUp { point, mouse_btn }) + } + _ => None, } - _ => None, - }) + } + Event::MouseButtonDown { + x, y, mouse_btn, .. + } if event.get_window_id() == Some(self.canvas.window().id()) => { + let point = output_settings.output_to_display(Point::new(x, y)); + Some(SimulatorEvent::MouseButtonDown { point, mouse_btn }) + } + Event::MouseWheel { + x, y, direction, .. + } if event.get_window_id() == Some(self.canvas.window().id()) => { + Some(SimulatorEvent::MouseWheel { + scroll_delta: Point::new(x, y), + direction, + }) + } + Event::MouseMotion { x, y, .. } + if event.get_window_id() == Some(self.canvas.window().id()) => + { + let point = output_settings.output_to_display(Point::new(x, y)); + Some(SimulatorEvent::MouseMove { point }) + } + _ => None, + }) } } From 28be599b08806f5eeac55fc39a810a81db78aa65 Mon Sep 17 00:00:00 2001 From: Adam Greig Date: Tue, 24 Dec 2024 13:50:17 +0000 Subject: [PATCH 4/4] update to embedded-graphics 0.8 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 8297f4b..4693a9e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ circle-ci = { repository = "embedded-graphics/simulator", branch = "master" } [dependencies] image = "0.23.0" base64 = "0.13.0" -embedded-graphics = "0.7.1" +embedded-graphics = "0.8" [dependencies.sdl2] version = "0.35.1"