use concinnity_core::ecs::ComponentAsset;
use concinnity_core::ecs::World;
use concinnity_core::ecs::asset_id::AssetId;
use concinnity_core::error::AssetError;
use concinnity_host::store::blob::BlobMeta;
use concinnity_host::store::blob::ResourceRecord;
use concinnity_host::store::blob::WorldManifest;
use concinnity_host::store::blob::{BlobData, BlobLoadError};
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum WorldLoadError {
#[error(transparent)]
Blob(#[from] BlobLoadError),
#[error(transparent)]
Asset(#[from] AssetError),
}
pub fn world_from(blob: BlobData) -> World {
World::from_payloads(Box::new(blob))
}
type NamedComponent = (Option<AssetId>, ComponentAsset);
pub(crate) struct LoadedBlob {
pub(crate) components: Vec<NamedComponent>,
pub(crate) resources: Vec<ResourceRecord>,
pub(crate) scene_groups: Vec<concinnity_core::ecs::SceneGroup>,
pub(crate) mesh_bounds: Vec<concinnity_core::ecs::MeshBoundsRecord>,
pub(crate) physics_budget: Option<concinnity_core::ecs::PhysicsBudgetRecord>,
pub(crate) manifest: WorldManifest,
pub(crate) blob: BlobData,
}
pub(crate) fn load_at(primary: &std::path::Path) -> Result<LoadedBlob, WorldLoadError> {
resolve(concinnity_host::store::blob::load_raw_at(primary)?)
}
fn resolve((meta, blob_data): (BlobMeta, BlobData)) -> Result<LoadedBlob, WorldLoadError> {
let components = meta
.defs
.iter()
.map(|def| {
let mut component = ComponentAsset::from_baked(def)?;
if let Some(locator) = &def.payload {
component.inject_locator(locator.clone());
}
Ok((def.name, component))
})
.collect::<Result<Vec<_>, AssetError>>()?;
Ok(LoadedBlob {
components,
resources: meta.resources,
scene_groups: meta.scene_groups,
mesh_bounds: meta.mesh_bounds,
physics_budget: meta.physics_budget,
manifest: meta.manifest,
blob: blob_data,
})
}