From 06a5ec35b363effc9ccdfeb451b8a724d8716561 Mon Sep 17 00:00:00 2001 From: mitchmindtree Date: Thu, 25 May 2017 02:29:51 +1000 Subject: [PATCH] [WIP] Remove Sync and Clone from EventsLoop. Add EventsLoopProxy. This commit only updates the top-level API to get some early feedback. None of the platform-specific code has been updated yet. I'm hoping to get around to this over the next couple days however if someone more familiar with the windows backend would like to do a PR against this fork that would be a great help. Closes #187. --- examples/proxy.rs | 29 +++++++++++++++++++++++++++++ src/lib.rs | 29 +++++++++++++++++++++++++---- tests/events_loop.rs | 10 ---------- 3 files changed, 54 insertions(+), 14 deletions(-) create mode 100644 examples/proxy.rs delete mode 100644 tests/events_loop.rs diff --git a/examples/proxy.rs b/examples/proxy.rs new file mode 100644 index 00000000..7f82788b --- /dev/null +++ b/examples/proxy.rs @@ -0,0 +1,29 @@ +extern crate winit; + +fn main() { + let 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(); + } + }); + + events_loop.run_forever(|event| { + println!("{:?}", event); + match event { + winit::Event::WindowEvent { event: winit::WindowEvent::Closed, .. } => + events_loop.interrupt(), + _ => () + } + }); +} diff --git a/src/lib.rs b/src/lib.rs index 623f03c3..abaaddb9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -186,10 +186,15 @@ pub struct AxisId(u32); pub struct ButtonId(u32); /// Provides a way to retreive events from the windows that were registered to it. -// TODO: document usage in multiple threads -#[derive(Clone)] +/// +/// To wake up an `EventsLoop` from a another thread, see the `EventsLoopProxy` docs. pub struct EventsLoop { - events_loop: Arc, + events_loop: platform::EventsLoop, +} + +/// Used to wake up the `EventsLoop` from another thread. +pub struct EventsLoopProxy { + events_loop_proxy: platform::EventsLoopProxy, } impl EventsLoop { @@ -218,11 +223,27 @@ impl EventsLoop { } /// If we called `run_forever()`, stops the process of waiting for events. - // TODO: what if we're waiting from multiple threads? #[inline] pub fn interrupt(&self) { self.events_loop.interrupt() } + + /// Creates an `EventsLoopProxy` that can be used to wake up the `EventsLoop` from another + /// thread. + pub fn create_proxy(&self) -> EventsLoopProxy { + EventsLoopProxy { + events_loop_proxy: platform::EventsLoopProxy::new(&self.events_loop), + } + } +} + +impl EventsLoopProxy { + /// Wake up the `EventsLoop` from which this proxy was created. + /// + /// This causes the `EventsLoop` to emit an `Awakened` event. + pub fn wakeup(&self) { + self.events_loop_proxy.wakeup(); + } } /// Object that allows you to build windows. diff --git a/tests/events_loop.rs b/tests/events_loop.rs deleted file mode 100644 index 85b3bb6b..00000000 --- a/tests/events_loop.rs +++ /dev/null @@ -1,10 +0,0 @@ -extern crate winit; - -// A part of the API requirement for `EventsLoop` is that it is `Send` + `Sync`. -// -// This short test will only compile if the `EventsLoop` is `Send` + `Sync`. -#[test] -fn send_sync() { - fn check_send_sync() {} - check_send_sync::(); -}