Further massive amounts of work

This commit is contained in:
2022-06-06 13:54:59 +02:00
parent df662ce6b5
commit ce33ec0649
33 changed files with 848 additions and 80 deletions

View File

@@ -1,8 +1,10 @@
use crate::dynamic_data::script_handling::script::Script;
use crate::dynamic_data::script_handling::script_set::ScriptSet;
use std::sync::Weak;
pub mod script;
pub mod script_set;
pub mod volatile_scripts;
#[macro_export]
macro_rules! script_hook {
@@ -24,20 +26,20 @@ pub trait ScriptSource {
fn get_script_count(&self);
}
pub enum ScriptWrapper<'a> {
Script(&'a Box<dyn Script>),
Set(&'a ScriptSet),
pub enum ScriptWrapper {
Script(Weak<Box<dyn Script>>),
Set(Weak<ScriptSet>),
}
pub struct ScriptAggregator<'a> {
scripts: Vec<Option<ScriptWrapper<'a>>>,
pub struct ScriptAggregator {
scripts: Vec<Option<ScriptWrapper>>,
size: i32,
index: i32,
set_index: i32,
}
impl<'a> ScriptAggregator<'a> {
pub fn new(scripts: Vec<Option<ScriptWrapper<'a>>>) -> Self {
impl ScriptAggregator {
pub fn new(scripts: Vec<Option<ScriptWrapper>>) -> Self {
let len = scripts.len();
Self {
scripts,
@@ -51,11 +53,13 @@ impl<'a> ScriptAggregator<'a> {
if self.index != -1 {
if let Some(wrapper) = &self.scripts[self.index as usize] {
if let ScriptWrapper::Set(set) = wrapper {
self.set_index += 1;
if self.set_index as usize >= set.count() {
self.set_index = -1;
} else {
return true;
if let Some(set) = set.upgrade() {
self.set_index += 1;
if self.set_index as usize >= set.count() {
self.set_index = -1;
} else {
return true;
}
}
}
}
@@ -64,10 +68,16 @@ impl<'a> ScriptAggregator<'a> {
for index in self.index..self.size {
self.index = index;
if let Some(wrapper) = &self.scripts[index as usize] {
if let ScriptWrapper::Set(..) = wrapper {
self.set_index = 0;
if let ScriptWrapper::Set(s) = wrapper {
if let Some(..) = s.upgrade() {
self.set_index = 0;
return true;
}
} else if let ScriptWrapper::Script(script) = wrapper {
if let Some(..) = script.upgrade() {
return true;
}
}
return true;
}
}
@@ -79,8 +89,13 @@ impl<'a> ScriptAggregator<'a> {
return None;
}
return match self.scripts[self.index as usize].as_ref().unwrap() {
ScriptWrapper::Script(script) => Some(script),
ScriptWrapper::Set(set) => Some(set.at(self.set_index as usize)),
// We can make this unsafe as we know there is a strong reference. This is validated in
// increment_to_next_value
ScriptWrapper::Script(script) => unsafe { Some(&*script.as_ptr()) },
ScriptWrapper::Set(set) => unsafe {
let r = (&*set.as_ptr()).at(self.set_index as usize);
Some(r.as_ref())
},
};
}
}

View File

@@ -2,6 +2,8 @@ use crate::dynamic_data::models::pokemon::Pokemon;
use std::fmt::{Debug, Formatter};
pub trait Script {
fn name(&self) -> &str;
fn is_suppressed(&self) -> bool {
self.get_suppressed_count() > 0
}

View File

@@ -1,14 +1,69 @@
use crate::dynamic_data::script_handling::script::Script;
use crate::PkmnResult;
use indexmap::IndexMap;
use std::sync::Arc;
#[derive(Debug)]
pub struct ScriptSet {}
#[derive(Debug, Default)]
pub struct ScriptSet {
scripts: IndexMap<String, Arc<Box<dyn Script>>>,
}
impl ScriptSet {
pub fn count(&self) -> usize {
todo!()
pub fn add(&mut self, script: Box<dyn Script>) -> Arc<Box<dyn Script>> {
if let Some(existing) = self.scripts.get(script.name()) {
existing.stack();
return existing.clone();
}
let arc = Arc::new(script);
self.scripts.insert(arc.name().to_string(), arc.clone());
self.scripts.last().unwrap().1.clone()
}
pub fn at(&self, _index: usize) -> &Box<dyn Script> {
todo!()
pub fn stack_or_add<'b, F>(
&mut self,
key: &str,
instantiation: &'b F,
) -> PkmnResult<Arc<Box<dyn Script>>>
where
F: Fn() -> PkmnResult<Box<dyn Script>>,
{
if let Some(existing) = self.scripts.get(key) {
existing.stack();
return Ok(existing.clone());
}
let script = instantiation()?;
let arc = Arc::new(script);
self.scripts.insert(arc.name().to_string(), arc.clone());
Ok(self.scripts.last().unwrap().1.clone())
}
pub fn get(&self, key: &str) -> Option<&Arc<Box<dyn Script>>> {
self.scripts.get(key)
}
pub fn remove(&mut self, key: &str) {
let value = self.scripts.shift_remove(key);
if let Some(script) = value {
script.on_remove();
}
}
pub fn clear(&mut self) {
for script in &self.scripts {
script.1.on_remove();
}
self.scripts.clear();
}
pub fn has(&self, key: &str) -> bool {
self.scripts.contains_key(key)
}
pub fn at(&self, index: usize) -> &Arc<Box<dyn Script>> {
&self.scripts[index]
}
pub fn count(&self) -> usize {
self.scripts.len()
}
}

View File

@@ -0,0 +1,30 @@
use crate::dynamic_data::script_handling::script::Script;
use crate::dynamic_data::script_handling::script_set::ScriptSet;
use crate::PkmnResult;
use std::sync::{Arc, RwLock};
pub trait VolatileScripts<'a> {
fn volatile_scripts(&self) -> &Arc<RwLock<ScriptSet>>;
fn load_volatile_script(&self, key: &str) -> PkmnResult<Box<dyn Script>>;
fn has_volatile_script(&self, key: &str) -> bool {
self.volatile_scripts().read().unwrap().has(key)
}
fn get_volatile_script(&self, key: &str) -> Option<Arc<Box<dyn Script>>> {
let scripts = self.volatile_scripts().read().unwrap();
let s = scripts.get(key);
s.cloned()
}
fn add_volatile_script(&mut self, key: &str) -> PkmnResult<Arc<Box<dyn Script>>> {
self.volatile_scripts()
.write()
.unwrap()
.stack_or_add(key, &|| self.load_volatile_script(key))
}
fn remove_volatile_script(&mut self, key: &str) {
self.volatile_scripts().write().unwrap().remove(key)
}
}