use std::{any::TypeId, fmt};
pub use self::{resource_id::ResourceId, unique::Unique};
mod resource_id;
mod unique;
pub trait Resource: 'static + Send + Sync + std::any::Any {
fn on_resource_wired(&mut self) {}
fn name() -> String;
}
pub(crate) trait StoredResource: 'static + std::any::Any + Send + Sync {
fn stored_resource_id(&self) -> ResourceId;
fn stored_resource_wired(&mut self);
}
impl fmt::Debug for dyn StoredResource {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Resource")
.field("resource_id", &self.stored_resource_id())
.finish()
}
}
impl<T: Resource> StoredResource for T {
fn stored_resource_id(&self) -> ResourceId {
ResourceId::of::<T>()
}
fn stored_resource_wired(&mut self) {
Resource::on_resource_wired(self);
}
}
impl dyn StoredResource {
pub(crate) fn downcast_ref<T: Resource>(&self) -> Option<&T> {
if self.type_id() == TypeId::of::<T>() {
unsafe { Some(&*(self as *const dyn StoredResource as *const T)) }
} else {
None
}
}
}