#[cfg(feature = "std")]
use std::path::Path;
use crate::World;
#[cfg(feature = "std")]
pub(crate) type Inner = concinnity_engine::App;
#[cfg(not(feature = "std"))]
pub(crate) type Inner = concinnity_core::App;
pub struct App {
inner: Inner,
}
impl core::fmt::Debug for App {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("App").finish_non_exhaustive()
}
}
impl App {
pub fn from_world(world: World) -> Self {
Self {
inner: Inner::from_world(world.into_inner()),
}
}
#[cfg(feature = "std")]
pub fn from_blob(path: impl AsRef<Path>) -> std::io::Result<Self> {
let path = path.as_ref();
concinnity_engine::App::from_blob(path)
.map(|inner| Self { inner })
.map_err(|e| std::io::Error::other(format!("{}: {e}", path.display())))
}
#[cfg(feature = "std")]
pub fn run(self) -> std::io::Result<()> {
self.inner.run()
}
#[cfg(not(feature = "std"))]
pub fn run(mut self) -> Result<(), concinnity_core::result::CnResult> {
self.inner.run().map(|_| ())
}
#[cfg(test)]
pub(crate) fn inner_mut(&mut self) -> &mut Inner {
&mut self.inner
}
}
#[cfg(all(test, feature = "cook"))]
mod tests {
use super::App;
use crate::components::DirectionalLight;
use crate::cook;
#[test]
fn a_written_blob_loads_back_into_a_runnable_app() {
let dir = std::env::temp_dir().join("concinnity-app-from-blob");
let primary = dir.join("data").join("0");
let _ = std::fs::remove_dir_all(&dir);
cook::world()
.add(
"sun",
DirectionalLight {
intensity: 3.5,
..Default::default()
},
)
.write_blob(&primary)
.expect("the world is written");
let mut app = App::from_blob(&primary).expect("the written blob loads");
assert_eq!(app.inner_mut().start(), Ok(()));
let _ = std::fs::remove_dir_all(&dir);
}
#[test]
fn a_missing_blob_reports_the_path_it_could_not_read() {
let missing = std::env::temp_dir()
.join("concinnity-no-such-blob")
.join("0");
let err = App::from_blob(&missing).expect_err("nothing to load");
assert!(err.to_string().contains("concinnity-no-such-blob"), "{err}");
}
}