use std::io::Write;
use astrelis_assets::prelude::*;
#[derive(Debug)]
struct JsonConfig {
data: serde_json::Value,
}
impl Asset for JsonConfig {
fn type_name() -> &'static str {
"JsonConfig"
}
}
struct JsonConfigLoader;
impl AssetLoader for JsonConfigLoader {
type Asset = JsonConfig;
fn extensions(&self) -> &[&str] {
&["json"]
}
fn load(&self, ctx: LoadContext<'_>) -> Result<Self::Asset, AssetError> {
let data: serde_json::Value =
serde_json::from_slice(ctx.bytes).map_err(|e| AssetError::LoaderError {
path: ctx.source.display_path(),
message: format!("JSON parse error: {}", e),
})?;
Ok(JsonConfig { data })
}
}
#[derive(Debug)]
struct SimpleImage {
width: u32,
height: u32,
pixel_count: usize,
}
impl Asset for SimpleImage {
fn type_name() -> &'static str {
"SimpleImage"
}
}
struct SimpleImageLoader;
impl AssetLoader for SimpleImageLoader {
type Asset = SimpleImage;
fn extensions(&self) -> &[&str] {
&["img"]
}
fn load(&self, ctx: LoadContext<'_>) -> Result<Self::Asset, AssetError> {
if ctx.bytes.len() < 8 {
return Err(AssetError::LoaderError {
path: ctx.source.display_path(),
message: "Image file too small".to_string(),
});
}
let width = u32::from_le_bytes([ctx.bytes[0], ctx.bytes[1], ctx.bytes[2], ctx.bytes[3]]);
let height = u32::from_le_bytes([ctx.bytes[4], ctx.bytes[5], ctx.bytes[6], ctx.bytes[7]]);
let pixel_count = ctx.bytes.len().saturating_sub(8) / 4;
Ok(SimpleImage {
width,
height,
pixel_count,
})
}
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let temp_dir = tempfile::tempdir()?;
let assets_path = temp_dir.path();
println!("Created temp directory: {}", assets_path.display());
create_test_assets(assets_path)?;
let mut server = AssetServer::with_base_path(assets_path);
server.register_loader(JsonConfigLoader);
server.register_loader(SimpleImageLoader);
server.register_loader(astrelis_assets::TextLoader);
println!("\n=== Loading Assets ===\n");
let config_handle: Handle<JsonConfig> = server.load_sync("config.json")?;
let readme_handle: Handle<String> = server.load_sync("readme.txt")?;
let image_handle: Handle<SimpleImage> = server.load_sync("sprite.img")?;
println!("Config ready: {}", server.is_ready(&config_handle));
println!("Readme ready: {}", server.is_ready(&readme_handle));
println!("Image ready: {}", server.is_ready(&image_handle));
if let Some(config) = server.get(&config_handle) {
println!("\nConfig data: {}", config.data);
}
if let Some(readme) = server.get(&readme_handle) {
println!("\nReadme contents:\n{}", *readme);
}
if let Some(image) = server.get(&image_handle) {
println!(
"\nImage: {}x{} ({} pixels)",
image.width, image.height, image.pixel_count
);
}
println!("\n=== Events ===\n");
for event in server.drain_events() {
match event {
AssetEvent::Created { version, .. } => {
println!("Asset created (version {})", version);
}
AssetEvent::Modified { version, .. } => {
println!("Asset modified (version {})", version);
}
AssetEvent::Removed { .. } => {
println!("Asset removed");
}
AssetEvent::LoadFailed { error, .. } => {
println!("Asset failed to load: {}", error);
}
}
}
println!("\n=== Version Tracking ===\n");
println!("Config version: {:?}", server.version(&config_handle));
println!("Readme version: {:?}", server.version(&readme_handle));
println!("\n=== Direct Insert ===\n");
let inline_config = JsonConfig {
data: serde_json::json!({
"name": "inline",
"value": 42
}),
};
let inline_handle = server.insert(AssetSource::memory("inline://config"), inline_config);
println!(
"Inserted inline config, ready: {}",
server.is_ready(&inline_handle)
);
if let Some(config) = server.get(&inline_handle) {
println!("Inline config: {}", config.data);
}
println!("\n=== Done ===");
Ok(())
}
fn create_test_assets(path: &std::path::Path) -> std::io::Result<()> {
let config_path = path.join("config.json");
let mut config_file = std::fs::File::create(&config_path)?;
writeln!(
config_file,
r#"{{
"game_name": "Astrelis Demo",
"version": "1.0.0",
"settings": {{
"fullscreen": false,
"vsync": true,
"volume": 0.8
}}
}}"#
)?;
println!("Created: {}", config_path.display());
let readme_path = path.join("readme.txt");
let mut readme_file = std::fs::File::create(&readme_path)?;
writeln!(readme_file, "Welcome to the Astrelis Asset System!")?;
writeln!(readme_file, "This is a simple text asset loaded from disk.")?;
println!("Created: {}", readme_path.display());
let image_path = path.join("sprite.img");
let mut image_file = std::fs::File::create(&image_path)?;
image_file.write_all(&64u32.to_le_bytes())?;
image_file.write_all(&64u32.to_le_bytes())?;
let pixels: Vec<u8> = (0..64 * 64 * 4).map(|i| (i % 256) as u8).collect();
image_file.write_all(&pixels)?;
println!("Created: {}", image_path.display());
Ok(())
}