use std::collections::BTreeMap;
use dces::prelude::{Component, Entity, EntityComponentManager, StringComponentStore};
use crate::tree::Tree;
use super::State;
pub struct StatesContext<'a> {
states: &'a mut BTreeMap<Entity, Box<dyn State>>,
ecm: &'a mut EntityComponentManager<Tree, StringComponentStore>,
}
impl<'a> StatesContext<'a> {
pub fn new(
states: &'a mut BTreeMap<Entity, Box<dyn State>>,
ecm: &'a mut EntityComponentManager<Tree, StringComponentStore>,
) -> Self {
StatesContext { states, ecm }
}
fn mark_as_dirty(&mut self, entity: Entity) {
*self
.ecm
.component_store_mut()
.get_mut::<bool>("dirty", entity)
.unwrap() = true;
let root = self.ecm.entity_store().root();
if let Ok(dirty_widgets) = self
.ecm
.component_store_mut()
.get_mut::<Vec<Entity>>("dirty_widgets", root)
{
if dirty_widgets.is_empty() || *dirty_widgets.last().unwrap() != entity {
dirty_widgets.push(entity);
}
}
}
pub fn get<S: Component>(&self, entity: Entity) -> &S {
self.states
.get(&entity)
.unwrap_or_else(|| {
panic!(
"StatesContext.get(): state for entity: {:?} could not be found.",
entity
)
})
.as_any()
.downcast_ref()
.unwrap_or_else(|| {
panic!(
"StatesContext.get(): wrong type of state for entity: {:?}",
entity
)
})
}
pub fn get_mut<S: Component>(&mut self, entity: Entity) -> &mut S {
self.mark_as_dirty(entity);
self.states
.get_mut(&entity)
.unwrap_or_else(|| {
panic!(
"StatesContext.get(): state for entity: {:?} could not be found.",
entity
)
})
.as_any_mut()
.downcast_mut()
.unwrap_or_else(|| {
panic!(
"StatesContext.get(): wrong type of state for entity: {:?}",
entity
)
})
}
pub fn try_get<S: Component>(&self, entity: Entity) -> Option<&S> {
if let Some(e) = self.states.get(&entity) {
if let Some(r) = e.as_any().downcast_ref() {
return Some(r);
}
}
None
}
pub fn try_get_mut<S: Component>(&mut self, entity: Entity) -> Option<&mut S> {
self.mark_as_dirty(entity);
if let Some(e) = self.states.get_mut(&entity) {
if let Some(r) = e.as_any_mut().downcast_mut() {
return Some(r);
}
}
None
}
}