use std::path::{Path, PathBuf};
mod blob;
mod state;
concinnity_core::install_global_allocator!();
#[cfg(backend_metal)]
#[used]
static CN_RUNTIME_PLATFORM: [u8; 26] = *b"cn-runtime-platform:metal\0";
#[cfg(backend_dx)]
#[used]
static CN_RUNTIME_PLATFORM: [u8; 25] = *b"cn-runtime-platform:hlsl\0";
#[cfg(backend_vk)]
#[used]
static CN_RUNTIME_PLATFORM: [u8; 25] = *b"cn-runtime-platform:glsl\0";
fn main() -> std::io::Result<()> {
concinnity_engine::crash::install();
#[cfg(any(backend_metal, backend_dx, backend_vk))]
std::hint::black_box(&CN_RUNTIME_PLATFORM);
let exe = std::env::current_exe()?;
let exe_dir = exe.parent().unwrap_or_else(|| Path::new("."));
let content_dir = state::state_dir_for_exe(exe_dir);
if !state::dir_is_writable(&content_dir)
&& let Some(writable) = state::per_user_state_dir(&state::app_name_from_exe(&exe))
{
concinnity_engine::set_writable_state_dir(writable);
}
let requested = std::env::args_os()
.nth(1)
.map_or_else(|| content_dir.join("data"), PathBuf::from);
let blob = blob::blob_source(&requested).ok_or_else(|| {
std::io::Error::new(
std::io::ErrorKind::NotFound,
format!("no world data at {}", requested.display()),
)
})?;
concinnity_engine::run_from(&content_dir, blob.as_source())
}
#[cfg(test)]
mod tests {
#[test]
fn the_shipped_player_tracks_its_own_heap() {
const MIB: usize = 1 << 20;
let before = concinnity_core::memory::stats()
.expect("this binary declares the tracking allocator")
.alloc_count;
let held: Vec<u8> = core::hint::black_box(vec![0; MIB]);
let after = concinnity_core::memory::stats().expect("the allocator stays installed");
assert!(
after.alloc_count > before,
"allocation count did not move ({before} -> {}) across a megabyte",
after.alloc_count
);
assert!(after.peak_bytes >= after.live_bytes);
drop(core::hint::black_box(held));
}
}