use comfy::{error, texture_id, EngineContext, HashSet, Lazy, Mutex, TextureHandle}; use std::{fs, io, sync::Arc}; static ASSETS_LOADED: Lazy>>> = Lazy::new(|| Arc::new(Mutex::new(HashSet::new()))); struct FurnitureAsset { folder: String, name: String } struct FurnitureTextureHandles { human: Option, magnet: Option, elec: Option } impl FurnitureAsset { fn asset_path(&self) -> String { format!("{}/{}.png", self.folder, self.name) } fn asset_path_magnet(&self) -> String { format!("{}/magnet/{}.png", self.folder, self.name) } fn asset_path_elec(&self) -> String { format!("{}/elec/{}.png", self.folder, self.name) } fn load_asset_path( &self, path: String, ctx: &mut EngineContext<'_> ) -> Option { let mut loaded = ASSETS_LOADED.lock(); if loaded.contains(&path) { return None; } let bytes = match fs::read(format!( "{}/assets/furniture/{path}", env!("CARGO_MANIFEST_DIR") )) { Ok(bytes) => bytes, Err(err) if err.kind() == io::ErrorKind::NotFound => return None, Err(err) => { error!("Failed to load asset {path:?}: {err}"); return None; } }; ctx.load_texture_from_bytes(&path, &bytes); let handle = texture_id(&path); loaded.insert(path); Some(handle) } /// Attempt to load the assets. Silently ignore missing assets. fn load_assets(&self, ctx: &mut EngineContext<'_>) -> FurnitureTextureHandles { FurnitureTextureHandles { human: self.load_asset_path(self.asset_path(), ctx), magnet: self.load_asset_path(self.asset_path_magnet(), ctx), elec: self.load_asset_path(self.asset_path_elec(), ctx) } } } pub struct Furniture { asset: FurnitureAsset, handles: FurnitureTextureHandles, on: Box bool> } impl Furniture { pub fn new, N: Into>( folder: F, name: N, ctx: &mut EngineContext<'_> ) -> Self { let asset = FurnitureAsset { folder: folder.into(), name: name.into() }; let handles = asset.load_assets(ctx); Self { asset, handles, on: Box::new(|| false) } } }