You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
59 lines
1.2 KiB
59 lines
1.2 KiB
//! Arbitrary object store
|
|
use std::any::{
|
|
TypeId,
|
|
Any,
|
|
};
|
|
use std::collections::HashMap;
|
|
|
|
/// Arbitrarily typed singleton store.
|
|
///
|
|
/// Stores one object per type.
|
|
#[derive(Debug)]
|
|
pub struct SingletonStore
|
|
{
|
|
objects: HashMap<TypeId, Box<dyn Any + 'static>>,
|
|
}
|
|
|
|
#[inline] fn unbox_to<T: Any>(b: Box<dyn Any + 'static>) -> Option<T>
|
|
{
|
|
b.downcast().map(|ok| *ok).ok()
|
|
}
|
|
|
|
impl SingletonStore
|
|
{
|
|
pub fn has<T: Any>(&self) -> bool
|
|
{
|
|
self.objects.contains_key(&TypeId::of::<T>())
|
|
}
|
|
|
|
pub fn remove<T: Any>(&mut self) -> Option<T>
|
|
{
|
|
self.objects.remove(&TypeId::of::<T>())
|
|
.and_then(|x| x.downcast().ok())
|
|
.map(|x| *x)
|
|
}
|
|
pub fn insert<T: Any>(&mut self, value: T) -> Option<T>
|
|
{
|
|
self.objects.insert(TypeId::of::<T>(), Box::new(value))
|
|
.and_then(unbox_to)
|
|
}
|
|
|
|
pub fn get_mut<T: Any>(&mut self) -> Option<&mut T>
|
|
{
|
|
self.objects.get_mut(&TypeId::of::<T>())
|
|
.and_then(|x| x.downcast_mut())
|
|
}
|
|
pub fn get<T: Any>(&self) -> Option<&T>
|
|
{
|
|
self.objects.get(&TypeId::of::<T>())
|
|
.and_then(|x| x.downcast_ref())
|
|
}
|
|
|
|
pub fn new() -> Self
|
|
{
|
|
Self {
|
|
objects: HashMap::new(),
|
|
}
|
|
}
|
|
}
|