use std::sync::Arc;
use super::WindowId;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum RenderErrorStage {
Create,
Prepare,
Draw,
Copy,
Present,
Commit,
}
impl RenderErrorStage {
pub const fn as_str(self) -> &'static str {
match self {
Self::Create => "create",
Self::Prepare => "prepare",
Self::Draw => "draw",
Self::Copy => "copy",
Self::Present => "present",
Self::Commit => "commit",
}
}
}
type RenderErrorHandler = Arc<dyn Fn(&RenderError) + Send + Sync + 'static>;
#[derive(Clone)]
pub(crate) struct RenderErrorRegistration {
handler: RenderErrorHandler,
}
impl RenderErrorRegistration {
pub(crate) fn new(handler: impl Fn(&RenderError) + Send + Sync + 'static) -> Self {
Self {
handler: Arc::new(handler),
}
}
pub(crate) fn report(&self, error: &RenderError) {
(self.handler)(error);
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct RenderError {
window: WindowId,
renderer: &'static str,
stage: RenderErrorStage,
operation: &'static str,
code: i32,
message: String,
}
impl RenderError {
pub(crate) fn new(
window: WindowId,
renderer: &'static str,
stage: RenderErrorStage,
operation: &'static str,
code: i32,
message: impl Into<String>,
) -> Self {
Self {
window,
renderer,
stage,
operation,
code,
message: message.into(),
}
}
pub fn window(&self) -> &WindowId {
&self.window
}
pub const fn renderer(&self) -> &'static str {
self.renderer
}
pub const fn stage(&self) -> RenderErrorStage {
self.stage
}
pub const fn operation(&self) -> &'static str {
self.operation
}
pub const fn code(&self) -> i32 {
self.code
}
pub fn message(&self) -> &str {
&self.message
}
}
impl std::fmt::Display for RenderError {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
formatter,
"renderer '{}' failed to {} window '{}' during {} (0x{:08X}): {}",
self.renderer,
self.operation,
self.window.as_str(),
self.stage.as_str(),
self.code as u32,
self.message
)
}
}
impl std::error::Error for RenderError {}