use crate::dynamic_data::script_handling::script::{Script, ScriptContainer}; use crate::{PkmnResult, StringKey}; use indexmap::IndexMap; use parking_lot::RwLock; use std::ops::Deref; use std::sync::Arc; #[derive(Debug, Default)] pub struct ScriptSet { scripts: RwLock>, } impl ScriptSet { pub fn add(&self, script: Arc) -> ScriptContainer { if let Some(lock) = self.scripts.read().get(script.name()) { if let Some(existing) = lock.get() { let existing = existing.read(); if let Some(v) = &*existing { v.stack(); return lock.clone(); } } } self.scripts .write() .insert(script.name().clone(), ScriptContainer::new(script)); self.scripts.read().last().unwrap().1.clone() } pub fn stack_or_add<'b, F>(&self, key: &StringKey, instantiation: &'b F) -> PkmnResult> where F: Fn() -> PkmnResult>>, { if let Some(lock) = self.scripts.read().get(key) { if let Some(existing) = lock.get() { let existing = existing.read(); if let Some(v) = &*existing { v.stack(); return Ok(Some(lock.clone())); } } } let script = instantiation()?; if let Some(script) = script { let name = script.name().clone(); let arc = ScriptContainer::new(script); self.scripts.write().insert(name, arc); Ok(Some(self.scripts.read().last().unwrap().1.clone())) } else { Ok(None) } } pub fn get(&self, key: &StringKey) -> Option { self.scripts.read().get(key).cloned() } pub fn remove(&self, key: &StringKey) { let value = self.scripts.write().shift_remove(key); if let Some(script) = value { if let Some(script) = script.get() { let script = script.read(); script.as_ref().unwrap().on_remove(); script.as_ref().unwrap().mark_for_deletion(); } } } pub fn clear(&self) { for script in self.scripts.read().deref() { if let Some(script) = script.1.get() { let script = script.read(); script.as_ref().unwrap().on_remove(); script.as_ref().unwrap().mark_for_deletion(); } } self.scripts.write().clear(); } pub fn has(&self, key: &StringKey) -> bool { self.scripts.read().contains_key(key) } pub fn at(&self, index: usize) -> ScriptContainer { self.scripts.read()[index].clone() } pub fn count(&self) -> usize { self.scripts.read().len() } pub(crate) fn get_owning_iterator(&self) -> Vec { let s = self.scripts.read(); let mut v = Vec::with_capacity(s.deref().len()); for script in s.deref().values() { v.push(script.clone()); } v } }