#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Platform {
Linux,
Windows,
MacOS,
Android,
IOS,
Wasm,
}
impl Platform {
pub fn is_desktop(self) -> bool {
matches!(self, Self::Linux | Self::Windows | Self::MacOS)
}
pub fn is_mobile(self) -> bool {
matches!(self, Self::Android | Self::IOS)
}
pub fn is_wasm(self) -> bool {
matches!(self, Self::Wasm)
}
pub fn supports_x11(self) -> bool {
matches!(self, Self::Linux)
}
pub fn supports_wayland(self) -> bool {
matches!(self, Self::Linux)
}
pub fn has_gpu(self) -> bool {
!matches!(self, Self::Wasm)
}
pub fn name(self) -> &'static str {
match self {
Self::Linux => "Linux",
Self::Windows => "Windows",
Self::MacOS => "macOS",
Self::Android => "Android",
Self::IOS => "iOS",
Self::Wasm => "WebAssembly",
}
}
pub fn arch(self) -> &'static str {
if cfg!(target_arch = "x86_64") {
"x86_64"
} else if cfg!(target_arch = "aarch64") {
"aarch64"
} else if cfg!(target_arch = "arm") {
"arm"
} else if cfg!(target_arch = "wasm32") {
"wasm32"
} else {
"unknown"
}
}
pub fn debug_info(self) -> String {
format!(
"Platform: {} | Arch: {} | Desktop: {} | Mobile: {} | GPU: {}",
self.name(),
self.arch(),
self.is_desktop(),
self.is_mobile(),
self.has_gpu()
)
}
}
#[inline]
pub const fn current_platform() -> Platform {
if cfg!(target_os = "linux") {
Platform::Linux
} else if cfg!(target_os = "windows") {
Platform::Windows
} else if cfg!(target_os = "macos") {
Platform::MacOS
} else if cfg!(target_os = "android") {
Platform::Android
} else if cfg!(target_os = "ios") {
Platform::IOS
} else if cfg!(target_arch = "wasm32") {
Platform::Wasm
} else {
Platform::Linux
}
}
#[derive(Debug, Clone)]
pub struct PlatformConfig {
pub vsync: bool,
pub antialiasing: bool,
pub default_width: u32,
pub default_height: u32,
pub fsr_auto: bool,
pub fsr_threshold: u32,
}
impl PlatformConfig {
pub fn for_current() -> Self {
let platform = current_platform();
match platform {
Platform::Linux => Self {
vsync: true,
antialiasing: false, default_width: 1280,
default_height: 720,
fsr_auto: true,
fsr_threshold: 30,
},
Platform::Windows | Platform::MacOS => Self {
vsync: true,
antialiasing: true,
default_width: 1920,
default_height: 1080,
fsr_auto: false,
fsr_threshold: 60,
},
Platform::Android => Self {
vsync: true,
antialiasing: false,
default_width: 1280,
default_height: 720,
fsr_auto: true,
fsr_threshold: 25,
},
Platform::IOS => Self {
vsync: true,
antialiasing: false,
default_width: 1170,
default_height: 2532,
fsr_auto: true,
fsr_threshold: 30,
},
Platform::Wasm => Self {
vsync: true,
antialiasing: false,
default_width: 800,
default_height: 600,
fsr_auto: false,
fsr_threshold: 30,
},
}
}
pub fn low_end() -> Self {
Self {
vsync: false,
antialiasing: false,
default_width: 960,
default_height: 540,
fsr_auto: true,
fsr_threshold: 25,
}
}
pub fn high_end() -> Self {
Self {
vsync: true,
antialiasing: true,
default_width: 2560,
default_height: 1440,
fsr_auto: false,
fsr_threshold: 120,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_current_platform() {
let p = current_platform();
assert!(p.is_desktop() || p.is_mobile() || p.is_wasm());
}
#[test]
fn test_platform_name() {
let p = current_platform();
let name = p.name();
assert!(!name.is_empty());
assert!(name.len() < 20);
}
#[test]
fn test_platform_config_defaults() {
let cfg = PlatformConfig::for_current();
assert!(cfg.vsync);
assert!(cfg.default_width > 0);
assert!(cfg.default_height > 0);
}
#[test]
fn test_platform_config_low_end() {
let cfg = PlatformConfig::low_end();
assert!(!cfg.vsync);
assert!(!cfg.antialiasing);
assert_eq!(cfg.default_width, 960);
assert_eq!(cfg.default_height, 540);
assert!(cfg.fsr_auto);
}
#[test]
fn test_platform_config_high_end() {
let cfg = PlatformConfig::high_end();
assert!(cfg.vsync);
assert!(cfg.antialiasing);
assert_eq!(cfg.default_width, 2560);
assert_eq!(cfg.default_height, 1440);
}
#[test]
fn test_platform_debug_info() {
let p = current_platform();
let info = p.debug_info();
assert!(info.contains("Platform:"));
assert!(info.contains("Arch:"));
}
}