diff options
| author | Valentin Popov <valentin@popov.link> | 2026-06-22 12:12:27 +0300 |
|---|---|---|
| committer | Valentin Popov <valentin@popov.link> | 2026-06-22 12:13:32 +0300 |
| commit | d0bdbaa1ed76dfbf3211bb43eee48c49cc4fd448 (patch) | |
| tree | a0bd35c3940be62a5b5de1acc2366af377ffd181 /adapters/fparkan-platform-sdl/src/lib.rs | |
| parent | 7416fdc7e9a48837fff5056e6dc8d0774e90964b (diff) | |
| download | fparkan-d0bdbaa1ed76dfbf3211bb43eee48c49cc4fd448.tar.xz fparkan-d0bdbaa1ed76dfbf3211bb43eee48c49cc4fd448.zip | |
feat: implement FParkan architecture foundation
Add the modular fparkan workspace, domain crates, adapters, apps, xtask policy/CI, acceptance evidence, and licensed corpus gates for the macOS-focused roadmap foundation.
Diffstat (limited to 'adapters/fparkan-platform-sdl/src/lib.rs')
| -rw-r--r-- | adapters/fparkan-platform-sdl/src/lib.rs | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/adapters/fparkan-platform-sdl/src/lib.rs b/adapters/fparkan-platform-sdl/src/lib.rs new file mode 100644 index 0000000..73aea1f --- /dev/null +++ b/adapters/fparkan-platform-sdl/src/lib.rs @@ -0,0 +1,123 @@ +#![forbid(unsafe_code)] +//! SDL platform adapter proof behind safe `FParkan` ports. + +use fparkan_platform::{ + EventSource, GraphicsContextRequest, GraphicsProfile, PhysicalSize, PlatformError, + PlatformEvent, Version, WindowPort, +}; + +/// Adapter capabilities compiled into this package. +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct SdlAdapterCapabilities { + /// Supported graphics context requests in preference order. + pub graphics: Vec<GraphicsContextRequest>, + /// Whether adapter-owned code is free of `unsafe`. + pub project_owned_unsafe_free: bool, +} + +impl Default for SdlAdapterCapabilities { + fn default() -> Self { + Self { + graphics: vec![ + GraphicsContextRequest { + profile: GraphicsProfile::DesktopCore, + version: Version { major: 3, minor: 3 }, + }, + GraphicsContextRequest { + profile: GraphicsProfile::Embedded, + version: Version { major: 2, minor: 0 }, + }, + ], + project_owned_unsafe_free: true, + } + } +} + +/// Returns adapter readiness status for the safe project-owned layer. +#[must_use] +pub fn safe_adapter_ready() -> bool { + SdlAdapterCapabilities::default().project_owned_unsafe_free +} + +/// In-memory event source used by adapter smoke tests and composition roots +/// before a concrete SDL runtime is injected. +#[derive(Clone, Debug, Default)] +pub struct SdlEventSourceProof { + pending: Vec<PlatformEvent>, +} + +impl SdlEventSourceProof { + /// Creates an event source with deterministic pending events. + #[must_use] + pub fn new(pending: Vec<PlatformEvent>) -> Self { + Self { pending } + } +} + +impl EventSource for SdlEventSourceProof { + fn poll(&mut self, out: &mut Vec<PlatformEvent>) -> Result<(), PlatformError> { + out.append(&mut self.pending); + Ok(()) + } +} + +/// Safe window-port proof with SDL-compatible drawable-size semantics. +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct SdlWindowProof { + size: PhysicalSize, + presents: u64, +} + +impl SdlWindowProof { + /// Creates a proof window with a fixed drawable size. + #[must_use] + pub fn new(size: PhysicalSize) -> Self { + Self { size, presents: 0 } + } + + /// Number of successful present calls. + #[must_use] + pub fn presents(&self) -> u64 { + self.presents + } +} + +impl WindowPort for SdlWindowProof { + fn drawable_size(&self) -> PhysicalSize { + self.size + } + + fn present(&mut self) -> Result<(), PlatformError> { + self.presents = self.presents.saturating_add(1); + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn adapter_reports_safe_project_layer_ready() { + assert!(safe_adapter_ready()); + assert_eq!(SdlAdapterCapabilities::default().graphics.len(), 2); + } + + #[test] + fn event_source_and_window_ports_are_deterministic() -> Result<(), PlatformError> { + let mut source = SdlEventSourceProof::new(vec![PlatformEvent::Quit]); + let mut events = Vec::new(); + source.poll(&mut events)?; + source.poll(&mut events)?; + assert_eq!(events, vec![PlatformEvent::Quit]); + + let mut window = SdlWindowProof::new(PhysicalSize { + width: 320, + height: 240, + }); + assert_eq!(window.drawable_size().width, 320); + window.present()?; + assert_eq!(window.presents(), 1); + Ok(()) + } +} |
