Files
fparkan/crates/fparkan-platform/src/lib.rs
T

234 lines
6.0 KiB
Rust
Raw Normal View History

#![forbid(unsafe_code)]
2026-06-23 22:32:50 +04:00
#![cfg_attr(
test,
allow(
clippy::cast_possible_truncation,
clippy::cast_possible_wrap,
clippy::cast_precision_loss,
clippy::expect_used,
clippy::float_cmp,
clippy::identity_op,
clippy::too_many_lines,
clippy::uninlined_format_args,
clippy::map_unwrap_or,
clippy::needless_raw_string_hashes,
clippy::semicolon_if_nothing_returned,
clippy::type_complexity,
clippy::panic,
clippy::unwrap_used
)
)]
2026-06-23 22:05:16 +04:00
//! Platform ports for clocks, event sources and window descriptors.
2026-06-23 22:50:32 +04:00
use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
2026-06-23 22:05:16 +04:00
/// Monotonic instant measured in milliseconds since process start.
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct MonotonicInstant(pub u64);
2026-06-23 22:05:16 +04:00
/// Platform clock.
pub trait MonotonicClock {
/// Current instant.
fn now(&self) -> MonotonicInstant;
}
/// Platform event.
2026-06-23 22:32:50 +04:00
#[derive(Clone, Debug, PartialEq)]
pub enum PlatformEvent {
2026-06-23 22:05:16 +04:00
/// Window/application requested to quit.
QuitRequested,
/// Window focus changed.
2026-06-23 22:32:50 +04:00
FocusChanged {
/// Whether the window is focused.
focused: bool,
},
2026-06-23 22:05:16 +04:00
/// Window resize or move to a new drawable size.
2026-06-23 22:32:50 +04:00
Resize {
/// Drawable width in physical pixels.
width: u32,
/// Drawable height in physical pixels.
height: u32,
},
2026-06-23 22:05:16 +04:00
/// Device pixel ratio changed.
2026-06-23 22:32:50 +04:00
DpiChanged {
/// Logical-to-physical scale factor.
scale: f64,
},
2026-06-23 22:05:16 +04:00
/// Window minimized/hidden.
2026-06-23 22:32:50 +04:00
Minimized {
/// Whether the window is minimized.
minimized: bool,
},
2026-06-23 22:05:16 +04:00
/// Window occlusion state changed.
2026-06-23 22:32:50 +04:00
Occluded {
/// Whether the window is occluded.
occluded: bool,
},
2026-06-23 22:05:16 +04:00
/// Window is being suspended.
Suspended,
/// Window resumed from suspend.
Resumed,
/// Keyboard/scancode input.
KeyboardInput {
/// Platform scancode.
scancode: u32,
/// Pressed state.
pressed: bool,
},
/// Mouse button input.
MouseInput {
/// Mouse button code.
button: u16,
/// Pressed state.
pressed: bool,
/// X position in window coordinates.
x: f64,
/// Y position in window coordinates.
y: f64,
},
/// Mouse cursor movement.
CursorMoved {
/// Cursor x.
x: f64,
/// Cursor y.
y: f64,
},
}
2026-06-23 22:05:16 +04:00
/// Platform error with optional source detail.
#[derive(Debug)]
pub enum PlatformError {
2026-06-23 22:05:16 +04:00
/// Backend/backend-specific failure.
Backend {
/// Operation or subsystem.
context: &'static str,
/// Human-readable details.
message: String,
},
}
impl std::fmt::Display for PlatformError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2026-06-23 22:05:16 +04:00
match self {
Self::Backend { context, message } => {
write!(f, "{context}: {message}")
}
}
}
}
impl std::error::Error for PlatformError {}
2026-06-23 22:05:16 +04:00
/// Event source contract for polling platform events.
pub trait EventSource {
/// Polls events.
///
/// # Errors
///
/// Returns [`PlatformError`] when the backend cannot collect events.
fn poll(&mut self, out: &mut Vec<PlatformEvent>) -> Result<(), PlatformError>;
}
2026-06-23 22:05:16 +04:00
/// Physical window size.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct PhysicalSize {
/// Width.
pub width: u32,
/// Height.
pub height: u32,
}
2026-06-23 22:05:16 +04:00
/// Window identity as a stable opaque handle token.
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
pub struct WindowHandle {
/// Opaque integer token.
pub id: u64,
}
2026-06-23 22:50:32 +04:00
/// Native raw window/display handles for render surface creation.
#[derive(Clone, Copy, Debug)]
pub struct NativeWindowHandles {
/// Raw display handle.
pub display: RawDisplayHandle,
/// Raw window handle.
pub window: RawWindowHandle,
}
2026-06-23 22:05:16 +04:00
/// Window presentation and lifecycle port.
///
/// Presentation is not owned by the window abstraction. Render adapters
/// own swapchain and present lifecycle.
pub trait WindowPort {
2026-06-23 22:05:16 +04:00
/// Current drawable size.
fn drawable_size(&self) -> PhysicalSize;
2026-06-23 22:05:16 +04:00
/// DPI scale for this window.
fn dpi_scale(&self) -> f64;
/// Whether the window is focused.
fn has_focus(&self) -> bool;
/// Whether the window is minimized.
fn is_minimized(&self) -> bool;
/// Whether the window is occluded.
fn is_occluded(&self) -> bool;
/// Opaque window identity.
fn handle(&self) -> WindowHandle;
2026-06-23 22:50:32 +04:00
/// Raw native handles for render surface creation, when backed by a native window.
fn native_handles(&self) -> Option<NativeWindowHandles> {
None
}
}
2026-06-23 22:05:16 +04:00
/// Render backend request contract.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2026-06-23 22:05:16 +04:00
pub struct RenderRequest {
/// Preferred color-space profile.
pub color_space: ColorSpace,
/// Preferred presentation mode.
pub presentation: PresentationMode,
/// Requested depth/stencil format.
pub depth: DepthStencilSupport,
}
2026-06-23 22:05:16 +04:00
/// Color-space profile.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2026-06-23 22:05:16 +04:00
pub enum ColorSpace {
/// sRGB nonlinear.
Srgb,
/// Linear color-space.
Linear,
}
2026-06-23 22:05:16 +04:00
/// Presentation mode.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
2026-06-23 22:05:16 +04:00
pub enum PresentationMode {
2026-06-23 22:32:50 +04:00
/// `VSync`.
2026-06-23 22:05:16 +04:00
Fifo,
2026-06-23 22:32:50 +04:00
/// No `VSync`.
2026-06-23 22:05:16 +04:00
Immediate,
/// Triple-buffer mailbox fallback.
Mailbox,
}
/// Depth/stencil support profile requested by the composition root.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct DepthStencilSupport {
/// Depth bits.
pub depth_bits: u8,
/// Stencil bits.
pub stencil_bits: u8,
}
impl RenderRequest {
/// Returns a conservative default request.
#[must_use]
pub const fn conservative() -> Self {
Self {
color_space: ColorSpace::Srgb,
presentation: PresentationMode::Fifo,
depth: DepthStencilSupport {
depth_bits: 24,
stencil_bits: 8,
},
}
}
}