Skip to content

Commit 05d23bc

Browse files
authored
ClassId must be cached (#81)
`ClassId::__alloc_next_unicode` cannot be called multiple times with the same class name.
1 parent 3ada98d commit 05d23bc

File tree

1 file changed

+29
-4
lines changed

1 file changed

+29
-4
lines changed

rust-script/src/static_script_registry.rs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
*/
66

77
use std::borrow::Cow;
8-
use std::collections::BTreeMap;
8+
use std::collections::{BTreeMap, HashMap};
99
use std::fmt::Debug;
10-
use std::sync::Arc;
10+
use std::sync::{Arc, LazyLock, RwLock};
1111

1212
use godot::builtin::{GString, StringName};
1313
use godot::global::{MethodFlags, PropertyHint, PropertyUsageFlags};
@@ -265,7 +265,7 @@ impl From<&RustScriptMethodInfo> for MethodInfo {
265265
Self {
266266
id: value.id,
267267
method_name: value.method_name.into(),
268-
class_name: ClassId::__alloc_next_unicode(value.class_name),
268+
class_name: get_class_id(value.class_name),
269269
return_type: (&value.return_type).into(),
270270
arguments: value.arguments.iter().map(|arg| arg.into()).collect(),
271271
default_arguments: vec![],
@@ -326,7 +326,7 @@ impl RustScriptMetaData {
326326
description: &'static str,
327327
) -> Self {
328328
Self {
329-
class_name: ClassId::__alloc_next_unicode(class_name),
329+
class_name: get_class_id(class_name),
330330

331331
base_type_name,
332332
properties,
@@ -381,10 +381,27 @@ where
381381
}
382382
}
383383

384+
fn get_class_id(class_name: &'static str) -> ClassId {
385+
static SCRIPT_CLASS_NAMES: LazyLock<RwLock<HashMap<&'static str, ClassId>>> =
386+
LazyLock::new(|| RwLock::new(HashMap::new()));
387+
388+
if let Some(class_id) = SCRIPT_CLASS_NAMES.read().unwrap().get(class_name) {
389+
return *class_id;
390+
}
391+
392+
*SCRIPT_CLASS_NAMES
393+
.write()
394+
.unwrap()
395+
.entry(class_name)
396+
.or_insert_with(|| ClassId::__alloc_next_unicode(class_name))
397+
}
398+
384399
#[cfg(test)]
385400
mod tests {
386401
use godot::meta::ClassId;
387402

403+
use crate::static_script_registry::get_class_id;
404+
388405
#[test]
389406
fn new_class_name() {
390407
let script_name = ClassId::__alloc_next_unicode("TestScript");
@@ -399,4 +416,12 @@ mod tests {
399416

400417
assert_eq!(script_name.to_cow_str(), "ÜbertragungsScript");
401418
}
419+
420+
#[test]
421+
fn cached_class_id() {
422+
let script_name_a = get_class_id("CachedTestScript");
423+
let script_name_b = get_class_id("CachedTestScript");
424+
425+
assert_eq!(script_name_a, script_name_b);
426+
}
402427
}

0 commit comments

Comments
 (0)