diff --git a/src/dynamic_data/choices.rs b/src/dynamic_data/choices.rs index 2e1c04f..46e3505 100644 --- a/src/dynamic_data/choices.rs +++ b/src/dynamic_data/choices.rs @@ -10,9 +10,9 @@ use crate::dynamic_data::{ScriptSource, ScriptSourceData}; /// The data on a turn choice that should be contained in every turn choice, regardless of type. #[derive(Debug)] -struct CommonChoiceData<'user, 'library> { +struct CommonChoiceData { /// The user of the turn choice - user: Arc>, + user: Arc, /// The speed of the user at the beginning of the turn. speed: u32, /// This random value is set at the beginning of the turn. It is used for tie breaking of the @@ -30,22 +30,22 @@ struct CommonChoiceData<'user, 'library> { /// This enum defines a single choice for a Pokemon for a battle turn. #[derive(Debug)] #[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))] -pub enum TurnChoice<'user, 'library> { +pub enum TurnChoice { /// A move choice tells a Pokemon to use a move on a target for this turn. - Move(MoveChoice<'user, 'library>), + Move(MoveChoice), /// An item choice tells a Pokemon to use an item. - Item(ItemChoice<'user, 'library>), + Item(ItemChoice), /// A switch choice tells a Pokemon to switch with another Pokemon from the party. - Switch(SwitchChoice<'user, 'library>), + Switch(SwitchChoice), /// A flee choice tells a Pokemon to flee from battle. - Flee(FleeChoice<'user, 'library>), + Flee(FleeChoice), /// A pass choice tells the user to do nothing that turn. - Pass(PassChoice<'user, 'library>), + Pass(PassChoice), } -impl<'user, 'library> TurnChoice<'user, 'library> { +impl TurnChoice { /// The shared choice data between each of the different turn choices. - fn choice_data(&self) -> &CommonChoiceData<'user, 'library> { + fn choice_data(&self) -> &CommonChoiceData { match self { TurnChoice::Move(data) => &data.choice_data, TurnChoice::Item(data) => &data.choice_data, @@ -55,7 +55,7 @@ impl<'user, 'library> TurnChoice<'user, 'library> { } } /// The shared choice data between each of the different turn choices. - fn choice_data_mut(&mut self) -> &mut Box> { + fn choice_data_mut(&mut self) -> &mut Box { match self { TurnChoice::Move(data) => &mut data.choice_data, TurnChoice::Item(data) => &mut data.choice_data, @@ -66,7 +66,7 @@ impl<'user, 'library> TurnChoice<'user, 'library> { } /// Get the user of the given choice. - pub fn user(&self) -> &Arc> { + pub fn user(&self) -> &Arc { &self.choice_data().user } @@ -108,7 +108,7 @@ impl<'user, 'library> TurnChoice<'user, 'library> { /// Helper function to get the move choice data from a turn. Note that this will panic if not /// used on a move choice. - pub(crate) fn get_move_turn_data<'b>(&'b self) -> &'b MoveChoice<'user, 'library> { + pub(crate) fn get_move_turn_data(&self) -> &MoveChoice { if let TurnChoice::Move(data) = self { return data; } @@ -116,7 +116,7 @@ impl<'user, 'library> TurnChoice<'user, 'library> { } } -impl<'user, 'library> ScriptSource<'user> for TurnChoice<'user, 'library> { +impl ScriptSource for TurnChoice { fn get_script_count(&self) -> usize { match self { TurnChoice::Move(data) => data.get_script_count(), @@ -160,9 +160,9 @@ impl<'user, 'library> ScriptSource<'user> for TurnChoice<'user, 'library> { /// The data attached to a move choice. #[derive(Debug)] -pub struct MoveChoice<'user, 'library> { +pub struct MoveChoice { /// The move that is used for this choice. - used_move: Arc>, + used_move: Arc, /// The side this move is aimed at. target_side: u8, /// The index of the Pokemon on the side we're aiming at. @@ -172,17 +172,12 @@ pub struct MoveChoice<'user, 'library> { /// The priority of the move choice at the beginning of the turn. priority: i8, /// The common turn choice data. - choice_data: Box>, + choice_data: Box, } -impl<'user, 'library> MoveChoice<'user, 'library> { +impl<'user, 'library> MoveChoice { /// Initializes the data for a new move choice. - pub fn new( - user: Arc>, - used_move: Arc>, - target_side: u8, - target_index: u8, - ) -> Self { + pub fn new(user: Arc, used_move: Arc, target_side: u8, target_index: u8) -> Self { Self { used_move, target_side, @@ -200,7 +195,7 @@ impl<'user, 'library> MoveChoice<'user, 'library> { } /// The actual learned move on the Pokemon we use for this choice. - pub fn used_move(&self) -> &Arc> { + pub fn used_move(&self) -> &Arc { &self.used_move } @@ -221,7 +216,7 @@ impl<'user, 'library> MoveChoice<'user, 'library> { &mut self.priority } /// The user of the choice. - pub fn user(&self) -> &Arc> { + pub fn user(&self) -> &Arc { &self.choice_data.user } /// The move script of the choice. @@ -230,7 +225,7 @@ impl<'user, 'library> MoveChoice<'user, 'library> { } } -impl<'user, 'library> ScriptSource<'user> for MoveChoice<'user, 'library> { +impl ScriptSource for MoveChoice { fn get_script_count(&self) -> usize { 1 + self.choice_data.user.get_script_count() } @@ -251,14 +246,14 @@ impl<'user, 'library> ScriptSource<'user> for MoveChoice<'user, 'library> { /// The data given when we select an item choice. #[derive(Debug)] -pub struct ItemChoice<'user, 'library> { +pub struct ItemChoice { /// The shared data of all turn choices. - choice_data: Box>, + choice_data: Box, } -impl<'user, 'library> ItemChoice<'user, 'library> { +impl ItemChoice { /// Initialised a new item choice. - pub fn new(user: Arc>) -> Self { + pub fn new(user: Arc) -> Self { Self { choice_data: Box::new(CommonChoiceData { user, @@ -271,7 +266,7 @@ impl<'user, 'library> ItemChoice<'user, 'library> { } } -impl<'user, 'library> ScriptSource<'user> for ItemChoice<'user, 'library> { +impl ScriptSource for ItemChoice { fn get_script_count(&self) -> usize { 0 } @@ -289,14 +284,14 @@ impl<'user, 'library> ScriptSource<'user> for ItemChoice<'user, 'library> { /// The data given when we select a switch choice. #[derive(Debug)] -pub struct SwitchChoice<'user, 'library> { +pub struct SwitchChoice { /// The shared data of all turn choices. - choice_data: Box>, + choice_data: Box, } -impl<'user, 'library> SwitchChoice<'user, 'library> { +impl SwitchChoice { /// Initialise the turn choice data. - pub fn new(user: Arc>) -> Self { + pub fn new(user: Arc) -> Self { Self { choice_data: Box::new(CommonChoiceData { user, @@ -309,7 +304,7 @@ impl<'user, 'library> SwitchChoice<'user, 'library> { } } -impl<'user, 'library> ScriptSource<'user> for SwitchChoice<'user, 'library> { +impl ScriptSource for SwitchChoice { fn get_script_count(&self) -> usize { 0 } @@ -327,14 +322,14 @@ impl<'user, 'library> ScriptSource<'user> for SwitchChoice<'user, 'library> { /// The data given when we select a flee choice. #[derive(Debug)] -pub struct FleeChoice<'user, 'library> { +pub struct FleeChoice { /// The common data all turn choices share. - choice_data: Box>, + choice_data: Box, } -impl<'user, 'library> FleeChoice<'user, 'library> { +impl FleeChoice { /// Initialises a new flee choice. - pub fn new(user: Arc>) -> Self { + pub fn new(user: Arc) -> Self { Self { choice_data: Box::new(CommonChoiceData { user, @@ -347,7 +342,7 @@ impl<'user, 'library> FleeChoice<'user, 'library> { } } -impl<'user, 'library> ScriptSource<'user> for FleeChoice<'user, 'library> { +impl ScriptSource for FleeChoice { fn get_script_count(&self) -> usize { 0 } @@ -365,14 +360,14 @@ impl<'user, 'library> ScriptSource<'user> for FleeChoice<'user, 'library> { /// The data given when we select a pass choice. #[derive(Debug)] -pub struct PassChoice<'user, 'library> { +pub struct PassChoice { /// The common data of all turn choices. - choice_data: Box>, + choice_data: Box, } -impl<'user, 'library> PassChoice<'user, 'library> { +impl PassChoice { /// Initialised a new pass choice. - pub fn new(user: Arc>) -> Self { + pub fn new(user: Arc) -> Self { Self { choice_data: Box::new(CommonChoiceData { user, @@ -385,7 +380,7 @@ impl<'user, 'library> PassChoice<'user, 'library> { } } -impl<'user, 'library> ScriptSource<'user> for PassChoice<'user, 'library> { +impl ScriptSource for PassChoice { fn get_script_count(&self) -> usize { 0 } @@ -401,21 +396,21 @@ impl<'user, 'library> ScriptSource<'user> for PassChoice<'user, 'library> { } } -impl<'user, 'library> PartialEq for TurnChoice<'user, 'library> { +impl PartialEq for TurnChoice { fn eq(&self, other: &Self) -> bool { std::ptr::eq(self, other) } } -impl<'user, 'library> Eq for TurnChoice<'user, 'library> {} +impl Eq for TurnChoice {} -impl<'user, 'library> PartialOrd for TurnChoice<'user, 'library> { +impl PartialOrd for TurnChoice { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } -impl<'user, 'library> Ord for TurnChoice<'user, 'library> { +impl Ord for TurnChoice { fn cmp(&self, other: &Self) -> Ordering { match self { TurnChoice::Move(data) => { diff --git a/src/dynamic_data/event_hooks.rs b/src/dynamic_data/event_hooks.rs index 9d6c6f9..d4df1b4 100644 --- a/src/dynamic_data/event_hooks.rs +++ b/src/dynamic_data/event_hooks.rs @@ -1,4 +1,5 @@ use std::fmt::{Debug, Formatter}; +use std::sync::Arc; use crate::dynamic_data::DamageSource; use crate::dynamic_data::ExecutingMove; @@ -27,7 +28,7 @@ impl<'battle, 'library> EventHook { /// Run a new event. This will send the event to all externally defined event listeners. It will /// dispose of the event afterwards. - pub fn trigger<'b>(&self, evt: Event<'b, 'battle, 'library>) { + pub fn trigger(&self, evt: Event) { let b = Box::new(&evt); for f in &self.evt_hook_function { f(&b); @@ -43,7 +44,7 @@ impl Debug for EventHook { /// The different events that can occur during the battle, for which a GUI should show something. #[derive(Debug)] -pub enum Event<'own, 'battle, 'library> { +pub enum Event<'own> { /// A switch event happens when a Pokemon gets switched out for something else. Switch { /// The side the Pokemon got switched from/on @@ -51,7 +52,7 @@ pub enum Event<'own, 'battle, 'library> { /// The index of the Pokemon that got switched in/out on its side index: u8, /// The new Pokemon that will be on the spot. If none, the spot will now be empty. - pokemon: Option<&'own Pokemon<'battle, 'library>>, + pokemon: Option<&'own Pokemon>, }, /// A swap event happens when two Pokemon on a side swap positions. Note that this is rare. Swap { @@ -67,23 +68,23 @@ pub enum Event<'own, 'battle, 'library> { /// enjoy. SpeciesChange { /// The pokemon that changed species. - pokemon: &'own Pokemon<'battle, 'library>, + pokemon: &'own Pokemon, /// The new species of the Pokemon. - species: &'own Species, + species: Arc, /// The form of the species the Pokemon will have. - form: &'own Form, + form: Arc
, }, /// This event happens when a Pokemon changes form during battle. This is rather common. FormChange { /// The pokemon that changed forms. - pokemon: &'own Pokemon<'battle, 'library>, + pokemon: &'own Pokemon, /// The new form of the Pokemon. form: &'own Form, }, /// This event happens when a Pokemon takes damage. Damage { /// The Pokemon that takes damage. - pokemon: &'own Pokemon<'battle, 'library>, + pokemon: &'own Pokemon, /// The source of damage. source: DamageSource, /// The health of the Pokemon before the damage. @@ -94,7 +95,7 @@ pub enum Event<'own, 'battle, 'library> { /// This event happens when a Pokemon gets healed Heal { /// The Pokemon that gets healed. - pokemon: &'own Pokemon<'battle, 'library>, + pokemon: &'own Pokemon, /// The health of the Pokemon before the heal. original_health: u32, /// The health of the Pokemon after the heal. @@ -103,24 +104,24 @@ pub enum Event<'own, 'battle, 'library> { /// This event happens when a Pokemon faints. Faint { /// The pokemon that has fainted. - pokemon: &'own Pokemon<'battle, 'library>, + pokemon: &'own Pokemon, }, /// This event happens when a Pokemon uses a move on a target, just before any hits. MoveUse { /// The data of the move used. - executing_move: &'own ExecutingMove<'own, 'battle, 'library>, + executing_move: &'own ExecutingMove, }, /// This event happens when a Pokemon missed. Miss { /// The pokemon that missed. - user: &'own Pokemon<'battle, 'library>, + user: &'own Pokemon, }, /// The turn is finished running, waiting for new input. EndTurn, /// A pokemon had its stat boost changed StatBoostChange { /// The pokemon that had its stat boosts changed. - user: &'own Pokemon<'battle, 'library>, + user: &'own Pokemon, /// The statistic that changed. stat: Statistic, /// The value of the stat before the change. diff --git a/src/dynamic_data/flow/choice_queue.rs b/src/dynamic_data/flow/choice_queue.rs index 87d9cd1..27fcc03 100644 --- a/src/dynamic_data/flow/choice_queue.rs +++ b/src/dynamic_data/flow/choice_queue.rs @@ -8,31 +8,31 @@ use crate::dynamic_data::Pokemon; /// helper functions to change the turn order while doing the execution. This is needed, as several /// moves in Pokemon actively mess with this order. #[derive(Debug)] -pub struct ChoiceQueue<'battle, 'library> { +pub struct ChoiceQueue { /// Our storage of turn choices. Starts out completely filled, then slowly empties as turns get /// executed. - queue: Vec>>, + queue: Vec>, /// The current index of the turn we need to execute next. current: usize, } -impl<'battle, 'library> ChoiceQueue<'battle, 'library> { +impl ChoiceQueue { /// Initializes a ChoiceQueue. We expect the given queue to already be sorted here. - pub(crate) fn new(queue: Vec>>) -> Self { + pub(crate) fn new(queue: Vec>) -> Self { Self { queue, current: 0 } } /// Dequeues the next turn choice to be executed. This gives ownership to the callee, and replaces /// our own reference to the turn choice with an empty spot. It also increments the current position /// by one. - pub fn dequeue<'b>(&'b mut self) -> TurnChoice<'battle, 'library> { + pub fn dequeue<'b>(&'b mut self) -> TurnChoice { let c = self.queue[self.current].take(); self.current += 1; c.unwrap() } /// This reads what the next choice to execute will be, without modifying state. - pub fn peek(&self) -> &'battle TurnChoice { + pub fn peek(&self) -> &TurnChoice { self.queue[self.current].as_ref().unwrap() } @@ -55,7 +55,7 @@ impl<'battle, 'library> ChoiceQueue<'battle, 'library> { } /// Internal helper function to be easily able to iterate over the yet to be executed choices. - pub(crate) fn get_queue(&self) -> &[Option>] { + pub(crate) fn get_queue(&self) -> &[Option] { &self.queue[self.current..self.queue.len()] } } diff --git a/src/dynamic_data/flow/target_resolver.rs b/src/dynamic_data/flow/target_resolver.rs index 5c0f53b..1a178c4 100644 --- a/src/dynamic_data/flow/target_resolver.rs +++ b/src/dynamic_data/flow/target_resolver.rs @@ -8,10 +8,10 @@ use crate::dynamic_data::Pokemon; use crate::static_data::MoveTarget; /// Helper type for the vector of targets we will return. -pub type TargetList<'own, 'library> = Vec>>>; +pub type TargetList = Vec>>; /// This returns all Pokemon in the battle. -fn get_all_targets<'b, 'library>(battle: &Battle<'b, 'library>) -> TargetList<'b, 'library> { +fn get_all_targets<'b, 'library>(battle: &Battle) -> TargetList { let mut v = Vec::with_capacity(battle.pokemon_per_side() as usize * battle.number_of_sides() as usize); for side in battle.sides() { for pokemon in side.pokemon().deref() { @@ -31,11 +31,7 @@ fn get_opposite_side(side: u8) -> u8 { /// Gets all Pokemon that are adjacent to of directly opposite of a Pokemon. This means the target, /// the Pokemon left of it, the Pokemon right of it, and the Pokemon opposite of it. -fn get_all_adjacent_opponent<'b, 'library>( - side: u8, - index: u8, - battle: &Battle<'b, 'library>, -) -> TargetList<'b, 'library> { +fn get_all_adjacent_opponent<'b, 'library>(side: u8, index: u8, battle: &Battle) -> TargetList { let left = index as i32 - 1; let right = index + 1; if left < 0 && right >= battle.pokemon_per_side() { @@ -80,7 +76,7 @@ fn get_all_adjacent_opponent<'b, 'library>( /// Gets all Pokemon that are adjacent to a Pokemon. This includes the target, the Pokemon to the /// left of it, and the Pokemon to the right of it. -fn get_all_adjacent<'b, 'library>(side: u8, index: u8, battle: &Battle<'b, 'library>) -> TargetList<'b, 'library> { +fn get_all_adjacent<'b, 'library>(side: u8, index: u8, battle: &Battle) -> TargetList { let left = index as i32 - 1; let right = index + 1; if left < 0 && right >= battle.pokemon_per_side() { @@ -106,12 +102,7 @@ fn get_all_adjacent<'b, 'library>(side: u8, index: u8, battle: &Battle<'b, 'libr } /// Gets the target for a specific move target type, given the targeted position. -pub fn resolve_targets<'b, 'library>( - side: u8, - index: u8, - target: MoveTarget, - battle: &Battle<'b, 'library>, -) -> TargetList<'b, 'library> { +pub fn resolve_targets<'b, 'library>(side: u8, index: u8, target: MoveTarget, battle: &Battle) -> TargetList { match target { // These all resolve to a single position. We let the client deal with where the target is, // and just return the Pokemon at that given target here. diff --git a/src/dynamic_data/flow/turn_runner.rs b/src/dynamic_data/flow/turn_runner.rs index 5312566..6bca850 100644 --- a/src/dynamic_data/flow/turn_runner.rs +++ b/src/dynamic_data/flow/turn_runner.rs @@ -12,7 +12,7 @@ use crate::dynamic_data::Pokemon; use crate::static_data::{DataLibrary, MoveCategory}; use crate::{run_scripts, script_hook, PkmnResult}; -impl<'own, 'library> Battle<'own, 'library> { +impl Battle { /// Execute the entire turn after the choices are all set. pub(crate) fn run_turn(&self) -> PkmnResult<()> { let choice_queue = self.current_turn_queue(); @@ -62,7 +62,7 @@ impl<'own, 'library> Battle<'own, 'library> { } /// Executes a single choice. - fn execute_choice(&self, choice: &TurnChoice<'own, 'library>) -> PkmnResult<()> { + fn execute_choice(&self, choice: &TurnChoice) -> PkmnResult<()> { // A pass turn choice means the user does not intend to do anything. As such, return. if let TurnChoice::Pass(..) = choice { return Ok(()); @@ -91,7 +91,7 @@ impl<'own, 'library> Battle<'own, 'library> { } /// Executes a move choice. - fn execute_move_choice<'func>(&'func self, choice: &'func TurnChoice<'own, 'library>) -> PkmnResult<()> { + fn execute_move_choice<'func>(&'func self, choice: &'func TurnChoice) -> PkmnResult<()> { let choice = choice.get_move_turn_data(); let used_move = choice.used_move(); let move_data = { @@ -111,11 +111,11 @@ impl<'own, 'library> Battle<'own, 'library> { return Ok(()); } let mut executing_move = ExecutingMove::new( - &targets, + targets.clone(), number_of_hits, choice.user().clone(), used_move.clone(), - move_data, + move_data.clone(), choice.script().clone(), ); let mut prevented = false; @@ -148,11 +148,7 @@ impl<'own, 'library> Battle<'own, 'library> { } /// Executes a move turn choice on a single target. - fn handle_move_for_target( - &self, - executing_move: &mut ExecutingMove<'_, 'own, 'library>, - target: &Arc>, - ) -> PkmnResult<()> { + fn handle_move_for_target(&self, executing_move: &mut ExecutingMove, target: &Arc) -> PkmnResult<()> { { let mut fail = false; script_hook!(fail_incoming_move, target, executing_move, target, &mut fail); diff --git a/src/dynamic_data/libraries/dynamic_library.rs b/src/dynamic_data/libraries/dynamic_library.rs index df42306..3812def 100644 --- a/src/dynamic_data/libraries/dynamic_library.rs +++ b/src/dynamic_data/libraries/dynamic_library.rs @@ -25,7 +25,7 @@ pub struct DynamicLibrary { damage_calculator: Box, /// The Misc Library holds minor functions that do not fall in any of the other libraries and /// calculators. - misc_library: Box>, + misc_library: Box, /// The script resolver deals with how to resolve the scripts from specific unique key combinations. script_resolver: Box, @@ -40,7 +40,7 @@ impl DynamicLibrary { static_data: StaticData, stat_calculator: Box, damage_calculator: Box, - misc_library: Box>, + misc_library: Box, script_resolver: Box, ) -> Self { Self { @@ -67,7 +67,7 @@ impl DynamicLibrary { } /// The Misc Library holds minor functions that do not fall in any of the other libraries and /// calculators. - pub fn misc_library(&self) -> &dyn MiscLibrary<'static> { + pub fn misc_library(&self) -> &dyn MiscLibrary { self.misc_library.deref() } @@ -84,7 +84,7 @@ impl DynamicLibrary { /// Loads an item script with the given unique key. If no script can be created with this /// combinations, returns None. Note that ItemScripts are immutable, as their script should be /// shared between all different usages. - pub fn load_item_script(&self, _key: &Item) -> PkmnResult>> { + pub fn load_item_script(&self, _key: &Arc) -> PkmnResult>> { todo!() } } diff --git a/src/dynamic_data/libraries/misc_library.rs b/src/dynamic_data/libraries/misc_library.rs index b94e0a9..d9c260c 100644 --- a/src/dynamic_data/libraries/misc_library.rs +++ b/src/dynamic_data/libraries/misc_library.rs @@ -10,35 +10,26 @@ use crate::static_data::{MoveCategory, MoveData, MoveTarget, SecondaryEffect}; use crate::StringKey; /// The misc library holds several misc functions required for the battle to run. -pub trait MiscLibrary<'library>: Debug { +pub trait MiscLibrary: Debug { /// Returns whether or not a Pokemon is allowed to flee or switch out. fn can_flee(&self, choice: &TurnChoice) -> bool; /// Returns the move we need to use if we can't use another move. Typically Struggle. - fn replacement_move<'func>( - &'func self, - user: &Arc>, - target_side: u8, - target_index: u8, - ) -> TurnChoice<'func, 'library>; + fn replacement_move<'func>(&'func self, user: &Arc, target_side: u8, target_index: u8) -> TurnChoice; // TODO: can evolve from level up? // TODO: get time } /// A gen 7 implementation for the MiscLibrary. #[derive(Debug)] -pub struct Gen7MiscLibrary<'library> { - /// The move data for struggle. This is a pointer due to lifetime issues; we know that the - /// learned move based on this has the same lifetime as the move data, but the compiler does not. - /// If possible in a sane manner, we should get rid of this pointer. - struggle_data: *const MoveData, +pub struct Gen7MiscLibrary { /// The learned move data for struggle. - struggle_learned_move: Arc>, + struggle_learned_move: Arc, } -impl<'library> Gen7MiscLibrary<'library> { +impl Gen7MiscLibrary { /// Instantiates a new MiscLibrary. pub fn new() -> Self { - let struggle_data = Box::new(MoveData::new( + let struggle_data = Arc::new(MoveData::new( &StringKey::new("struggle"), 0.into(), MoveCategory::Physical, @@ -50,40 +41,23 @@ impl<'library> Gen7MiscLibrary<'library> { Some(SecondaryEffect::new(-1.0, StringKey::new("struggle"), vec![])), HashSet::new(), )); - let struggle_ptr = Box::into_raw(struggle_data); - let struggle_learned_move = Arc::new(LearnedMove::new(unsafe { &*struggle_ptr }, MoveLearnMethod::Unknown)); - Self { - struggle_data: struggle_ptr, - struggle_learned_move, - } + let struggle_learned_move = Arc::new(LearnedMove::new(&struggle_data.clone(), MoveLearnMethod::Unknown)); + Self { struggle_learned_move } } } -impl<'library> Default for Gen7MiscLibrary<'library> { +impl Default for Gen7MiscLibrary { fn default() -> Self { Self::new() } } -impl<'library> Drop for Gen7MiscLibrary<'library> { - fn drop(&mut self) { - unsafe { - let _ = Box::from_raw(self.struggle_data as *mut MoveData); - } - } -} - -impl<'library> MiscLibrary<'library> for Gen7MiscLibrary<'library> { +impl MiscLibrary for Gen7MiscLibrary { fn can_flee(&self, _choice: &TurnChoice) -> bool { todo!() } - fn replacement_move<'func>( - &'func self, - user: &Arc>, - target_side: u8, - target_index: u8, - ) -> TurnChoice<'func, 'library> { + fn replacement_move<'func>(&'func self, user: &Arc, target_side: u8, target_index: u8) -> TurnChoice { self.struggle_learned_move.restore_all_uses(); TurnChoice::Move(MoveChoice::new( user.clone(), diff --git a/src/dynamic_data/models/battle.rs b/src/dynamic_data/models/battle.rs index ce41443..6463af3 100644 --- a/src/dynamic_data/models/battle.rs +++ b/src/dynamic_data/models/battle.rs @@ -22,11 +22,11 @@ use crate::{script_hook, PkmnResult, StringKey}; /// A pokemon battle, with any amount of sides and pokemon per side. #[derive(Debug)] -pub struct Battle<'own, 'library> { +pub struct Battle { /// The library the battle uses for handling. - library: &'own DynamicLibrary, + library: Arc, /// A list of all different parties in the battle. - parties: Vec>, + parties: Vec, /// Whether or not Pokemon can flee from the battle. can_flee: bool, /// The number of sides in the battle. Typically 2. @@ -34,11 +34,11 @@ pub struct Battle<'own, 'library> { /// The number of Pokemon that can be on each side. pokemon_per_side: u8, /// A list of all sides in the battle. - sides: Vec>, + sides: Vec, /// The RNG used for the battle. random: BattleRandom, /// A queue of the yet to be executed choices in a turn. - current_turn_queue: RwLock>>, + current_turn_queue: RwLock>, /// Whether or not the battle has ended. has_ended: AtomicBool, /// The eventual result of the battle. Inconclusive until the battle is ended. @@ -55,11 +55,11 @@ pub struct Battle<'own, 'library> { script_source_data: RwLock, } -impl<'own, 'library> Battle<'own, 'library> { +impl<'own, 'library> Battle { /// Initializes a new battle. pub fn new( - library: &'own DynamicLibrary, - parties: Vec>, + library: Arc, + parties: Vec, can_flee: bool, number_of_sides: u8, pokemon_per_side: u8, @@ -104,11 +104,11 @@ impl<'own, 'library> Battle<'own, 'library> { } /// The library the battle uses for handling. - pub fn library(&self) -> &'own DynamicLibrary { - self.library + pub fn library(&self) -> &Arc { + &self.library } /// A list of all different parties in the battle. - pub fn parties(&self) -> &Vec> { + pub fn parties(&self) -> &Vec { &self.parties } /// Whether or not Pokemon can flee from the battle. @@ -124,11 +124,11 @@ impl<'own, 'library> Battle<'own, 'library> { self.pokemon_per_side } /// A list of all sides in the battle. - pub fn sides(&self) -> &Vec> { + pub fn sides(&self) -> &Vec { &self.sides } /// A mutable list of all sides in the battle. - pub fn sides_mut(&mut self) -> &mut Vec> { + pub fn sides_mut(&mut self) -> &mut Vec { &mut self.sides } /// The RNG used for the battle. @@ -156,12 +156,12 @@ impl<'own, 'library> Battle<'own, 'library> { self.last_turn_time.load(Ordering::Relaxed) } /// A queue of the yet to be executed choices in a turn. - pub fn current_turn_queue(&self) -> &RwLock>> { + pub fn current_turn_queue(&self) -> &RwLock> { &self.current_turn_queue } /// Get a Pokemon on the battlefield, on a specific side and an index on that side. - pub fn get_pokemon(&self, side: u8, index: u8) -> Option>> { + pub fn get_pokemon(&self, side: u8, index: u8) -> Option> { let side = self.sides.get(side as usize); side?; let pokemon_read_lock = side.unwrap().pokemon(); @@ -254,7 +254,7 @@ impl<'own, 'library> Battle<'own, 'library> { } /// Try and set the choice for the battle. If the choice is not valid, this returns false. - pub fn try_set_choice(&mut self, choice: TurnChoice<'own, 'library>) -> PkmnResult { + pub fn try_set_choice(&mut self, choice: TurnChoice) -> PkmnResult { if !self.can_use(&choice) { return Ok(false); } @@ -332,7 +332,7 @@ impl<'own, 'library> Battle<'own, 'library> { } } -impl<'own, 'library> VolatileScriptsOwner<'own> for Battle<'own, 'library> { +impl VolatileScriptsOwner for Battle { fn volatile_scripts(&self) -> &Arc { &self.volatile_scripts } @@ -343,7 +343,7 @@ impl<'own, 'library> VolatileScriptsOwner<'own> for Battle<'own, 'library> { } } -impl<'own, 'library> ScriptSource<'own> for Battle<'own, 'library> { +impl ScriptSource for Battle { fn get_script_count(&self) -> usize { 1 } diff --git a/src/dynamic_data/models/battle_party.rs b/src/dynamic_data/models/battle_party.rs index e7275c7..0273e4f 100644 --- a/src/dynamic_data/models/battle_party.rs +++ b/src/dynamic_data/models/battle_party.rs @@ -6,17 +6,17 @@ use crate::dynamic_data::models::pokemon_party::PokemonParty; /// A battle party is a wrapper around a party, with the indices for which the party is responsible /// on the field attached. #[derive(Debug)] -pub struct BattleParty<'own, 'library> { +pub struct BattleParty { /// The party the BattleParty is holding. - party: Arc>, + party: Arc, /// The indices for which the party is responsible, in the format (side, index) responsible_indices: Vec<(u8, u8)>, } -impl<'own, 'library> BattleParty<'own, 'library> { +impl BattleParty { /// Initializes a battle party with the underlying party, and the indices the party is responsible /// for. - pub fn new(party: Arc>, responsible_indices: Vec<(u8, u8)>) -> Self { + pub fn new(party: Arc, responsible_indices: Vec<(u8, u8)>) -> Self { Self { party, responsible_indices, @@ -44,7 +44,7 @@ impl<'own, 'library> BattleParty<'own, 'library> { } /// Gets a Pokemon at an index. - pub fn get_pokemon(&self, index: usize) -> &Option>> { + pub fn get_pokemon(&self, index: usize) -> &Option> { self.party.at(index) } } diff --git a/src/dynamic_data/models/battle_side.rs b/src/dynamic_data/models/battle_side.rs index 7010d43..b515652 100644 --- a/src/dynamic_data/models/battle_side.rs +++ b/src/dynamic_data/models/battle_side.rs @@ -18,22 +18,22 @@ use crate::{script_hook, PkmnResult, StringKey}; /// A side on a battle. #[derive(Debug)] -pub struct BattleSide<'own, 'library> { +pub struct BattleSide { /// The index of the side on the battle. index: u8, /// The number of Pokemon that can be on the side. pokemon_per_side: u8, /// A list of pokemon currently on the battlefield. - pokemon: RwLock>>>>, + pokemon: RwLock>>>, /// The currently set choices for all Pokemon on the battlefield. Cleared when the turn starts. - choices: RwLock>>>, + choices: RwLock>>, /// The slots on the side that can still be filled. Once all slots are set to false, this side /// has lost the battle. fillable_slots: Vec, /// The number of choices that are set. choices_set: AtomicU8, /// A reference to the battle we're part of. - battle: *mut Battle<'own, 'library>, + battle: *mut Battle, /// Whether or not this side has fled. has_fled_battle: bool, /// The volatile scripts that are attached to the side. @@ -43,7 +43,7 @@ pub struct BattleSide<'own, 'library> { script_source_data: RwLock, } -impl<'own, 'library> BattleSide<'own, 'library> { +impl<'own, 'library> BattleSide { /// Instantiates a battle side. pub fn new(index: u8, pokemon_per_side: u8) -> Self { let mut pokemon = Vec::with_capacity(pokemon_per_side as usize); @@ -73,7 +73,7 @@ impl<'own, 'library> BattleSide<'own, 'library> { } /// Set the battle this side belongs to. - pub(crate) fn set_battle(&mut self, battle: *mut Battle<'own, 'library>) { + pub(crate) fn set_battle(&mut self, battle: *mut Battle) { self.battle = battle; } @@ -86,11 +86,11 @@ impl<'own, 'library> BattleSide<'own, 'library> { self.pokemon_per_side } /// A list of pokemon currently on the battlefield. - pub fn pokemon(&self) -> RwLockReadGuard<'_, RawRwLock, Vec>>>> { + pub fn pokemon(&self) -> RwLockReadGuard<'_, RawRwLock, Vec>>> { self.pokemon.read() } /// The currently set choices for all Pokemon on the battlefield. Cleared when the turn starts. - pub fn choices(&self) -> &RwLock>>> { + pub fn choices(&self) -> &RwLock>> { &self.choices } /// The slots on the side that can still be filled. Once all slots are set to false, this side @@ -103,7 +103,7 @@ impl<'own, 'library> BattleSide<'own, 'library> { self.choices_set.load(Ordering::SeqCst) } /// A reference to the battle we're part of. - pub fn battle(&self) -> &Battle<'own, 'library> { + pub fn battle(&self) -> &Battle { unsafe { self.battle.as_ref().unwrap() } } /// Whether or not this side has fled. @@ -135,7 +135,7 @@ impl<'own, 'library> BattleSide<'own, 'library> { } /// Sets a choice for a Pokemon on this side. - pub(crate) fn set_choice(&self, choice: TurnChoice<'own, 'library>) { + pub(crate) fn set_choice(&self, choice: TurnChoice) { for (index, pokemon_slot) in self.pokemon.read().iter().enumerate() { if let Some(pokemon) = pokemon_slot { if std::ptr::eq(pokemon.deref(), choice.user().deref()) { @@ -161,7 +161,7 @@ impl<'own, 'library> BattleSide<'own, 'library> { } /// Switches out a spot on the field for a different Pokemon. - pub fn set_pokemon(&self, index: u8, pokemon: Option>>) { + pub fn set_pokemon(&self, index: u8, pokemon: Option>) { { let old = &self.pokemon.read()[index as usize]; if let Some(old_pokemon) = old { @@ -202,7 +202,7 @@ impl<'own, 'library> BattleSide<'own, 'library> { } /// Checks whether a Pokemon is on the field in this side. - pub fn is_pokemon_on_side(&self, pokemon: Arc>) -> bool { + pub fn is_pokemon_on_side(&self, pokemon: Arc) -> bool { for p in self.pokemon.read().iter().flatten() { if std::ptr::eq(p.deref().deref(), pokemon.deref()) { return true; @@ -218,7 +218,7 @@ impl<'own, 'library> BattleSide<'own, 'library> { } /// Checks whether a slot is unfillable or not. - pub fn is_slot_unfillable(&self, pokemon: Arc>) -> bool { + pub fn is_slot_unfillable(&self, pokemon: Arc) -> bool { for (i, slot) in self.pokemon.read().iter().enumerate() { if let Some(p) = slot { if std::ptr::eq(p.deref().deref(), pokemon.deref()) { @@ -296,7 +296,7 @@ impl<'own, 'library> BattleSide<'own, 'library> { } } -impl<'own, 'library> VolatileScriptsOwner<'own> for BattleSide<'own, 'library> { +impl VolatileScriptsOwner for BattleSide { fn volatile_scripts(&self) -> &Arc { &self.volatile_scripts } @@ -308,7 +308,7 @@ impl<'own, 'library> VolatileScriptsOwner<'own> for BattleSide<'own, 'library> { } } -impl<'own, 'library> ScriptSource<'own> for BattleSide<'own, 'library> { +impl ScriptSource for BattleSide { fn get_script_count(&self) -> usize { self.battle().get_script_count() + 1 } diff --git a/src/dynamic_data/models/executing_move.rs b/src/dynamic_data/models/executing_move.rs index c893173..8237a3d 100644 --- a/src/dynamic_data/models/executing_move.rs +++ b/src/dynamic_data/models/executing_move.rs @@ -84,34 +84,34 @@ impl HitData { /// An executing move is the data of the move for while it is executing. #[derive(Debug)] -pub struct ExecutingMove<'own, 'battle, 'library> { +pub struct ExecutingMove { /// The number of hits this move has. number_of_hits: u8, /// A list of hits for this move. For multi target multi hit moves, this stores the hits linearly, /// for example: (target1, hit1), (target1, hit2), (target2, hit1), (target2, hit2), etc. hits: Vec, /// The user of the move. - user: Arc>, + user: Arc, /// The move the user has actually chosen to do. - chosen_move: Arc>, + chosen_move: Arc, /// The move that the user is actually going to do. - use_move: &'own MoveData, + use_move: Arc, /// The script of the move. script: ScriptContainer, /// The targets for this move. - targets: &'own TargetList<'battle, 'library>, + targets: TargetList, /// Data required for this to be a script source. script_source_data: RwLock, } -impl<'own, 'battle, 'library> ExecutingMove<'own, 'battle, 'library> { +impl ExecutingMove { /// Instantiates an executing move. pub fn new( - targets: &'own TargetList<'battle, 'library>, + targets: TargetList, number_of_hits: u8, - user: Arc>, - chosen_move: Arc>, - use_move: &'own MoveData, + user: Arc, + chosen_move: Arc, + use_move: Arc, script: ScriptContainer, ) -> Self { let total_hits = number_of_hits as usize * targets.len(); @@ -140,16 +140,16 @@ impl<'own, 'battle, 'library> ExecutingMove<'own, 'battle, 'library> { self.number_of_hits } /// The user of the move. - pub fn user(&self) -> &Arc> { + pub fn user(&self) -> &Arc { &self.user } /// The move the user has actually chosen to do. - pub fn chosen_move(&self) -> &Arc> { + pub fn chosen_move(&self) -> &Arc { &self.chosen_move } /// The move that the user is actually going to do. - pub fn use_move(&self) -> &'own MoveData { - self.use_move + pub fn use_move(&self) -> &Arc { + &self.use_move } /// The script of the move. pub fn script(&self) -> &ScriptContainer { @@ -157,11 +157,7 @@ impl<'own, 'battle, 'library> ExecutingMove<'own, 'battle, 'library> { } /// Gets a hit data for a target, with a specific index. - pub fn get_hit_data<'func>( - &'func self, - for_target: &'func Arc>, - hit: u8, - ) -> PkmnResult<&'func HitData> { + pub fn get_hit_data<'func>(&'func self, for_target: &'func Arc, hit: u8) -> PkmnResult<&'func HitData> { for (index, target) in self.targets.iter().enumerate() { if let Some(target) = target { if std::ptr::eq(target.deref().deref(), for_target.deref().deref()) { @@ -174,7 +170,7 @@ impl<'own, 'battle, 'library> ExecutingMove<'own, 'battle, 'library> { } /// Checks whether a Pokemon is a target for this move. - pub fn is_pokemon_target(&self, pokemon: &Arc>) -> bool { + pub fn is_pokemon_target(&self, pokemon: &Arc) -> bool { for target in self.targets.iter().flatten() { if std::ptr::eq(target.deref().deref(), pokemon.deref().deref()) { return true; @@ -184,7 +180,7 @@ impl<'own, 'battle, 'library> ExecutingMove<'own, 'battle, 'library> { } /// Gets the index of the hits in this move where the hits for a specific target start. - pub(crate) fn get_index_of_target(&self, for_target: &Arc>) -> PkmnResult { + pub(crate) fn get_index_of_target(&self, for_target: &Arc) -> PkmnResult { for (index, target) in self.targets.iter().enumerate() { if let Some(target) = target { if std::ptr::eq(target.deref().deref(), for_target.deref().deref()) { @@ -202,7 +198,7 @@ impl<'own, 'battle, 'library> ExecutingMove<'own, 'battle, 'library> { } } -impl<'own, 'battle, 'library> ScriptSource<'own> for ExecutingMove<'own, 'battle, 'library> { +impl ScriptSource for ExecutingMove { fn get_script_count(&self) -> usize { 1 } diff --git a/src/dynamic_data/models/learned_move.rs b/src/dynamic_data/models/learned_move.rs index 781e8fe..5a151f2 100644 --- a/src/dynamic_data/models/learned_move.rs +++ b/src/dynamic_data/models/learned_move.rs @@ -1,4 +1,5 @@ use std::sync::atomic::{AtomicU8, Ordering}; +use std::sync::Arc; use crate::static_data::MoveData; @@ -6,9 +7,9 @@ use crate::static_data::MoveData; /// such as the remaining amount of users, how it has been learned, etc. #[derive(Debug)] #[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))] -pub struct LearnedMove<'library> { +pub struct LearnedMove { /// The immutable move information of the move. - move_data: &'library MoveData, + move_data: Arc, /// The maximal power points for this move. max_pp: u8, /// The amount of remaining power points. If this is 0, we can not use the move anymore. @@ -28,11 +29,11 @@ pub enum MoveLearnMethod { Level = 1, } -impl<'a> LearnedMove<'a> { +impl LearnedMove { /// Instantiate a new learned move. - pub fn new(move_data: &'a MoveData, learn_method: MoveLearnMethod) -> Self { + pub fn new(move_data: &Arc, learn_method: MoveLearnMethod) -> Self { Self { - move_data, + move_data: move_data.clone(), max_pp: move_data.base_usages(), remaining_pp: AtomicU8::new(move_data.base_usages()), learn_method, @@ -40,8 +41,8 @@ impl<'a> LearnedMove<'a> { } /// The immutable move information of the move. - pub fn move_data(&self) -> &MoveData { - self.move_data + pub fn move_data(&self) -> &Arc { + &self.move_data } /// The maximal power points for this move. pub fn max_pp(&self) -> u8 { diff --git a/src/dynamic_data/models/pokemon.rs b/src/dynamic_data/models/pokemon.rs index dc61d4c..b6b1c74 100644 --- a/src/dynamic_data/models/pokemon.rs +++ b/src/dynamic_data/models/pokemon.rs @@ -26,23 +26,20 @@ use crate::{script_hook, PkmnResult, StringKey}; /// An individual Pokemon as we know and love them. #[derive(Debug)] #[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))] -pub struct Pokemon<'own, 'library> -where - 'own: 'library, -{ +pub struct Pokemon { /// The library data of the Pokemon. - library: &'own DynamicLibrary, + library: Arc, /// The species of the Pokemon. - species: &'own Species, + species: Arc, /// The form of the Pokemon. - form: &'own Form, + form: Arc, /// An optional display species of the Pokemon. If this is set, the client should display this /// species. An example of usage for this is the Illusion ability. - display_species: Option<&'own Species>, + display_species: Option>, /// An optional display form of the Pokemon. If this is set, the client should display this // species. An example of usage for this is the Illusion ability. - display_form: Option<&'own Form>, + display_form: Option>, /// The current level of the Pokemon. level: LevelInt, @@ -57,7 +54,7 @@ where /// currently not used, and can be used for other implementations. coloring: u8, /// The held item of the Pokemon. - held_item: RwLock>, + held_item: RwLock>>, /// The remaining health points of the Pokemon. current_health: AtomicU32, @@ -78,7 +75,7 @@ where /// The [effort values](https://bulbapedia.bulbagarden.net/wiki/Effort_values) of the Pokemon. effort_values: ClampedStatisticSet, /// The [nature](https://bulbapedia.bulbagarden.net/wiki/Nature) of the Pokemon. - nature: &'own Nature, + nature: Arc, /// An optional nickname of the Pokemon. nickname: Option, @@ -90,11 +87,11 @@ where override_ability: Option, /// If in battle, we have additional data. - battle_data: RwLock>>, + battle_data: RwLock>, /// The moves the Pokemon has learned. This is of a set length of [`MAX_MOVES`]. Empty move slots /// are defined by None. - moves: RwLock<[Option>>; MAX_MOVES]>, + moves: RwLock<[Option>; MAX_MOVES]>, /// Whether or not the Pokemon is allowed to gain experience. allowed_experience: bool, @@ -118,12 +115,12 @@ where script_source_data: RwLock, } -impl<'own, 'library> Pokemon<'own, 'library> { +impl Pokemon { /// Instantiates a new Pokemon. pub fn new( - library: &'own DynamicLibrary, - species: &'own Species, - form: &'own Form, + library: Arc, + species: Arc, + form: &Arc, ability: AbilityIndex, level: LevelInt, unique_identifier: u32, @@ -142,11 +139,12 @@ impl<'own, 'library> Pokemon<'own, 'library> { .static_data() .natures() .get_nature(nature) - .unwrap_or_else(|| panic!("Unknown nature name was given: {}.", &nature)); + .unwrap_or_else(|| panic!("Unknown nature name was given: {}.", &nature)) + .clone(); let mut pokemon = Self { library, species, - form, + form: form.clone(), display_species: None, display_form: None, level, @@ -187,31 +185,31 @@ impl<'own, 'library> Pokemon<'own, 'library> { } /// The library data of the Pokemon. - pub fn library(&self) -> &'own DynamicLibrary { - self.library + pub fn library(&self) -> &Arc { + &self.library } /// The species of the Pokemon. - pub fn species(&self) -> &'own Species { - self.species + pub fn species(&self) -> &Arc { + &self.species } /// The form of the Pokemon. - pub fn form(&self) -> &'own Form { - self.form + pub fn form(&self) -> &Arc { + &self.form } /// The species that should be displayed to the user. This handles stuff like the Illusion ability. - pub fn display_species(&self) -> &'own Species { - if let Some(v) = self.display_species { + pub fn display_species(&self) -> &Arc { + if let Some(v) = &self.display_species { v } else { - self.species + &self.species } } /// The form that should be displayed to the user. This handles stuff like the Illusion ability. - pub fn display_form(&self) -> &'own Form { - if let Some(v) = self.display_form { + pub fn display_form(&self) -> &Arc { + if let Some(v) = &self.display_form { v } else { - self.form + &self.form } } /// The current level of the Pokemon. @@ -235,8 +233,8 @@ impl<'own, 'library> Pokemon<'own, 'library> { pub fn coloring(&self) -> u8 { self.coloring } - /// Checks whether the Pokemon is holding an item, - pub fn held_item(&self) -> &RwLock> { + /// Gets the held item of a Pokemon + pub fn held_item(&self) -> &RwLock>> { &self.held_item } /// Checks whether the Pokemon is holding a specific item. @@ -248,11 +246,11 @@ impl<'own, 'library> Pokemon<'own, 'library> { false } /// Changes the held item of the Pokemon/ - pub fn set_held_item(&self, item: &'own Item) -> Option<&'own Item> { - self.held_item.write().replace(item) + pub fn set_held_item(&self, item: &Arc) -> Option> { + self.held_item.write().replace(item.clone()) } /// Removes the held item from the Pokemon. - pub fn remove_held_item(&self) -> Option<&'own Item> { + pub fn remove_held_item(&self) -> Option> { self.held_item.write().take() } /// Makes the Pokemon uses its held item. @@ -260,7 +258,10 @@ impl<'own, 'library> Pokemon<'own, 'library> { if self.held_item.read().is_none() { return false; } - let script = self.library.load_item_script(self.held_item.read().unwrap()).unwrap(); + let script = self + .library + .load_item_script(&self.held_item.read().as_ref().unwrap()) + .unwrap(); if script.is_none() { return false; } @@ -299,7 +300,7 @@ impl<'own, 'library> Pokemon<'own, 'library> { } /// The moves the Pokemon has learned. This is of a set length of [`MAX_MOVES`]. Empty move slots /// are defined by None. - pub fn learned_moves(&self) -> &RwLock<[Option>>; MAX_MOVES]> { + pub fn learned_moves(&self) -> &RwLock<[Option>; MAX_MOVES]> { &self.moves } @@ -384,7 +385,7 @@ impl<'own, 'library> Pokemon<'own, 'library> { } /// Gets the battle the battle is currently in. - pub fn get_battle(&self) -> Option<&Battle<'own, 'library>> { + pub fn get_battle(&self) -> Option<&Battle> { let r = self.battle_data.read(); if let Some(data) = &r.deref() { unsafe { data.battle.as_ref() } @@ -434,8 +435,8 @@ impl<'own, 'library> Pokemon<'own, 'library> { } /// The [nature](https://bulbapedia.bulbagarden.net/wiki/Nature) of the Pokemon. - pub fn nature(&self) -> &'own Nature { - self.nature + pub fn nature(&self) -> &Arc { + &self.nature } /// Calculates the flat stats on the Pokemon. @@ -453,9 +454,9 @@ impl<'own, 'library> Pokemon<'own, 'library> { } /// Change the species of the Pokemon. - pub fn change_species(&mut self, species: &'own Species, form: &'own Form) { - self.species = species; - self.form = form; + pub fn change_species(&mut self, species: Arc, form: Arc) { + self.species = species.clone(); + self.form = form.clone(); // If the pokemon is genderless, but it's new species is not, we want to set its gender if self.gender != Gender::Genderless && species.gender_rate() < 0.0 { @@ -486,11 +487,11 @@ impl<'own, 'library> Pokemon<'own, 'library> { } /// Change the form of the Pokemon. - pub fn change_form(&mut self, form: &'own Form) { - if std::ptr::eq(self.form, form) { + pub fn change_form(&mut self, form: &Arc) { + if Arc::ptr_eq(&self.form, form) { return; } - self.form = form; + self.form = form.clone(); self.types.clear(); for t in form.types() { @@ -512,7 +513,7 @@ impl<'own, 'library> Pokemon<'own, 'library> { .set(ability_script) .as_ref() // Ensure the ability script gets initialized with the parameters for the ability. - .on_initialize(self.library, self.active_ability().parameters()) + .on_initialize(self.library.as_ref(), self.active_ability().parameters()) } else { self.ability_script.clear(); } @@ -547,7 +548,7 @@ impl<'own, 'library> Pokemon<'own, 'library> { } /// Sets the current battle the Pokemon is in. - pub fn set_battle_data(&self, battle: *mut Battle<'own, 'library>, battle_side_index: u8) { + pub fn set_battle_data(&self, battle: *mut Battle, battle_side_index: u8) { let mut w = self.battle_data.write(); if let Some(battle_data) = w.deref_mut() { battle_data.battle = battle; @@ -590,7 +591,7 @@ impl<'own, 'library> Pokemon<'own, 'library> { } /// Marks an opponent as seen, for use in experience gain. - pub fn mark_opponent_as_seen(&self, pokemon: Weak>) { + pub fn mark_opponent_as_seen(&self, pokemon: Weak) { let r = self.battle_data.read(); if let Some(battle_data) = &r.deref() { let mut opponents = battle_data.seen_opponents().write(); @@ -692,9 +693,9 @@ impl<'own, 'library> Pokemon<'own, 'library> { /// The data of the Pokemon related to being in a battle. #[derive(Debug)] -pub struct PokemonBattleData<'pokemon, 'library> { +pub struct PokemonBattleData { /// The battle data of the Pokemon - battle: *mut Battle<'pokemon, 'library>, + battle: *mut Battle, /// The index of the side of the Pokemon battle_side_index: AtomicU8, /// The index of the slot on the side of the Pokemon. @@ -702,16 +703,16 @@ pub struct PokemonBattleData<'pokemon, 'library> { /// Whether or not the Pokemon is on the battlefield. on_battle_field: AtomicBool, /// A list of opponents the Pokemon has seen this battle. - seen_opponents: RwLock>>>, + seen_opponents: RwLock>>, } -impl<'pokemon, 'library> PokemonBattleData<'pokemon, 'library> { +impl PokemonBattleData { /// The battle data of the Pokemon - pub fn battle_mut(&mut self) -> Option<&mut Battle<'pokemon, 'library>> { + pub fn battle_mut(&mut self) -> Option<&mut Battle> { unsafe { self.battle.as_mut() } } /// The battle data of the Pokemon - pub fn battle(&self) -> Option<&Battle<'pokemon, 'library>> { + pub fn battle(&self) -> Option<&Battle> { unsafe { self.battle.as_ref() } } @@ -728,12 +729,12 @@ impl<'pokemon, 'library> PokemonBattleData<'pokemon, 'library> { self.on_battle_field.load(Ordering::Relaxed) } /// A list of opponents the Pokemon has seen this battle. - pub fn seen_opponents(&self) -> &RwLock>>> { + pub fn seen_opponents(&self) -> &RwLock>> { &self.seen_opponents } } -impl<'own, 'library> ScriptSource<'own> for Pokemon<'own, 'library> { +impl ScriptSource for Pokemon { fn get_script_count(&self) -> usize { let mut c = 3; if let Some(battle_data) = &self.battle_data.read().deref() { @@ -765,7 +766,7 @@ impl<'own, 'library> ScriptSource<'own> for Pokemon<'own, 'library> { } } -impl<'own, 'library> VolatileScriptsOwner<'own> for Pokemon<'own, 'library> { +impl VolatileScriptsOwner for Pokemon { fn volatile_scripts(&self) -> &Arc { &self.volatile } @@ -794,7 +795,7 @@ pub mod test { #[test] fn construct_pokemon() { - let lib = crate::dynamic_data::libraries::dynamic_library::test::build(); + let lib = Arc::new(crate::dynamic_data::libraries::dynamic_library::test::build()); let species = lib.static_data().species().get(&"foo".into()).unwrap(); let form = species.get_form(&"default".into()).unwrap(); diff --git a/src/dynamic_data/models/pokemon_builder.rs b/src/dynamic_data/models/pokemon_builder.rs index 161e7e6..056e123 100644 --- a/src/dynamic_data/models/pokemon_builder.rs +++ b/src/dynamic_data/models/pokemon_builder.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use crate::defines::LevelInt; use crate::dynamic_data::models::learned_move::MoveLearnMethod; use crate::dynamic_data::models::pokemon::Pokemon; @@ -6,9 +8,9 @@ use crate::static_data::{AbilityIndex, DataLibrary, Gender}; use crate::{Random, StringKey}; /// This allows for the easy chain building of a Pokemon. -pub struct PokemonBuilder<'own> { +pub struct PokemonBuilder { /// The library of the Pokemon. - library: &'own DynamicLibrary, + library: Arc, /// The name of the species of the Pokemon. species: StringKey, /// The level of the Pokemon. @@ -19,9 +21,9 @@ pub struct PokemonBuilder<'own> { random_seed: Option, } -impl<'own> PokemonBuilder<'own> { +impl PokemonBuilder { /// Creates a new PokemonBuilder with a library, species, and level. - pub fn new(library: &'own DynamicLibrary, species: StringKey, level: LevelInt) -> Self { + pub fn new(library: Arc, species: StringKey, level: LevelInt) -> Self { Self { library, species, @@ -37,19 +39,19 @@ impl<'own> PokemonBuilder<'own> { } /// Finally turn the builder into an actual Pokemon. - pub fn build(self) -> Pokemon<'own, 'own> { + pub fn build(self) -> Pokemon { let mut random = if let Some(seed) = self.random_seed { Random::new(seed) } else { Random::default() }; - let species = self.library.static_data().species().get(&self.species).unwrap(); - let form = species.get_default_form(); + let species = self.library.static_data().species().get(&self.species).unwrap().clone(); + let form = species.get_default_form().clone(); let p = Pokemon::new( self.library, species, - form, + &form, AbilityIndex { hidden: false, index: 0, diff --git a/src/dynamic_data/models/pokemon_party.rs b/src/dynamic_data/models/pokemon_party.rs index d190580..a54b1a0 100644 --- a/src/dynamic_data/models/pokemon_party.rs +++ b/src/dynamic_data/models/pokemon_party.rs @@ -4,12 +4,12 @@ use crate::dynamic_data::models::pokemon::Pokemon; /// A list of Pokemon belonging to a trainer. #[derive(Debug)] -pub struct PokemonParty<'pokemon, 'library> { +pub struct PokemonParty { /// The underlying list of Pokemon. - pokemon: Vec>>>, + pokemon: Vec>>, } -impl<'own, 'library> PokemonParty<'own, 'library> { +impl<'own, 'library> PokemonParty { /// Instantiates a party with a set size. pub fn new(size: usize) -> Self { let mut pokemon = Vec::with_capacity(size); @@ -20,12 +20,12 @@ impl<'own, 'library> PokemonParty<'own, 'library> { } /// Instantiates a party with a list. - pub fn new_from_vec(pokemon: Vec>>>) -> Self { + pub fn new_from_vec(pokemon: Vec>>) -> Self { Self { pokemon } } /// Gets a Pokemon at an index in the party. - pub fn at(&self, index: usize) -> &Option>> { + pub fn at(&self, index: usize) -> &Option> { let opt = self.pokemon.get(index); if let Some(v) = opt { v @@ -40,11 +40,7 @@ impl<'own, 'library> PokemonParty<'own, 'library> { } /// Sets the Pokemon at an index to a Pokemon, returning the old Pokemon. - pub fn swap_into( - &mut self, - index: usize, - pokemon: Option>>, - ) -> Option>> { + pub fn swap_into(&mut self, index: usize, pokemon: Option>) -> Option> { if index >= self.pokemon.len() { return pokemon; } @@ -69,7 +65,7 @@ impl<'own, 'library> PokemonParty<'own, 'library> { } /// Gets the underlying list of Pokemon. - pub fn pokemon(&self) -> &Vec>>> { + pub fn pokemon(&self) -> &Vec>> { &self.pokemon } diff --git a/src/dynamic_data/script_handling/mod.rs b/src/dynamic_data/script_handling/mod.rs index dc3dbd3..7e1c4a4 100644 --- a/src/dynamic_data/script_handling/mod.rs +++ b/src/dynamic_data/script_handling/mod.rs @@ -86,7 +86,7 @@ pub struct ScriptSourceData { } /// A script source is a struct on which we can trigger scripts to be run from. -pub trait ScriptSource<'a> { +pub trait ScriptSource { /// Gets an iterator over all the scripts that are relevant to this script source. If the data /// has not been initialised, it will do so here. fn get_script_iterator(&self) -> ScriptIterator { diff --git a/src/dynamic_data/script_handling/volatile_scripts_owner.rs b/src/dynamic_data/script_handling/volatile_scripts_owner.rs index f37cf86..c503174 100644 --- a/src/dynamic_data/script_handling/volatile_scripts_owner.rs +++ b/src/dynamic_data/script_handling/volatile_scripts_owner.rs @@ -5,7 +5,7 @@ use crate::dynamic_data::script_handling::script_set::ScriptSet; use crate::{PkmnResult, StringKey}; /// This trait adds a bunch of helper functions to deal with volatile scripts on a struct. -pub trait VolatileScriptsOwner<'a> { +pub trait VolatileScriptsOwner { /// Return the [`ScriptSet`] that are our volatile scripts. fn volatile_scripts(&self) -> &Arc; /// Loads a volatile script by name. diff --git a/src/script_implementations/wasm/export_registry/dynamic_data/learned_move.rs b/src/script_implementations/wasm/export_registry/dynamic_data/learned_move.rs index b0f8cb3..87693d1 100644 --- a/src/script_implementations/wasm/export_registry/dynamic_data/learned_move.rs +++ b/src/script_implementations/wasm/export_registry/dynamic_data/learned_move.rs @@ -1,13 +1,13 @@ use std::intrinsics::transmute; -use crate::dynamic_data::{LearnedMove, MoveLearnMethod, Pokemon, TurnChoice}; +use crate::dynamic_data::LearnedMove; use crate::script_implementations::wasm::export_registry::register; use crate::script_implementations::wasm::extern_ref::ExternRef; use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv; use crate::static_data::MoveData; register! { - fn learned_move_get_learn_method<'a>( + fn learned_move_get_learn_method( env: &WebAssemblyEnv, turn_choice: ExternRef, ) -> u8 { @@ -16,7 +16,7 @@ register! { } } - fn learned_move_get_move_data<'a>( + fn learned_move_get_move_data( env: &WebAssemblyEnv, turn_choice: ExternRef, ) -> ExternRef { diff --git a/src/script_implementations/wasm/export_registry/dynamic_data/pokemon.rs b/src/script_implementations/wasm/export_registry/dynamic_data/pokemon.rs index 4f4912d..f24af61 100644 --- a/src/script_implementations/wasm/export_registry/dynamic_data/pokemon.rs +++ b/src/script_implementations/wasm/export_registry/dynamic_data/pokemon.rs @@ -1,6 +1,6 @@ use std::mem::transmute; -use crate::dynamic_data::{DamageSource, DynamicLibrary, Pokemon}; +use crate::dynamic_data::{DynamicLibrary, Pokemon}; use crate::script_implementations::wasm::export_registry::register; use crate::script_implementations::wasm::extern_ref::ExternRef; use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv; diff --git a/src/script_implementations/wasm/export_registry/dynamic_data/turn_choice.rs b/src/script_implementations/wasm/export_registry/dynamic_data/turn_choice.rs index 7bbcd51..ecb9773 100644 --- a/src/script_implementations/wasm/export_registry/dynamic_data/turn_choice.rs +++ b/src/script_implementations/wasm/export_registry/dynamic_data/turn_choice.rs @@ -7,10 +7,10 @@ use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv; register! { - fn turn_choice_get_user<'a>( + fn turn_choice_get_user( env: &WebAssemblyEnv, - turn_choice: ExternRef>, - ) -> ExternRef> { + turn_choice: ExternRef, + ) -> ExternRef { let turn_choice = turn_choice.value(env).unwrap(); ExternRef::new(env.data().as_ref(), turn_choice.user().as_ref().deref()) } @@ -28,10 +28,10 @@ register! { } } - fn turn_choice_move_used_move<'a>( + fn turn_choice_move_used_move( env: &WebAssemblyEnv, - turn_choice: ExternRef>, - ) -> ExternRef> { + turn_choice: ExternRef, + ) -> ExternRef { if let TurnChoice::Move(d) = turn_choice.value(env).unwrap() { return ExternRef::new(env.data().as_ref(), d.used_move().as_ref()); } diff --git a/src/script_implementations/wasm/export_registry/mod.rs b/src/script_implementations/wasm/export_registry/mod.rs index be356cb..cc03714 100644 --- a/src/script_implementations/wasm/export_registry/mod.rs +++ b/src/script_implementations/wasm/export_registry/mod.rs @@ -1,12 +1,8 @@ use std::ffi::CString; use std::mem::{align_of, forget}; -use std::process::exit; use wasmer::{Exports, Store}; -pub(crate) use register; -pub(crate) use register_func_with_env; - use crate::dynamic_data::DynamicLibrary; use crate::script_implementations::wasm::extern_ref::ExternRef; use crate::script_implementations::wasm::script_resolver::WebAssemblyEnv; @@ -35,7 +31,7 @@ macro_rules! register_func_with_env { macro_rules! register { ( $( - fn $name:ident$(<$($lt:lifetime)*>)?($($par:ident: $par_type:ty),*$(,)?) $(-> $return:ty)? $block:block + fn $name:ident($($par:ident: $par_type:ty),*$(,)?) $(-> $return:ty)? $block:block )* ) => { pub(crate) fn register(exports: &mut crate::script_implementations::wasm::export_registry::Exports, @@ -43,7 +39,7 @@ macro_rules! register { env: crate::script_implementations::wasm::script_resolver::WebAssemblyEnv) { $( - fn $name<$($($lt)*)*>( + fn $name( $( $par: $par_type, )* @@ -55,6 +51,9 @@ macro_rules! register { }; } +pub(crate) use register; +pub(crate) use register_func_with_env; + pub(crate) fn register_webassembly_funcs(exports: &mut Exports, store: &Store, env: WebAssemblyEnv) { register_func_with_env!(exports, store, _print, env); register_func_with_env!(exports, store, _error, env); diff --git a/src/script_implementations/wasm/extern_ref.rs b/src/script_implementations/wasm/extern_ref.rs index a6883b6..f46a184 100644 --- a/src/script_implementations/wasm/extern_ref.rs +++ b/src/script_implementations/wasm/extern_ref.rs @@ -21,10 +21,6 @@ impl> ExternRef { } } - pub(crate) fn index(&self) -> u32 { - self.index - } - /// Creates an ExternRef with a given resolver. This can be used in cases where we do not have an environment variable. pub(crate) fn new_with_resolver(resolver: &WebAssemblyScriptResolver, value: &T) -> Self { Self { diff --git a/src/script_implementations/wasm/script.rs b/src/script_implementations/wasm/script.rs index a0f53cb..aa60e4d 100644 --- a/src/script_implementations/wasm/script.rs +++ b/src/script_implementations/wasm/script.rs @@ -1,12 +1,11 @@ use std::any::Any; -use std::mem::{align_of, size_of}; use std::sync::atomic::{AtomicBool, AtomicPtr, AtomicUsize}; use std::sync::{Arc, Weak}; use hashbrown::HashSet; use wasmer::NativeFunc; -use crate::dynamic_data::{DynamicLibrary, Pokemon, Script, TurnChoice}; +use crate::dynamic_data::{DynamicLibrary, Script, TurnChoice}; use crate::script_implementations::wasm::extern_ref::{ExternRef, VecExternRef}; use crate::script_implementations::wasm::script_resolver::WebAssemblyEnvironmentData; use crate::script_implementations::wasm::WebAssemblyScriptCapabilities; @@ -92,8 +91,7 @@ impl Script for WebAssemblyScript { let env = self.environment.upgrade().unwrap(); let func = env.script_function_cache().on_before_turn(&env); if let Some(func) = func { - func.call(self.self_ptr, ExternRef::new(env.as_ref(), choice).index()) - .unwrap(); + func.call(self.self_ptr, ExternRef::new(env.as_ref(), choice)).unwrap(); } } diff --git a/src/script_implementations/wasm/script_function_cache.rs b/src/script_implementations/wasm/script_function_cache.rs index bc845d3..3e1fec6 100644 --- a/src/script_implementations/wasm/script_function_cache.rs +++ b/src/script_implementations/wasm/script_function_cache.rs @@ -58,5 +58,5 @@ macro_rules! script_function_cache { script_function_cache! { on_initialize -> NativeFunc<(u32, ExternRef, VecExternRef), ()> - on_before_turn -> NativeFunc<(u32, u32), ()> + on_before_turn -> NativeFunc<(u32, ExternRef), ()> } diff --git a/src/static_data/libraries/ability_library.rs b/src/static_data/libraries/ability_library.rs index b803b87..2c23e93 100644 --- a/src/static_data/libraries/ability_library.rs +++ b/src/static_data/libraries/ability_library.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use indexmap::IndexMap; use crate::static_data::Ability; @@ -8,7 +10,7 @@ use crate::StringKey; #[derive(Debug)] pub struct AbilityLibrary { /// The underlying map for the library. - map: IndexMap>, + map: IndexMap>, } impl AbilityLibrary { @@ -20,11 +22,11 @@ impl AbilityLibrary { } } -impl DataLibrary<'_, Box> for AbilityLibrary { - fn map(&self) -> &IndexMap> { +impl DataLibrary<'_, Ability> for AbilityLibrary { + fn map(&self) -> &IndexMap> { &self.map } - fn get_modify(&mut self) -> &mut IndexMap> { + fn get_modify(&mut self) -> &mut IndexMap> { &mut self.map } } diff --git a/src/static_data/libraries/data_library.rs b/src/static_data/libraries/data_library.rs index 38f6b4a..dbc891e 100644 --- a/src/static_data/libraries/data_library.rs +++ b/src/static_data/libraries/data_library.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use indexmap::IndexMap; use crate::Random; @@ -7,13 +9,13 @@ use crate::StringKey; /// by both key, while keeping their insertion order. pub trait DataLibrary<'a, T: 'a> { /// Returns the underlying map. - fn map(&self) -> &IndexMap; + fn map(&self) -> &IndexMap>; /// Returns the underlying map in mutable manner. - fn get_modify(&mut self) -> &mut IndexMap; + fn get_modify(&mut self) -> &mut IndexMap>; /// Adds a new value to the library. fn add(&mut self, key: &StringKey, value: T) { - self.get_modify().insert(key.clone(), value); + self.get_modify().insert(key.clone(), Arc::new(value)); } /// Removes a value from the library. @@ -22,20 +24,15 @@ pub trait DataLibrary<'a, T: 'a> { } /// Gets a value from the library. - fn get(&'a self, key: &StringKey) -> Option<&'a T> { + fn get(&'a self, key: &StringKey) -> Option<&Arc> { self.map().get::(key) } /// Gets a value from the library. - fn get_by_hash(&'a self, key: u32) -> Option<&'a T> { + fn get_by_hash(&'a self, key: u32) -> Option<&Arc> { self.map().get::(&key) } - /// Gets a mutable value from the library. - fn get_mut(&mut self, key: &StringKey) -> Option<&mut T> { - self.get_modify().get_mut(key) - } - /// Gets the amount of values in the library. fn len(&self) -> usize { self.map().len() @@ -46,7 +43,7 @@ pub trait DataLibrary<'a, T: 'a> { } /// Gets a random value from the library. - fn random_value(&self, rand: &mut Random) -> &T { + fn random_value(&self, rand: &mut Random) -> &Arc { let i = rand.get_between(0, self.len() as i32); return self.map().get_index(i as usize).unwrap().1; } diff --git a/src/static_data/libraries/item_library.rs b/src/static_data/libraries/item_library.rs index 6cfc66e..c10a0b2 100644 --- a/src/static_data/libraries/item_library.rs +++ b/src/static_data/libraries/item_library.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use indexmap::IndexMap; use crate::static_data::DataLibrary; @@ -9,7 +11,7 @@ use crate::StringKey; #[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))] pub struct ItemLibrary { /// The underlying data structure. - map: IndexMap>, + map: IndexMap>, } impl ItemLibrary { @@ -21,12 +23,12 @@ impl ItemLibrary { } } -impl DataLibrary<'_, Box> for ItemLibrary { - fn map(&self) -> &IndexMap> { +impl DataLibrary<'_, Item> for ItemLibrary { + fn map(&self) -> &IndexMap> { &self.map } - fn get_modify(&mut self) -> &mut IndexMap> { + fn get_modify(&mut self) -> &mut IndexMap> { &mut self.map } } diff --git a/src/static_data/libraries/move_library.rs b/src/static_data/libraries/move_library.rs index 9b1661e..e40c19b 100644 --- a/src/static_data/libraries/move_library.rs +++ b/src/static_data/libraries/move_library.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use indexmap::IndexMap; use crate::static_data::DataLibrary; @@ -9,7 +11,7 @@ use crate::StringKey; #[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))] pub struct MoveLibrary { /// The underlying map. - map: IndexMap, + map: IndexMap>, } impl MoveLibrary { @@ -22,10 +24,10 @@ impl MoveLibrary { } impl DataLibrary<'_, MoveData> for MoveLibrary { - fn map(&self) -> &IndexMap { + fn map(&self) -> &IndexMap> { &self.map } - fn get_modify(&mut self) -> &mut IndexMap { + fn get_modify(&mut self) -> &mut IndexMap> { &mut self.map } } diff --git a/src/static_data/libraries/species_library.rs b/src/static_data/libraries/species_library.rs index b95822f..5618769 100644 --- a/src/static_data/libraries/species_library.rs +++ b/src/static_data/libraries/species_library.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use indexmap::IndexMap; use crate::static_data::DataLibrary; @@ -9,7 +11,7 @@ use crate::StringKey; #[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))] pub struct SpeciesLibrary { /// The underlying map. - map: IndexMap>, + map: IndexMap>, } impl SpeciesLibrary { @@ -21,11 +23,11 @@ impl SpeciesLibrary { } } -impl<'a> DataLibrary<'a, Box> for SpeciesLibrary { - fn map(&self) -> &IndexMap> { +impl<'a> DataLibrary<'a, Species> for SpeciesLibrary { + fn map(&self) -> &IndexMap> { &self.map } - fn get_modify(&mut self) -> &mut IndexMap> { + fn get_modify(&mut self) -> &mut IndexMap> { &mut self.map } } diff --git a/src/static_data/natures.rs b/src/static_data/natures.rs index 5d5acc7..7054bb9 100644 --- a/src/static_data/natures.rs +++ b/src/static_data/natures.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use hashbrown::HashMap; use crate::static_data::Statistic; @@ -60,7 +62,7 @@ impl Nature { #[derive(Debug)] pub struct NatureLibrary { /// The underlying data structure. - map: HashMap, + map: HashMap>, } impl NatureLibrary { @@ -73,20 +75,20 @@ impl NatureLibrary { /// Adds a new nature with name to the library. pub fn load_nature(&mut self, name: StringKey, nature: Nature) { - self.map.insert(name, nature); + self.map.insert(name, Arc::new(nature)); } /// Gets a nature by name. - pub fn get_nature(&self, key: &StringKey) -> Option<&Nature> { + pub fn get_nature(&self, key: &StringKey) -> Option<&Arc> { self.map.get(key) } /// Finds a nature name by nature. - pub fn get_nature_name(&self, nature: &Nature) -> StringKey { + pub fn get_nature_name(&self, nature: &Arc) -> StringKey { for kv in &self.map { // As natures can't be copied, and should always be the same reference as the value // in the map, we just compare by reference. - if std::ptr::eq(kv.1, nature) { + if Arc::ptr_eq(kv.1, nature) { return kv.0.clone(); } } diff --git a/src/static_data/species_data/species.rs b/src/static_data/species_data/species.rs index 5a767bf..2520a7d 100644 --- a/src/static_data/species_data/species.rs +++ b/src/static_data/species_data/species.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use hashbrown::{HashMap, HashSet}; use crate::static_data::Form; @@ -21,7 +23,7 @@ pub struct Species { /// uncatchable. capture_rate: u8, /// The forms that belong to this Pokemon. - forms: HashMap, + forms: HashMap>, /// The arbitrary flags that can be set on a Pokemon for script use. flags: HashSet, } @@ -46,7 +48,7 @@ impl Species { flags: HashSet, ) -> Species { let mut forms = HashMap::with_capacity(1); - forms.insert_unique_unchecked(get_default_key(), default_form); + forms.insert_unique_unchecked(get_default_key(), Arc::new(default_form)); Species { id, name: name.clone(), @@ -80,7 +82,7 @@ impl Species { self.capture_rate } /// The forms that belong to this Pokemon. - pub fn forms(&self) -> &HashMap { + pub fn forms(&self) -> &HashMap> { &self.forms } /// The arbitrary flags that can be set on a Pokemon for script use. @@ -90,16 +92,16 @@ impl Species { /// Adds a new form to the species. pub fn add_form(&mut self, id: StringKey, form: Form) { - self.forms.insert(id, form); + self.forms.insert(id, Arc::new(form)); } /// Gets a form by name. - pub fn get_form(&self, id: &StringKey) -> Option<&Form> { + pub fn get_form(&self, id: &StringKey) -> Option<&Arc> { self.forms.get(id) } /// Gets the form the Pokemon will have by default, if no other form is specified. - pub fn get_default_form(&self) -> &Form { + pub fn get_default_form(&self) -> &Arc { self.forms.get(&get_default_key()).unwrap() } diff --git a/tests/common/library_loader.rs b/tests/common/library_loader.rs index c1d72c0..3027432 100644 --- a/tests/common/library_loader.rs +++ b/tests/common/library_loader.rs @@ -115,10 +115,7 @@ pub fn load_items(path: &String, lib: &mut ItemLibrary) { } } - lib.add( - &name, - Box::new(Item::new(&name, category, battle_category, price as i32, flags)), - ); + lib.add(&name, Item::new(&name, category, battle_category, price as i32, flags)); } } @@ -161,7 +158,7 @@ pub fn load_abilities(path: &String, ability_library: &mut AbilityLibrary) { } } - ability_library.add(&name, Box::new(Ability::new(&name, &effect, parameters))); + ability_library.add(&name, Ability::new(&name, &effect, parameters)); } } @@ -262,7 +259,7 @@ pub fn load_species(path: &String, library: &mut StaticData) { let default_form_value = &forms["default"]; let default_form = parse_form("default".into(), default_form_value, library); - let species = Box::new(Species::new( + let species = Species::new( id as u16, &name, gender_rate as f32, @@ -270,7 +267,7 @@ pub fn load_species(path: &String, library: &mut StaticData) { catch_rate as u8, default_form, Default::default(), - )); + ); library.species_mut().add(&name, species); } } diff --git a/tests/common/test_case.rs b/tests/common/test_case.rs index 1ce19a1..ea0e19d 100644 --- a/tests/common/test_case.rs +++ b/tests/common/test_case.rs @@ -43,13 +43,13 @@ struct TestPokemon { } impl TestCase { - pub fn run_test(&self, library: &DynamicLibrary) { + pub fn run_test(&self, library: Arc) { let mut parties = Vec::new(); for party in &self.battle_setup.parties { let pokemon = party .pokemon .iter() - .map(|a| Some(Arc::new(a.to_pokemon(library)))) + .map(|a| Some(Arc::new(a.to_pokemon(library.clone())))) .collect(); let indices = party.indices.iter().map(|a| (a[0], a[1])).collect(); parties.push((Arc::new(PokemonParty::new_from_vec(pokemon)), indices)); @@ -73,7 +73,7 @@ impl TestCase { } impl TestPokemon { - fn to_pokemon<'a>(&'a self, library: &'a DynamicLibrary) -> Pokemon { + fn to_pokemon(&self, library: Arc) -> Pokemon { let mut builder = PokemonBuilder::new(library, StringKey::new(self.species.as_str()), self.level); for move_name in &self.moves { builder = builder.learn_move(StringKey::new(move_name)); diff --git a/tests/main.rs b/tests/main.rs index 69dbe69..6cbb2a3 100644 --- a/tests/main.rs +++ b/tests/main.rs @@ -16,16 +16,18 @@ use crate::common::{library_loader, TestCase}; pub mod common; -static LIBRARY: OnceCell = OnceCell::uninit(); +static LIBRARY: OnceCell> = OnceCell::uninit(); -fn get_library<'a>() -> &'a DynamicLibrary { - LIBRARY.get_or_init(|| { - let start_time = chrono::Utc::now(); - let lib = library_loader::load_library(); - let end_time = chrono::Utc::now(); - println!("Built library in {} ms", (end_time - start_time).num_milliseconds()); - lib - }) +fn get_library<'a>() -> Arc { + LIBRARY + .get_or_init(|| { + let start_time = chrono::Utc::now(); + let lib = library_loader::load_library(); + let end_time = chrono::Utc::now(); + println!("Built library in {} ms", (end_time - start_time).num_milliseconds()); + Arc::new(lib) + }) + .clone() } #[test] @@ -73,7 +75,7 @@ fn validate_script_2() { .unwrap() .unwrap(); let user = Arc::new( - PokemonBuilder::new(&lib, "charizard".into(), 100) + PokemonBuilder::new(lib, "charizard".into(), 100) .learn_move("fire_blast".into()) .build(), );