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
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::indexing_slicing)]
mod tests {
use std::sync::atomic::{AtomicBool, AtomicPtr};
use std::sync::atomic::AtomicPtr;
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 std::sync::Arc;
mod script;
pub mod script_resolver;
pub(self) mod wrappers;
mod wrappers;
#[derive(Debug, Default)]
pub(self) struct RuneScriptType {
struct RuneScriptType {
pub fn_on_initialize: Option<Hash>,
pub fn_on_stack: Option<Hash>,
pub fn_on_remove: Option<Hash>,

View File

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

View File

@ -4,12 +4,11 @@ use crate::script_implementations::rune::RuneScriptType;
use crate::static_data::Item;
use crate::StringKey;
use hashbrown::HashMap;
use parking_lot::RwLock;
use rune::compile::meta::AssociatedKind;
use rune::compile::{ComponentRef, MetaError};
use rune::diagnostics::Diagnostic;
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::path::Path;
use std::sync::Arc;
@ -128,11 +127,13 @@ impl rune::compile::CompileVisitor for FindScriptTypeVisitor {
if meta.item.iter().count() < 2 {
return Ok(());
}
#[allow(clippy::unwrap_used)] // We know that the first element exists
let mod_name = meta.item.iter().nth(0).unwrap();
let category = match get_mod_category(mod_name) {
Ok(value) => value,
Err(value) => return value,
};
#[allow(clippy::unwrap_used)] // We know that the last element exists
let name = meta.item.last().unwrap();
self.script_types
.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)]
pub struct RuneExecutingMove {
inner: Arc<ExecutingMove>,
}
pub struct RuneExecutingMove(Arc<ExecutingMove>);
impl RuneExecutingMove {
#[rune::function]
pub fn target_count(&self) -> usize { self.inner.target_count() }
pub fn target_count(&self) -> usize { self.0.target_count() }
#[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]
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);

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::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;
pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
@ -10,13 +10,11 @@ pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
}
#[derive(Any)]
pub struct RunePokemon {
inner: Pokemon,
}
pub struct RunePokemon(Pokemon);
impl RunePokemon {
#[rune::function]
fn level(&self) -> LevelInt { self.inner.level() }
fn level(&self) -> LevelInt { self.0.level() }
}
impl_rune_wrapper!(&Pokemon, RunePokemon);

View File

@ -1,5 +1,5 @@
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 std::sync::Arc;
@ -11,16 +11,14 @@ pub fn register(module: &mut rune::Module) -> anyhow::Result<()> {
}
#[derive(Any)]
pub struct RuneTurnChoice {
inner: Arc<TurnChoice>,
}
pub struct RuneTurnChoice(Arc<TurnChoice>);
impl RuneTurnChoice {
#[rune::function]
fn speed(&self) -> u32 { self.inner.speed() }
fn speed(&self) -> u32 { self.0.speed() }
#[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);

View File

@ -1,27 +1,18 @@
use rune::runtime::Protocol;
use rune::runtime::{AnyObj, Shared};
use rune::{Any, Value};
use std::ops::Deref;
mod executing_move;
mod pokemon;
mod turn_choice;
pub use executing_move::*;
pub use pokemon::*;
mod dynamic_data;
mod static_data;
pub trait RuneWrapper {
#[inline]
fn wrap(self) -> Shared<AnyObj>;
}
pub fn module() -> anyhow::Result<rune::Module> {
let mut module = rune::Module::new();
module.ty::<RuneValueIntWrapper>()?;
turn_choice::register(&mut module)?;
pokemon::register(&mut module)?;
executing_move::register(&mut module)?;
dynamic_data::register(&mut module)?;
static_data::register(&mut 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> {
let obj = value.into_any().into_result()?;
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())
}
@ -57,11 +51,10 @@ macro_rules! impl_rune_wrapper {
($t:ty, $wrapped_type:ident) => {
impl crate::script_implementations::rune::wrappers::RuneWrapper for $t {
fn wrap(self) -> rune::runtime::Shared<rune::runtime::AnyObj> {
rune::runtime::Shared::new(rune::runtime::AnyObj::new($wrapped_type { inner: self.clone() }).unwrap())
.unwrap()
rune::runtime::Shared::new(rune::runtime::AnyObj::new($wrapped_type(self.clone())).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 DataLibrary<dyn Ability> for AbilityLibraryImpl {
fn map(&self) -> &IndexMap<StringKey, Arc<dyn Ability>> {
&self.map
}
fn get_modify(&mut self) -> &mut IndexMap<StringKey, Arc<dyn Ability>> {
&mut self.map
}
fn map(&self) -> &IndexMap<StringKey, Arc<dyn Ability>> { &self.map }
fn get_modify(&mut self) -> &mut IndexMap<StringKey, Arc<dyn Ability>> { &mut self.map }
}
#[cfg(test)]
@ -45,6 +41,7 @@ pub mod tests {
use crate::static_data::AbilityImpl;
use crate::static_data::DataLibrary;
use crate::StringKey;
use hashbrown::HashMap;
use std::sync::Arc;
pub fn build() -> AbilityLibraryImpl {
@ -54,7 +51,7 @@ pub mod tests {
Arc::new(AbilityImpl::new(
&"test_ability".into(),
&"test_ability".into(),
Vec::new(),
HashMap::new(),
)),
);
lib

View File

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

View File

@ -69,7 +69,7 @@ pub(crate) mod tests {
impl Ability for Ability {
fn name(&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.
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "rune", derive(rune::Any))]
#[repr(u8)]
pub enum Statistic {
/// 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
/// gen 5. The exact times these correspond to differ between games.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "rune", derive(rune::Any))]
#[repr(u8)]
pub enum TimeOfDay {
/// The morning.