fyrox_ui/style/
resource.rs1use crate::style::{IntoPrimitive, Style, StyleProperty, StyledProperty};
24use fyrox_core::visitor::error::VisitError;
25use fyrox_core::{
26 io::FileError,
27 log::Log,
28 type_traits::prelude::*,
29 visitor::{prelude::*, Visitor},
30 ImmutableString, Uuid,
31};
32use fyrox_resource::{
33 io::ResourceIo,
34 loader::{BoxedLoaderFuture, LoaderPayload, ResourceLoader},
35 manager::ResourceManager,
36 state::LoadError,
37 Resource, ResourceData,
38};
39use std::{
40 error::Error,
41 fmt::{Display, Formatter},
42 path::{Path, PathBuf},
43 sync::Arc,
44};
45
46#[derive(Debug)]
48pub enum StyleResourceError {
49 Io(FileError),
51
52 Visit(VisitError),
54}
55
56impl Display for StyleResourceError {
57 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
58 match self {
59 Self::Io(v) => {
60 write!(f, "A file load error has occurred {v:?}")
61 }
62 Self::Visit(v) => {
63 write!(
64 f,
65 "An error that may occur due to version incompatibilities. {v:?}"
66 )
67 }
68 }
69 }
70}
71
72impl From<FileError> for StyleResourceError {
73 fn from(e: FileError) -> Self {
74 Self::Io(e)
75 }
76}
77
78impl From<VisitError> for StyleResourceError {
79 fn from(e: VisitError) -> Self {
80 Self::Visit(e)
81 }
82}
83
84impl ResourceData for Style {
85 fn type_uuid(&self) -> Uuid {
86 <Self as TypeUuidProvider>::type_uuid()
87 }
88
89 fn save(&mut self, path: &Path) -> Result<(), Box<dyn Error>> {
90 let mut visitor = Visitor::new();
91 self.visit("Style", &mut visitor)?;
92 visitor.save_ascii_to_file(path)?;
93 Ok(())
94 }
95
96 fn can_be_saved(&self) -> bool {
97 true
98 }
99
100 fn try_clone_box(&self) -> Option<Box<dyn ResourceData>> {
101 Some(Box::new(self.clone()))
102 }
103}
104
105pub struct StyleLoader {
107 pub resource_manager: ResourceManager,
109}
110
111impl ResourceLoader for StyleLoader {
112 fn extensions(&self) -> &[&str] {
113 &["style"]
114 }
115
116 fn is_native_extension(&self, ext: &str) -> bool {
117 fyrox_core::cmp_strings_case_insensitive(ext, "style")
118 }
119
120 fn data_type_uuid(&self) -> Uuid {
121 <Style as TypeUuidProvider>::type_uuid()
122 }
123
124 fn load(&self, path: PathBuf, io: Arc<dyn ResourceIo>) -> BoxedLoaderFuture {
125 let resource_manager = self.resource_manager.clone();
126 Box::pin(async move {
127 let tile_set = Style::from_file(&path, io.as_ref(), resource_manager)
128 .await
129 .map_err(LoadError::new)?;
130 Ok(LoaderPayload::new(tile_set))
131 })
132 }
133}
134
135pub type StyleResource = Resource<Style>;
137
138pub trait StyleResourceExt {
140 fn set(&self, name: impl Into<ImmutableString>, property: impl Into<StyleProperty>);
142
143 fn get<P>(&self, name: impl Into<ImmutableString>) -> Option<P>
145 where
146 StyleProperty: IntoPrimitive<P>;
147
148 fn get_or<P>(&self, name: impl Into<ImmutableString>, default: P) -> P
150 where
151 StyleProperty: IntoPrimitive<P>;
152
153 fn get_or_default<P>(&self, name: impl Into<ImmutableString>) -> P
155 where
156 P: Default,
157 StyleProperty: IntoPrimitive<P>;
158
159 fn property<P>(&self, name: impl Into<ImmutableString>) -> StyledProperty<P>
161 where
162 P: Default,
163 StyleProperty: IntoPrimitive<P>;
164}
165
166impl StyleResourceExt for StyleResource {
167 fn set(&self, name: impl Into<ImmutableString>, property: impl Into<StyleProperty>) {
168 let mut state = self.state();
169 if let Some(data) = state.data() {
170 data.set(name, property);
171 } else {
172 Log::err("Unable to set style property, because the resource is invalid!")
173 }
174 }
175
176 fn get<P>(&self, name: impl Into<ImmutableString>) -> Option<P>
177 where
178 StyleProperty: IntoPrimitive<P>,
179 {
180 let state = self.state();
181 if let Some(data) = state.data_ref() {
182 data.get(name)
183 } else {
184 Log::err("Unable to get style property, because the resource is invalid!");
185 None
186 }
187 }
188
189 fn get_or<P>(&self, name: impl Into<ImmutableString>, default: P) -> P
190 where
191 StyleProperty: IntoPrimitive<P>,
192 {
193 let state = self.state();
194 if let Some(data) = state.data_ref() {
195 data.get_or(name, default)
196 } else {
197 Log::err("Unable to get style property, because the resource is invalid!");
198 default
199 }
200 }
201
202 fn get_or_default<P>(&self, name: impl Into<ImmutableString>) -> P
203 where
204 P: Default,
205 StyleProperty: IntoPrimitive<P>,
206 {
207 let state = self.state();
208 if let Some(data) = state.data_ref() {
209 data.get_or_default(name)
210 } else {
211 Log::err("Unable to get style property, because the resource is invalid!");
212 P::default()
213 }
214 }
215
216 fn property<P>(&self, name: impl Into<ImmutableString>) -> StyledProperty<P>
217 where
218 P: Default,
219 StyleProperty: IntoPrimitive<P>,
220 {
221 let state = self.state();
222 if let Some(data) = state.data_ref() {
223 data.property(name)
224 } else {
225 Log::err("Unable to get style property, because the resource is invalid!");
226 Default::default()
227 }
228 }
229}