From 36279744ff46ba224f6655e84545a2be2ed367a4 Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Tue, 24 Oct 2023 14:12:45 +0200 Subject: [PATCH] On wasm, provide intradoc-link for `spawn()` function in `EventLoop` docs And on any other platform, emit a footnote explaining that this function is only available on wasm. --- src/event_loop.rs | 12 ++++++-- src/lib.rs | 56 ++++++++++++++++++++++++++--------- src/platform/run_on_demand.rs | 15 ++++++---- src/platform/web.rs | 19 ++++++++++-- 4 files changed, 79 insertions(+), 23 deletions(-) diff --git a/src/event_loop.rs b/src/event_loop.rs index 3d334a79b66..13e7488e80e 100644 --- a/src/event_loop.rs +++ b/src/event_loop.rs @@ -224,14 +224,22 @@ impl EventLoop { /// (that Rust doesn't see) that will also mean that the rest of the function is never executed /// and any values not passed to this function will *not* be dropped. /// - /// Web applications are recommended to use `spawn()` instead of `run()` to avoid the need + /// Web applications are recommended to use + #[cfg_attr( + wasm_platform, + doc = "[`EventLoopExtWebSys::spawn()`][crate::platform::web::EventLoopExtWebSys::spawn()]" + )] + #[cfg_attr(not(wasm_platform), doc = "`EventLoopExtWebSys::spawn()`")] + /// [^1] instead of [`run()`] to avoid the need /// for the Javascript exception trick, and to make it clearer that the event loop runs /// asynchronously (via the browser's own, internal, event loop) and doesn't block the /// current thread of execution like it does on other platforms. /// /// This function won't be available with `target_feature = "exception-handling"`. /// - /// [`set_control_flow()`]: EventLoopWindowTarget::set_control_flow + /// [`set_control_flow()`]: EventLoopWindowTarget::set_control_flow() + /// [`run()`]: Self::run() + /// [^1]: `EventLoopExtWebSys::spawn()` is only available on WASM. #[inline] #[cfg(not(all(wasm_platform, target_feature = "exception-handling")))] pub fn run(self, event_handler: F) -> Result<(), EventLoopError> diff --git a/src/lib.rs b/src/lib.rs index 54b43cd4f57..18bfb66b306 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,16 +26,36 @@ //! window or a key getting pressed while the window is focused. Devices can generate //! [`DeviceEvent`]s, which contain unfiltered event data that isn't specific to a certain window. //! Some user activity, like mouse movement, can generate both a [`WindowEvent`] *and* a -//! [`DeviceEvent`]. You can also create and handle your own custom [`UserEvent`]s, if desired. +//! [`DeviceEvent`]. You can also create and handle your own custom [`Event::UserEvent`]s, if desired. //! -//! You can retrieve events by calling [`EventLoop::run`][event_loop_run]. This function will +//! You can retrieve events by calling [`EventLoop::run()`]. This function will //! dispatch events for every [`Window`] that was created with that particular [`EventLoop`], and -//! will run until [`exit()`] is used, at which point [`Event`]`::`[`LoopExiting`]. +//! will run until [`exit()`] is used, at which point [`Event::LoopExiting`]. //! //! Winit no longer uses a `EventLoop::poll_events() -> impl Iterator`-based event loop //! model, since that can't be implemented properly on some platforms (e.g web, iOS) and works poorly on //! most other platforms. However, this model can be re-implemented to an extent with -//! [`EventLoopExtPumpEvents::pump_events`]. See that method's documentation for more reasons about why +#![cfg_attr( + any( + windows_platform, + macos_platform, + android_platform, + x11_platform, + wayland_platform + ), + doc = "[`EventLoopExtPumpEvents::pump_events()`][platform::pump_events::EventLoopExtPumpEvents::pump_events()]" +)] +#![cfg_attr( + not(any( + windows_platform, + macos_platform, + android_platform, + x11_platform, + wayland_platform + )), + doc = "`EventLoopExtPumpEvents::pump_events()`[^1]" +)] +//! . See that method's documentation for more reasons about why //! it's discouraged, beyond compatibility reasons. //! //! @@ -92,8 +112,8 @@ //! }); //! ``` //! -//! [`Event`]`::`[`WindowEvent`] has a [`WindowId`] member. In multi-window environments, it should be -//! compared to the value returned by [`Window::id()`][window_id_fn] to determine which [`Window`] +//! [`WindowEvent`] has a [`WindowId`] member. In multi-window environments, it should be +//! compared to the value returned by [`Window::id()`] to determine which [`Window`] //! dispatched the event. //! //! # Drawing on the window @@ -101,7 +121,7 @@ //! Winit doesn't directly provide any methods for drawing on a [`Window`]. However it allows you to //! retrieve the raw handle of the window and display (see the [`platform`] module and/or the //! [`raw_window_handle`] and [`raw_display_handle`] methods), which in turn allows -//! you to create an OpenGL/Vulkan/DirectX/Metal/etc. context that can be used to render graphics. +//! you to create an OpenGL/Vulkan/DirectX/Metal/etc. context that can be used to render graphics. //! //! Note that many platforms will display garbage data in the window's client area if the //! application doesn't render anything to the window by the time the desktop compositor is ready to @@ -109,10 +129,20 @@ //! [`visible` set to `false`](crate::window::WindowBuilder::with_visible) and explicitly make the //! window visible only once you're ready to render into it. //! +#![cfg_attr( + not(any( + windows_platform, + macos_platform, + android_platform, + x11_platform, + wayland_platform + )), + doc = "[^1]: `EventLoopExtPumpEvents::pump_events()` is only available on Windows, macOS, Android, X11 and Wayland." +)] +//! //! [`EventLoop`]: event_loop::EventLoop -//! [`EventLoopExtPumpEvents::pump_events`]: ./platform/pump_events/trait.EventLoopExtPumpEvents.html#tymethod.pump_events //! [`EventLoop::new()`]: event_loop::EventLoop::new -//! [event_loop_run]: event_loop::EventLoop::run +//! [`EventLoop::run()`]: event_loop::EventLoop::run //! [`exit()`]: event_loop::EventLoopWindowTarget::exit //! [`Window`]: window::Window //! [`WindowId`]: window::WindowId @@ -120,13 +150,11 @@ //! [window_new]: window::Window::new //! [window_builder_new]: window::WindowBuilder::new //! [window_builder_build]: window::WindowBuilder::build -//! [window_id_fn]: window::Window::id -//! [`Event`]: event::Event +//! [`Window::id()`]: window::Window::id //! [`WindowEvent`]: event::WindowEvent //! [`DeviceEvent`]: event::DeviceEvent -//! [`UserEvent`]: event::Event::UserEvent -//! [`LoopExiting`]: event::Event::LoopExiting -//! [`platform`]: platform +//! [`Event::UserEvent`]: event::Event::UserEvent +//! [`Event::LoopExiting`]: event::Event::LoopExiting //! [`raw_window_handle`]: ./window/struct.Window.html#method.raw_window_handle //! [`raw_display_handle`]: ./window/struct.Window.html#method.raw_display_handle diff --git a/src/platform/run_on_demand.rs b/src/platform/run_on_demand.rs index 7443c2bd929..5326e92c74a 100644 --- a/src/platform/run_on_demand.rs +++ b/src/platform/run_on_demand.rs @@ -35,9 +35,9 @@ pub trait EventLoopExtRunOnDemand { /// See the [`set_control_flow()`] docs on how to change the event loop's behavior. /// /// # Caveats - /// - This extension isn't available on all platforms, since it's not always possible to - /// return to the caller (specifically this is impossible on iOS and Web - though with - /// the Web backend it is possible to use `spawn()` more than once instead). + /// - This extension isn't available on all platforms, since it's not always possible to return + /// to the caller (specifically this is impossible on iOS and Web - though with the Web + /// backend it is possible to use `EventLoopExtWebSys::spawn()`[^1] more than once instead). /// - No [`Window`] state can be carried between separate runs of the event loop. /// /// You are strongly encouraged to use [`EventLoop::run()`] for portability, unless you specifically need @@ -57,8 +57,13 @@ pub trait EventLoopExtRunOnDemand { /// on an event loop that is internal to the browser itself. /// - **iOS:** It's not possible to stop and start an `NSApplication` repeatedly on iOS. /// - /// [`exit()`]: EventLoopWindowTarget::exit - /// [`set_control_flow()`]: EventLoopWindowTarget::set_control_flow + #[cfg_attr( + not(wasm_platform), + doc = "[^1]: `spawn()` is only available on `wasm` platforms." + )] + /// + /// [`exit()`]: EventLoopWindowTarget::exit() + /// [`set_control_flow()`]: EventLoopWindowTarget::set_control_flow() fn run_on_demand(&mut self, event_handler: F) -> Result<(), EventLoopError> where F: FnMut(Event, &EventLoopWindowTarget); diff --git a/src/platform/web.rs b/src/platform/web.rs index 8a9a3d01ff5..06e3f682a44 100644 --- a/src/platform/web.rs +++ b/src/platform/web.rs @@ -109,13 +109,28 @@ pub trait EventLoopExtWebSys { /// Initializes the winit event loop. /// - /// Unlike `run`, this returns immediately, and doesn't throw an exception in order to - /// satisfy its `!` return type. + /// Unlike + #[cfg_attr( + all(wasm_platform, target_feature = "exception-handling"), + doc = "`run()`" + )] + #[cfg_attr( + not(all(wasm_platform, target_feature = "exception-handling")), + doc = "[`run()`]" + )] + /// [^1], this returns immediately, and doesn't throw an exception in order to + /// satisfy its [`!`] return type. /// /// Once the event loop has been destroyed, it's possible to reinitialize another event loop /// by calling this function again. This can be useful if you want to recreate the event loop /// while the WebAssembly module is still loaded. For example, this can be used to recreate the /// event loop when switching between tabs on a single page application. + /// + #[cfg_attr( + not(all(wasm_platform, target_feature = "exception-handling")), + doc = "[`run()`]: EventLoop::run()" + )] + /// [^1]: `run()` is _not_ available on WASM when the target supports `exception-handling`. fn spawn(self, event_handler: F) where F: 'static + FnMut(Event, &EventLoopWindowTarget);