Skip to content
Snippets Groups Projects
widget_state.rs 1.51 KiB
Newer Older
use std::sync::{Arc, RwLock};

use bevy::{
    prelude::{BuildChildren, Commands, Component, Entity},
    utils::HashMap,
};

/// Stores mappings between widget entities and their corresponding state entities.
#[derive(Default, Debug, Clone)]
pub struct WidgetState {
    mapping: Arc<RwLock<HashMap<Entity, Entity>>>,
}

impl WidgetState {
    /// Attempts to create a state entity or return the existing entity.
    pub fn add<State: Component + PartialEq + Clone>(
        &self,
        commands: &mut Commands,
        widget_entity: Entity,
        initial_state: State,
    ) -> Entity {
        if let Ok(mut mapping) = self.mapping.try_write() {
            if mapping.contains_key(&widget_entity) {
                *mapping.get(&widget_entity).unwrap()
            } else {
                let mut state_entity = None;
                commands
                    .entity(widget_entity)
                    .with_children(|child_builder| {
                        state_entity = Some(child_builder.spawn(initial_state).id());
                        mapping.insert(widget_entity, state_entity.unwrap());
                    });
                state_entity.expect("State entity did not spawn!")
            }
        } else {
            panic!("Couldn't get mapping lock!");
        }
    }

    /// Attempts to get a state entity
    pub fn get(&self, widget_entity: Entity) -> Option<Entity> {
        if let Ok(mapping) = self.mapping.try_read() {
            return mapping.get(&widget_entity).cloned();
        }

        None
    }
}