Clippy fixes and documentation
continuous-integration/drone/push Build is passing Details

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

View File

@ -25,6 +25,8 @@ pub trait ScriptResolver: Debug {
/// shared between all different usages.
fn load_item_script(&self, _key: &dyn Item) -> Result<Option<Arc<dyn ItemScript>>>;
/// Returns a reference to this script resolver as an Any. This is used to downcast the
/// ScriptResolver to a specific implementation.
fn as_any(&self) -> &dyn std::any::Any;
}

View File

@ -378,6 +378,7 @@ impl Battle {
}
}
/// Gets the inner pointer to the reference counted data.
pub fn as_ptr(&self) -> *const c_void {
Arc::as_ptr(&self.data) as *const c_void
}

View File

@ -354,6 +354,7 @@ impl BattleSide {
}
}
/// Gets the inner pointer to the reference counted data.
pub fn as_ptr(&self) -> *const c_void {
Arc::as_ptr(&self.data) as *const c_void
}

View File

@ -543,7 +543,7 @@ impl Pokemon {
/// Change the form of the Pokemon.
pub fn change_form(&self, form: &Arc<dyn Form>) -> Result<()> {
if Arc::ptr_eq(&self.form(), form) {
if self.form().eq(form.deref()) {
return Ok(());
}
*self.data.form.write() = form.clone();
@ -816,6 +816,7 @@ impl Pokemon {
}
}
/// Gets the inner pointer to the reference counted data.
pub fn as_ptr(&self) -> *const c_void {
Arc::as_ptr(&self.data) as *const c_void
}

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;

View File

@ -8,8 +8,8 @@
#![allow(ambiguous_glob_reexports)]
#![allow(hidden_glob_reexports)]
// Documentation linters
// #![deny(missing_docs)]
// #![deny(clippy::missing_docs_in_private_items)]
#![deny(missing_docs)]
#![deny(clippy::missing_docs_in_private_items)]
// Linter rules to prevent panics
// Currently still a WIP to fix all of these
#![deny(clippy::unwrap_used)]

View File

@ -5,6 +5,7 @@ use anyhow_ext::{ensure, Result};
use indexmap::IndexMap;
use parking_lot::RwLock;
use std::fmt::Debug;
use std::ops::Deref;
use std::sync::Arc;
/// A library of all natures that can be used, stored by their names.
@ -64,7 +65,7 @@ impl NatureLibrary for NatureLibraryImpl {
for kv in read_lock.iter() {
// 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 Arc::ptr_eq(&kv.1, nature) {
if kv.1.eq(nature.deref()) {
return Ok(kv.0.clone());
}
}

View File

@ -77,6 +77,9 @@ impl TypeLibraryImpl {
}
impl TypeLibraryImpl {
/// Helper function to get the effectiveness for a single attacking type against a single
/// defending type, without having to acquire read locks multiple times when used in a loop.
#[inline]
fn get_single_effectiveness_with_lock(
lock: &RwLockReadGuard<Vec<Vec<f32>>>,
attacking: TypeIdentifier,

View File

@ -20,6 +20,9 @@ pub trait Nature: Debug {
/// Calculates the modifier for a given stat. If it's the increased stat, returns the increased
/// modifier, if it's the decreased stat, returns the decreased modifier. Otherwise returns 1.0
fn get_stat_modifier(&self, stat: Statistic) -> f32;
/// Checks if two natures are equal.
fn eq(&self, other: &dyn Nature) -> bool;
}
/// A nature is an attribute on a Pokemon that modifies the effective base stats on a Pokemon. They
@ -83,6 +86,10 @@ impl Nature for NatureImpl {
1.0
}
}
fn eq(&self, other: &dyn Nature) -> bool {
std::ptr::eq(self, other as *const dyn Nature as *const Self)
}
}
#[cfg(test)]
@ -100,6 +107,7 @@ pub(crate) mod tests {
fn increased_modifier(&self) -> f32;
fn decreased_modifier(&self) -> f32;
fn get_stat_modifier(&self, stat: Statistic) -> f32;
fn eq(&self, other: &dyn Nature) -> bool;
}
}
}

View File

@ -56,6 +56,9 @@ pub trait Form: Debug {
/// Arbitrary flags that can be applied to the move.
fn has_flag_by_hash(&self, key_hash: u32) -> bool;
/// Check if two forms are equal.
fn eq(&self, other: &dyn Form) -> bool;
}
/// A form is a variant of a specific species. A species always has at least one form, but can have
@ -217,6 +220,10 @@ impl Form for FormImpl {
fn has_flag_by_hash(&self, key_hash: u32) -> bool {
self.flags.contains::<u32>(&key_hash)
}
fn eq(&self, other: &dyn Form) -> bool {
std::ptr::eq(self, other as *const dyn Form as *const Self)
}
}
#[cfg(test)]
@ -247,6 +254,7 @@ pub(crate) mod tests {
fn get_random_hidden_ability<'a>(&'a self, rand: &mut Random) -> Result<&'a StringKey>;
fn has_flag(&self, key: &StringKey) -> bool;
fn has_flag_by_hash(&self, key_hash: u32) -> bool;
fn eq(&self, other: &dyn Form) -> bool;
}
}
}