Skip to content

Commit 2d2476a

Browse files
bors[bot]Waridley
andauthored
Merge #837
837: Allow `impl Into<NodePath>` for `NodeExt` methods and simplify impls r=Bromeon a=Waridley For reference, as discussed several months ago in Discord: > Part of the problem is that using `impl Into<NodePath>` means that you can no longer explicitly declare `T` with e.g. `owner.get_node_as::<Node>(path)`, because the compiler complains about `impl Trait` creating an implicit type parameter. But turning it into > ```rust > unsafe fn get_node_as<'a, T, P>(&self, path: P) -> Option<TRef<'a, T>> > where > T: SubClass<Node>, > P: Into<NodePath>; > ``` > Means you have to always either declare the type of the path argument, or use `get_node_as::<Node, _>(path)` Eventually I came up with the solution of putting the path generic parameter in the trait declaration rather than the methods, and haven't been able to come up with a significant drawback. Just today I realized there was little reason to have impls for both `&T` and `TRef` when all methods already take `&self` -- the compiler will auto-dereference `TRef`s, and this will also let it work with unique & thread-local `Ref`s. Co-authored-by: Waridley <[email protected]>
2 parents c1c1354 + c7e0517 commit 2d2476a

File tree

2 files changed

+7
-15
lines changed

2 files changed

+7
-15
lines changed

gdnative-bindings/src/utils.rs

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Utility functions and extension traits that depend on generated bindings
22
3+
use gdnative_core::core_types::NodePath;
34
use gdnative_core::export::NativeClass;
45
use gdnative_core::object::{SubClass, TInstance, TRef};
56

@@ -30,7 +31,7 @@ where
3031
.cast::<T>()
3132
}
3233

33-
pub trait NodeExt {
34+
pub trait NodeResolveExt<P: Into<NodePath>> {
3435
/// Convenience method to obtain a reference to a node at `path` relative to `self`,
3536
/// and cast it to the desired type. Returns `None` if the node does not exist or is
3637
/// not of the correct type.
@@ -42,7 +43,7 @@ pub trait NodeExt {
4243
/// invariants must be observed for the resulting node during `'a`, if any.
4344
///
4445
/// [thread-safety]: https://docs.godotengine.org/en/stable/tutorials/threads/thread_safe_apis.html
45-
unsafe fn get_node_as<'a, T>(&self, path: &str) -> Option<TRef<'a, T>>
46+
unsafe fn get_node_as<'a, T>(&self, path: P) -> Option<TRef<'a, T>>
4647
where
4748
T: SubClass<Node>;
4849

@@ -57,7 +58,7 @@ pub trait NodeExt {
5758
/// invariants must be observed for the resulting node during `'a`, if any.
5859
///
5960
/// [thread-safety]: https://docs.godotengine.org/en/stable/tutorials/threads/thread_safe_apis.html
60-
unsafe fn get_node_as_instance<'a, T>(&self, path: &str) -> Option<TInstance<'a, T>>
61+
unsafe fn get_node_as_instance<'a, T>(&self, path: P) -> Option<TInstance<'a, T>>
6162
where
6263
T: NativeClass,
6364
T::Base: SubClass<Node>,
@@ -66,20 +67,11 @@ pub trait NodeExt {
6667
}
6768
}
6869

69-
impl<'n, N: SubClass<Node>> NodeExt for &'n N {
70-
unsafe fn get_node_as<'a, T>(&self, path: &str) -> Option<TRef<'a, T>>
70+
impl<N: SubClass<Node>, P: Into<NodePath>> NodeResolveExt<P> for N {
71+
unsafe fn get_node_as<'a, T>(&self, path: P) -> Option<TRef<'a, T>>
7172
where
7273
T: SubClass<Node>,
7374
{
7475
self.upcast().get_node(path)?.assume_safe().cast()
7576
}
7677
}
77-
78-
impl<'n, N: SubClass<Node>> NodeExt for TRef<'n, N> {
79-
unsafe fn get_node_as<'a, T>(&self, path: &str) -> Option<TRef<'a, T>>
80-
where
81-
T: SubClass<Node>,
82-
{
83-
self.as_ref().get_node_as(path)
84-
}
85-
}

test/src/test_as_arg.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use gdnative::derive::{methods, NativeClass};
2-
use gdnative::prelude::NodeExt;
2+
use gdnative::prelude::NodeResolveExt;
33
use gdnative::prelude::*;
44
use std::ops::Deref;
55

0 commit comments

Comments
 (0)