use crate::dynamic_data::{EventData, Pokemon}; use crate::ffi::ffi_handle::FromFFIHandle; use crate::ffi::FFIHandle; use std::ops::Deref; use std::sync::Arc; /// The kind of the event. #[no_mangle] extern "C" fn event_kind(ptr: FFIHandle>) -> u8 { match ptr.from_ffi_handle().deref() { EventData::Switch { .. } => 1, EventData::Swap { .. } => 2, EventData::SpeciesChange { .. } => 3, EventData::FormChange { .. } => 4, EventData::Damage { .. } => 5, EventData::Heal { .. } => 6, EventData::Faint { .. } => 7, EventData::MoveUse { .. } => 8, EventData::Miss { .. } => 9, EventData::EndTurn => 10, EventData::StatBoostChange { .. } => 11, EventData::MoveHit { .. } => 12, } } /// Generates the entire FFI function we need for an event. macro_rules! event_ffi { ( $event_name:ident { $( $(#[doc = $doc:expr])? $par_name:ident: $par_type:ty, )+ }, $ctor:block ) => { paste::paste!{ /// A C struct to hold the data for the event #[repr(C)] struct [<$event_name Data>]{ $( $(#[doc = $doc])? $par_name: $par_type, )+ } /// The getter for the data for the relevant event. #[no_mangle] extern "C" fn [](ptr: FFIHandle>) -> [<$event_name Data>] { if let EventData::$event_name { $( $par_name, )+ } = ptr.from_ffi_handle().deref() { $ctor } panic!(concat!("Event was not a ", stringify!($event_name), " data")); } } }; } event_ffi!( Switch { /// The side the Pokemon got switched from/on side_index: u8, /// 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 be null. pokemon: FFIHandle, }, { let pokemon_handle = match pokemon { Some(pokemon) => FFIHandle::get_handle(pokemon.clone().into()), None => FFIHandle::none(), }; return SwitchData{ side_index: *side_index, index: *index, pokemon: pokemon_handle, } } ); event_ffi!( Swap { /// The side the Pokemon swapped on. side_index: u8, /// The index on the side of the first Pokemon that was swapped. index_a: u8, /// The index on the side of the second pokemon that was swapped. index_b: u8, }, { return SwapData { side_index: *side_index, index_a: *index_a, index_b: *index_b, }; } );