Minor performance tweaks
This commit is contained in:
parent
055fbfba78
commit
43bc811704
|
@ -6,8 +6,8 @@ use std::ptr::drop_in_place;
|
||||||
|
|
||||||
/// Instantiates a new Learnable Moves.
|
/// Instantiates a new Learnable Moves.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern "C" fn learnable_moves_new() -> OwnedPtr<Box<dyn LearnableMoves>> {
|
extern "C" fn learnable_moves_new(max_level: LevelInt) -> OwnedPtr<Box<dyn LearnableMoves>> {
|
||||||
Box::into_raw(Box::new(Box::new(LearnableMovesImpl::new())))
|
Box::into_raw(Box::new(Box::new(LearnableMovesImpl::new(max_level))))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// drops a learnablemoves struct.
|
/// drops a learnablemoves struct.
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use hashbrown::hash_map::Entry::{Occupied, Vacant};
|
use indexmap::IndexSet;
|
||||||
use hashbrown::HashMap;
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
|
||||||
use crate::defines::LevelInt;
|
use crate::defines::LevelInt;
|
||||||
|
@ -12,48 +11,42 @@ pub trait LearnableMoves: Debug {
|
||||||
/// Gets all moves a Pokemon can learn when leveling up to a specific level.
|
/// Gets all moves a Pokemon can learn when leveling up to a specific level.
|
||||||
fn get_learned_by_level(&self, level: LevelInt) -> Option<&Vec<StringKey>>;
|
fn get_learned_by_level(&self, level: LevelInt) -> Option<&Vec<StringKey>>;
|
||||||
/// Gets the distinct moves a Pokemon can learn through leveling up.
|
/// Gets the distinct moves a Pokemon can learn through leveling up.
|
||||||
fn get_distinct_level_moves(&self) -> &Vec<StringKey>;
|
fn get_distinct_level_moves(&self) -> &IndexSet<StringKey>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The storage of the moves a Pokemon can learn.
|
/// The storage of the moves a Pokemon can learn.
|
||||||
#[derive(Default, PartialEq, Eq, Debug)]
|
#[derive(PartialEq, Eq, Debug)]
|
||||||
pub struct LearnableMovesImpl {
|
pub struct LearnableMovesImpl {
|
||||||
/// A map of the moves a Pokemon can learn per level.
|
/// A map of the moves a Pokemon can learn per level.
|
||||||
learned_by_level: HashMap<LevelInt, Vec<StringKey>>,
|
learned_by_level: Vec<Vec<StringKey>>,
|
||||||
/// A list of the distinct moves a Pokemon can learn through leveling up.
|
/// A list of the distinct moves a Pokemon can learn through leveling up.
|
||||||
distinct_level_moves: Vec<StringKey>,
|
distinct_level_moves: IndexSet<StringKey>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LearnableMovesImpl {
|
impl LearnableMovesImpl {
|
||||||
/// Instantiates a new Learnable Moves.
|
/// Instantiates a new Learnable Moves.
|
||||||
pub fn new() -> Self {
|
pub fn new(max_level: LevelInt) -> Self {
|
||||||
Self::default()
|
Self {
|
||||||
|
learned_by_level: vec![Vec::new(); (max_level + 1) as usize],
|
||||||
|
distinct_level_moves: Default::default(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LearnableMoves for LearnableMovesImpl {
|
impl LearnableMoves for LearnableMovesImpl {
|
||||||
/// Adds a new level move the Pokemon can learn.
|
/// Adds a new level move the Pokemon can learn.
|
||||||
fn add_level_move(&mut self, level: LevelInt, m: &StringKey) {
|
fn add_level_move(&mut self, level: LevelInt, m: &StringKey) {
|
||||||
match self.learned_by_level.entry(level) {
|
self.learned_by_level.get_mut(level as usize).unwrap().push(m.clone());
|
||||||
Occupied(x) => {
|
self.distinct_level_moves.insert(m.clone());
|
||||||
x.into_mut().push(m.clone());
|
|
||||||
}
|
|
||||||
Vacant(_) => {
|
|
||||||
self.learned_by_level.insert(level, vec![m.clone()]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !self.distinct_level_moves.contains(m) {
|
|
||||||
self.distinct_level_moves.push(m.clone());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets all moves a Pokemon can learn when leveling up to a specific level.
|
/// Gets all moves a Pokemon can learn when leveling up to a specific level.
|
||||||
fn get_learned_by_level(&self, level: LevelInt) -> Option<&Vec<StringKey>> {
|
fn get_learned_by_level(&self, level: LevelInt) -> Option<&Vec<StringKey>> {
|
||||||
self.learned_by_level.get(&level)
|
self.learned_by_level.get(level as usize)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the distinct moves a Pokemon can learn through leveling up.
|
/// Gets the distinct moves a Pokemon can learn through leveling up.
|
||||||
fn get_distinct_level_moves(&self) -> &Vec<StringKey> {
|
fn get_distinct_level_moves(&self) -> &IndexSet<StringKey> {
|
||||||
&self.distinct_level_moves
|
&self.distinct_level_moves
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,7 +57,7 @@ pub(crate) mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn adds_level_moves() {
|
fn adds_level_moves() {
|
||||||
let mut moves = LearnableMovesImpl::new();
|
let mut moves = LearnableMovesImpl::new(100);
|
||||||
moves.add_level_move(1, &"foo".into());
|
moves.add_level_move(1, &"foo".into());
|
||||||
moves.add_level_move(1, &"bar".into());
|
moves.add_level_move(1, &"bar".into());
|
||||||
|
|
||||||
|
@ -76,7 +69,7 @@ pub(crate) mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn adds_two_same_moves_at_different_level() {
|
fn adds_two_same_moves_at_different_level() {
|
||||||
let mut moves = LearnableMovesImpl::new();
|
let mut moves = LearnableMovesImpl::new(100);
|
||||||
|
|
||||||
moves.add_level_move(1, &"foo".into());
|
moves.add_level_move(1, &"foo".into());
|
||||||
moves.add_level_move(5, &"foo".into());
|
moves.add_level_move(5, &"foo".into());
|
||||||
|
|
|
@ -14,7 +14,6 @@ use std::sync::LazyLock;
|
||||||
/// free speed out of it. Note that StringKeys also compare case insensitive, so that for example
|
/// free speed out of it. Note that StringKeys also compare case insensitive, so that for example
|
||||||
/// `charmander` == `Charmander`.
|
/// `charmander` == `Charmander`.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
|
||||||
pub struct StringKey {
|
pub struct StringKey {
|
||||||
/// The underlying reference counted string.
|
/// The underlying reference counted string.
|
||||||
str: ArcStr,
|
str: ArcStr,
|
||||||
|
@ -29,12 +28,14 @@ static STRING_CACHE: LazyLock<RwLock<HashMap<u32, ArcStr>>> = LazyLock::new(|| R
|
||||||
static EMPTY: LazyLock<StringKey> = LazyLock::new(|| StringKey::new(""));
|
static EMPTY: LazyLock<StringKey> = LazyLock::new(|| StringKey::new(""));
|
||||||
|
|
||||||
impl StringKey {
|
impl StringKey {
|
||||||
|
#[inline(always)]
|
||||||
/// Gets the hash of a string.
|
/// Gets the hash of a string.
|
||||||
pub const fn get_hash(s: &str) -> u32 {
|
pub const fn get_hash(s: &str) -> u32 {
|
||||||
let mut crc: u32 = 0xffffffff;
|
let mut crc: u32 = 0xffffffff;
|
||||||
let mut i: usize = 0;
|
let mut i: usize = 0;
|
||||||
|
let bytes = s.as_bytes();
|
||||||
while i < s.len() {
|
while i < s.len() {
|
||||||
crc = (crc >> 8) ^ CRC_TABLE[((crc ^ (to_lower(s.as_bytes()[i]) as u32)) & 0xff) as usize];
|
crc = (crc >> 8) ^ CRC_TABLE[((crc ^ (to_lower(bytes[i]) as u32)) & 0xff) as usize];
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
crc ^ 0xffffffff
|
crc ^ 0xffffffff
|
||||||
|
@ -132,6 +133,7 @@ impl ValueIdentifiable for StringKey {
|
||||||
/// The difference in ascii characters to translate from uppercase to lowercase.
|
/// The difference in ascii characters to translate from uppercase to lowercase.
|
||||||
const CAPITAL_DIFF: u8 = b'a' - b'A';
|
const CAPITAL_DIFF: u8 = b'a' - b'A';
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
/// Converts a character to lowercased in a const safe way.
|
/// Converts a character to lowercased in a const safe way.
|
||||||
const fn to_lower(c: u8) -> u8 {
|
const fn to_lower(c: u8) -> u8 {
|
||||||
if c >= b'A' && c <= b'Z' {
|
if c >= b'A' && c <= b'Z' {
|
||||||
|
|
|
@ -450,7 +450,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_moves(value: &Value, move_library: &Box<dyn MoveLibrary>) -> Box<dyn LearnableMoves> {
|
fn parse_moves(value: &Value, move_library: &Box<dyn MoveLibrary>) -> Box<dyn LearnableMoves> {
|
||||||
let mut moves = LearnableMovesImpl::default();
|
let mut moves = LearnableMovesImpl::new(100);
|
||||||
|
|
||||||
let level_moves = value.get("levelMoves").unwrap().as_array().unwrap();
|
let level_moves = value.get("levelMoves").unwrap().as_array().unwrap();
|
||||||
for level_move in level_moves {
|
for level_move in level_moves {
|
||||||
|
|
Loading…
Reference in New Issue