Skip to content

Commit ee16b7c

Browse files
committed
Built-in types: implement more traits, make use of impl_builtin_traits macro
1 parent 8c91d89 commit ee16b7c

File tree

7 files changed

+103
-109
lines changed

7 files changed

+103
-109
lines changed

godot-core/src/builtin/macros.rs

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,16 @@
66

77
#![macro_use]
88

9-
macro_rules! impl_basic_trait_as_sys {
10-
( Drop for $Type:ty => $gd_method:ident ) => {
11-
impl Drop for $Type {
9+
macro_rules! impl_builtin_traits_inner {
10+
( Default for $Type:ty => $gd_method:ident ) => {
11+
impl Default for $Type {
1212
#[inline]
13-
fn drop(&mut self) {
14-
unsafe { (get_api().$gd_method)(self.sys_mut()) }
13+
fn default() -> Self {
14+
unsafe {
15+
let mut gd_val = sys::$GdType::default();
16+
(sys::method_table().$gd_method)(&mut gd_val);
17+
<$Type>::from_sys(gd_val)
18+
}
1519
}
1620
}
1721
};
@@ -21,22 +25,23 @@ macro_rules! impl_basic_trait_as_sys {
2125
#[inline]
2226
fn clone(&self) -> Self {
2327
unsafe {
24-
let mut result = sys::$GdType::default();
25-
(get_api().$gd_method)(&mut result, self.sys());
26-
<$Type>::from_sys(result)
28+
Self::from_sys_init(|self_ptr| {
29+
let ctor = sys::method_table().$gd_method;
30+
let args = [self.sys()];
31+
ctor(self_ptr, args.as_ptr());
32+
})
2733
}
2834
}
2935
}
3036
};
3137

32-
( Default for $Type:ty => $gd_method:ident ) => {
33-
impl Default for $Type {
38+
( Drop for $Type:ty => $gd_method:ident ) => {
39+
impl Drop for $Type {
3440
#[inline]
35-
fn default() -> Self {
41+
fn drop(&mut self) {
3642
unsafe {
37-
let mut gd_val = sys::$GdType::default();
38-
(get_api().$gd_method)(&mut gd_val);
39-
<$Type>::from_sys(gd_val)
43+
let destructor = sys::method_table().$gd_method;
44+
destructor(self.sys_mut());
4045
}
4146
}
4247
}
@@ -58,7 +63,7 @@ macro_rules! impl_basic_trait_as_sys {
5863
};
5964

6065
( Eq for $Type:ty => $gd_method:ident ) => {
61-
impl_basic_trait_as_sys!(PartialEq for $Type => $gd_method);
66+
impl_builtin_traits_inner!(PartialEq for $Type => $gd_method);
6267
impl Eq for $Type {}
6368
};
6469

@@ -86,7 +91,7 @@ macro_rules! impl_basic_trait_as_sys {
8691
};
8792

8893
( Ord for $Type:ty => $gd_method:ident ) => {
89-
impl_basic_trait_as_sys!(PartialOrd for $Type => $gd_method);
94+
impl_builtin_traits_inner!(PartialOrd for $Type => $gd_method);
9095
impl Ord for $Type {
9196
#[inline]
9297
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
@@ -96,16 +101,16 @@ macro_rules! impl_basic_trait_as_sys {
96101
};
97102
}
98103

99-
macro_rules! impl_traits_as_sys {
104+
macro_rules! impl_builtin_traits {
100105
(
101106
for $Type:ty {
102107
$( $Trait:ident => $gd_method:ident; )*
103108
}
104109
) => (
105110
$(
106-
impl_basic_trait_as_sys!(
111+
impl_builtin_traits_inner! {
107112
$Trait for $Type => $gd_method
108-
);
113+
}
109114
)*
110115
)
111116
}

godot-core/src/builtin/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ mod macros;
1010

1111
mod arrays;
1212
mod color;
13+
mod node_path;
1314
mod others;
1415
mod string;
1516
mod string_name;
@@ -22,6 +23,7 @@ pub mod meta;
2223

2324
pub use arrays::*;
2425
pub use color::*;
26+
pub use node_path::*;
2527
pub use others::*;
2628
pub use string::*;
2729
pub use string_name::*;

godot-core/src/builtin/node_path.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
use crate::builtin::GodotString;
2+
use godot_ffi as sys;
3+
use godot_ffi::{ffi_methods, GodotFfi};
4+
use std::fmt::{Display, Formatter, Result as FmtResult};
5+
6+
pub struct NodePath {
7+
opaque: sys::types::OpaqueNodePath,
8+
}
9+
10+
impl NodePath {
11+
fn from_opaque(opaque: sys::types::OpaqueNodePath) -> Self {
12+
Self { opaque }
13+
}
14+
}
15+
16+
impl GodotFfi for NodePath {
17+
ffi_methods! { type sys::GDNativeTypePtr = *mut Opaque; .. }
18+
}
19+
20+
impl From<&GodotString> for NodePath {
21+
fn from(path: &GodotString) -> Self {
22+
unsafe {
23+
Self::from_sys_init(|self_ptr| {
24+
let ctor = sys::method_table().node_path_from_string;
25+
let args = [path.sys()];
26+
ctor(self_ptr, args.as_ptr());
27+
})
28+
}
29+
}
30+
}
31+
32+
impl From<&NodePath> for GodotString {
33+
fn from(path: &NodePath) -> Self {
34+
unsafe {
35+
Self::from_sys_init(|self_ptr| {
36+
let ctor = sys::method_table().string_from_node_path;
37+
let args = [path.sys()];
38+
ctor(self_ptr, args.as_ptr());
39+
})
40+
}
41+
}
42+
}
43+
44+
impl From<&str> for NodePath {
45+
fn from(path: &str) -> Self {
46+
Self::from(&GodotString::from(path))
47+
}
48+
}
49+
50+
impl Display for NodePath {
51+
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
52+
let string = GodotString::from(self);
53+
<GodotString as Display>::fmt(&string, f)
54+
}
55+
}
56+
57+
impl_builtin_traits! {
58+
for NodePath {
59+
Clone => node_path_construct_copy;
60+
Drop => node_path_destroy;
61+
}
62+
}

godot-core/src/builtin/others.rs

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,9 @@
44
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
55
*/
66

7-
use std::fmt::{Display, Formatter, Result as FmtResult};
8-
97
// Stub for various other built-in classes, which are currently incomplete, but whose types
108
// are required for codegen
11-
use crate::builtin::{GodotString, StringName, Vector2};
9+
use crate::builtin::{StringName, Vector2};
1210
use crate::obj::{Gd, GodotClass};
1311
use godot_ffi as sys;
1412
use sys::{ffi_methods, GodotFfi};
@@ -24,7 +22,6 @@ impl_builtin_stub!(Basis, OpaqueBasis);
2422
impl_builtin_stub!(Transform2D, OpaqueTransform2D);
2523
impl_builtin_stub!(Transform3D, OpaqueTransform3D);
2624
impl_builtin_stub!(Projection, OpaqueProjection);
27-
impl_builtin_stub!(NodePath, OpaqueNodePath);
2825
impl_builtin_stub!(RID, OpaqueRID);
2926
impl_builtin_stub!(Callable, OpaqueCallable);
3027
impl_builtin_stub!(Signal, OpaqueSignal);
@@ -46,43 +43,6 @@ impl Rect2 {
4643
}
4744
}
4845

49-
impl From<&GodotString> for NodePath {
50-
fn from(path: &GodotString) -> Self {
51-
unsafe {
52-
Self::from_sys_init(|self_ptr| {
53-
let ctor = sys::method_table().node_path_from_string;
54-
let args = [path.sys()];
55-
ctor(self_ptr, args.as_ptr());
56-
})
57-
}
58-
}
59-
}
60-
61-
impl From<&NodePath> for GodotString {
62-
fn from(path: &NodePath) -> Self {
63-
unsafe {
64-
Self::from_sys_init(|self_ptr| {
65-
let ctor = sys::method_table().string_from_node_path;
66-
let args = [path.sys()];
67-
ctor(self_ptr, args.as_ptr());
68-
})
69-
}
70-
}
71-
}
72-
73-
impl From<&str> for NodePath {
74-
fn from(path: &str) -> Self {
75-
Self::from(&GodotString::from(path))
76-
}
77-
}
78-
79-
impl Display for NodePath {
80-
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
81-
let string = GodotString::from(self);
82-
<GodotString as Display>::fmt(&string, f)
83-
}
84-
}
85-
8646
impl Callable {
8747
pub fn from_object_method<T, S>(object: Gd<T>, method: S) -> Self
8848
where

godot-core/src/builtin/string.rs

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,12 @@ impl Default for GodotString {
6969
}
7070
}
7171

72-
impl Clone for GodotString {
73-
fn clone(&self) -> Self {
74-
unsafe {
75-
Self::from_sys_init(|self_ptr| {
76-
let ctor = sys::method_table().string_construct_copy;
77-
let args = [self.sys()];
78-
ctor(self_ptr, args.as_ptr());
79-
})
80-
}
72+
impl_builtin_traits! {
73+
for GodotString {
74+
Clone => string_construct_copy;
75+
Drop => string_destroy;
76+
Eq => string_operator_equal;
77+
Ord => string_operator_less;
8178
}
8279
}
8380

@@ -149,21 +146,6 @@ impl fmt::Debug for GodotString {
149146
}
150147
}
151148

152-
impl_traits_as_sys! {
153-
for GodotString {
154-
Eq => string_operator_equal;
155-
Ord => string_operator_less;
156-
}
157-
}
158-
159-
impl Drop for GodotString {
160-
fn drop(&mut self) {
161-
unsafe {
162-
let destructor = sys::method_table().string_destroy;
163-
destructor(self.sys_mut());
164-
}
165-
}
166-
}
167149

168150
// While this is a nice optimisation for ptrcalls, it's not easily possible
169151
// to pass in &GodotString when doing varcalls.

godot-core/src/builtin/string_name.rs

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -50,23 +50,12 @@ impl GodotFfi for StringName {
5050
}
5151
}
5252

53-
impl Drop for StringName {
54-
fn drop(&mut self) {
55-
unsafe {
56-
(sys::method_table().string_name_destroy)(self.sys());
57-
}
58-
}
59-
}
60-
61-
impl Clone for StringName {
62-
fn clone(&self) -> Self {
63-
unsafe {
64-
Self::from_sys_init(|self_ptr| {
65-
let ctor = sys::method_table().string_name_construct_copy;
66-
let args = [self.sys()];
67-
ctor(self_ptr, args.as_ptr());
68-
})
69-
}
53+
impl_builtin_traits! {
54+
for StringName {
55+
Clone => string_name_construct_copy;
56+
Drop => string_name_destroy;
57+
Eq => string_name_operator_equal;
58+
Ord => string_name_operator_less;
7059
}
7160
}
7261

@@ -104,13 +93,6 @@ impl Debug for StringName {
10493
}
10594
}
10695

107-
impl_traits_as_sys! {
108-
for StringName {
109-
Eq => string_name_operator_equal;
110-
Ord => string_name_operator_less;
111-
}
112-
}
113-
11496
impl Hash for StringName {
11597
fn hash<H: Hasher>(&self, state: &mut H) {
11698
// TODO use Godot hash via codegen

godot-core/src/engine.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,11 @@ pub trait NodeExt {
5858
T: GodotClass + Inherits<Node>,
5959
{
6060
let path = path.into();
61+
let copy = path.clone(); // TODO avoid copy
6162

6263
self.try_get_node_as(path).unwrap_or_else(|| {
6364
panic!(
64-
"There is no node of type {ty} path `{path}`",
65+
"There is no node of type {ty} path `{copy}`",
6566
ty = T::CLASS_NAME
6667
)
6768
})

0 commit comments

Comments
 (0)