From 9ae75c0c0351bba16192279d364bbb0967b948c0 Mon Sep 17 00:00:00 2001 From: Jacob Kiesel Date: Fri, 21 Dec 2018 09:51:48 -0700 Subject: [PATCH] Add support for generating dummy DeviceIDs and WindowIDs (#738) * Add support for generating dummy DeviceIDs and WindowIDs * Fix linux * Improve docs and move dummy to unsafe * Strengthen guarantees a bit * Add backticks to CHANGELOG.md Co-Authored-By: Xaeroxe --- CHANGELOG.md | 1 + src/lib.rs | 22 ++++++++++++++++++++++ src/platform/android/mod.rs | 12 ++++++++++++ src/platform/emscripten/mod.rs | 12 ++++++++++++ src/platform/ios/mod.rs | 12 ++++++++++++ src/platform/linux/mod.rs | 12 ++++++++++++ src/platform/linux/wayland/mod.rs | 12 ++++++++++++ src/platform/linux/x11/mod.rs | 12 ++++++++++++ src/platform/macos/mod.rs | 6 ++++++ src/platform/macos/window.rs | 6 ++++++ src/platform/windows/mod.rs | 14 ++++++++++++++ 11 files changed, 121 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50ca45c5..ce5b4dd4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ - On Wayland, fix resizing and DPI calculation when a `wl_output` is removed without sending a `leave` event to the `wl_surface`, such as disconnecting a monitor from a laptop. - On Wayland, DPI calculation is handled by smithay-client-toolkit. - On X11, `WindowBuilder::with_min_dimensions` and `WindowBuilder::with_max_dimensions` now correctly account for DPI. +- Added support for generating dummy `DeviceId`s and `WindowId`s to better support unit testing. # Version 0.18.0 (2018-11-07) diff --git a/src/lib.rs b/src/lib.rs index 4ab8f44e..ece7d35f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -169,6 +169,17 @@ impl std::fmt::Debug for Window { #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct WindowId(platform::WindowId); +impl WindowId { + /// Returns a dummy `WindowId`, useful for unit testing. The only guarantee made about the return + /// value of this function is that it will always be equal to itself and to future values returned + /// by this function. No other guarantees are made. This may be equal to a real `WindowId`. + /// + /// **Passing this into a winit function will result in undefined behavior.** + pub unsafe fn dummy() -> Self { + WindowId(platform::WindowId::dummy()) + } +} + /// Identifier of an input device. /// /// Whenever you receive an event arising from a particular input device, this event contains a `DeviceId` which @@ -177,6 +188,17 @@ pub struct WindowId(platform::WindowId); #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct DeviceId(platform::DeviceId); +impl DeviceId { + /// Returns a dummy `DeviceId`, useful for unit testing. The only guarantee made about the return + /// value of this function is that it will always be equal to itself and to future values returned + /// by this function. No other guarantees are made. This may be equal to a real `DeviceId`. + /// + /// **Passing this into a winit function will result in undefined behavior.** + pub unsafe fn dummy() -> Self { + DeviceId(platform::DeviceId::dummy()) + } +} + /// Provides a way to retrieve events from the system and from the windows that were registered to /// the events loop. /// diff --git a/src/platform/android/mod.rs b/src/platform/android/mod.rs index 165c5459..dad73801 100644 --- a/src/platform/android/mod.rs +++ b/src/platform/android/mod.rs @@ -170,9 +170,21 @@ impl EventsLoopProxy { #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct WindowId; +impl WindowId { + pub unsafe fn dummy() -> Self { + WindowId + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct DeviceId; +impl DeviceId { + pub unsafe fn dummy() -> Self { + DeviceId + } +} + pub struct Window { native_window: *const c_void, } diff --git a/src/platform/emscripten/mod.rs b/src/platform/emscripten/mod.rs index a3d25ef1..3a5feb61 100644 --- a/src/platform/emscripten/mod.rs +++ b/src/platform/emscripten/mod.rs @@ -27,6 +27,12 @@ unsafe impl Sync for PlatformSpecificWindowBuilderAttributes {} #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct DeviceId; +impl DeviceId { + pub unsafe fn dummy() -> Self { + DeviceId + } +} + #[derive(Clone, Default)] pub struct PlatformSpecificHeadlessBuilderAttributes; @@ -149,6 +155,12 @@ impl EventsLoop { #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct WindowId(usize); +impl WindowId { + pub unsafe fn dummy() -> Self { + WindowId(0) + } +} + pub struct Window2 { cursor_grabbed: Mutex, cursor_hidden: Mutex, diff --git a/src/platform/ios/mod.rs b/src/platform/ios/mod.rs index 1c8e7c85..6830ace4 100644 --- a/src/platform/ios/mod.rs +++ b/src/platform/ios/mod.rs @@ -290,9 +290,21 @@ impl EventsLoopProxy { #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct WindowId; +impl WindowId { + pub unsafe fn dummy() -> Self { + WindowId + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct DeviceId; +impl DeviceId { + pub unsafe fn dummy() -> Self { + DeviceId + } +} + #[derive(Clone)] pub struct PlatformSpecificWindowBuilderAttributes { pub root_view_class: &'static Class, diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index cf302caa..1f88cdfe 100644 --- a/src/platform/linux/mod.rs +++ b/src/platform/linux/mod.rs @@ -66,12 +66,24 @@ pub enum WindowId { Wayland(wayland::WindowId), } +impl WindowId { + pub unsafe fn dummy() -> Self { + WindowId::X(x11::WindowId::dummy()) + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum DeviceId { X(x11::DeviceId), Wayland(wayland::DeviceId), } +impl DeviceId { + pub unsafe fn dummy() -> Self { + DeviceId::X(x11::DeviceId::dummy()) + } +} + #[derive(Debug, Clone)] pub enum MonitorId { X(x11::MonitorId), diff --git a/src/platform/linux/wayland/mod.rs b/src/platform/linux/wayland/mod.rs index e938b8a7..659cb7af 100644 --- a/src/platform/linux/wayland/mod.rs +++ b/src/platform/linux/wayland/mod.rs @@ -16,9 +16,21 @@ mod window; #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct DeviceId; +impl DeviceId { + pub unsafe fn dummy() -> Self { + DeviceId + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct WindowId(usize); +impl WindowId { + pub unsafe fn dummy() -> Self { + WindowId(0) + } +} + #[inline] fn make_wid(s: &Proxy) -> WindowId { WindowId(s.c_ptr() as usize) diff --git a/src/platform/linux/x11/mod.rs b/src/platform/linux/x11/mod.rs index a4eb39eb..31712894 100644 --- a/src/platform/linux/x11/mod.rs +++ b/src/platform/linux/x11/mod.rs @@ -1262,9 +1262,21 @@ impl<'a> Deref for DeviceInfo<'a> { #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct WindowId(ffi::Window); +impl WindowId { + pub unsafe fn dummy() -> Self { + WindowId(0) + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct DeviceId(c_int); +impl DeviceId { + pub unsafe fn dummy() -> Self { + DeviceId(0) + } +} + pub struct Window(Arc); impl Deref for Window { diff --git a/src/platform/macos/mod.rs b/src/platform/macos/mod.rs index 9639482a..1091648e 100644 --- a/src/platform/macos/mod.rs +++ b/src/platform/macos/mod.rs @@ -8,6 +8,12 @@ use std::sync::Arc; #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct DeviceId; +impl DeviceId { + pub unsafe fn dummy() -> Self { + DeviceId + } +} + use {CreationError}; pub struct Window { diff --git a/src/platform/macos/window.rs b/src/platform/macos/window.rs index 90a258df..d344f126 100644 --- a/src/platform/macos/window.rs +++ b/src/platform/macos/window.rs @@ -50,6 +50,12 @@ use window::MonitorId as RootMonitorId; #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Id(pub usize); +impl Id { + pub unsafe fn dummy() -> Self { + Id(0) + } +} + // TODO: It's possible for delegate methods to be called asynchronously, causing data races / `RefCell` panics. pub struct DelegateState { view: IdRef, diff --git a/src/platform/windows/mod.rs b/src/platform/windows/mod.rs index f7a576eb..16f9e148 100644 --- a/src/platform/windows/mod.rs +++ b/src/platform/windows/mod.rs @@ -26,6 +26,12 @@ unsafe impl Sync for Cursor {} #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct DeviceId(u32); +impl DeviceId { + pub unsafe fn dummy() -> Self { + DeviceId(0) + } +} + impl DeviceId { pub fn get_persistent_identifier(&self) -> Option { if self.0 != 0 { @@ -48,6 +54,14 @@ pub struct WindowId(HWND); unsafe impl Send for WindowId {} unsafe impl Sync for WindowId {} +impl WindowId { + pub unsafe fn dummy() -> Self { + use std::ptr::null_mut; + + WindowId(null_mut()) + } +} + mod dpi; mod drop_handler; mod event;