Skip to content

Commit

Permalink
Merge pull request #191 from mitchmindtree/remove_sync
Browse files Browse the repository at this point in the history
Remove Sync and Clone from EventsLoop. Add EventsLoopProxy.
  • Loading branch information
tomaka authored Jun 21, 2017
2 parents f9f1000 + fe61d81 commit a08347e
Show file tree
Hide file tree
Showing 25 changed files with 586 additions and 331 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ another library.
extern crate winit;

fn main() {
let events_loop = winit::EventsLoop::new();
let mut events_loop = winit::EventsLoop::new();
let window = winit::Window::new(&events_loop).unwrap();

events_loop.run_forever(|event| {
match event {
winit::Event::WindowEvent { event: winit::WindowEvent::Closed, .. } => {
events_loop.interrupt();
winit::ControlFlow::Break
},
_ => ()
_ => winit::ControlFlow::Continue,
}
});
}
Expand Down
7 changes: 4 additions & 3 deletions examples/cursor.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
extern crate winit;

use winit::{Event, ElementState, MouseCursor, WindowEvent, KeyboardInput};
use winit::{Event, ElementState, MouseCursor, WindowEvent, KeyboardInput, ControlFlow};

fn main() {
let events_loop = winit::EventsLoop::new();
let mut events_loop = winit::EventsLoop::new();

let window = winit::WindowBuilder::new().build(&events_loop).unwrap();
window.set_title("A fantastic window!");
Expand All @@ -23,9 +23,10 @@ fn main() {
}
},
Event::WindowEvent { event: WindowEvent::Closed, .. } => {
events_loop.interrupt()
return ControlFlow::Break;
},
_ => ()
}
ControlFlow::Continue
});
}
13 changes: 8 additions & 5 deletions examples/fullscreen.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
extern crate winit;

use std::io::{self, Write};
use winit::{ControlFlow, Event, WindowEvent};

fn main() {
// enumerating monitors
Expand All @@ -22,7 +23,7 @@ fn main() {
monitor
};

let events_loop = winit::EventsLoop::new();
let mut events_loop = winit::EventsLoop::new();

let _window = winit::WindowBuilder::new()
.with_title("Hello world!")
Expand All @@ -34,16 +35,18 @@ fn main() {
println!("{:?}", event);

match event {
winit::Event::WindowEvent { event, .. } => {
Event::WindowEvent { event, .. } => {
match event {
winit::WindowEvent::Closed => events_loop.interrupt(),
winit::WindowEvent::KeyboardInput {
WindowEvent::Closed => return ControlFlow::Break,
WindowEvent::KeyboardInput {
input: winit::KeyboardInput { virtual_keycode: Some(winit::VirtualKeyCode::Escape), .. }, ..
} => events_loop.interrupt(),
} => return ControlFlow::Break,
_ => ()
}
},
_ => {}
}

ControlFlow::Continue
});
}
8 changes: 5 additions & 3 deletions examples/grabbing.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
extern crate winit;

use winit::{WindowEvent, ElementState, KeyboardInput};
use winit::{ControlFlow, WindowEvent, ElementState, KeyboardInput};

fn main() {
let events_loop = winit::EventsLoop::new();
let mut events_loop = winit::EventsLoop::new();

let window = winit::WindowBuilder::new().build(&events_loop).unwrap();
window.set_title("winit - Cursor grabbing test");
Expand All @@ -28,7 +28,7 @@ fn main() {
}
},

WindowEvent::Closed => events_loop.interrupt(),
WindowEvent::Closed => return ControlFlow::Break,

a @ WindowEvent::MouseMoved { .. } => {
println!("{:?}", a);
Expand All @@ -39,5 +39,7 @@ fn main() {
}
_ => {}
}

ControlFlow::Continue
});
}
6 changes: 3 additions & 3 deletions examples/min_max_size.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
extern crate winit;

fn main() {
let events_loop = winit::EventsLoop::new();
let mut events_loop = winit::EventsLoop::new();

let _window = winit::WindowBuilder::new()
.with_min_dimensions(400, 200)
Expand All @@ -13,8 +13,8 @@ fn main() {
println!("{:?}", event);

match event {
winit::Event::WindowEvent { event: winit::WindowEvent::Closed, .. } => events_loop.interrupt(),
_ => ()
winit::Event::WindowEvent { event: winit::WindowEvent::Closed, .. } => winit::ControlFlow::Break,
_ => winit::ControlFlow::Continue,
}
});
}
5 changes: 3 additions & 2 deletions examples/multiwindow.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
extern crate winit;

fn main() {
let events_loop = winit::EventsLoop::new();
let mut events_loop = winit::EventsLoop::new();

let window1 = winit::Window::new(&events_loop).unwrap();
let window2 = winit::Window::new(&events_loop).unwrap();
Expand All @@ -24,10 +24,11 @@ fn main() {

num_windows -= 1;
if num_windows == 0 {
events_loop.interrupt();
return winit::ControlFlow::Break;
}
},
_ => (),
}
winit::ControlFlow::Continue
})
}
29 changes: 29 additions & 0 deletions examples/proxy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
extern crate winit;

fn main() {
let mut events_loop = winit::EventsLoop::new();

let _window = winit::WindowBuilder::new()
.with_title("A fantastic window!")
.build(&events_loop)
.unwrap();

let proxy = events_loop.create_proxy();

std::thread::spawn(move || {
// Wake up the `events_loop` once every second.
loop {
std::thread::sleep(std::time::Duration::from_secs(1));
proxy.wakeup().unwrap();
}
});

events_loop.run_forever(|event| {
println!("{:?}", event);
match event {
winit::Event::WindowEvent { event: winit::WindowEvent::Closed, .. } =>
winit::ControlFlow::Break,
_ => winit::ControlFlow::Continue,
}
});
}
6 changes: 3 additions & 3 deletions examples/transparent.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
extern crate winit;

fn main() {
let events_loop = winit::EventsLoop::new();
let mut events_loop = winit::EventsLoop::new();

let window = winit::WindowBuilder::new().with_decorations(false)
.with_transparency(true)
Expand All @@ -13,8 +13,8 @@ fn main() {
println!("{:?}", event);

match event {
winit::Event::WindowEvent { event: winit::WindowEvent::Closed, .. } => events_loop.interrupt(),
_ => ()
winit::Event::WindowEvent { event: winit::WindowEvent::Closed, .. } => winit::ControlFlow::Break,
_ => winit::ControlFlow::Continue,
}
});
}
10 changes: 6 additions & 4 deletions examples/window.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
extern crate winit;

fn main() {
let events_loop = winit::EventsLoop::new();
let mut events_loop = winit::EventsLoop::new();

let window = winit::WindowBuilder::new()
let _window = winit::WindowBuilder::new()
.with_title("A fantastic window!")
.build(&events_loop)
.unwrap();
Expand All @@ -12,8 +12,10 @@ fn main() {
println!("{:?}", event);

match event {
winit::Event::WindowEvent { event: winit::WindowEvent::Closed, .. } => events_loop.interrupt(),
_ => ()
winit::Event::WindowEvent { event: winit::WindowEvent::Closed, .. } => {
winit::ControlFlow::Break
},
_ => winit::ControlFlow::Continue,
}
});
}
71 changes: 50 additions & 21 deletions src/api_transition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,31 @@
macro_rules! gen_api_transition {
() => {
pub struct EventsLoop {
windows: ::std::sync::Mutex<Vec<::std::sync::Arc<Window>>>,
interrupted: ::std::sync::atomic::AtomicBool,
windows: ::std::sync::Arc<::std::sync::Mutex<Vec<::std::sync::Arc<Window>>>>,
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),
windows: ::std::sync::Arc::new(::std::sync::Mutex::new(vec![])),
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<F>(&self, mut callback: F)
pub fn poll_events<F>(&mut self, mut callback: F)
where F: FnMut(::Event)
{
let mut windows = self.windows.lock().unwrap();
if self.awakened.load(::std::sync::atomic::Ordering::Relaxed) {
self.awakened.store(false, ::std::sync::atomic::Ordering::Relaxed);
callback(::Event::Awakened);
}

let windows = self.windows.lock().unwrap();
for window in windows.iter() {
for event in window.poll_events() {
callback(::Event::WindowEvent {
Expand All @@ -38,18 +43,41 @@ macro_rules! gen_api_transition {
}
}

pub fn run_forever<F>(&self, mut callback: F)
where F: FnMut(::Event)
pub fn run_forever<F>(&mut self, mut callback: F)
where F: FnMut(::Event) -> ::ControlFlow,
{
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) {
let mut control_flow = ::ControlFlow::Continue;
self.poll_events(|e| {
if let ::ControlFlow::Break = callback(e) {
control_flow = ::ControlFlow::Break;
}
});
if let ::ControlFlow::Break = control_flow {
break;
}
::std::thread::sleep(::std::time::Duration::from_millis(5));
}
}

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(())
},
}
}
}
Expand All @@ -62,7 +90,7 @@ macro_rules! gen_api_transition {

pub struct Window2 {
pub window: ::std::sync::Arc<Window>,
events_loop: ::std::sync::Weak<EventsLoop>,
windows: ::std::sync::Weak<::std::sync::Mutex<Vec<::std::sync::Arc<Window>>>>
}

impl ::std::ops::Deref for Window2 {
Expand All @@ -74,15 +102,16 @@ macro_rules! gen_api_transition {
}

impl Window2 {
pub fn new(events_loop: ::std::sync::Arc<EventsLoop>, window: &::WindowAttributes,
pub fn new(events_loop: &EventsLoop,
window: &::WindowAttributes,
pl_attribs: &PlatformSpecificWindowBuilderAttributes)
-> Result<Window2, CreationError>
{
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),
windows: ::std::sync::Arc::downgrade(&events_loop.windows),
})
}

Expand All @@ -94,8 +123,8 @@ macro_rules! gen_api_transition {

impl Drop for Window2 {
fn drop(&mut self) {
if let Some(ev) = self.events_loop.upgrade() {
let mut windows = ev.windows.lock().unwrap();
if let Some(windows) = self.windows.upgrade() {
let mut windows = windows.lock().unwrap();
windows.retain(|w| &**w as *const Window != &*self.window as *const _);
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@ pub enum Event {
device_id: DeviceId,
event: DeviceEvent,
},
Awakened,
}

#[derive(Clone, Debug)]
pub enum WindowEvent {
// TODO: remove ; can break the lib internally so be careful
Awakened,

/// The size of the window has changed.
Resized(u32, u32),
Expand Down
Loading

0 comments on commit a08347e

Please sign in to comment.