From d46b8653d96a7e405bd12fa54cc9c51c4946b7a0 Mon Sep 17 00:00:00 2001 From: Yarvin Date: Mon, 6 Jan 2025 11:59:13 +0100 Subject: [PATCH] - Derive Var and Export for DynGd --- godot-core/src/obj/dyn_gd.rs | 27 +++++++++++++++++++++- itest/godot/ManualFfiTests.gd | 19 +++++++++++++++ itest/rust/src/object_tests/dyn_gd_test.rs | 22 ++++++++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/godot-core/src/obj/dyn_gd.rs b/godot-core/src/obj/dyn_gd.rs index 96611ea76..db869a06b 100644 --- a/godot-core/src/obj/dyn_gd.rs +++ b/godot-core/src/obj/dyn_gd.rs @@ -7,10 +7,11 @@ use crate::builtin::Variant; use crate::meta::error::ConvertError; -use crate::meta::{FromGodot, GodotConvert, ToGodot}; +use crate::meta::{ClassName, FromGodot, GodotConvert, ToGodot}; use crate::obj::guards::DynGdRef; use crate::obj::{bounds, AsDyn, Bounds, DynGdMut, Gd, GodotClass, Inherits}; use crate::registry::class::try_dynify_object; +use crate::registry::property::{Export, Var}; use crate::{meta, sys}; use std::{fmt, ops}; @@ -478,3 +479,27 @@ where D: ?Sized + 'static, { } + +impl Var for DynGd +where + T: GodotClass, + D: ?Sized + 'static, +{ + fn get_property(&self) -> Self::Via { + self.to_godot() + } + + fn set_property(&mut self, value: Self::Via) { + *self = FromGodot::from_godot(value); + } +} + +impl Export for DynGd +where + T: GodotClass, + D: ?Sized + 'static, +{ + fn as_node_class() -> Option { + Some(T::class_name()) + } +} diff --git a/itest/godot/ManualFfiTests.gd b/itest/godot/ManualFfiTests.gd index 8eeaa9c95..bc71b71e2 100644 --- a/itest/godot/ManualFfiTests.gd +++ b/itest/godot/ManualFfiTests.gd @@ -68,6 +68,25 @@ func test_export(): obj.free() node.free() +func test_export_dyn_gd(): + var dyn_gd_exporter = DynGdExporter.new() + # Nodehealth is valid candidate both for `empty` and `second` fields. + var node = NodeHealth.new() + dyn_gd_exporter.first = node + assert_eq(dyn_gd_exporter.first, node) + dyn_gd_exporter.second = node + assert_eq(dyn_gd_exporter.second, node) + + # RefcHealth is valid candidate for `first` field + var refc = RefcHealth.new() + dyn_gd_exporter.first = refc + assert_eq(dyn_gd_exporter.first, refc) + disable_error_messages() + dyn_gd_exporter.second = refc # Should fail. + enable_error_messages() + assert_fail("DynGdExporter.second should only accept NodeHealth if it implements InstanceIdProvider trait") + + class MockObjGd extends Object: var i: int = 0 diff --git a/itest/rust/src/object_tests/dyn_gd_test.rs b/itest/rust/src/object_tests/dyn_gd_test.rs index 72394acfb..89f4cb004 100644 --- a/itest/rust/src/object_tests/dyn_gd_test.rs +++ b/itest/rust/src/object_tests/dyn_gd_test.rs @@ -445,3 +445,25 @@ impl InstanceIdProvider for foreign::NodeHealth { self.base().instance_id() } } + +// ---------------------------------------------------------------------------------------------------------------------------------------------- +// Check if DynGd can be properly exported + +#[derive(GodotClass)] +#[class(base=Node)] +struct DynGdExporter { + #[export] + first: Option>, + #[export] + second: Option>, +} + +#[godot_api] +impl INode for DynGdExporter { + fn init(_base: Base) -> Self { + Self { + first: None, + second: None, + } + } +}