shuyi_ui/
platform_facts.rs1use crate::prelude::*;
12
13pub use shuyi_assets::target::Quit;
14use shuyi_assets::target::TargetProfile;
15
16use crate::ctx::Keyboard;
17use crate::input::state::Device;
18
19#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
22#[serde(deny_unknown_fields)]
23#[non_exhaustive]
24pub struct PlatformFacts {
25 pub target: String,
28 pub quit: Quit,
31 pub windowed: bool,
35 pub keyboard: Keyboard,
39 pub pointer: bool,
41 pub touch: bool,
43 pub device: Option<Device>,
48}
49
50impl PlatformFacts {
51 pub fn from_profile(profile: &TargetProfile) -> Self {
53 let input = &profile.input;
54 Self {
55 target: profile.id.clone(),
56 quit: profile.quit,
57 windowed: profile.display.windowed,
58 keyboard: if input.keyboard {
59 Keyboard::Present
60 } else {
61 Keyboard::Absent
62 },
63 pointer: input.pointer,
64 touch: input.touch,
65 device: None,
66 }
67 }
68
69 #[must_use]
71 pub fn with_device(mut self, device: Device) -> Self {
72 self.device = Some(device);
73 self
74 }
75
76 pub fn can_quit(&self) -> bool {
80 self.quit == Quit::Game
81 }
82}
83
84impl Default for PlatformFacts {
85 fn default() -> Self {
88 Self {
89 target: "desktop".to_owned(),
90 quit: Quit::Game,
91 windowed: true,
92 keyboard: Keyboard::Present,
93 pointer: true,
94 touch: false,
95 device: None,
96 }
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103
104 #[test]
105 fn a_target_says_the_device_its_player_holds() {
106 let device = Device::Pad(crate::input::pad::PadKind::Playdate);
107 assert_eq!(PlatformFacts::default().device, None);
108 assert_eq!(
109 PlatformFacts::default().with_device(device).device,
110 Some(device)
111 );
112 }
113
114 fn engine(id: &str, source: &str) -> TargetProfile {
116 let file = format!("targets/{id}.ron");
117 TargetProfile::from_source(&file, id, source).unwrap()
118 }
119
120 fn desktop() -> TargetProfile {
121 engine("desktop", include_str!("../../../targets/desktop.ron"))
122 }
123
124 #[test]
125 fn the_default_facts_are_the_desktops() {
126 assert_eq!(
127 PlatformFacts::default(),
128 PlatformFacts::from_profile(&desktop())
129 );
130 }
131
132 #[test]
133 fn each_engine_profile_gives_its_facts() {
134 let facts = |id, source| PlatformFacts::from_profile(&engine(id, source));
135 let web = facts("web", include_str!("../../../targets/web.ron"));
136 assert_eq!(web.target, "web");
137 assert!(!web.can_quit());
138 assert!(web.windowed && web.pointer && !web.touch);
139 assert_eq!(web.keyboard, Keyboard::Present);
140 let deck = facts(
141 "steam-deck",
142 include_str!("../../../targets/steam-deck.ron"),
143 );
144 assert!(deck.can_quit());
145 assert!(!deck.windowed && !deck.pointer && deck.touch);
146 assert_eq!(deck.keyboard, Keyboard::Absent);
147 let playdate = facts("playdate", include_str!("../../../targets/playdate.ron"));
148 assert!(!playdate.can_quit() && !playdate.windowed);
149 assert!(!playdate.pointer && !playdate.touch);
150 assert_eq!(playdate.keyboard, Keyboard::Absent);
151 let desktop = PlatformFacts::from_profile(&desktop());
152 assert!(desktop.can_quit());
153 }
154}