Skip to content

Commit

Permalink
Merge pull request #962 from 0x53A/dev-test-godot_dyn
Browse files Browse the repository at this point in the history
Fix `#[godot_dyn]` causing error when implemented for two traits
  • Loading branch information
Bromeon authored Dec 6, 2024
2 parents 735d88f + c4fd83d commit 032af6e
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 6 deletions.
5 changes: 4 additions & 1 deletion godot-core/src/registry/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,10 @@ impl ClassRegistrationInfo {
PluginItem::Struct { .. } => 0,
PluginItem::InherentImpl(_) => 1,
PluginItem::ITraitImpl { .. } => 2,
PluginItem::DynTraitImpl { .. } => 3,

// Multiple dyn traits can be registered, thus don't validate for uniqueness.
// (Still keep array size, so future additions don't have to regard this).
PluginItem::DynTraitImpl { .. } => return,
};

if self.component_already_filled[index] {
Expand Down
37 changes: 32 additions & 5 deletions itest/rust/src/object_tests/dyn_gd_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ fn dyn_gd_hash() {

#[itest]
fn dyn_gd_exclusive_guard() {
let mut a = foreign::NodeHealth::new_alloc().into_dyn();
let mut a = foreign::NodeHealth::new_alloc().into_dyn::<dyn Health>();
let mut b = a.clone();

let guard = a.dyn_bind_mut();
Expand All @@ -187,7 +187,7 @@ fn dyn_gd_exclusive_guard() {

#[itest]
fn dyn_gd_shared_guard() {
let a = foreign::NodeHealth::new_alloc().into_dyn();
let a = foreign::NodeHealth::new_alloc().into_dyn::<dyn Health>();
let b = a.clone();
let mut c = a.clone();

Expand Down Expand Up @@ -227,7 +227,7 @@ fn dyn_gd_downgrade() {

#[itest]
fn dyn_gd_call_godot_method() {
let mut node = foreign::NodeHealth::new_alloc().into_dyn();
let mut node = foreign::NodeHealth::new_alloc().into_dyn::<dyn Health>();

node.set_name("dyn-name!");
assert_eq!(node.get_name(), "dyn-name!".into());
Expand All @@ -237,7 +237,7 @@ fn dyn_gd_call_godot_method() {

#[itest]
fn dyn_gd_pass_to_godot_api() {
let child = foreign::NodeHealth::new_alloc().into_dyn();
let child = foreign::NodeHealth::new_alloc().into_dyn::<dyn Health>();

let mut parent = Node::new_alloc();
parent.add_child(&child);
Expand Down Expand Up @@ -331,7 +331,7 @@ fn dyn_gd_error_unimplemented_trait() {

#[itest]
fn dyn_gd_free_while_dyn_bound() {
let mut obj = foreign::NodeHealth::new_alloc().into_dyn();
let mut obj: DynGd<_, dyn Health> = foreign::NodeHealth::new_alloc().into_dyn();

{
let copy = obj.clone();
Expand All @@ -354,6 +354,18 @@ fn dyn_gd_free_while_dyn_bound() {
obj.free();
}

#[itest]
fn dyn_gd_multiple_traits() {
let obj = foreign::NodeHealth::new_alloc();
let original_id = obj.instance_id();

let obj = obj.into_dyn::<dyn InstanceIdProvider>().upcast::<Node>();
let id = obj.dyn_bind().get_id_dynamic();
assert_eq!(id, original_id);

obj.free();
}

// ----------------------------------------------------------------------------------------------------------------------------------------------
// Example symbols

Expand Down Expand Up @@ -418,3 +430,18 @@ impl Health for foreign::NodeHealth {
self.base_mut().set_meta("hp", &new_hp.to_variant());
}
}

// ----------------------------------------------------------------------------------------------------------------------------------------------
// Check that one class can implement two or more traits.

// Pointless trait, but tests access to object.
trait InstanceIdProvider {
fn get_id_dynamic(&self) -> InstanceId;
}

#[godot_dyn]
impl InstanceIdProvider for foreign::NodeHealth {
fn get_id_dynamic(&self) -> InstanceId {
self.base().instance_id()
}
}

0 comments on commit 032af6e

Please sign in to comment.