//! This temporary module generates types that wrap around the old API (winit v5 and below) and //! expose the new API (winit v6 and above). //! //! This is temporary so that existing backends can smoothly transition. After all implementations //! have finished transitionning, this module should disappear. macro_rules! gen_api_transition { () => { pub struct EventsLoop { windows: ::std::sync::Mutex>>, interrupted: ::std::sync::atomic::AtomicBool, awakened: ::std::sync::Arc<::std::sync::atomic::AtomicBool>, } pub struct EventsLoopProxy { awakened: ::std::sync::Weak<::std::sync::atomic::AtomicBool>, } impl EventsLoop { pub fn new() -> EventsLoop { EventsLoop { windows: ::std::sync::Mutex::new(vec![]), interrupted: ::std::sync::atomic::AtomicBool::new(false), awakened: ::std::sync::Arc::new(::std::sync::atomic::AtomicBool::new(false)), } } pub fn interrupt(&self) { self.interrupted.store(true, ::std::sync::atomic::Ordering::Relaxed); } pub fn poll_events(&self, mut callback: F) where F: FnMut(::Event) { if self.awakened.load(::std::sync::atomic::Ordering::Relaxed) { self.awakened.store(false, ::std::sync::atomic::Ordering::Relaxed); callback(::Event::Awakened); } let mut windows = self.windows.lock().unwrap(); for window in windows.iter() { for event in window.poll_events() { callback(::Event::WindowEvent { window_id: ::WindowId(WindowId(&**window as *const Window as usize)), event: event, }) } } } pub fn run_forever(&self, mut callback: F) where F: FnMut(::Event) { self.interrupted.store(false, ::std::sync::atomic::Ordering::Relaxed); self.awakened.store(false, ::std::sync::atomic::Ordering::Relaxed); // Yeah that's a very bad implementation. loop { self.poll_events(|e| callback(e)); ::std::thread::sleep_ms(5); if self.interrupted.load(::std::sync::atomic::Ordering::Relaxed) { break; } } } pub fn create_proxy(&self) -> EventsLoopProxy { EventsLoopProxy { awakened: ::std::sync::Arc::downgrade(&self.awakened), } } } impl EventsLoopProxy { pub fn wakeup(&self) -> Result<(), ::EventsLoopClosed> { match self.awakened.upgrade() { None => Err(::EventsLoopClosed), Some(awakened) => { awakened.store(true, ::std::sync::atomic::Ordering::Relaxed); Ok(()) }, } } } #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct WindowId(usize); #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct DeviceId; pub struct Window2 { pub window: ::std::sync::Arc, events_loop: ::std::sync::Weak, } impl ::std::ops::Deref for Window2 { type Target = Window; #[inline] fn deref(&self) -> &Window { &*self.window } } impl Window2 { pub fn new(events_loop: ::std::sync::Arc, window: &::WindowAttributes, pl_attribs: &PlatformSpecificWindowBuilderAttributes) -> Result { let win = ::std::sync::Arc::new(try!(Window::new(window, pl_attribs))); events_loop.windows.lock().unwrap().push(win.clone()); Ok(Window2 { window: win, events_loop: ::std::sync::Arc::downgrade(&events_loop), }) } #[inline] pub fn id(&self) -> WindowId { WindowId(&*self.window as *const Window as usize) } } impl Drop for Window2 { fn drop(&mut self) { if let Some(ev) = self.events_loop.upgrade() { let mut windows = ev.windows.lock().unwrap(); windows.retain(|w| &**w as *const Window != &*self.window as *const _); } } } }; }