Clippy fixes and documentation
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
78bb91093b
commit
3400d9ec1e
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue