use std::sync::Arc;
use dashmap::DashMap;
use super::EntityStore;
pub struct StoreRegistry {
stores: DashMap<Arc<str>, Arc<EntityStore>>,
}
impl StoreRegistry {
pub fn new() -> Self {
Self {
stores: DashMap::new(),
}
}
pub fn get_or_create(&self, entity_type: &str) -> Arc<EntityStore> {
let key: Arc<str> = entity_type.into();
self.stores
.entry(key.clone())
.or_insert_with(|| Arc::new(EntityStore::new().with_name(format!("store:{}", key))))
.clone()
}
pub fn get(&self, entity_type: &str) -> Option<Arc<EntityStore>> {
self.stores.get(entity_type).map(|r| r.clone())
}
pub fn entity_types(&self) -> Vec<Arc<str>> {
self.stores.iter().map(|r| r.key().clone()).collect()
}
pub fn len(&self) -> usize {
self.stores.len()
}
pub fn is_empty(&self) -> bool {
self.stores.is_empty()
}
}
impl Default for StoreRegistry {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_registry_get_or_create() {
let registry = StoreRegistry::new();
let store1 = registry.get_or_create("Target");
assert_eq!(registry.len(), 1);
let store2 = registry.get_or_create("Target");
assert!(Arc::ptr_eq(&store1, &store2));
let store3 = registry.get_or_create("Scene");
assert_eq!(registry.len(), 2);
assert!(!Arc::ptr_eq(&store1, &store3));
}
#[test]
fn test_registry_get() {
let registry = StoreRegistry::new();
assert!(registry.get("Target").is_none());
registry.get_or_create("Target");
assert!(registry.get("Target").is_some());
}
#[test]
fn test_registry_entity_types() {
let registry = StoreRegistry::new();
registry.get_or_create("Target");
registry.get_or_create("Scene");
registry.get_or_create("Binding");
let types = registry.entity_types();
assert_eq!(types.len(), 3);
}
}