PkmnLib_rs/src/dynamic_data/script_handling/script_set.rs

92 lines
2.8 KiB
Rust

use crate::dynamic_data::script_handling::script::{Script, ScriptContainer};
use crate::{PkmnResult, StringKey};
use indexmap::IndexMap;
use std::sync::Arc;
#[derive(Debug, Default)]
pub struct ScriptSet {
scripts: IndexMap<StringKey, ScriptContainer>,
}
impl ScriptSet {
pub fn add(&mut self, script: Arc<dyn Script>) -> ScriptContainer {
if let Some(lock) = self.scripts.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.insert(script.name().clone(), ScriptContainer::new(script));
self.scripts.last().unwrap().1.clone()
}
pub fn stack_or_add<'b, F>(&mut self, key: &StringKey, instantiation: &'b F) -> PkmnResult<Option<ScriptContainer>>
where
F: Fn() -> PkmnResult<Option<Arc<dyn Script>>>,
{
if let Some(lock) = self.scripts.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.insert(name, arc);
Ok(Some(self.scripts.last().unwrap().1.clone()))
} else {
Ok(None)
}
}
pub fn get(&self, key: &StringKey) -> Option<&ScriptContainer> {
self.scripts.get(key)
}
pub fn remove(&mut self, key: &StringKey) {
let value = self.scripts.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(&mut self) {
for script in &self.scripts {
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.clear();
}
pub fn has(&self, key: &StringKey) -> bool {
self.scripts.contains_key(key)
}
pub fn at(&self, index: usize) -> &ScriptContainer {
&self.scripts[index]
}
pub fn count(&self) -> usize {
self.scripts.len()
}
pub(crate) fn get_underlying(&self) -> &IndexMap<StringKey, ScriptContainer> {
&self.scripts
}
}