More work on Rune
continuous-integration/drone/push Build is failing Details

This commit is contained in:
Deukhoofd 2024-04-13 10:47:40 +02:00
parent 67b0abe59f
commit 4bc76b0ee4
Signed by: Deukhoofd
GPG Key ID: F63E044490819F6F
18 changed files with 166 additions and 67 deletions

View File

@ -1,2 +1,4 @@
max_width = 120 max_width = 120
fn_single_line = true fn_single_line = true
inline_attribute_width = 120
unstable_features = true

View File

@ -554,7 +554,7 @@ impl Clone for ScriptContainer {
#[allow(clippy::unwrap_used)] #[allow(clippy::unwrap_used)]
#[allow(clippy::indexing_slicing)] #[allow(clippy::indexing_slicing)]
mod tests { mod tests {
use std::sync::atomic::{AtomicBool, AtomicPtr}; use std::sync::atomic::AtomicPtr;
use super::*; use super::*;

View File

@ -1,15 +1,11 @@
use crate::dynamic_data::{Battle, DamageSource, ExecutingMove, Pokemon, TurnChoice};
use crate::static_data::{Item, Statistic, TypeIdentifier};
use crate::StringKey;
use rune::Hash; use rune::Hash;
use std::sync::Arc;
mod script; mod script;
pub mod script_resolver; pub mod script_resolver;
pub(self) mod wrappers; mod wrappers;
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub(self) struct RuneScriptType { struct RuneScriptType {
pub fn_on_initialize: Option<Hash>, pub fn_on_initialize: Option<Hash>,
pub fn_on_stack: Option<Hash>, pub fn_on_stack: Option<Hash>,
pub fn_on_remove: Option<Hash>, pub fn_on_remove: Option<Hash>,

View File

@ -6,9 +6,8 @@ use crate::StringKey;
use hashbrown::HashMap; use hashbrown::HashMap;
use parking_lot::RwLock; use parking_lot::RwLock;
use rune::runtime::{Object, RuntimeContext, Shared, VmError, VmResult}; use rune::runtime::{Object, RuntimeContext, Shared, VmError, VmResult};
use rune::{Any, Unit, Value}; use rune::{Unit, Value};
use std::convert::TryFrom; use std::convert::TryFrom;
use std::error::Error;
use std::ops::Deref; use std::ops::Deref;
use std::sync::atomic::{AtomicBool, AtomicUsize}; use std::sync::atomic::{AtomicBool, AtomicUsize};
use std::sync::Arc; use std::sync::Arc;
@ -73,7 +72,7 @@ impl Script for RuneScript {
if pars.is_empty() { if pars.is_empty() {
return Ok(()); return Ok(());
} }
let mut write_lock = self.state.write(); let write_lock = self.state.write();
for par in pars { for par in pars {
let key = rune::alloc::string::String::try_from(par.0.str())?; let key = rune::alloc::string::String::try_from(par.0.str())?;
write_lock write_lock

View File

@ -4,12 +4,11 @@ use crate::script_implementations::rune::RuneScriptType;
use crate::static_data::Item; use crate::static_data::Item;
use crate::StringKey; use crate::StringKey;
use hashbrown::HashMap; use hashbrown::HashMap;
use parking_lot::RwLock;
use rune::compile::meta::AssociatedKind; use rune::compile::meta::AssociatedKind;
use rune::compile::{ComponentRef, MetaError}; use rune::compile::{ComponentRef, MetaError};
use rune::diagnostics::Diagnostic; use rune::diagnostics::Diagnostic;
use rune::runtime::{RuntimeContext, Shared}; use rune::runtime::{RuntimeContext, Shared};
use rune::{Context, Diagnostics, Hash, Options, Source, Sources, Unit, Vm}; use rune::{Context, Diagnostics, Options, Source, Sources, Unit};
use std::any::Any; use std::any::Any;
use std::path::Path; use std::path::Path;
use std::sync::Arc; use std::sync::Arc;
@ -128,11 +127,13 @@ impl rune::compile::CompileVisitor for FindScriptTypeVisitor {
if meta.item.iter().count() < 2 { if meta.item.iter().count() < 2 {
return Ok(()); return Ok(());
} }
#[allow(clippy::unwrap_used)] // We know that the first element exists
let mod_name = meta.item.iter().nth(0).unwrap(); let mod_name = meta.item.iter().nth(0).unwrap();
let category = match get_mod_category(mod_name) { let category = match get_mod_category(mod_name) {
Ok(value) => value, Ok(value) => value,
Err(value) => return value, Err(value) => return value,
}; };
#[allow(clippy::unwrap_used)] // We know that the last element exists
let name = meta.item.last().unwrap(); let name = meta.item.last().unwrap();
self.script_types self.script_types
.insert((category, name.to_string().as_str().into()), RuneScriptType::default()); .insert((category, name.to_string().as_str().into()), RuneScriptType::default());

View File

@ -10,17 +10,15 @@ pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
} }
#[derive(Debug, Any)] #[derive(Debug, Any)]
pub struct RuneExecutingMove { pub struct RuneExecutingMove(Arc<ExecutingMove>);
inner: Arc<ExecutingMove>,
}
impl RuneExecutingMove { impl RuneExecutingMove {
#[rune::function] #[rune::function]
pub fn target_count(&self) -> usize { self.inner.target_count() } pub fn target_count(&self) -> usize { self.0.target_count() }
#[rune::function] #[rune::function]
pub fn number_of_hits(&self) -> u8 { self.inner.number_of_hits() } pub fn number_of_hits(&self) -> u8 { self.0.number_of_hits() }
#[rune::function] #[rune::function]
pub fn user(&self) -> Shared<AnyObj> { self.inner.user().wrap() } pub fn user(&self) -> Shared<AnyObj> { self.0.user().wrap() }
} }
impl_rune_wrapper!(&Arc<ExecutingMove>, RuneExecutingMove); impl_rune_wrapper!(&Arc<ExecutingMove>, RuneExecutingMove);

View File

@ -0,0 +1,10 @@
mod executing_move;
mod pokemon;
mod turn_choice;
pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
executing_move::register(module)?;
pokemon::register(module)?;
turn_choice::register(module)?;
Ok(())
}

View File

@ -1,6 +1,6 @@
use crate::defines::LevelInt; use crate::defines::LevelInt;
use crate::dynamic_data::Pokemon; use crate::dynamic_data::Pokemon;
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneWrapper}; use crate::script_implementations::rune::wrappers::impl_rune_wrapper;
use rune::Any; use rune::Any;
pub fn register(module: &mut rune::Module) -> anyhow::Result<()> { pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
@ -10,13 +10,11 @@ pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
} }
#[derive(Any)] #[derive(Any)]
pub struct RunePokemon { pub struct RunePokemon(Pokemon);
inner: Pokemon,
}
impl RunePokemon { impl RunePokemon {
#[rune::function] #[rune::function]
fn level(&self) -> LevelInt { self.inner.level() } fn level(&self) -> LevelInt { self.0.level() }
} }
impl_rune_wrapper!(&Pokemon, RunePokemon); impl_rune_wrapper!(&Pokemon, RunePokemon);

View File

@ -1,5 +1,5 @@
use crate::dynamic_data::TurnChoice; use crate::dynamic_data::TurnChoice;
use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneExecutingMove, RuneWrapper}; use crate::script_implementations::rune::wrappers::{impl_rune_wrapper, RuneWrapper};
use rune::{Any, Value}; use rune::{Any, Value};
use std::sync::Arc; use std::sync::Arc;
@ -11,16 +11,14 @@ pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
} }
#[derive(Any)] #[derive(Any)]
pub struct RuneTurnChoice { pub struct RuneTurnChoice(Arc<TurnChoice>);
inner: Arc<TurnChoice>,
}
impl RuneTurnChoice { impl RuneTurnChoice {
#[rune::function] #[rune::function]
fn speed(&self) -> u32 { self.inner.speed() } fn speed(&self) -> u32 { self.0.speed() }
#[rune::function] #[rune::function]
fn user(&self) -> Value { Value::from(self.inner.user().wrap()) } fn user(&self) -> Value { Value::from(self.0.user().wrap()) }
} }
impl_rune_wrapper!(&Arc<TurnChoice>, RuneTurnChoice); impl_rune_wrapper!(&Arc<TurnChoice>, RuneTurnChoice);

View File

@ -1,27 +1,18 @@
use rune::runtime::Protocol;
use rune::runtime::{AnyObj, Shared}; use rune::runtime::{AnyObj, Shared};
use rune::{Any, Value}; use rune::{Any, Value};
use std::ops::Deref;
mod executing_move; mod dynamic_data;
mod pokemon; mod static_data;
mod turn_choice;
pub use executing_move::*;
pub use pokemon::*;
pub trait RuneWrapper { pub trait RuneWrapper {
#[inline]
fn wrap(self) -> Shared<AnyObj>; fn wrap(self) -> Shared<AnyObj>;
} }
pub fn module() -> anyhow::Result<rune::Module> { pub fn module() -> anyhow::Result<rune::Module> {
let mut module = rune::Module::new(); let mut module = rune::Module::new();
module.ty::<RuneValueIntWrapper>()?; module.ty::<RuneValueIntWrapper>()?;
turn_choice::register(&mut module)?; dynamic_data::register(&mut module)?;
pokemon::register(&mut module)?; static_data::register(&mut module)?;
executing_move::register(&mut module)?;
Ok(module) Ok(module)
} }
@ -32,7 +23,10 @@ pub fn wrap_value_reference(value: i64) -> anyhow::Result<Value> {
pub fn get_value_reference(value: Value) -> anyhow::Result<i64> { pub fn get_value_reference(value: Value) -> anyhow::Result<i64> {
let obj = value.into_any().into_result()?; let obj = value.into_any().into_result()?;
let obj = obj.take()?; let obj = obj.take()?;
let obj = obj.downcast_borrow_ref::<RuneValueIntWrapper>().unwrap(); let obj = match obj.downcast_borrow_ref::<RuneValueIntWrapper>() {
Some(obj) => obj,
None => return Err(anyhow::anyhow!("Value is not a RuneValueIntWrapper")),
};
Ok(obj.value()) Ok(obj.value())
} }
@ -57,11 +51,10 @@ macro_rules! impl_rune_wrapper {
($t:ty, $wrapped_type:ident) => { ($t:ty, $wrapped_type:ident) => {
impl crate::script_implementations::rune::wrappers::RuneWrapper for $t { impl crate::script_implementations::rune::wrappers::RuneWrapper for $t {
fn wrap(self) -> rune::runtime::Shared<rune::runtime::AnyObj> { fn wrap(self) -> rune::runtime::Shared<rune::runtime::AnyObj> {
rune::runtime::Shared::new(rune::runtime::AnyObj::new($wrapped_type { inner: self.clone() }).unwrap()) rune::runtime::Shared::new(rune::runtime::AnyObj::new($wrapped_type(self.clone())).unwrap()).unwrap()
.unwrap()
} }
} }
}; };
} }
pub(self) use impl_rune_wrapper; use impl_rune_wrapper;

View File

@ -0,0 +1,12 @@
mod nature;
mod statistic_set;
use crate::static_data::{Statistic, TimeOfDay};
pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
module.ty::<TimeOfDay>()?;
module.ty::<Statistic>()?;
statistic_set::register(module)?;
nature::register(module)?;
Ok(())
}

View File

@ -0,0 +1,31 @@
use crate::script_implementations::rune::wrappers::impl_rune_wrapper;
use crate::static_data::{Nature, Statistic};
use rune::Any;
use std::sync::Arc;
pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
module.ty::<RuneNature>()?;
Ok(())
}
#[derive(Debug, Any)]
pub struct RuneNature(Arc<dyn Nature>);
impl_rune_wrapper!(&Arc<dyn Nature>, RuneNature);
impl RuneNature {
#[rune::function]
pub fn increased_stat(&self) -> Statistic { self.0.increased_stat() }
#[rune::function]
pub fn decreased_stat(&self) -> Statistic { self.0.decreased_stat() }
#[rune::function]
pub fn increased_modifier(&self) -> f32 { self.0.increased_modifier() }
#[rune::function]
pub fn decreased_modifier(&self) -> f32 { self.0.decreased_modifier() }
#[rune::function]
pub fn get_stat_modifier(&self, stat: Statistic) -> f32 { self.0.get_stat_modifier(stat) }
}

View File

@ -0,0 +1,68 @@
use crate::script_implementations::rune::wrappers::impl_rune_wrapper;
use crate::static_data::{StaticStatisticSet, Statistic, StatisticSet};
use rune::Any;
use std::sync::Arc;
pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
module.ty::<RuneStatisticSet>()?;
module.ty::<RuneStaticStatisticSet>()?;
Ok(())
}
#[derive(Debug, Any)]
pub struct RuneStatisticSet(Arc<StatisticSet<u32>>);
impl_rune_wrapper!(&Arc<StatisticSet<u32>>, RuneStatisticSet);
impl RuneStatisticSet {
#[rune::function]
pub fn get(&self, stat: Statistic) -> u32 { self.0.get_stat(stat) }
#[rune::function]
pub fn set(&mut self, stat: Statistic, value: u32) { self.0.set_stat(stat, value) }
#[rune::function]
pub fn hp(&self) -> u32 { self.0.hp() }
#[rune::function]
pub fn attack(&self) -> u32 { self.0.attack() }
#[rune::function]
pub fn defense(&self) -> u32 { self.0.defense() }
#[rune::function]
pub fn special_attack(&self) -> u32 { self.0.special_attack() }
#[rune::function]
pub fn special_defense(&self) -> u32 { self.0.special_defense() }
#[rune::function]
pub fn speed(&self) -> u32 { self.0.speed() }
}
#[derive(Debug, Any)]
pub struct RuneStaticStatisticSet(Arc<StaticStatisticSet<u16>>);
impl_rune_wrapper!(&Arc<StaticStatisticSet<u16>>, RuneStaticStatisticSet);
impl RuneStaticStatisticSet {
#[rune::function]
pub fn get(&self, stat: Statistic) -> u16 { self.0.get_stat(stat) }
#[rune::function]
pub fn hp(&self) -> u16 { self.0.hp() }
#[rune::function]
pub fn attack(&self) -> u16 { self.0.attack() }
#[rune::function]
pub fn defense(&self) -> u16 { self.0.defense() }
#[rune::function]
pub fn special_attack(&self) -> u16 { self.0.special_attack() }
#[rune::function]
pub fn special_defense(&self) -> u16 { self.0.special_defense() }
#[rune::function]
pub fn speed(&self) -> u16 { self.0.speed() }
}

View File

@ -29,12 +29,8 @@ impl AbilityLibraryImpl {
impl AbilityLibrary for AbilityLibraryImpl {} impl AbilityLibrary for AbilityLibraryImpl {}
impl DataLibrary<dyn Ability> for AbilityLibraryImpl { impl DataLibrary<dyn Ability> for AbilityLibraryImpl {
fn map(&self) -> &IndexMap<StringKey, Arc<dyn Ability>> { fn map(&self) -> &IndexMap<StringKey, Arc<dyn Ability>> { &self.map }
&self.map fn get_modify(&mut self) -> &mut IndexMap<StringKey, Arc<dyn Ability>> { &mut self.map }
}
fn get_modify(&mut self) -> &mut IndexMap<StringKey, Arc<dyn Ability>> {
&mut self.map
}
} }
#[cfg(test)] #[cfg(test)]
@ -45,6 +41,7 @@ pub mod tests {
use crate::static_data::AbilityImpl; use crate::static_data::AbilityImpl;
use crate::static_data::DataLibrary; use crate::static_data::DataLibrary;
use crate::StringKey; use crate::StringKey;
use hashbrown::HashMap;
use std::sync::Arc; use std::sync::Arc;
pub fn build() -> AbilityLibraryImpl { pub fn build() -> AbilityLibraryImpl {
@ -54,7 +51,7 @@ pub mod tests {
Arc::new(AbilityImpl::new( Arc::new(AbilityImpl::new(
&"test_ability".into(), &"test_ability".into(),
&"test_ability".into(), &"test_ability".into(),
Vec::new(), HashMap::new(),
)), )),
); );
lib lib

View File

@ -38,17 +38,11 @@ impl SecondaryEffectImpl {
impl SecondaryEffect for SecondaryEffectImpl { impl SecondaryEffect for SecondaryEffectImpl {
/// The chance in percentages that the effect triggers. -1 to make it always trigger. /// The chance in percentages that the effect triggers. -1 to make it always trigger.
fn chance(&self) -> f32 { fn chance(&self) -> f32 { self.chance }
self.chance
}
/// The name of the effect. /// The name of the effect.
fn effect_name(&self) -> &StringKey { fn effect_name(&self) -> &StringKey { &self.effect_name }
&self.effect_name
}
/// A list of parameters for the effect. /// A list of parameters for the effect.
fn parameters(&self) -> &HashMap<StringKey, Arc<Parameter>> { fn parameters(&self) -> &HashMap<StringKey, Arc<Parameter>> { &self.parameters }
&self.parameters
}
} }
#[cfg(test)] #[cfg(test)]
@ -67,17 +61,17 @@ pub(crate) mod tests {
impl SecondaryEffect for SecondaryEffect { impl SecondaryEffect for SecondaryEffect {
fn chance(&self) -> f32; fn chance(&self) -> f32;
fn effect_name(&self) -> &StringKey; fn effect_name(&self) -> &StringKey;
fn parameters(&self) -> &Vec<Arc<Parameter >>; fn parameters(&self) -> &HashMap<StringKey, Arc<Parameter >>;
} }
} }
#[test] #[test]
fn create_secondary_effect() { fn create_secondary_effect() {
let empty = SecondaryEffectImpl::new(0.0, "".into(), vec![]); let empty = SecondaryEffectImpl::new(0.0, "".into(), HashMap::new());
assert_approx_eq!(empty.chance(), 0.0); assert_approx_eq!(empty.chance(), 0.0);
assert_eq!(empty.effect_name(), &"".into()); assert_eq!(empty.effect_name(), &"".into());
assert_eq!(empty.parameters().len(), 0); assert_eq!(empty.parameters().len(), 0);
let set = SecondaryEffectImpl::new(50.0, "foo".into(), Vec::new()); let set = SecondaryEffectImpl::new(50.0, "foo".into(), HashMap::new());
assert_approx_eq!(set.chance(), 50.0); assert_approx_eq!(set.chance(), 50.0);
assert_eq!(set.effect_name(), &"foo".into()); assert_eq!(set.effect_name(), &"foo".into());
assert_eq!(set.parameters().len(), 0); assert_eq!(set.parameters().len(), 0);

View File

@ -69,7 +69,7 @@ pub(crate) mod tests {
impl Ability for Ability { impl Ability for Ability {
fn name(&self) -> &StringKey; fn name(&self) -> &StringKey;
fn effect(&self) -> &StringKey; fn effect(&self) -> &StringKey;
fn parameters(&self) -> &Vec<Arc<Parameter >>; fn parameters(&self) -> &HashMap<StringKey, Arc<Parameter >>;
} }
} }
} }

View File

@ -4,6 +4,7 @@ use serde::{Deserialize, Serialize};
/// Stats are numerical values on Pokemon that are used in battle. /// Stats are numerical values on Pokemon that are used in battle.
#[derive(Debug, PartialEq, Eq, Copy, Clone)] #[derive(Debug, PartialEq, Eq, Copy, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "rune", derive(rune::Any))]
#[repr(u8)] #[repr(u8)]
pub enum Statistic { pub enum Statistic {
/// Health Points determine how much damage a Pokemon can receive before fainting. /// Health Points determine how much damage a Pokemon can receive before fainting.

View File

@ -1,6 +1,7 @@
/// The time of day. These values are the 4 different groups of time of day in Pokemon games since /// The time of day. These values are the 4 different groups of time of day in Pokemon games since
/// gen 5. The exact times these correspond to differ between games. /// gen 5. The exact times these correspond to differ between games.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "rune", derive(rune::Any))]
#[repr(u8)] #[repr(u8)]
pub enum TimeOfDay { pub enum TimeOfDay {
/// The morning. /// The morning.