Initial work on wasm scripting backend

This commit is contained in:
2022-07-18 10:16:47 +02:00
parent 8eb1159d64
commit 7682704945
21 changed files with 651 additions and 31 deletions

View File

@@ -1,15 +1,17 @@
use std::fmt::{Display, Formatter};
use std::hash::{Hash, Hasher};
use std::lazy::SyncLazy;
use std::sync::{Arc, Mutex, Weak};
use conquer_once::OnceCell;
use hashbrown::HashMap;
use indexmap::Equivalent;
/// 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
/// free speed out of it. Note that StringKeys also compare case insensitive, so that for example
/// `charmander` == `Charmander`.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "wasm", derive(unique_type_id_derive::UniqueTypeId))]
pub struct StringKey {
/// The underlying reference counted string.
str: Arc<str>,
@@ -19,9 +21,9 @@ pub struct StringKey {
/// A cache of all allocated strings. This allows us to re-use strings that are often used without
/// allocation.
static STRING_CACHE: SyncLazy<Mutex<HashMap<u32, Weak<str>>>> = SyncLazy::new(|| Mutex::new(HashMap::new()));
static STRING_CACHE: OnceCell<Mutex<HashMap<u32, Weak<str>>>> = OnceCell::uninit();
/// An empty StringKey
static EMPTY: SyncLazy<StringKey> = SyncLazy::new(|| StringKey::new(""));
static EMPTY: OnceCell<StringKey> = OnceCell::uninit();
impl StringKey {
/// Calculates the hash of a string key in a const manner.
@@ -49,7 +51,7 @@ impl StringKey {
/// that value.
pub fn new(s: &str) -> Self {
let hash = StringKey::get_hash(s);
let mut cache = STRING_CACHE.lock().unwrap();
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() {
@@ -66,7 +68,7 @@ impl StringKey {
/// Gets the empty StringKey.
pub fn empty() -> Self {
EMPTY.clone()
EMPTY.get_or_init(|| StringKey::new("")).clone()
}
/// Gets the underlying string for the StringKey.
@@ -100,6 +102,12 @@ impl From<&str> for StringKey {
}
}
impl Equivalent<StringKey> for u32 {
fn equivalent(&self, key: &StringKey) -> bool {
*self == key.hash
}
}
impl Display for StringKey {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str(&*self.str)