A bunch of fixes and improvements
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
@@ -239,7 +239,7 @@ mod tests {
|
||||
impl TestScript {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
name: StringKey::new("test"),
|
||||
name: StringKey::new("test".into()),
|
||||
is_marked_for_deletion: Default::default(),
|
||||
suppressed_count: AtomicUsize::new(0),
|
||||
test_count: AtomicUsize::new(0),
|
||||
@@ -247,7 +247,7 @@ mod tests {
|
||||
}
|
||||
fn new_with_name(name: &str) -> Self {
|
||||
Self {
|
||||
name: StringKey::new(name),
|
||||
name: StringKey::new(name.into()),
|
||||
is_marked_for_deletion: Default::default(),
|
||||
suppressed_count: AtomicUsize::new(0),
|
||||
test_count: AtomicUsize::new(0),
|
||||
@@ -424,7 +424,7 @@ mod tests {
|
||||
"test_b"
|
||||
);
|
||||
|
||||
set.remove(&StringKey::new("test_c"));
|
||||
set.remove(&StringKey::new("test_c".into()));
|
||||
assert!(aggregator.get_next().is_none());
|
||||
}
|
||||
|
||||
@@ -451,7 +451,7 @@ mod tests {
|
||||
"test_a"
|
||||
);
|
||||
|
||||
set.remove(&StringKey::new("test_b"));
|
||||
set.remove(&StringKey::new("test_b".into()));
|
||||
|
||||
assert_eq!(
|
||||
aggregator
|
||||
|
||||
@@ -398,7 +398,7 @@ mod tests {
|
||||
impl TestScript {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
name: StringKey::new("test"),
|
||||
name: StringKey::new("test".into()),
|
||||
container: AtomicPtr::<ScriptContainer>::default(),
|
||||
suppressed_count: AtomicUsize::new(0),
|
||||
marked_for_deletion: Default::default(),
|
||||
@@ -539,7 +539,7 @@ mod tests {
|
||||
|
||||
assert_eq!(
|
||||
container.script.read().as_ref().unwrap().name(),
|
||||
&StringKey::new("script2")
|
||||
&StringKey::new("script2".into())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#![feature(is_some_with)]
|
||||
#![feature(new_uninit)]
|
||||
#![feature(get_mut_unchecked)]
|
||||
#![feature(strict_provenance)]
|
||||
|
||||
//! PkmnLib
|
||||
//! PkmnLib is a full featured implementation of Pokemon. while currently focused on implementing
|
||||
|
||||
@@ -194,7 +194,7 @@ register! {
|
||||
) -> u8 {
|
||||
let name : *mut c_char = env.data().data().get_raw_pointer(name);
|
||||
let name = unsafe { CStr::from_ptr(name) };
|
||||
let key = StringKey::new(&name.to_str().unwrap().clone());
|
||||
let key = StringKey::new(name.to_str().unwrap().into());
|
||||
if pokemon.value_func(&env).unwrap().has_held_item(&key) { 1 } else { 0 }
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ pub mod tests {
|
||||
pub fn build() -> AbilityLibrary {
|
||||
let mut lib = AbilityLibrary::new(1);
|
||||
lib.add(
|
||||
&StringKey::new("test_ability"),
|
||||
&StringKey::new("test_ability".into()),
|
||||
Ability::new(&"test_ability".into(), &"test_ability".into(), Vec::new()),
|
||||
);
|
||||
// Drops borrow as mut
|
||||
|
||||
@@ -61,7 +61,7 @@ pub mod tests {
|
||||
let m = build_move();
|
||||
// Borrow as mut so we can insert
|
||||
let w = &mut lib;
|
||||
w.add(&StringKey::new("foo"), m);
|
||||
w.add(&StringKey::new("foo".into()), m);
|
||||
// Drops borrow as mut
|
||||
|
||||
lib
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use std::sync::Arc;
|
||||
use std::sync::{Arc, LazyLock};
|
||||
|
||||
use hashbrown::{HashMap, HashSet};
|
||||
|
||||
@@ -29,11 +29,11 @@ pub struct Species {
|
||||
}
|
||||
|
||||
/// A cached String Key to get the default form.
|
||||
static DEFAULT_KEY: conquer_once::OnceCell<StringKey> = conquer_once::OnceCell::uninit();
|
||||
static DEFAULT_KEY: LazyLock<StringKey> = LazyLock::new(|| StringKey::new("default"));
|
||||
|
||||
/// Gets the StringKey for "default". Initialises it if it does not exist.
|
||||
fn get_default_key() -> StringKey {
|
||||
DEFAULT_KEY.get_or_init(|| StringKey::new("default")).clone()
|
||||
DEFAULT_KEY.clone()
|
||||
}
|
||||
|
||||
impl Species {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use arcstr::ArcStr;
|
||||
use hashbrown::HashMap;
|
||||
use parking_lot::RwLock;
|
||||
use std::borrow::Borrow;
|
||||
use std::ffi::CStr;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::ops::Deref;
|
||||
use std::sync::{Arc, Mutex, Weak};
|
||||
|
||||
use conquer_once::OnceCell;
|
||||
use hashbrown::HashMap;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
/// StringKey is an immutable string that is used for indexing of hashmaps or equality a lot.
|
||||
/// By reference counting the string instead of copying, and caching the hash, we can get some
|
||||
@@ -16,16 +16,16 @@ use hashbrown::HashMap;
|
||||
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
|
||||
pub struct StringKey {
|
||||
/// The underlying reference counted string.
|
||||
str: Arc<str>,
|
||||
str: ArcStr,
|
||||
/// The unique hash of the string.
|
||||
hash: u32,
|
||||
}
|
||||
|
||||
/// A cache of all allocated strings. This allows us to re-use strings that are often used without
|
||||
/// allocation.
|
||||
static STRING_CACHE: OnceCell<Mutex<HashMap<u32, Weak<str>>>> = OnceCell::uninit();
|
||||
static STRING_CACHE: LazyLock<RwLock<HashMap<u32, ArcStr>>> = LazyLock::new(|| RwLock::new(HashMap::new()));
|
||||
/// An empty StringKey
|
||||
static EMPTY: OnceCell<StringKey> = OnceCell::uninit();
|
||||
static EMPTY: LazyLock<StringKey> = LazyLock::new(|| StringKey::new(""));
|
||||
|
||||
impl StringKey {
|
||||
/// Gets the hash of a string.
|
||||
@@ -42,25 +42,29 @@ impl StringKey {
|
||||
/// Creates a new StringKey. If we can find a value for this StringKey in the cache, we re-use
|
||||
/// that value.
|
||||
pub fn new(s: &str) -> Self {
|
||||
let hash = StringKey::get_hash(s);
|
||||
let mut cache = STRING_CACHE.get_or_init(|| Mutex::new(HashMap::new())).lock().unwrap();
|
||||
let cached_value = cache.get(&hash);
|
||||
if let Some(cached_value) = cached_value {
|
||||
if let Some(cached_value) = cached_value.upgrade() {
|
||||
let s: ArcStr = s.into();
|
||||
let hash = StringKey::get_hash(s.as_str());
|
||||
{
|
||||
let cache_read = STRING_CACHE.read();
|
||||
let cached_value = cache_read.get(&hash);
|
||||
if let Some(cached_value) = cached_value {
|
||||
return Self {
|
||||
str: cached_value,
|
||||
str: cached_value.clone(),
|
||||
hash,
|
||||
};
|
||||
}
|
||||
}
|
||||
let v = Self { str: s.into(), hash };
|
||||
cache.insert(hash, Arc::downgrade(&v.str));
|
||||
v
|
||||
{
|
||||
let v = Self { str: s.clone(), hash };
|
||||
let mut cache_write = STRING_CACHE.write();
|
||||
cache_write.insert(hash, s);
|
||||
v
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the empty StringKey.
|
||||
pub fn empty() -> Self {
|
||||
EMPTY.get_or_init(|| StringKey::new("")).clone()
|
||||
EMPTY.clone()
|
||||
}
|
||||
|
||||
/// Gets the underlying string for the StringKey.
|
||||
@@ -108,7 +112,7 @@ impl Display for StringKey {
|
||||
|
||||
impl Into<StringKey> for &CStr {
|
||||
fn into(self) -> StringKey {
|
||||
StringKey::new(self.to_str().unwrap())
|
||||
StringKey::new(self.to_str().unwrap().into())
|
||||
}
|
||||
}
|
||||
/// Converts a character to lowercased in a const safe way.
|
||||
@@ -160,7 +164,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn create_empty_stringkey() {
|
||||
let sk = StringKey::new("");
|
||||
let sk = StringKey::new("".into());
|
||||
assert_eq!(sk.str(), "");
|
||||
assert_eq!(sk.hash(), 0);
|
||||
assert_eq!(sk.hash(), StringKey::get_hash(""));
|
||||
@@ -168,7 +172,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn create_stringkey_foo() {
|
||||
let sk = StringKey::new("foo");
|
||||
let sk = StringKey::new("foo".into());
|
||||
assert_eq!(sk.str(), "foo");
|
||||
assert_eq!(sk.hash(), 2356372769);
|
||||
assert_eq!(sk.hash(), StringKey::get_hash("foo"));
|
||||
@@ -177,7 +181,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn create_stringkey_bar() {
|
||||
let sk = StringKey::new("bar");
|
||||
let sk = StringKey::new("bar".into());
|
||||
assert_eq!(sk.str(), "bar");
|
||||
assert_eq!(sk.hash(), 1996459178);
|
||||
assert_eq!(sk.hash(), StringKey::get_hash("bar"));
|
||||
|
||||
Reference in New Issue
Block a user