Skip to content

Commit e5a27e0

Browse files
authored
Merge pull request #1141 from DominikMendel/master
Clarify `Node::duplicate()` semantics on `#[var]` and `#[export]` fields
2 parents 4a78a24 + edfdc61 commit e5a27e0

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

itest/rust/src/object_tests/property_template_test.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ fn property_template_test(ctx: &TestContext) {
107107
"mismatch in property {name}:\n GDScript: {gdscript_prop:?}\n Rust: {rust_prop:?}"
108108
));
109109
}
110+
/*else { // Keep around for debugging.
111+
println!(
112+
"good property {name}:\n GDScript: {gdscript_prop:?}\n Rust: {rust_prop:?}"
113+
);
114+
}*/
110115
}
111116

112117
rust_properties.free();

itest/rust/src/object_tests/property_test.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -537,3 +537,61 @@ fn test_var_with_renamed_funcs() {
537537

538538
obj.free();
539539
}
540+
541+
// ----------------------------------------------------------------------------------------------------------------------------------------------
542+
543+
#[derive(GodotClass)]
544+
#[class(init, base=Node)]
545+
struct Duplicator {
546+
// #[export] would also make tests pass, but #[export(storage)] additionally hides the properties from the editor.
547+
// See https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_exports.html#export-storage.
548+
#[export(storage)]
549+
int_export: i32,
550+
551+
// Low-level #[var] should also work.
552+
#[var(usage_flags = [STORAGE])]
553+
int_var: i32,
554+
555+
// Not copied because not marked as serialize ("storage").
556+
#[var]
557+
int_ignored: i32,
558+
559+
#[export(storage)]
560+
optional_node: Option<Gd<Node>>,
561+
562+
#[export(storage)]
563+
oneditor_node: OnEditor<Gd<Node>>,
564+
}
565+
566+
#[itest]
567+
fn test_duplicate_retains_properties() {
568+
let optional_node = Node::new_alloc();
569+
let oneditor_node = Node::new_alloc();
570+
571+
// Set up original node.
572+
let mut original = Duplicator::new_alloc();
573+
{
574+
let mut original = original.bind_mut();
575+
original.int_export = 5;
576+
original.int_var = 7;
577+
original.int_ignored = 9; // Will not be copied.
578+
original.optional_node = Some(optional_node.clone());
579+
original.oneditor_node.init(oneditor_node.clone());
580+
}
581+
582+
// Create duplicate and verify all properties are copied correctly.
583+
let duplicated: Gd<Duplicator> = original.duplicate().unwrap().cast();
584+
{
585+
let duplicated = duplicated.bind();
586+
assert_eq!(duplicated.int_export, 5);
587+
assert_eq!(duplicated.int_var, 7);
588+
assert_eq!(duplicated.int_ignored, 0); // Not copied.
589+
assert_eq!(duplicated.optional_node.as_ref().unwrap(), &optional_node);
590+
assert_eq!(&*duplicated.oneditor_node, &oneditor_node);
591+
}
592+
593+
optional_node.free();
594+
oneditor_node.free();
595+
duplicated.free();
596+
original.free();
597+
}

0 commit comments

Comments
 (0)