Replace &EventLoop in callback with &EventLoopWindowTarget

This commit is contained in:
Osspial
2018-11-15 16:40:48 -05:00
parent 9f36a7a68e
commit fa46825a28
6 changed files with 55 additions and 30 deletions

View File

@@ -11,6 +11,7 @@
//! [send_event]: ./struct.EventLoopProxy.html#method.send_event
use std::{fmt, error};
use std::time::Instant;
use std::ops::Deref;
use platform_impl;
use event::Event;
@@ -34,6 +35,11 @@ pub struct EventLoop<T: 'static> {
pub(crate) _marker: ::std::marker::PhantomData<*mut ()> // Not Send nor Sync
}
pub struct EventLoopWindowTarget<T: 'static> {
pub(crate) p: platform_impl::EventLoopWindowTarget<T>,
pub(crate) _marker: ::std::marker::PhantomData<*mut ()> // Not Send nor Sync
}
impl<T> fmt::Debug for EventLoop<T> {
fn fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result {
fmtr.pad("EventLoop { .. }")
@@ -123,7 +129,7 @@ impl<T> EventLoop<T> {
/// [`ControlFlow`]: ./enum.ControlFlow.html
#[inline]
pub fn run<F>(self, event_handler: F) -> !
where F: 'static + FnMut(Event<T>, &EventLoop<T>, &mut ControlFlow)
where F: 'static + FnMut(Event<T>, &EventLoopWindowTarget<T>, &mut ControlFlow)
{
self.event_loop.run(event_handler)
}
@@ -137,6 +143,13 @@ impl<T> EventLoop<T> {
}
}
impl<T> Deref for EventLoop<T> {
type Target = EventLoopWindowTarget<T>;
fn deref(&self) -> &EventLoopWindowTarget<T> {
self.event_loop.window_target()
}
}
/// Used to send custom events to `EventLoop`.
#[derive(Clone)]
pub struct EventLoopProxy<T> {

View File

@@ -5,7 +5,7 @@
))]
use event::Event;
use event_loop::{EventLoop, ControlFlow};
use event_loop::{EventLoop, EventLoopWindowTarget, ControlFlow};
/// Additional methods on `EventLoop` that are specific to desktop platforms.
pub trait EventLoopExtDesktop {
@@ -17,14 +17,14 @@ pub trait EventLoopExtDesktop {
/// Unlikes `run`, this function accepts non-`'static` (i.e. non-`move`) closures and returns
/// control flow to the caller when `control_flow` is set to `ControlFlow::Exit`.
fn run_return<F>(&mut self, event_handler: F)
where F: FnMut(Event<Self::UserEvent>, &EventLoop<Self::UserEvent>, &mut ControlFlow);
where F: FnMut(Event<Self::UserEvent>, &EventLoopWindowTarget<Self::UserEvent>, &mut ControlFlow);
}
impl<T> EventLoopExtDesktop for EventLoop<T> {
type UserEvent = T;
fn run_return<F>(&mut self, event_handler: F)
where F: FnMut(Event<T>, &EventLoop<T>, &mut ControlFlow)
where F: FnMut(Event<T>, &EventLoopWindowTarget<T>, &mut ControlFlow)
{
self.event_loop.run_return(event_handler)
}

View File

@@ -22,6 +22,7 @@ use std::time::{Duration, Instant};
use std::rc::Rc;
use std::cell::RefCell;
use std::collections::VecDeque;
use std::marker::PhantomData;
use parking_lot::Mutex;
use winapi::ctypes::c_int;
@@ -43,7 +44,7 @@ use winapi::um::winnt::{LONG, LPCSTR, SHORT};
use window::WindowId as RootWindowId;
use monitor::MonitorHandle;
use event_loop::{ControlFlow, EventLoop as RootEventLoop, EventLoopClosed};
use event_loop::{ControlFlow, EventLoopWindowTarget as RootELW, EventLoopClosed};
use dpi::{LogicalPosition, LogicalSize, PhysicalSize};
use event::{DeviceEvent, Touch, TouchPhase, StartCause, KeyboardInput, Event, WindowEvent};
use platform_impl::platform::{event, Cursor, WindowId, DEVICE_ID, wrap_device_id, util};
@@ -138,11 +139,15 @@ impl<T> ThreadMsgTargetSubclassInput<T> {
}
}
pub struct EventLoop<T> {
pub struct EventLoop<T: 'static> {
// Id of the background thread from the Win32 API.
thread_id: DWORD,
thread_msg_target: HWND,
thread_msg_sender: Sender<T>,
window_target: RootELW<T>
}
pub struct EventLoopWindowTarget<T> {
thread_id: DWORD,
trigger_newevents_on_redraw: Arc<AtomicBool>,
pub(crate) runner_shared: EventLoopRunnerShared<T>,
}
@@ -152,6 +157,10 @@ impl<T: 'static> EventLoop<T> {
Self::with_dpi_awareness(true)
}
pub fn window_target(&self) -> &RootELW<T> {
&self.window_target
}
pub fn with_dpi_awareness(dpi_aware: bool) -> EventLoop<T> {
become_dpi_aware(dpi_aware);
@@ -163,37 +172,40 @@ impl<T: 'static> EventLoop<T> {
let (thread_msg_target, thread_msg_sender) = thread_event_target_window(runner_shared.clone());
EventLoop {
thread_id,
thread_msg_target, thread_msg_sender,
trigger_newevents_on_redraw: Arc::new(AtomicBool::new(true)),
runner_shared
window_target: RootELW {
p: EventLoopWindowTarget {
thread_id,
trigger_newevents_on_redraw: Arc::new(AtomicBool::new(true)),
runner_shared
},
_marker: PhantomData
}
}
}
pub fn run<F>(mut self, event_handler: F) -> !
where F: 'static + FnMut(Event<T>, &RootEventLoop<T>, &mut ControlFlow)
where F: 'static + FnMut(Event<T>, &RootELW<T>, &mut ControlFlow)
{
self.run_return(event_handler);
::std::process::exit(0);
}
pub fn run_return<F>(&mut self, mut event_handler: F)
where F: FnMut(Event<T>, &RootEventLoop<T>, &mut ControlFlow)
where F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow)
{
unsafe{ winuser::IsGUIThread(1); }
assert_eq!(mem::size_of::<RootEventLoop<T>>(), mem::size_of::<EventLoop<T>>());
let self_ptr = self as *const EventLoop<T>;
let event_loop_windows_ref = &self.window_target;
let mut runner = unsafe{ EventLoopRunner::new(
self,
move |event, control_flow| {
let event_loop_ref = &*(self_ptr as *const RootEventLoop<T>);
event_handler(event, event_loop_ref, control_flow)
event_handler(event, event_loop_windows_ref, control_flow)
}
) };
{
let runner_shared = self.runner_shared.clone();
let runner_shared = self.window_target.p.runner_shared.clone();
let mut runner_ref = runner_shared.runner.borrow_mut();
loop {
let event = runner_shared.buffer.borrow_mut().pop_front();
@@ -206,7 +218,7 @@ impl<T: 'static> EventLoop<T> {
}
macro_rules! runner {
() => {{ self.runner_shared.runner.borrow_mut().as_mut().unwrap() }};
() => {{ self.window_target.p.runner_shared.runner.borrow_mut().as_mut().unwrap() }};
}
unsafe {
@@ -244,7 +256,7 @@ impl<T: 'static> EventLoop<T> {
}
runner!().call_event_handler(Event::LoopDestroyed);
*self.runner_shared.runner.borrow_mut() = None;
*self.window_target.p.runner_shared.runner.borrow_mut() = None;
}
pub fn create_proxy(&self) -> EventLoopProxy<T> {
@@ -253,7 +265,9 @@ impl<T: 'static> EventLoop<T> {
event_send: self.thread_msg_sender.clone()
}
}
}
impl<T> EventLoopWindowTarget<T> {
#[inline(always)]
pub(crate) fn create_thread_executor(&self) -> EventLoopThreadExecutor {
EventLoopThreadExecutor {
@@ -309,7 +323,7 @@ impl<T> EventLoopRunner<T> {
where F: FnMut(Event<T>, &mut ControlFlow)
{
EventLoopRunner {
trigger_newevents_on_redraw: event_loop.trigger_newevents_on_redraw.clone(),
trigger_newevents_on_redraw: event_loop.window_target.p.trigger_newevents_on_redraw.clone(),
control_flow: ControlFlow::default(),
runner_state: RunnerState::New,
in_modal_loop: false,
@@ -545,8 +559,6 @@ impl<T> Drop for EventLoop<T> {
fn drop(&mut self) {
unsafe {
winuser::DestroyWindow(self.thread_msg_target);
// Posting `WM_QUIT` will cause `GetMessage` to stop.
winuser::PostThreadMessageA(self.thread_id, winuser::WM_QUIT, 0, 0);
}
}
}

View File

@@ -3,7 +3,7 @@
use winapi;
use winapi::shared::windef::HWND;
pub use self::event_loop::{EventLoop, EventLoopProxy};
pub use self::event_loop::{EventLoop, EventLoopWindowTarget, EventLoopProxy};
pub use self::monitor::MonitorHandle;
pub use self::window::Window;

View File

@@ -23,7 +23,7 @@ use dpi::{LogicalPosition, LogicalSize, PhysicalSize};
use monitor::MonitorHandle as RootMonitorHandle;
use platform_impl::platform::{Cursor, PlatformSpecificWindowBuilderAttributes, WindowId};
use platform_impl::platform::dpi::{dpi_to_scale_factor, get_hwnd_dpi};
use platform_impl::platform::event_loop::{self, EventLoop, DESTROY_MSG_ID, INITIAL_DPI_MSG_ID, REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID};
use platform_impl::platform::event_loop::{self, EventLoopWindowTarget, DESTROY_MSG_ID, INITIAL_DPI_MSG_ID, REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID};
use platform_impl::platform::event_loop::WindowState;
use platform_impl::platform::icon::{self, IconType, WinIcon};
use platform_impl::platform::monitor;
@@ -69,7 +69,7 @@ unsafe fn unjust_window_rect(prc: &mut RECT, style: DWORD, ex_style: DWORD) -> B
impl Window {
pub fn new<T: 'static>(
event_loop: &EventLoop<T>,
event_loop: &EventLoopWindowTarget<T>,
w_attr: WindowAttributes,
pl_attr: PlatformSpecificWindowBuilderAttributes,
) -> Result<Window, CreationError> {
@@ -857,7 +857,7 @@ pub unsafe fn adjust_size(
unsafe fn init<T: 'static>(
mut attributes: WindowAttributes,
mut pl_attribs: PlatformSpecificWindowBuilderAttributes,
event_loop: &event_loop::EventLoop<T>,
event_loop: &EventLoopWindowTarget<T>,
) -> Result<Window, CreationError> {
let title = OsStr::new(&attributes.title)
.encode_wide()

View File

@@ -2,7 +2,7 @@
use std::{fmt, error};
use platform_impl;
use event_loop::EventLoop;
use event_loop::EventLoopWindowTarget;
use monitor::{AvailableMonitorsIter, MonitorHandle};
use dpi::{LogicalPosition, LogicalSize};
@@ -283,7 +283,7 @@ impl WindowBuilder {
/// Error should be very rare and only occur in case of permission denied, incompatible system,
/// out of memory, etc.
#[inline]
pub fn build<T: 'static>(mut self, event_loop: &EventLoop<T>) -> Result<Window, CreationError> {
pub fn build<T: 'static>(mut self, window_target: &EventLoopWindowTarget<T>) -> Result<Window, CreationError> {
self.window.dimensions = Some(self.window.dimensions.unwrap_or_else(|| {
if let Some(ref monitor) = self.window.fullscreen {
// resizing the window to the dimensions of the monitor when fullscreen
@@ -296,7 +296,7 @@ impl WindowBuilder {
// building
platform_impl::Window::new(
&event_loop.event_loop,
&window_target.p,
self.window,
self.platform_specific,
).map(|window| Window { window })
@@ -311,7 +311,7 @@ impl Window {
/// Error should be very rare and only occur in case of permission denied, incompatible system,
/// out of memory, etc.
#[inline]
pub fn new<T: 'static>(event_loop: &EventLoop<T>) -> Result<Window, CreationError> {
pub fn new<T: 'static>(event_loop: &EventLoopWindowTarget<T>) -> Result<Window, CreationError> {
let builder = WindowBuilder::new();
builder.build(event_loop)
}