lyra-engine/lyra-ecs/src/resource.rs

69 lines
2.1 KiB
Rust
Raw Normal View History

use std::{any::{TypeId, Any}, cell::{RefCell, Ref, RefMut}};
2023-11-29 04:25:47 +00:00
/// Shorthand for `Send + Sync + 'static`, so it never needs to be implemented manually.
pub trait ResourceObject: 'static {}
impl<T: 'static> ResourceObject for T {}
2023-11-29 04:25:47 +00:00
/// A type erased storage for a Resource.
pub struct ResourceData {
data: Box<RefCell<dyn Any>>,
2023-11-29 04:25:47 +00:00
type_id: TypeId,
}
impl ResourceData {
pub fn new<T: Any>(data: T) -> Self {
2023-11-29 04:25:47 +00:00
Self {
data: Box::new(RefCell::new(data)),
2023-11-29 04:25:47 +00:00
type_id: TypeId::of::<T>(),
}
}
/// Returns a boolean indicating whether or not `T`` is of the same type of the Resource
2023-11-29 04:25:47 +00:00
pub fn is<T: 'static>(&self) -> bool {
self.type_id == TypeId::of::<T>()
}
/// Borrow the data inside of the resource.
///
/// # Panics
2023-11-29 04:25:47 +00:00
///
/// * If the data is already borrowed mutably, this will panic.
/// * If the type of `T` is not the same as the resource type.
pub fn get<T: 'static>(&self) -> Ref<T> {
Ref::map(self.data.borrow(), |a| a.downcast_ref().unwrap())
2023-11-29 04:25:47 +00:00
}
/// Mutably borrow the data inside of the resource.
///
2023-11-30 04:21:27 +00:00
/// # Panics
2023-11-29 04:25:47 +00:00
///
2023-11-30 04:21:27 +00:00
/// * If the data is already borrowed mutably, this will panic.
/// * If the type of `T` is not the same as the resource type.
pub fn get_mut<T: 'static>(&self) -> RefMut<T> {
RefMut::map(self.data.borrow_mut(), |a| a.downcast_mut().unwrap())
2023-11-29 04:25:47 +00:00
}
2023-11-30 04:21:27 +00:00
/// Borrow the data inside of the resource.
///
/// # Panics
2023-11-30 04:21:27 +00:00
///
/// * If the type of `T` is not the same as the resource type.
pub fn try_get<T: 'static>(&self) -> Option<Ref<T>> {
2023-11-30 04:21:27 +00:00
self.data.try_borrow()
.map(|r| Ref::map(r, |a| a.downcast_ref().unwrap()))
2023-11-30 04:21:27 +00:00
.ok()
}
/// Mutably borrow the data inside of the resource.
///
/// # Panics
///
/// * If the type of `T` is not the same as the resource type.
pub fn try_get_mut<T: 'static>(&self) -> Option<RefMut<T>> {
2023-11-30 04:21:27 +00:00
self.data.try_borrow_mut()
.map(|r| RefMut::map(r, |a| a.downcast_mut().unwrap()))
2023-11-30 04:21:27 +00:00
.ok()
}
2023-11-29 04:25:47 +00:00
}