Skip to content

Commit

Permalink
Replace &EventLoop in callback with &EventLoopWindowTarget
Browse files Browse the repository at this point in the history
  • Loading branch information
Osspial committed Nov 15, 2018
1 parent 9f36a7a commit fa46825
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 30 deletions.
15 changes: 14 additions & 1 deletion src/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 { .. }")
Expand Down Expand Up @@ -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)
}
Expand All @@ -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> {
Expand Down
6 changes: 3 additions & 3 deletions src/platform/desktop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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)
}
Expand Down
48 changes: 30 additions & 18 deletions src/platform_impl/windows/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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};
Expand Down Expand Up @@ -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>,
}
Expand All @@ -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);

Expand All @@ -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();
Expand All @@ -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 {
Expand Down Expand Up @@ -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> {
Expand All @@ -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 {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/platform_impl/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
6 changes: 3 additions & 3 deletions src/platform_impl/windows/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -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()
Expand Down
8 changes: 4 additions & 4 deletions src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -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
Expand All @@ -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 })
Expand All @@ -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)
}
Expand Down

0 comments on commit fa46825

Please sign in to comment.