aboutsummaryrefslogtreecommitdiff
path: root/crates/fparkan-platform/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/fparkan-platform/src')
-rw-r--r--crates/fparkan-platform/src/lib.rs165
1 files changed, 127 insertions, 38 deletions
diff --git a/crates/fparkan-platform/src/lib.rs b/crates/fparkan-platform/src/lib.rs
index cfa021b..bc908f4 100644
--- a/crates/fparkan-platform/src/lib.rs
+++ b/crates/fparkan-platform/src/lib.rs
@@ -1,11 +1,11 @@
#![forbid(unsafe_code)]
-//! Platform ports for clocks, input, events, windows, and graphics requests.
+//! Platform ports for clocks, event sources and window descriptors.
-/// Monotonic instant.
+/// Monotonic instant measured in milliseconds since process start.
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct MonotonicInstant(pub u64);
-/// Monotonic clock.
+/// Platform clock.
pub trait MonotonicClock {
/// Current instant.
fn now(&self) -> MonotonicInstant;
@@ -14,26 +14,74 @@ pub trait MonotonicClock {
/// Platform event.
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum PlatformEvent {
- /// Quit requested.
- Quit,
+ /// Window/application requested to quit.
+ QuitRequested,
+ /// Window focus changed.
+ FocusChanged { focused: bool },
+ /// Window resize or move to a new drawable size.
+ Resize { width: u32, height: u32 },
+ /// Device pixel ratio changed.
+ DpiChanged { scale: f64 },
+ /// Window minimized/hidden.
+ Minimized { minimized: bool },
+ /// Window occlusion state changed.
+ Occluded { occluded: bool },
+ /// 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,
+ },
}
-/// Platform error.
+/// Platform error with optional source detail.
#[derive(Debug)]
pub enum PlatformError {
- /// Backend failed.
- Backend,
+ /// 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 {
- write!(f, "{self:?}")
+ match self {
+ Self::Backend { context, message } => {
+ write!(f, "{context}: {message}")
+ }
+ }
}
}
impl std::error::Error for PlatformError {}
-/// Event source.
+/// Event source contract for polling platform events.
pub trait EventSource {
/// Polls events.
///
@@ -43,7 +91,7 @@ pub trait EventSource {
fn poll(&mut self, out: &mut Vec<PlatformEvent>) -> Result<(), PlatformError>;
}
-/// Physical size.
+/// Physical window size.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct PhysicalSize {
/// Width.
@@ -52,42 +100,83 @@ pub struct PhysicalSize {
pub height: u32,
}
-/// Window port.
+/// Window identity as a stable opaque handle token.
+#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
+pub struct WindowHandle {
+ /// Opaque integer token.
+ pub id: u64,
+}
+
+/// Window presentation and lifecycle port.
+///
+/// Presentation is not owned by the window abstraction. Render adapters
+/// own swapchain and present lifecycle.
pub trait WindowPort {
- /// Drawable size.
+ /// Current drawable size.
fn drawable_size(&self) -> PhysicalSize;
- /// Presents.
- ///
- /// # Errors
- ///
- /// Returns [`PlatformError`] when the backend cannot present the current
- /// frame.
- fn present(&mut self) -> Result<(), PlatformError>;
+ /// 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;
}
-/// Graphics profile.
+/// Render backend request contract.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
-pub enum GraphicsProfile {
- /// Desktop core.
- DesktopCore,
- /// Embedded profile.
- Embedded,
+pub struct RenderRequest {
+ /// Preferred color-space profile.
+ pub color_space: ColorSpace,
+ /// Preferred presentation mode.
+ pub presentation: PresentationMode,
+ /// Requested depth/stencil format.
+ pub depth: DepthStencilSupport,
}
-/// Version.
+/// Color-space profile.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
-pub struct Version {
- /// Major.
- pub major: u8,
- /// Minor.
- pub minor: u8,
+pub enum ColorSpace {
+ /// sRGB nonlinear.
+ Srgb,
+ /// Linear color-space.
+ Linear,
}
-/// Graphics context request.
+/// Presentation mode.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
-pub struct GraphicsContextRequest {
- /// Profile.
- pub profile: GraphicsProfile,
- /// Version.
- pub version: Version,
+pub enum PresentationMode {
+ /// VSync.
+ Fifo,
+ /// No VSync.
+ 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,
+ },
+ }
+ }
}