ori_core/context/
contexts.rs
use std::{any::Any, mem};
#[derive(Debug, Default)]
pub struct Contexts {
contexts: Vec<Box<dyn Any>>,
}
impl Contexts {
pub fn new() -> Self {
Self::default()
}
#[inline(always)]
fn index_of<T: Any>(&self) -> Option<usize> {
self.contexts
.iter()
.enumerate()
.find(|(_, c)| c.as_ref().is::<T>())
.map(|(i, _)| i)
}
#[inline(always)]
pub fn len(&self) -> usize {
self.contexts.len()
}
#[inline(always)]
pub fn is_empty(&self) -> bool {
self.contexts.is_empty()
}
#[inline(always)]
pub fn contains<T: Any>(&self) -> bool {
self.index_of::<T>().is_some()
}
#[inline(always)]
pub fn insert<T: Any>(&mut self, mut context: T) -> Option<T> {
if let Some(index) = self.get_mut::<T>() {
mem::swap(index, &mut context);
return Some(context);
}
self.contexts.push(Box::new(context));
None
}
#[inline(always)]
pub fn remove<T: Any>(&mut self) -> Option<T> {
let index = self.index_of::<T>()?;
let context = self.contexts.remove(index);
Some(*context.downcast::<T>().expect("downcast failed"))
}
#[inline(always)]
pub fn get<T: Any>(&self) -> Option<&T> {
let index = self.index_of::<T>()?;
self.contexts[index].downcast_ref::<T>()
}
#[inline(always)]
pub fn get_mut<T: Any>(&mut self) -> Option<&mut T> {
let index = self.index_of::<T>()?;
self.contexts[index].downcast_mut::<T>()
}
#[inline(always)]
pub fn get_or_default<T: Any + Default>(&mut self) -> &mut T {
if !self.contains::<T>() {
self.insert(T::default());
}
self.get_mut::<T>().unwrap()
}
}