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.
|
/// shared between all different usages.
|
||||||
fn load_item_script(&self, _key: &dyn Item) -> Result<Option<Arc<dyn ItemScript>>>;
|
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;
|
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 {
|
pub fn as_ptr(&self) -> *const c_void {
|
||||||
Arc::as_ptr(&self.data) as *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 {
|
pub fn as_ptr(&self) -> *const c_void {
|
||||||
Arc::as_ptr(&self.data) as *const c_void
|
Arc::as_ptr(&self.data) as *const c_void
|
||||||
}
|
}
|
||||||
|
|
|
@ -543,7 +543,7 @@ impl Pokemon {
|
||||||
|
|
||||||
/// Change the form of the Pokemon.
|
/// Change the form of the Pokemon.
|
||||||
pub fn change_form(&self, form: &Arc<dyn Form>) -> Result<()> {
|
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(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
*self.data.form.write() = form.clone();
|
*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 {
|
pub fn as_ptr(&self) -> *const c_void {
|
||||||
Arc::as_ptr(&self.data) as *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())
|
FFIHandle::get_handle(handle.from_ffi_handle().display_form().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The level of the Pokemon.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_level(handle: FFIHandle<Pokemon>) -> LevelInt {
|
extern "C" fn pokemon_level(handle: FFIHandle<Pokemon>) -> LevelInt {
|
||||||
handle.from_ffi_handle().level()
|
handle.from_ffi_handle().level()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The experience of the Pokemon.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_experience(handle: FFIHandle<Pokemon>) -> u32 {
|
extern "C" fn pokemon_experience(handle: FFIHandle<Pokemon>) -> u32 {
|
||||||
handle.from_ffi_handle().experience()
|
handle.from_ffi_handle().experience()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The unique identifier of the Pokemon.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_unique_identifier(handle: FFIHandle<Pokemon>) -> u32 {
|
extern "C" fn pokemon_unique_identifier(handle: FFIHandle<Pokemon>) -> u32 {
|
||||||
handle.from_ffi_handle().unique_identifier()
|
handle.from_ffi_handle().unique_identifier()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The gender of the Pokemon.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_gender(handle: FFIHandle<Pokemon>) -> Gender {
|
extern "C" fn pokemon_gender(handle: FFIHandle<Pokemon>) -> Gender {
|
||||||
handle.from_ffi_handle().gender()
|
handle.from_ffi_handle().gender()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The coloring of the Pokemon.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_coloring(handle: FFIHandle<Pokemon>) -> u8 {
|
extern "C" fn pokemon_coloring(handle: FFIHandle<Pokemon>) -> u8 {
|
||||||
handle.from_ffi_handle().coloring()
|
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]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_current_health(handle: FFIHandle<Pokemon>) -> u32 {
|
extern "C" fn pokemon_current_health(handle: FFIHandle<Pokemon>) -> u32 {
|
||||||
handle.from_ffi_handle().current_health()
|
handle.from_ffi_handle().current_health()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The max health of the Pokemon.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_max_health(handle: FFIHandle<Pokemon>) -> u32 {
|
extern "C" fn pokemon_max_health(handle: FFIHandle<Pokemon>) -> u32 {
|
||||||
handle.from_ffi_handle().max_health()
|
handle.from_ffi_handle().max_health()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The current weight of the Pokemon.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_weight(handle: FFIHandle<Pokemon>) -> f32 {
|
extern "C" fn pokemon_weight(handle: FFIHandle<Pokemon>) -> f32 {
|
||||||
handle.from_ffi_handle().weight()
|
handle.from_ffi_handle().weight()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The current height of the Pokemon.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_height(handle: FFIHandle<Pokemon>) -> f32 {
|
extern "C" fn pokemon_height(handle: FFIHandle<Pokemon>) -> f32 {
|
||||||
handle.from_ffi_handle().height()
|
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
|
handle.from_ffi_handle().real_ability().index
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The amount of types the Pokemon has.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_types_length(ptr: FFIHandle<Pokemon>) -> usize {
|
extern "C" fn pokemon_types_length(ptr: FFIHandle<Pokemon>) -> usize {
|
||||||
ptr.from_ffi_handle().types().len()
|
ptr.from_ffi_handle().types().len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets a type of the Pokemon.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn pokemon_types_get(ptr: FFIHandle<Pokemon>, index: usize) -> FFIResult<TypeIdentifier> {
|
extern "C" fn pokemon_types_get(ptr: FFIHandle<Pokemon>, index: usize) -> FFIResult<TypeIdentifier> {
|
||||||
match ptr.from_ffi_handle().types().get_res(index) {
|
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::atomic::AtomicUsize;
|
||||||
use std::sync::{Arc, LazyLock};
|
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)]
|
#[repr(C)]
|
||||||
pub(super) struct FFIHandle<T> {
|
pub(super) struct FFIHandle<T> {
|
||||||
|
/// An incrementing handle that is unique for each object.
|
||||||
handle: usize,
|
handle: usize,
|
||||||
|
/// The type of the object.
|
||||||
_marker: std::marker::PhantomData<T>,
|
_marker: std::marker::PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,7 +31,10 @@ impl<T> Clone for FFIHandle<T> {
|
||||||
|
|
||||||
impl<T> Copy 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)]
|
#[derive(Clone)]
|
||||||
|
#[allow(clippy::missing_docs_in_private_items)] // I'm not documenting these items.
|
||||||
pub(super) enum FFIObject {
|
pub(super) enum FFIObject {
|
||||||
Ability(Arc<dyn Ability>),
|
Ability(Arc<dyn Ability>),
|
||||||
EffectParameter(Arc<EffectParameter>),
|
EffectParameter(Arc<EffectParameter>),
|
||||||
|
@ -75,11 +83,15 @@ unsafe impl Send for FFIObject {}
|
||||||
|
|
||||||
unsafe impl Sync for FFIObject {}
|
unsafe impl Sync for FFIObject {}
|
||||||
|
|
||||||
|
/// The next handle to be used.
|
||||||
static NEXT_HANDLE: AtomicUsize = AtomicUsize::new(0);
|
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()));
|
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()));
|
static FFI_OBJECTS_INVERSE: LazyLock<RwLock<HashMap<FFIObject, usize>>> = LazyLock::new(|| RwLock::new(HashMap::new()));
|
||||||
|
|
||||||
impl<T> FFIHandle<T> {
|
impl<T> FFIHandle<T> {
|
||||||
|
/// Get a handle from an object.
|
||||||
pub fn get_handle(o: FFIObject) -> Self {
|
pub fn get_handle(o: FFIObject) -> Self {
|
||||||
if let Some(handle) = FFI_OBJECTS_INVERSE.read().get(&o) {
|
if let Some(handle) = FFI_OBJECTS_INVERSE.read().get(&o) {
|
||||||
return Self {
|
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 {
|
pub fn none() -> Self {
|
||||||
Self {
|
Self {
|
||||||
handle: 0,
|
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
|
#[allow(clippy::unwrap_used)] // Unwrap used, as it is a potential security bug if this fails
|
||||||
pub fn resolve(&self) -> FFIObject {
|
pub fn resolve(&self) -> FFIObject {
|
||||||
FFI_OBJECTS
|
FFI_OBJECTS
|
||||||
|
@ -114,6 +128,7 @@ impl<T> FFIHandle<T> {
|
||||||
.clone()
|
.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if the handle is empty.
|
||||||
pub fn is_none(&self) -> bool {
|
pub fn is_none(&self) -> bool {
|
||||||
self.handle == 0
|
self.handle == 0
|
||||||
}
|
}
|
||||||
|
@ -132,9 +147,12 @@ impl<T> Into<anyhow_ext::Result<FFIObject>> for FFIHandle<T> {
|
||||||
|
|
||||||
impl Eq for FFIObject {}
|
impl Eq for FFIObject {}
|
||||||
|
|
||||||
|
/// A trait to convert a handle into an object.
|
||||||
#[allow(clippy::wrong_self_convention)]
|
#[allow(clippy::wrong_self_convention)]
|
||||||
pub(super) trait FromFFIHandle<T> {
|
pub(super) trait FromFFIHandle<T> {
|
||||||
|
/// Convert a handle into an object.
|
||||||
fn from_ffi_handle(&self) -> T;
|
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>;
|
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 {
|
macro_rules! ffi_obj_conversions {
|
||||||
($res_type:ty, $ffi_obj_name:ident) => {
|
($res_type:ty, $ffi_obj_name:ident) => {
|
||||||
impl From<$res_type> for FFIObject {
|
impl From<$res_type> for FFIObject {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/// The foreign function interfaces for the dynamic data
|
/// The foreign function interfaces for the dynamic data
|
||||||
mod dynamic_data;
|
mod dynamic_data;
|
||||||
|
/// The handling of handles for the foreign function interfaces
|
||||||
mod ffi_handle;
|
mod ffi_handle;
|
||||||
/// The foreign function interfaces for that static data
|
/// The foreign function interfaces for that static data
|
||||||
mod static_data;
|
mod static_data;
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
#![allow(ambiguous_glob_reexports)]
|
#![allow(ambiguous_glob_reexports)]
|
||||||
#![allow(hidden_glob_reexports)]
|
#![allow(hidden_glob_reexports)]
|
||||||
// Documentation linters
|
// Documentation linters
|
||||||
// #![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
// #![deny(clippy::missing_docs_in_private_items)]
|
#![deny(clippy::missing_docs_in_private_items)]
|
||||||
// Linter rules to prevent panics
|
// Linter rules to prevent panics
|
||||||
// Currently still a WIP to fix all of these
|
// Currently still a WIP to fix all of these
|
||||||
#![deny(clippy::unwrap_used)]
|
#![deny(clippy::unwrap_used)]
|
||||||
|
|
|
@ -5,6 +5,7 @@ use anyhow_ext::{ensure, Result};
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
use std::ops::Deref;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
/// A library of all natures that can be used, stored by their names.
|
/// 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() {
|
for kv in read_lock.iter() {
|
||||||
// As natures can't be copied, and should always be the same reference as the value
|
// As natures can't be copied, and should always be the same reference as the value
|
||||||
// in the map, we just compare by reference.
|
// 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());
|
return Ok(kv.0.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,9 @@ impl TypeLibraryImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
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(
|
fn get_single_effectiveness_with_lock(
|
||||||
lock: &RwLockReadGuard<Vec<Vec<f32>>>,
|
lock: &RwLockReadGuard<Vec<Vec<f32>>>,
|
||||||
attacking: TypeIdentifier,
|
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
|
/// 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
|
/// modifier, if it's the decreased stat, returns the decreased modifier. Otherwise returns 1.0
|
||||||
fn get_stat_modifier(&self, stat: Statistic) -> f32;
|
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
|
/// 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
|
1.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn eq(&self, other: &dyn Nature) -> bool {
|
||||||
|
std::ptr::eq(self, other as *const dyn Nature as *const Self)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -100,6 +107,7 @@ pub(crate) mod tests {
|
||||||
fn increased_modifier(&self) -> f32;
|
fn increased_modifier(&self) -> f32;
|
||||||
fn decreased_modifier(&self) -> f32;
|
fn decreased_modifier(&self) -> f32;
|
||||||
fn get_stat_modifier(&self, stat: Statistic) -> 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.
|
/// Arbitrary flags that can be applied to the move.
|
||||||
fn has_flag_by_hash(&self, key_hash: u32) -> bool;
|
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
|
/// 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 {
|
fn has_flag_by_hash(&self, key_hash: u32) -> bool {
|
||||||
self.flags.contains::<u32>(&key_hash)
|
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)]
|
#[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 get_random_hidden_ability<'a>(&'a self, rand: &mut Random) -> Result<&'a StringKey>;
|
||||||
fn has_flag(&self, key: &StringKey) -> bool;
|
fn has_flag(&self, key: &StringKey) -> bool;
|
||||||
fn has_flag_by_hash(&self, key_hash: u32) -> bool;
|
fn has_flag_by_hash(&self, key_hash: u32) -> bool;
|
||||||
|
fn eq(&self, other: &dyn Form) -> bool;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue