2024-02-23 14:37:21 +04:00
|
|
|
use crate::application::ApplicationHandler;
|
|
|
|
|
use crate::error::EventLoopError;
|
2024-05-20 20:27:36 +04:00
|
|
|
use crate::event_loop::{ActiveEventLoop, EventLoop};
|
Add EventLoopExtPumpEvents and EventLoopExtRunOnDemand
This adds two new extensions for running a Winit event loop which will
replace `EventLoopExtRunReturn`
The `run_return` API is trying to solve multiple problems and address
multiple, unrelated, use cases but in doing so it is not succeeding
at addressing any of them fully.
The notable use cases we have are:
1. Applications want to be able to implement their own external
event loop and call some Winit API to poll / pump events, once
per iteration of their own loop, without blocking the outer,
external loop. Addressing #2706
2. Applications want to be able to re-run separate instantiations
of some Winit-based GUI and want to allow the event loop to exit with
a status, and then later be able to run the loop again for a new
instantiation of their GUI. Addressing #2431
It's very notable that these use cases can't be supported across
all platforms and so they are extensions, similar to
`EventLoopExtRunReturn`
The intention is to support these extensions on:
- Windows
- Linux (X11 + Wayland)
- macOS
- Android
These extensions aren't compatible with Web or iOS though.
Each method of running the loop will behave consistently in terms of how
`NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched
(so portable application code wouldn't necessarily need to have any awareness
of which method of running the loop was being used)
Once all backends have support for these extensions then we can
remove `EventLoopExtRunReturn`
For simplicity, the extensions are documented with the assumption that
the above platforms will be supported.
This patch makes no functional change, it only introduces these new
extensions so we can then handle adding platform-specific backends
in separate pull requests, so the work can be landed in stages.
2023-04-11 12:50:52 +01:00
|
|
|
#[cfg(doc)]
|
|
|
|
|
use crate::{platform::pump_events::EventLoopExtPumpEvents, window::Window};
|
|
|
|
|
|
|
|
|
|
/// Additional methods on [`EventLoop`] to return control flow to the caller.
|
|
|
|
|
pub trait EventLoopExtRunOnDemand {
|
2024-02-23 14:37:21 +04:00
|
|
|
/// Run the application with the event loop on the calling thread.
|
|
|
|
|
///
|
|
|
|
|
/// Unlike [`EventLoop::run_app`], this function accepts non-`'static` (i.e. non-`move`)
|
Add EventLoopExtPumpEvents and EventLoopExtRunOnDemand
This adds two new extensions for running a Winit event loop which will
replace `EventLoopExtRunReturn`
The `run_return` API is trying to solve multiple problems and address
multiple, unrelated, use cases but in doing so it is not succeeding
at addressing any of them fully.
The notable use cases we have are:
1. Applications want to be able to implement their own external
event loop and call some Winit API to poll / pump events, once
per iteration of their own loop, without blocking the outer,
external loop. Addressing #2706
2. Applications want to be able to re-run separate instantiations
of some Winit-based GUI and want to allow the event loop to exit with
a status, and then later be able to run the loop again for a new
instantiation of their GUI. Addressing #2431
It's very notable that these use cases can't be supported across
all platforms and so they are extensions, similar to
`EventLoopExtRunReturn`
The intention is to support these extensions on:
- Windows
- Linux (X11 + Wayland)
- macOS
- Android
These extensions aren't compatible with Web or iOS though.
Each method of running the loop will behave consistently in terms of how
`NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched
(so portable application code wouldn't necessarily need to have any awareness
of which method of running the loop was being used)
Once all backends have support for these extensions then we can
remove `EventLoopExtRunReturn`
For simplicity, the extensions are documented with the assumption that
the above platforms will be supported.
This patch makes no functional change, it only introduces these new
extensions so we can then handle adding platform-specific backends
in separate pull requests, so the work can be landed in stages.
2023-04-11 12:50:52 +01:00
|
|
|
/// closures and it is possible to return control back to the caller without
|
2023-09-07 08:25:04 +02:00
|
|
|
/// consuming the `EventLoop` (by using [`exit()`]) and
|
Add EventLoopExtPumpEvents and EventLoopExtRunOnDemand
This adds two new extensions for running a Winit event loop which will
replace `EventLoopExtRunReturn`
The `run_return` API is trying to solve multiple problems and address
multiple, unrelated, use cases but in doing so it is not succeeding
at addressing any of them fully.
The notable use cases we have are:
1. Applications want to be able to implement their own external
event loop and call some Winit API to poll / pump events, once
per iteration of their own loop, without blocking the outer,
external loop. Addressing #2706
2. Applications want to be able to re-run separate instantiations
of some Winit-based GUI and want to allow the event loop to exit with
a status, and then later be able to run the loop again for a new
instantiation of their GUI. Addressing #2431
It's very notable that these use cases can't be supported across
all platforms and so they are extensions, similar to
`EventLoopExtRunReturn`
The intention is to support these extensions on:
- Windows
- Linux (X11 + Wayland)
- macOS
- Android
These extensions aren't compatible with Web or iOS though.
Each method of running the loop will behave consistently in terms of how
`NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched
(so portable application code wouldn't necessarily need to have any awareness
of which method of running the loop was being used)
Once all backends have support for these extensions then we can
remove `EventLoopExtRunReturn`
For simplicity, the extensions are documented with the assumption that
the above platforms will be supported.
This patch makes no functional change, it only introduces these new
extensions so we can then handle adding platform-specific backends
in separate pull requests, so the work can be landed in stages.
2023-04-11 12:50:52 +01:00
|
|
|
/// so the event loop can be re-run after it has exit.
|
|
|
|
|
///
|
|
|
|
|
/// It's expected that each run of the loop will be for orthogonal instantiations of your
|
|
|
|
|
/// Winit application, but internally each instantiation may re-use some common window
|
|
|
|
|
/// system resources, such as a display server connection.
|
|
|
|
|
///
|
|
|
|
|
/// This API is not designed to run an event loop in bursts that you can exit from and return
|
|
|
|
|
/// to while maintaining the full state of your application. (If you need something like this
|
2024-02-23 14:37:21 +04:00
|
|
|
/// you can look at the [`EventLoopExtPumpEvents::pump_app_events()`] API)
|
Add EventLoopExtPumpEvents and EventLoopExtRunOnDemand
This adds two new extensions for running a Winit event loop which will
replace `EventLoopExtRunReturn`
The `run_return` API is trying to solve multiple problems and address
multiple, unrelated, use cases but in doing so it is not succeeding
at addressing any of them fully.
The notable use cases we have are:
1. Applications want to be able to implement their own external
event loop and call some Winit API to poll / pump events, once
per iteration of their own loop, without blocking the outer,
external loop. Addressing #2706
2. Applications want to be able to re-run separate instantiations
of some Winit-based GUI and want to allow the event loop to exit with
a status, and then later be able to run the loop again for a new
instantiation of their GUI. Addressing #2431
It's very notable that these use cases can't be supported across
all platforms and so they are extensions, similar to
`EventLoopExtRunReturn`
The intention is to support these extensions on:
- Windows
- Linux (X11 + Wayland)
- macOS
- Android
These extensions aren't compatible with Web or iOS though.
Each method of running the loop will behave consistently in terms of how
`NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched
(so portable application code wouldn't necessarily need to have any awareness
of which method of running the loop was being used)
Once all backends have support for these extensions then we can
remove `EventLoopExtRunReturn`
For simplicity, the extensions are documented with the assumption that
the above platforms will be supported.
This patch makes no functional change, it only introduces these new
extensions so we can then handle adding platform-specific backends
in separate pull requests, so the work can be landed in stages.
2023-04-11 12:50:52 +01:00
|
|
|
///
|
2024-02-23 14:37:21 +04:00
|
|
|
/// Each time `run_app_on_demand` is called the startup sequence of `init`, followed by
|
|
|
|
|
/// `resume` is being preserved.
|
Add EventLoopExtPumpEvents and EventLoopExtRunOnDemand
This adds two new extensions for running a Winit event loop which will
replace `EventLoopExtRunReturn`
The `run_return` API is trying to solve multiple problems and address
multiple, unrelated, use cases but in doing so it is not succeeding
at addressing any of them fully.
The notable use cases we have are:
1. Applications want to be able to implement their own external
event loop and call some Winit API to poll / pump events, once
per iteration of their own loop, without blocking the outer,
external loop. Addressing #2706
2. Applications want to be able to re-run separate instantiations
of some Winit-based GUI and want to allow the event loop to exit with
a status, and then later be able to run the loop again for a new
instantiation of their GUI. Addressing #2431
It's very notable that these use cases can't be supported across
all platforms and so they are extensions, similar to
`EventLoopExtRunReturn`
The intention is to support these extensions on:
- Windows
- Linux (X11 + Wayland)
- macOS
- Android
These extensions aren't compatible with Web or iOS though.
Each method of running the loop will behave consistently in terms of how
`NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched
(so portable application code wouldn't necessarily need to have any awareness
of which method of running the loop was being used)
Once all backends have support for these extensions then we can
remove `EventLoopExtRunReturn`
For simplicity, the extensions are documented with the assumption that
the above platforms will be supported.
This patch makes no functional change, it only introduces these new
extensions so we can then handle adding platform-specific backends
in separate pull requests, so the work can be landed in stages.
2023-04-11 12:50:52 +01:00
|
|
|
///
|
2023-09-07 08:25:04 +02:00
|
|
|
/// See the [`set_control_flow()`] docs on how to change the event loop's behavior.
|
Add EventLoopExtPumpEvents and EventLoopExtRunOnDemand
This adds two new extensions for running a Winit event loop which will
replace `EventLoopExtRunReturn`
The `run_return` API is trying to solve multiple problems and address
multiple, unrelated, use cases but in doing so it is not succeeding
at addressing any of them fully.
The notable use cases we have are:
1. Applications want to be able to implement their own external
event loop and call some Winit API to poll / pump events, once
per iteration of their own loop, without blocking the outer,
external loop. Addressing #2706
2. Applications want to be able to re-run separate instantiations
of some Winit-based GUI and want to allow the event loop to exit with
a status, and then later be able to run the loop again for a new
instantiation of their GUI. Addressing #2431
It's very notable that these use cases can't be supported across
all platforms and so they are extensions, similar to
`EventLoopExtRunReturn`
The intention is to support these extensions on:
- Windows
- Linux (X11 + Wayland)
- macOS
- Android
These extensions aren't compatible with Web or iOS though.
Each method of running the loop will behave consistently in terms of how
`NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched
(so portable application code wouldn't necessarily need to have any awareness
of which method of running the loop was being used)
Once all backends have support for these extensions then we can
remove `EventLoopExtRunReturn`
For simplicity, the extensions are documented with the assumption that
the above platforms will be supported.
This patch makes no functional change, it only introduces these new
extensions so we can then handle adding platform-specific backends
in separate pull requests, so the work can be landed in stages.
2023-04-11 12:50:52 +01:00
|
|
|
///
|
|
|
|
|
/// # Caveats
|
2023-10-25 17:42:51 +02:00
|
|
|
/// - 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
|
2024-07-10 16:17:39 +02:00
|
|
|
/// backend it is possible to use
|
|
|
|
|
#[cfg_attr(
|
|
|
|
|
any(web_platform, docsrs),
|
|
|
|
|
doc = " [`EventLoopExtWeb::spawn_app()`][crate::platform::web::EventLoopExtWeb::spawn_app()]"
|
|
|
|
|
)]
|
|
|
|
|
#[cfg_attr(not(any(web_platform, docsrs)), doc = " `EventLoopExtWeb::spawn_app()`")]
|
|
|
|
|
/// [^1] more than once instead).
|
Add EventLoopExtPumpEvents and EventLoopExtRunOnDemand
This adds two new extensions for running a Winit event loop which will
replace `EventLoopExtRunReturn`
The `run_return` API is trying to solve multiple problems and address
multiple, unrelated, use cases but in doing so it is not succeeding
at addressing any of them fully.
The notable use cases we have are:
1. Applications want to be able to implement their own external
event loop and call some Winit API to poll / pump events, once
per iteration of their own loop, without blocking the outer,
external loop. Addressing #2706
2. Applications want to be able to re-run separate instantiations
of some Winit-based GUI and want to allow the event loop to exit with
a status, and then later be able to run the loop again for a new
instantiation of their GUI. Addressing #2431
It's very notable that these use cases can't be supported across
all platforms and so they are extensions, similar to
`EventLoopExtRunReturn`
The intention is to support these extensions on:
- Windows
- Linux (X11 + Wayland)
- macOS
- Android
These extensions aren't compatible with Web or iOS though.
Each method of running the loop will behave consistently in terms of how
`NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched
(so portable application code wouldn't necessarily need to have any awareness
of which method of running the loop was being used)
Once all backends have support for these extensions then we can
remove `EventLoopExtRunReturn`
For simplicity, the extensions are documented with the assumption that
the above platforms will be supported.
This patch makes no functional change, it only introduces these new
extensions so we can then handle adding platform-specific backends
in separate pull requests, so the work can be landed in stages.
2023-04-11 12:50:52 +01:00
|
|
|
/// - No [`Window`] state can be carried between separate runs of the event loop.
|
|
|
|
|
///
|
2024-02-23 14:37:21 +04:00
|
|
|
/// You are strongly encouraged to use [`EventLoop::run_app()`] for portability, unless you
|
|
|
|
|
/// specifically need the ability to re-run a single event loop more than once
|
Add EventLoopExtPumpEvents and EventLoopExtRunOnDemand
This adds two new extensions for running a Winit event loop which will
replace `EventLoopExtRunReturn`
The `run_return` API is trying to solve multiple problems and address
multiple, unrelated, use cases but in doing so it is not succeeding
at addressing any of them fully.
The notable use cases we have are:
1. Applications want to be able to implement their own external
event loop and call some Winit API to poll / pump events, once
per iteration of their own loop, without blocking the outer,
external loop. Addressing #2706
2. Applications want to be able to re-run separate instantiations
of some Winit-based GUI and want to allow the event loop to exit with
a status, and then later be able to run the loop again for a new
instantiation of their GUI. Addressing #2431
It's very notable that these use cases can't be supported across
all platforms and so they are extensions, similar to
`EventLoopExtRunReturn`
The intention is to support these extensions on:
- Windows
- Linux (X11 + Wayland)
- macOS
- Android
These extensions aren't compatible with Web or iOS though.
Each method of running the loop will behave consistently in terms of how
`NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched
(so portable application code wouldn't necessarily need to have any awareness
of which method of running the loop was being used)
Once all backends have support for these extensions then we can
remove `EventLoopExtRunReturn`
For simplicity, the extensions are documented with the assumption that
the above platforms will be supported.
This patch makes no functional change, it only introduces these new
extensions so we can then handle adding platform-specific backends
in separate pull requests, so the work can be landed in stages.
2023-04-11 12:50:52 +01:00
|
|
|
///
|
|
|
|
|
/// # Supported Platforms
|
|
|
|
|
/// - Windows
|
|
|
|
|
/// - Linux
|
|
|
|
|
/// - macOS
|
|
|
|
|
/// - Android
|
|
|
|
|
///
|
|
|
|
|
/// # Unsupported Platforms
|
|
|
|
|
/// - **Web:** This API is fundamentally incompatible with the event-based way in which Web
|
|
|
|
|
/// browsers work because it's not possible to have a long-running external loop that would
|
|
|
|
|
/// block the browser and there is nothing that can be polled to ask for new events. Events
|
|
|
|
|
/// are delivered via callbacks based on an event loop that is internal to the browser itself.
|
2024-01-29 19:06:03 +01:00
|
|
|
/// - **iOS:** It's not possible to stop and start an `UIApplication` repeatedly on iOS.
|
2024-07-10 16:17:39 +02:00
|
|
|
///
|
|
|
|
|
/// [^1]: `spawn_app()` is only available on the Web platforms.
|
2023-10-25 17:42:51 +02:00
|
|
|
///
|
2024-01-31 17:29:59 +04:00
|
|
|
/// [`exit()`]: ActiveEventLoop::exit()
|
|
|
|
|
/// [`set_control_flow()`]: ActiveEventLoop::set_control_flow()
|
2024-06-24 13:04:55 +03:00
|
|
|
fn run_app_on_demand<A: ApplicationHandler>(
|
2024-02-23 14:37:21 +04:00
|
|
|
&mut self,
|
|
|
|
|
app: &mut A,
|
2024-05-20 20:27:36 +04:00
|
|
|
) -> Result<(), EventLoopError>;
|
Add EventLoopExtPumpEvents and EventLoopExtRunOnDemand
This adds two new extensions for running a Winit event loop which will
replace `EventLoopExtRunReturn`
The `run_return` API is trying to solve multiple problems and address
multiple, unrelated, use cases but in doing so it is not succeeding
at addressing any of them fully.
The notable use cases we have are:
1. Applications want to be able to implement their own external
event loop and call some Winit API to poll / pump events, once
per iteration of their own loop, without blocking the outer,
external loop. Addressing #2706
2. Applications want to be able to re-run separate instantiations
of some Winit-based GUI and want to allow the event loop to exit with
a status, and then later be able to run the loop again for a new
instantiation of their GUI. Addressing #2431
It's very notable that these use cases can't be supported across
all platforms and so they are extensions, similar to
`EventLoopExtRunReturn`
The intention is to support these extensions on:
- Windows
- Linux (X11 + Wayland)
- macOS
- Android
These extensions aren't compatible with Web or iOS though.
Each method of running the loop will behave consistently in terms of how
`NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched
(so portable application code wouldn't necessarily need to have any awareness
of which method of running the loop was being used)
Once all backends have support for these extensions then we can
remove `EventLoopExtRunReturn`
For simplicity, the extensions are documented with the assumption that
the above platforms will be supported.
This patch makes no functional change, it only introduces these new
extensions so we can then handle adding platform-specific backends
in separate pull requests, so the work can be landed in stages.
2023-04-11 12:50:52 +01:00
|
|
|
}
|
|
|
|
|
|
2024-06-24 13:04:55 +03:00
|
|
|
impl EventLoopExtRunOnDemand for EventLoop {
|
|
|
|
|
fn run_app_on_demand<A: ApplicationHandler>(
|
2024-05-20 20:27:36 +04:00
|
|
|
&mut self,
|
|
|
|
|
app: &mut A,
|
|
|
|
|
) -> Result<(), EventLoopError> {
|
2023-12-22 20:00:20 +04:00
|
|
|
self.event_loop.window_target().clear_exit();
|
2024-05-20 20:27:36 +04:00
|
|
|
self.event_loop.run_app_on_demand(app)
|
Add EventLoopExtPumpEvents and EventLoopExtRunOnDemand
This adds two new extensions for running a Winit event loop which will
replace `EventLoopExtRunReturn`
The `run_return` API is trying to solve multiple problems and address
multiple, unrelated, use cases but in doing so it is not succeeding
at addressing any of them fully.
The notable use cases we have are:
1. Applications want to be able to implement their own external
event loop and call some Winit API to poll / pump events, once
per iteration of their own loop, without blocking the outer,
external loop. Addressing #2706
2. Applications want to be able to re-run separate instantiations
of some Winit-based GUI and want to allow the event loop to exit with
a status, and then later be able to run the loop again for a new
instantiation of their GUI. Addressing #2431
It's very notable that these use cases can't be supported across
all platforms and so they are extensions, similar to
`EventLoopExtRunReturn`
The intention is to support these extensions on:
- Windows
- Linux (X11 + Wayland)
- macOS
- Android
These extensions aren't compatible with Web or iOS though.
Each method of running the loop will behave consistently in terms of how
`NewEvents(Init)`, `Resumed` and `LoopDestroyed` events are dispatched
(so portable application code wouldn't necessarily need to have any awareness
of which method of running the loop was being used)
Once all backends have support for these extensions then we can
remove `EventLoopExtRunReturn`
For simplicity, the extensions are documented with the assumption that
the above platforms will be supported.
This patch makes no functional change, it only introduces these new
extensions so we can then handle adding platform-specific backends
in separate pull requests, so the work can be landed in stages.
2023-04-11 12:50:52 +01:00
|
|
|
}
|
|
|
|
|
}
|
2023-12-22 20:00:20 +04:00
|
|
|
|
2024-01-31 17:29:59 +04:00
|
|
|
impl ActiveEventLoop {
|
2023-12-22 20:00:20 +04:00
|
|
|
/// Clear exit status.
|
|
|
|
|
pub(crate) fn clear_exit(&self) {
|
|
|
|
|
self.p.clear_exit()
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-01-29 19:06:03 +01:00
|
|
|
|
|
|
|
|
/// ```compile_fail
|
|
|
|
|
/// use winit::event_loop::EventLoop;
|
|
|
|
|
/// use winit::platform::run_on_demand::EventLoopExtRunOnDemand;
|
|
|
|
|
///
|
|
|
|
|
/// let mut event_loop = EventLoop::new().unwrap();
|
|
|
|
|
/// event_loop.run_on_demand(|_, _| {
|
|
|
|
|
/// // Attempt to run the event loop re-entrantly; this must fail.
|
|
|
|
|
/// event_loop.run_on_demand(|_, _| {});
|
|
|
|
|
/// });
|
|
|
|
|
/// ```
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
|
fn test_run_on_demand_cannot_access_event_loop() {}
|