2022-06-12 15:57:39 +00:00
|
|
|
use crate::dynamic_data::script_handling::script::{Script, ScriptContainer};
|
2022-06-11 15:22:46 +00:00
|
|
|
use crate::{PkmnResult, StringKey};
|
2022-06-06 11:54:59 +00:00
|
|
|
use indexmap::IndexMap;
|
2022-06-19 10:07:54 +00:00
|
|
|
use parking_lot::RwLock;
|
|
|
|
use std::ops::Deref;
|
2022-06-18 16:41:23 +00:00
|
|
|
use std::sync::Arc;
|
2022-06-03 14:35:18 +00:00
|
|
|
|
2022-06-06 11:54:59 +00:00
|
|
|
#[derive(Debug, Default)]
|
|
|
|
pub struct ScriptSet {
|
2022-06-19 10:07:54 +00:00
|
|
|
scripts: RwLock<IndexMap<StringKey, ScriptContainer>>,
|
2022-06-06 11:54:59 +00:00
|
|
|
}
|
2022-06-03 14:35:18 +00:00
|
|
|
|
|
|
|
impl ScriptSet {
|
2022-06-19 10:07:54 +00:00
|
|
|
pub fn add(&self, script: Arc<dyn Script>) -> ScriptContainer {
|
|
|
|
if let Some(lock) = self.scripts.read().get(script.name()) {
|
2022-06-18 16:08:25 +00:00
|
|
|
if let Some(existing) = lock.get() {
|
|
|
|
let existing = existing.read();
|
|
|
|
if let Some(v) = &*existing {
|
|
|
|
v.stack();
|
|
|
|
return lock.clone();
|
|
|
|
}
|
2022-06-12 15:57:39 +00:00
|
|
|
}
|
2022-06-06 11:54:59 +00:00
|
|
|
}
|
2022-06-19 10:07:54 +00:00
|
|
|
self.scripts
|
|
|
|
.write()
|
|
|
|
.insert(script.name().clone(), ScriptContainer::new(script));
|
|
|
|
self.scripts.read().last().unwrap().1.clone()
|
2022-06-06 11:54:59 +00:00
|
|
|
}
|
|
|
|
|
2022-06-19 10:07:54 +00:00
|
|
|
pub fn stack_or_add<'b, F>(&self, key: &StringKey, instantiation: &'b F) -> PkmnResult<Option<ScriptContainer>>
|
2022-06-06 11:54:59 +00:00
|
|
|
where
|
2022-06-18 16:41:23 +00:00
|
|
|
F: Fn() -> PkmnResult<Option<Arc<dyn Script>>>,
|
2022-06-06 11:54:59 +00:00
|
|
|
{
|
2022-06-19 10:07:54 +00:00
|
|
|
if let Some(lock) = self.scripts.read().get(key) {
|
2022-06-18 16:08:25 +00:00
|
|
|
if let Some(existing) = lock.get() {
|
|
|
|
let existing = existing.read();
|
|
|
|
if let Some(v) = &*existing {
|
|
|
|
v.stack();
|
|
|
|
return Ok(Some(lock.clone()));
|
|
|
|
}
|
2022-06-12 15:57:39 +00:00
|
|
|
}
|
2022-06-06 11:54:59 +00:00
|
|
|
}
|
|
|
|
let script = instantiation()?;
|
2022-06-11 15:22:46 +00:00
|
|
|
if let Some(script) = script {
|
2022-06-12 15:57:39 +00:00
|
|
|
let name = script.name().clone();
|
|
|
|
let arc = ScriptContainer::new(script);
|
2022-06-19 10:07:54 +00:00
|
|
|
self.scripts.write().insert(name, arc);
|
|
|
|
Ok(Some(self.scripts.read().last().unwrap().1.clone()))
|
2022-06-11 15:22:46 +00:00
|
|
|
} else {
|
|
|
|
Ok(None)
|
|
|
|
}
|
2022-06-06 11:54:59 +00:00
|
|
|
}
|
|
|
|
|
2022-06-19 10:07:54 +00:00
|
|
|
pub fn get(&self, key: &StringKey) -> Option<ScriptContainer> {
|
|
|
|
self.scripts.read().get(key).cloned()
|
2022-06-06 11:54:59 +00:00
|
|
|
}
|
|
|
|
|
2022-06-19 10:07:54 +00:00
|
|
|
pub fn remove(&self, key: &StringKey) {
|
|
|
|
let value = self.scripts.write().shift_remove(key);
|
2022-06-06 11:54:59 +00:00
|
|
|
if let Some(script) = value {
|
2022-06-18 16:08:25 +00:00
|
|
|
if let Some(script) = script.get() {
|
|
|
|
let script = script.read();
|
|
|
|
script.as_ref().unwrap().on_remove();
|
|
|
|
script.as_ref().unwrap().mark_for_deletion();
|
|
|
|
}
|
2022-06-06 11:54:59 +00:00
|
|
|
}
|
2022-06-03 14:35:18 +00:00
|
|
|
}
|
|
|
|
|
2022-06-19 10:07:54 +00:00
|
|
|
pub fn clear(&self) {
|
|
|
|
for script in self.scripts.read().deref() {
|
2022-06-18 16:08:25 +00:00
|
|
|
if let Some(script) = script.1.get() {
|
|
|
|
let script = script.read();
|
|
|
|
script.as_ref().unwrap().on_remove();
|
|
|
|
script.as_ref().unwrap().mark_for_deletion();
|
|
|
|
}
|
2022-06-06 11:54:59 +00:00
|
|
|
}
|
2022-06-19 10:07:54 +00:00
|
|
|
self.scripts.write().clear();
|
2022-06-06 11:54:59 +00:00
|
|
|
}
|
|
|
|
|
2022-06-11 15:22:46 +00:00
|
|
|
pub fn has(&self, key: &StringKey) -> bool {
|
2022-06-19 10:07:54 +00:00
|
|
|
self.scripts.read().contains_key(key)
|
2022-06-06 11:54:59 +00:00
|
|
|
}
|
|
|
|
|
2022-06-19 10:07:54 +00:00
|
|
|
pub fn at(&self, index: usize) -> ScriptContainer {
|
|
|
|
self.scripts.read()[index].clone()
|
2022-06-06 11:54:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn count(&self) -> usize {
|
2022-06-19 10:07:54 +00:00
|
|
|
self.scripts.read().len()
|
2022-06-03 14:35:18 +00:00
|
|
|
}
|
2022-06-16 15:59:33 +00:00
|
|
|
|
2022-06-19 10:07:54 +00:00
|
|
|
pub(crate) fn get_owning_iterator(&self) -> Vec<ScriptContainer> {
|
|
|
|
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
|
2022-06-16 15:59:33 +00:00
|
|
|
}
|
2022-06-03 14:35:18 +00:00
|
|
|
}
|