Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::fmt::Debug;
- use std::collections::{BTreeMap, BTreeSet};
- use std::any::{Any, TypeId};
- trait Component: Debug + Sized + Any {
- type Storage: Storage<Self>;
- }
- trait Storage<T: Debug>: Debug + Any {
- fn new() -> Self
- where
- Self: Sized;
- fn insert(&mut self, value: T);
- }
- #[derive(Debug)]
- struct VecStorage<T: Debug + 'static> {
- internal: Vec<T>,
- }
- impl<T: Debug> Storage<T> for VecStorage<T> {
- fn new() -> Self {
- Self {
- internal: Vec::new(),
- }
- }
- fn insert(&mut self, value: T) {
- self.internal.push(value);
- }
- }
- #[derive(Debug)]
- struct BTreeStorage<T: Debug + 'static + Ord> {
- internal: BTreeSet<T>,
- }
- impl<T: Debug + Ord> Storage<T> for BTreeStorage<T> {
- fn new() -> Self {
- Self {
- internal: BTreeSet::new(),
- }
- }
- fn insert(&mut self, value: T) {
- self.internal.insert(value);
- }
- }
- struct StorageMgr {
- storages: BTreeMap<TypeId, Box<Any>>,
- }
- impl StorageMgr {
- pub fn new() -> Self {
- Self {
- storages: BTreeMap::new(),
- }
- }
- pub fn get_storage_mut<C: Component>(&mut self) -> &mut <C as Component>::Storage {
- let type_id = TypeId::of::<C>();
- if !self.storages.contains_key(&type_id) {
- let new_storage = <C as Component>::Storage::new();
- self.storages.insert(type_id, Box::new(new_storage));
- }
- match self.storages.get_mut(&type_id) {
- Some(probably_storage) => {
- match probably_storage.downcast_mut::<<C as Component>::Storage>() {
- Some(storage) => storage,
- None => unreachable!(), // <- you may want to do something less explosive here
- }
- }
- None => unreachable!(),
- }
- }
- pub fn get_storage<C: Component>(&self) -> Option<&<C as Component>::Storage> {
- let type_id = TypeId::of::<C>();
- match self.storages.get(&type_id) {
- Some(probably_storage) => {
- match probably_storage.downcast_ref::<<C as Component>::Storage>() {
- Some(storage) => Some(storage),
- None => unreachable!(), // <- you may want to do something less explosive here
- }
- }
- None => None,
- }
- }
- }
- #[derive(Debug)]
- struct Pos(f64, f64);
- impl Component for Pos {
- type Storage = VecStorage<Self>;
- }
- #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
- struct AudioVolume(u8);
- impl Component for AudioVolume {
- type Storage = BTreeStorage<Self>;
- }
- fn main() {
- let mut mgr: StorageMgr = StorageMgr::new();
- mgr.get_storage_mut::<Pos>().insert(Pos(1.2, 3.4));
- mgr.get_storage_mut::<AudioVolume>().insert(AudioVolume(7));
- println!("{:?}", mgr.get_storage::<Pos>());
- println!("{:?}", mgr.get_storage::<AudioVolume>());
- }
Add Comment
Please, Sign In to add comment