1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
28pub enum Platform {
29 Linux,
31 Windows,
33 MacOS,
35 Android,
37 IOS,
39 Wasm,
41}
42
43impl Platform {
44 pub fn is_desktop(self) -> bool {
46 matches!(self, Self::Linux | Self::Windows | Self::MacOS)
47 }
48
49 pub fn is_mobile(self) -> bool {
51 matches!(self, Self::Android | Self::IOS)
52 }
53
54 pub fn is_wasm(self) -> bool {
56 matches!(self, Self::Wasm)
57 }
58
59 pub fn supports_x11(self) -> bool {
61 matches!(self, Self::Linux)
62 }
63
64 pub fn supports_wayland(self) -> bool {
66 matches!(self, Self::Linux)
67 }
68
69 pub fn has_gpu(self) -> bool {
71 !matches!(self, Self::Wasm)
72 }
73
74 pub fn name(self) -> &'static str {
76 match self {
77 Self::Linux => "Linux",
78 Self::Windows => "Windows",
79 Self::MacOS => "macOS",
80 Self::Android => "Android",
81 Self::IOS => "iOS",
82 Self::Wasm => "WebAssembly",
83 }
84 }
85
86 pub fn arch(self) -> &'static str {
88 if cfg!(target_arch = "x86_64") {
89 "x86_64"
90 } else if cfg!(target_arch = "aarch64") {
91 "aarch64"
92 } else if cfg!(target_arch = "arm") {
93 "arm"
94 } else if cfg!(target_arch = "wasm32") {
95 "wasm32"
96 } else {
97 "unknown"
98 }
99 }
100
101 pub fn debug_info(self) -> String {
103 format!(
104 "Platform: {} | Arch: {} | Desktop: {} | Mobile: {} | GPU: {}",
105 self.name(),
106 self.arch(),
107 self.is_desktop(),
108 self.is_mobile(),
109 self.has_gpu()
110 )
111 }
112}
113
114#[inline]
116pub const fn current_platform() -> Platform {
117 if cfg!(target_os = "linux") {
118 Platform::Linux
119 } else if cfg!(target_os = "windows") {
120 Platform::Windows
121 } else if cfg!(target_os = "macos") {
122 Platform::MacOS
123 } else if cfg!(target_os = "android") {
124 Platform::Android
125 } else if cfg!(target_os = "ios") {
126 Platform::IOS
127 } else if cfg!(target_arch = "wasm32") {
128 Platform::Wasm
129 } else {
130 Platform::Linux
132 }
133}
134
135#[derive(Debug, Clone)]
137pub struct PlatformConfig {
138 pub vsync: bool,
140 pub antialiasing: bool,
142 pub default_width: u32,
144 pub default_height: u32,
146 pub fsr_auto: bool,
148 pub fsr_threshold: u32,
150}
151
152impl PlatformConfig {
153 pub fn for_current() -> Self {
155 let platform = current_platform();
156 match platform {
157 Platform::Linux => Self {
158 vsync: true,
159 antialiasing: false, default_width: 1280,
161 default_height: 720,
162 fsr_auto: true,
163 fsr_threshold: 30,
164 },
165 Platform::Windows | Platform::MacOS => Self {
166 vsync: true,
167 antialiasing: true,
168 default_width: 1920,
169 default_height: 1080,
170 fsr_auto: false,
171 fsr_threshold: 60,
172 },
173 Platform::Android => Self {
174 vsync: true,
175 antialiasing: false,
176 default_width: 1280,
177 default_height: 720,
178 fsr_auto: true,
179 fsr_threshold: 25,
180 },
181 Platform::IOS => Self {
182 vsync: true,
183 antialiasing: false,
184 default_width: 1170,
185 default_height: 2532,
186 fsr_auto: true,
187 fsr_threshold: 30,
188 },
189 Platform::Wasm => Self {
190 vsync: true,
191 antialiasing: false,
192 default_width: 800,
193 default_height: 600,
194 fsr_auto: false,
195 fsr_threshold: 30,
196 },
197 }
198 }
199
200 pub fn low_end() -> Self {
202 Self {
203 vsync: false,
204 antialiasing: false,
205 default_width: 960,
206 default_height: 540,
207 fsr_auto: true,
208 fsr_threshold: 25,
209 }
210 }
211
212 pub fn high_end() -> Self {
214 Self {
215 vsync: true,
216 antialiasing: true,
217 default_width: 2560,
218 default_height: 1440,
219 fsr_auto: false,
220 fsr_threshold: 120,
221 }
222 }
223}
224
225#[cfg(test)]
226mod tests {
227 use super::*;
228
229 #[test]
230 fn test_current_platform() {
231 let p = current_platform();
232 assert!(p.is_desktop() || p.is_mobile() || p.is_wasm());
235 }
236
237 #[test]
238 fn test_platform_name() {
239 let p = current_platform();
240 let name = p.name();
241 assert!(!name.is_empty());
242 assert!(name.len() < 20);
243 }
244
245 #[test]
246 fn test_platform_config_defaults() {
247 let cfg = PlatformConfig::for_current();
248 assert!(cfg.vsync);
249 assert!(cfg.default_width > 0);
250 assert!(cfg.default_height > 0);
251 }
252
253 #[test]
254 fn test_platform_config_low_end() {
255 let cfg = PlatformConfig::low_end();
256 assert!(!cfg.vsync);
257 assert!(!cfg.antialiasing);
258 assert_eq!(cfg.default_width, 960);
259 assert_eq!(cfg.default_height, 540);
260 assert!(cfg.fsr_auto);
261 }
262
263 #[test]
264 fn test_platform_config_high_end() {
265 let cfg = PlatformConfig::high_end();
266 assert!(cfg.vsync);
267 assert!(cfg.antialiasing);
268 assert_eq!(cfg.default_width, 2560);
269 assert_eq!(cfg.default_height, 1440);
270 }
271
272 #[test]
273 fn test_platform_debug_info() {
274 let p = current_platform();
275 let info = p.debug_info();
276 assert!(info.contains("Platform:"));
277 assert!(info.contains("Arch:"));
278 }
279}