Skip to content

Commit

Permalink
- Derive Var and Export for DynGd<T, D>
Browse files Browse the repository at this point in the history
  • Loading branch information
Yarwin committed Jan 6, 2025
1 parent b619959 commit d46b865
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 1 deletion.
27 changes: 26 additions & 1 deletion godot-core/src/obj/dyn_gd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -478,3 +479,27 @@ where
D: ?Sized + 'static,
{
}

impl<T, D> Var for DynGd<T, D>
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<T, D> Export for DynGd<T, D>
where
T: GodotClass,
D: ?Sized + 'static,
{
fn as_node_class() -> Option<ClassName> {
Some(T::class_name())
}
}
19 changes: 19 additions & 0 deletions itest/godot/ManualFfiTests.gd
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
22 changes: 22 additions & 0 deletions itest/rust/src/object_tests/dyn_gd_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<DynGd<Object, dyn Health>>,
#[export]
second: Option<DynGd<foreign::NodeHealth, dyn InstanceIdProvider>>,
}

#[godot_api]
impl INode for DynGdExporter {
fn init(_base: Base<Node>) -> Self {
Self {
first: None,
second: None,
}
}
}

0 comments on commit d46b865

Please sign in to comment.