Clippy fixes and documentation
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2023-06-24 15:05:58 +02:00
parent 78bb91093b
commit 3400d9ec1e
12 changed files with 61 additions and 4 deletions

View File

@@ -75,26 +75,31 @@ extern "C" fn pokemon_display_form(handle: FFIHandle<Pokemon>) -> FFIHandle<Arc<
FFIHandle::get_handle(handle.from_ffi_handle().display_form().into())
}
/// The level of the Pokemon.
#[no_mangle]
extern "C" fn pokemon_level(handle: FFIHandle<Pokemon>) -> LevelInt {
handle.from_ffi_handle().level()
}
/// The experience of the Pokemon.
#[no_mangle]
extern "C" fn pokemon_experience(handle: FFIHandle<Pokemon>) -> u32 {
handle.from_ffi_handle().experience()
}
/// The unique identifier of the Pokemon.
#[no_mangle]
extern "C" fn pokemon_unique_identifier(handle: FFIHandle<Pokemon>) -> u32 {
handle.from_ffi_handle().unique_identifier()
}
/// The gender of the Pokemon.
#[no_mangle]
extern "C" fn pokemon_gender(handle: FFIHandle<Pokemon>) -> Gender {
handle.from_ffi_handle().gender()
}
/// The coloring of the Pokemon.
#[no_mangle]
extern "C" fn pokemon_coloring(handle: FFIHandle<Pokemon>) -> u8 {
handle.from_ffi_handle().coloring()
@@ -149,21 +154,25 @@ extern "C" fn pokemon_consume_held_item(handle: FFIHandle<Pokemon>) -> FFIResult
}
}
/// The current health of the Pokemon.
#[no_mangle]
extern "C" fn pokemon_current_health(handle: FFIHandle<Pokemon>) -> u32 {
handle.from_ffi_handle().current_health()
}
/// The max health of the Pokemon.
#[no_mangle]
extern "C" fn pokemon_max_health(handle: FFIHandle<Pokemon>) -> u32 {
handle.from_ffi_handle().max_health()
}
/// The current weight of the Pokemon.
#[no_mangle]
extern "C" fn pokemon_weight(handle: FFIHandle<Pokemon>) -> f32 {
handle.from_ffi_handle().weight()
}
/// The current height of the Pokemon.
#[no_mangle]
extern "C" fn pokemon_height(handle: FFIHandle<Pokemon>) -> f32 {
handle.from_ffi_handle().height()
@@ -196,11 +205,13 @@ extern "C" fn pokemon_real_ability_index(handle: FFIHandle<Pokemon>) -> u8 {
handle.from_ffi_handle().real_ability().index
}
/// The amount of types the Pokemon has.
#[no_mangle]
extern "C" fn pokemon_types_length(ptr: FFIHandle<Pokemon>) -> usize {
ptr.from_ffi_handle().types().len()
}
/// Gets a type of the Pokemon.
#[no_mangle]
extern "C" fn pokemon_types_get(ptr: FFIHandle<Pokemon>, index: usize) -> FFIResult<TypeIdentifier> {
match ptr.from_ffi_handle().types().get_res(index) {

View File

@@ -9,9 +9,14 @@ use std::hash::Hash;
use std::sync::atomic::AtomicUsize;
use std::sync::{Arc, LazyLock};
/// A handle of an object that can be passed over FFI. We use this to avoid passing pointers over the
/// FFI boundary. This allows us to be able to move the data around in memory without having to worry
/// about the pointers being invalidated. It also allows us to have a type-safe interface.
#[repr(C)]
pub(super) struct FFIHandle<T> {
/// An incrementing handle that is unique for each object.
handle: usize,
/// The type of the object.
_marker: std::marker::PhantomData<T>,
}
@@ -26,7 +31,10 @@ impl<T> Clone for FFIHandle<T> {
impl<T> Copy for FFIHandle<T> {}
/// An FFIObject we can fetch from the FFIHandle. We store this in a hashmap to be able to fetch
/// the object from the handle, and to be able to drop the object when the FFI is done with the handle
#[derive(Clone)]
#[allow(clippy::missing_docs_in_private_items)] // I'm not documenting these items.
pub(super) enum FFIObject {
Ability(Arc<dyn Ability>),
EffectParameter(Arc<EffectParameter>),
@@ -75,11 +83,15 @@ unsafe impl Send for FFIObject {}
unsafe impl Sync for FFIObject {}
/// The next handle to be used.
static NEXT_HANDLE: AtomicUsize = AtomicUsize::new(0);
/// A lookup to get an actual object from a handle.
static FFI_OBJECTS: LazyLock<RwLock<HashMap<usize, FFIObject>>> = LazyLock::new(|| RwLock::new(HashMap::new()));
/// A lookup to get a handle from an object.
static FFI_OBJECTS_INVERSE: LazyLock<RwLock<HashMap<FFIObject, usize>>> = LazyLock::new(|| RwLock::new(HashMap::new()));
impl<T> FFIHandle<T> {
/// Get a handle from an object.
pub fn get_handle(o: FFIObject) -> Self {
if let Some(handle) = FFI_OBJECTS_INVERSE.read().get(&o) {
return Self {
@@ -97,6 +109,7 @@ impl<T> FFIHandle<T> {
}
}
/// An empty handle. This is used when no value is returned. Represented as handle 0
pub fn none() -> Self {
Self {
handle: 0,
@@ -104,6 +117,7 @@ impl<T> FFIHandle<T> {
}
}
/// Get the object from the handle.
#[allow(clippy::unwrap_used)] // Unwrap used, as it is a potential security bug if this fails
pub fn resolve(&self) -> FFIObject {
FFI_OBJECTS
@@ -114,6 +128,7 @@ impl<T> FFIHandle<T> {
.clone()
}
/// Check if the handle is empty.
pub fn is_none(&self) -> bool {
self.handle == 0
}
@@ -132,9 +147,12 @@ impl<T> Into<anyhow_ext::Result<FFIObject>> for FFIHandle<T> {
impl Eq for FFIObject {}
/// A trait to convert a handle into an object.
#[allow(clippy::wrong_self_convention)]
pub(super) trait FromFFIHandle<T> {
/// Convert a handle into an object.
fn from_ffi_handle(&self) -> T;
/// Convert a handle into an object, returning `None` if the handle is empty.
fn from_ffi_handle_opt(&self) -> Option<T>;
}
@@ -229,6 +247,8 @@ impl PartialEq for FFIObject {
}
}
/// Helper macro to implement the `From` trait for a `FFIObject` enum variant, and the `FromFFIHandle`
/// trait for a `FFIHandle` enum variant.
macro_rules! ffi_obj_conversions {
($res_type:ty, $ffi_obj_name:ident) => {
impl From<$res_type> for FFIObject {

View File

@@ -1,5 +1,6 @@
/// The foreign function interfaces for the dynamic data
mod dynamic_data;
/// The handling of handles for the foreign function interfaces
mod ffi_handle;
/// The foreign function interfaces for that static data
mod static_data;