98 lines
2.6 KiB
Rust
98 lines
2.6 KiB
Rust
|
use crate::dynamic_data::{Event, Pokemon};
|
||
|
use crate::ffi::{ExternPointer, IdentifiablePointer};
|
||
|
use std::sync::Arc;
|
||
|
|
||
|
/// The kind of the event.
|
||
|
#[no_mangle]
|
||
|
extern "C" fn event_kind(ptr: ExternPointer<Event>) -> u8 {
|
||
|
match ptr.as_ref() {
|
||
|
Event::Switch { .. } => 1,
|
||
|
Event::Swap { .. } => 2,
|
||
|
Event::SpeciesChange { .. } => 3,
|
||
|
Event::FormChange { .. } => 4,
|
||
|
Event::Damage { .. } => 5,
|
||
|
Event::Heal { .. } => 6,
|
||
|
Event::Faint { .. } => 7,
|
||
|
Event::MoveUse { .. } => 8,
|
||
|
Event::Miss { .. } => 9,
|
||
|
Event::EndTurn => 10,
|
||
|
Event::StatBoostChange { .. } => 11,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// 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 [<event_ $event_name:snake _data>](ptr: ExternPointer<Event>) -> [<$event_name Data>] {
|
||
|
if let Event::$event_name {
|
||
|
$(
|
||
|
$par_name,
|
||
|
)+
|
||
|
} = ptr.as_ref()
|
||
|
{
|
||
|
$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: IdentifiablePointer<Arc<Pokemon>>,
|
||
|
},
|
||
|
{
|
||
|
return SwitchData{
|
||
|
side_index: *side_index,
|
||
|
index: *index,
|
||
|
pokemon: pokemon.clone().into(),
|
||
|
}
|
||
|
}
|
||
|
);
|
||
|
|
||
|
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,
|
||
|
};
|
||
|
}
|
||
|
);
|