winit/src/error.rs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

151 lines
3.8 KiB
Rust
Raw Normal View History

use std::error::Error;
use std::fmt::{self, Display};
/// A general error that may occur while running or creating
/// the event loop.
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
#[derive(Debug)]
#[non_exhaustive]
pub enum EventLoopError {
/// The event loop can't be re-created.
RecreationAttempt,
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
/// Application has exit with an error status.
ExitFailure(i32),
/// Got unspecified OS-specific error during the request.
Os(OsError),
/// Creating the event loop with the requested configuration is not supported.
NotSupported(NotSupportedError),
}
impl fmt::Display for EventLoopError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::RecreationAttempt => write!(f, "EventLoop can't be recreated"),
Self::Os(err) => err.fmt(f),
Self::ExitFailure(status) => write!(f, "Exit Failure: {status}"),
Self::NotSupported(err) => err.fmt(f),
}
}
}
impl Error for EventLoopError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
if let Self::Os(err) = self {
err.source()
} else {
None
}
}
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
}
impl From<OsError> for EventLoopError {
fn from(value: OsError) -> Self {
Self::Os(value)
}
}
impl From<NotSupportedError> for EventLoopError {
fn from(value: NotSupportedError) -> Self {
Self::NotSupported(value)
}
}
/// A general error that may occur during a request to the windowing system.
#[derive(Debug)]
#[non_exhaustive]
pub enum RequestError {
/// The request is not supported.
NotSupported(NotSupportedError),
/// The request was ignored by the operating system.
Ignored,
/// Got unspecified OS specific error during the request.
Os(OsError),
}
impl Display for RequestError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::NotSupported(err) => err.fmt(f),
Self::Ignored => write!(f, "The request was ignored"),
Self::Os(err) => err.fmt(f),
}
}
}
impl Error for RequestError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
if let Self::Os(err) = self {
err.source()
} else {
None
}
}
}
impl From<NotSupportedError> for RequestError {
fn from(value: NotSupportedError) -> Self {
Self::NotSupported(value)
}
}
impl From<OsError> for RequestError {
fn from(value: OsError) -> Self {
Self::Os(value)
}
}
/// The requested operation is not supported.
#[derive(Debug)]
pub struct NotSupportedError {
/// The reason why a certain operation is not supported.
reason: &'static str,
}
impl NotSupportedError {
pub(crate) fn new(reason: &'static str) -> Self {
Self { reason }
}
}
impl fmt::Display for NotSupportedError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Operation is not supported: {}", self.reason)
}
}
impl Error for NotSupportedError {}
/// Unclassified error from the OS.
#[derive(Debug)]
pub struct OsError {
line: u32,
file: &'static str,
error: Box<dyn Error + Send + Sync + 'static>,
}
impl OsError {
#[allow(dead_code)]
pub(crate) fn new(
line: u32,
file: &'static str,
error: impl Into<Box<dyn Error + Send + Sync + 'static>>,
) -> Self {
Self { line, file, error: error.into() }
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
}
}
impl Display for OsError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.pad(&format!("os error at {}:{}: {}", self.file, self.line, self.error))
}
}
impl Error for OsError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
Some(self.error.as_ref())
}
}
#[allow(unused_macros)]
macro_rules! os_error {
($error:expr) => {{
crate::error::OsError::new(line!(), file!(), $error)
}};
}