use std::sync::{Mutex, OnceLock};
use concinnity_host::store::paths::StateTree;
fn opened() -> &'static Mutex<Option<StateTree>> {
static OPENED: OnceLock<Mutex<Option<StateTree>>> = OnceLock::new();
OPENED.get_or_init(|| Mutex::new(None))
}
pub fn open(tree: StateTree) {
concinnity_cook::cache::anchor(&tree.build_cache_path());
*opened().lock().unwrap() = Some(tree);
}
pub fn close() {
concinnity_cook::cache::clear_anchor();
*opened().lock().unwrap() = None;
}
pub fn tree() -> Option<StateTree> {
opened().lock().unwrap().clone()
}
pub(crate) fn app() -> concinnity_engine::App {
let app = concinnity_engine::App::new();
match tree() {
Some(tree) => app.in_tree(tree),
None => app,
}
}
pub(crate) fn require() -> std::io::Result<StateTree> {
tree().ok_or_else(|| {
std::io::Error::new(
std::io::ErrorKind::NotFound,
"no project state directory to build into",
)
})
}
pub(crate) fn assets_dir() -> Option<std::path::PathBuf> {
tree().map(|tree| tree.assets_dir())
}
pub(crate) fn data_dir() -> Option<std::path::PathBuf> {
tree().map(|tree| tree.data_dir())
}
pub(crate) fn worlds_dir() -> Option<std::path::PathBuf> {
tree().map(|tree| tree.worlds_dir())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn opening_a_project_is_what_gives_the_session_its_directories() {
let _guard = crate::test_support::lock();
let dir = concinnity_testing::TempTree::new();
close();
assert_eq!(tree(), None);
assert_eq!(assets_dir(), None);
assert_eq!(data_dir(), None);
assert_eq!(worlds_dir(), None);
assert_eq!(
require().unwrap_err().kind(),
std::io::ErrorKind::NotFound,
"a build with no project reports it rather than writing somewhere"
);
open(StateTree::at(dir.path()));
assert_eq!(
tree().as_ref().map(StateTree::content_root),
Some(dir.path())
);
assert_eq!(assets_dir(), Some(dir.path().join("assets")));
assert_eq!(data_dir(), Some(dir.path().join("data")));
assert_eq!(worlds_dir(), Some(dir.path().join("worlds")));
assert!(require().is_ok());
assert_eq!(app().state_tree(), tree().as_ref());
crate::test_support::isolate_state_dir();
}
}