use crate::ecs::asset_id::AssetId;
use crate::ecs::{ComponentAsset, PayloadLocator};
use crate::result::CnResult;
#[diagnostic::on_unimplemented(
message = "`{Self}` cannot be added to a world",
label = "not a runtime component",
note = "`{Self}` is a build-time asset: either the cook expands it into the components it stands for (`BuildOnlyAsset`), or it compiles into the blob's resource stream and is reached by handle (`ResourceAsset`). Either way it never reaches a world as a component. Declare it in a world.jsonl and build."
)]
pub trait RuntimeComponent: Into<ComponentAsset> {}
pub trait ResourceAsset {}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum AssetOrigin {
External,
RuntimeOnly,
BuildOnly,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub enum AssetPayload {
None,
Compiled,
}
pub trait Component: Sized + Send + core::fmt::Debug + 'static {
const NAME: &'static str;
fn from_baked(_bytes: &[u8]) -> Result<Self, CnResult> {
Err(CnResult::AssetInvalidType)
}
fn inject_locator(&mut self, _locator: PayloadLocator) {}
fn inject_name(&mut self, _id: AssetId) {}
}
#[cfg(test)]
mod tests {
use super::{ResourceAsset, RuntimeComponent};
use crate::components::{TextLabel, Texture, Transform};
fn runtime<C: RuntimeComponent>() {}
fn resource<A: ResourceAsset>() {}
#[test]
fn origin_markers_follow_the_registry() {
runtime::<TextLabel>();
runtime::<Transform>();
resource::<Texture>();
}
}