Skip to content

Commit 6a9fd81

Browse files
committed
Refactor meta-information types, fix more dangling pointers
1 parent 3e7647b commit 6a9fd81

File tree

13 files changed

+203
-159
lines changed

13 files changed

+203
-159
lines changed

godot-codegen/src/central_generator.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ fn make_sys_code(central_items: &CentralItems) -> String {
124124

125125
impl VariantType {
126126
#[doc(hidden)]
127-
pub fn from_ord(enumerator: crate::GDNativeVariantType) -> Self {
127+
pub fn from_sys(enumerator: crate::GDNativeVariantType) -> Self {
128128
// Annoying, but only stable alternative is transmute(), which dictates enum size
129129
match enumerator {
130130
0 => Self::Nil,
@@ -136,7 +136,7 @@ fn make_sys_code(central_items: &CentralItems) -> String {
136136
}
137137

138138
#[doc(hidden)]
139-
pub fn to_ord(self) -> crate::GDNativeVariantType {
139+
pub fn sys(self) -> crate::GDNativeVariantType {
140140
self as _
141141
}
142142
}
@@ -155,7 +155,7 @@ fn make_sys_code(central_items: &CentralItems) -> String {
155155

156156
impl VariantOperator {
157157
#[doc(hidden)]
158-
pub fn from_ord(enumerator: crate::GDNativeVariantOperator) -> Self {
158+
pub fn from_sys(enumerator: crate::GDNativeVariantOperator) -> Self {
159159
match enumerator {
160160
#(
161161
#variant_op_enumerators_ord => Self::#variant_op_enumerators_pascal,
@@ -165,7 +165,7 @@ fn make_sys_code(central_items: &CentralItems) -> String {
165165
}
166166

167167
#[doc(hidden)]
168-
pub fn to_ord(self) -> crate::GDNativeVariantOperator {
168+
pub fn sys(self) -> crate::GDNativeVariantOperator {
169169
self as _
170170
}
171171
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* This Source Code Form is subject to the terms of the Mozilla Public
3+
* License, v. 2.0. If a copy of the MPL was not distributed with this
4+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
5+
*/
6+
7+
use godot_ffi as sys;
8+
9+
use std::fmt::{Display, Formatter, Result as FmtResult};
10+
11+
use crate::builtin::*;
12+
use crate::obj::GodotClass;
13+
14+
/// Utility to construct class names known at compile time.
15+
/// Cannot be a function since the backing string must be retained.
16+
#[derive(Eq, PartialEq, Hash, Clone, Debug)]
17+
pub struct ClassName {
18+
backing: StringName,
19+
}
20+
21+
impl ClassName {
22+
pub fn new<T: GodotClass>() -> Self {
23+
Self {
24+
backing: StringName::from(T::CLASS_NAME),
25+
}
26+
}
27+
28+
pub fn from_static(string: &'static str) -> Self {
29+
Self {
30+
backing: StringName::from(string),
31+
}
32+
}
33+
34+
pub fn string_sys(&self) -> sys::GDNativeStringNamePtr {
35+
self.backing.string_sys()
36+
}
37+
38+
#[must_use]
39+
pub fn leak_string_name(self) -> sys::GDNativeStringNamePtr {
40+
self.backing.leak_string_sys()
41+
}
42+
}
43+
44+
impl Display for ClassName {
45+
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
46+
self.backing.fmt(f)
47+
}
48+
}

godot-core/src/builtin/meta/mod.rs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* This Source Code Form is subject to the terms of the Mozilla Public
3+
* License, v. 2.0. If a copy of the MPL was not distributed with this
4+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
5+
*/
6+
7+
mod class_name;
8+
mod signature;
9+
10+
pub use class_name::*;
11+
pub use signature::*;
12+
13+
use crate::builtin::*;
14+
use crate::engine::global;
15+
16+
use godot_ffi as sys;
17+
18+
/// Stores meta-information about registered types or properties.
19+
///
20+
/// Filling this information properly is important so that Godot can use ptrcalls instead of varcalls
21+
/// (requires typed GDScript + sufficient information from the extension side)
22+
pub trait VariantMetadata {
23+
fn variant_type() -> VariantType;
24+
25+
fn property_info(property_name: &str) -> PropertyInfo {
26+
PropertyInfo::new(
27+
Self::variant_type(),
28+
ClassName::new::<()>(), // FIXME Option or so
29+
StringName::from(property_name),
30+
)
31+
}
32+
33+
fn param_metadata() -> sys::GDNativeExtensionClassMethodArgumentMetadata {
34+
sys::GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE
35+
}
36+
}
37+
38+
// ----------------------------------------------------------------------------------------------------------------------------------------------
39+
40+
/// Rusty abstraction of sys::GDNativePropertyInfo
41+
/// Keeps the actual allocated values (the sys equivalent only keeps pointers, which fall out of scope)
42+
#[derive(Debug)]
43+
pub struct PropertyInfo {
44+
variant_type: VariantType,
45+
class_name: ClassName,
46+
property_name: StringName,
47+
hint: global::PropertyHint,
48+
hint_string: GodotString,
49+
usage: global::PropertyUsageFlags,
50+
}
51+
52+
impl PropertyInfo {
53+
pub fn new(
54+
variant_type: VariantType,
55+
class_name: ClassName,
56+
property_name: StringName,
57+
) -> Self {
58+
Self {
59+
variant_type,
60+
class_name,
61+
property_name,
62+
hint: global::PropertyHint::PROPERTY_HINT_NONE,
63+
hint_string: GodotString::new(),
64+
usage: global::PropertyUsageFlags::PROPERTY_USAGE_DEFAULT,
65+
}
66+
}
67+
68+
/// Converts to the FFI type. Keep this object allocated while using that!
69+
pub fn sys(&self) -> sys::GDNativePropertyInfo {
70+
use crate::obj::EngineEnum as _;
71+
72+
sys::GDNativePropertyInfo {
73+
type_: self.variant_type.sys(),
74+
name: self.property_name.string_sys(),
75+
class_name: self.class_name.string_sys(),
76+
hint: u32::try_from(self.hint.ord()).expect("hint.ord()"),
77+
hint_string: self.hint_string.string_sys(),
78+
usage: u32::try_from(self.usage.ord()).expect("usage.ord()"),
79+
}
80+
}
81+
}

godot-core/src/builtin/variant/variant_metadata.rs renamed to godot-core/src/builtin/meta/signature.rs

Lines changed: 7 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -5,38 +5,16 @@
55
*/
66

77
use godot_ffi as sys;
8+
use godot_ffi::VariantType;
89
use std::fmt::Debug;
910

10-
pub trait VariantMetadata {
11-
fn variant_type() -> sys::GDNativeVariantType;
12-
13-
fn property_info(property_name: &str) -> sys::GDNativePropertyInfo {
14-
let property_name = StringName::from(property_name);
15-
16-
sys::GDNativePropertyInfo {
17-
type_: Self::variant_type(),
18-
name: property_name.leak_string_sys(),
19-
class_name: std::ptr::null_mut(),
20-
hint: 0,
21-
hint_string: std::ptr::null_mut(),
22-
usage: 7, // Default, TODO generate global enums
23-
}
24-
}
25-
26-
fn param_metadata() -> sys::GDNativeExtensionClassMethodArgumentMetadata {
27-
sys::GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE
28-
}
29-
}
30-
31-
// ----------------------------------------------------------------------------------------------------------------------------------------------
32-
3311
pub trait SignatureTuple {
3412
type Params;
3513
type Ret;
3614

37-
fn variant_type(index: i32) -> sys::GDNativeVariantType;
15+
fn variant_type(index: i32) -> VariantType;
16+
fn property_info(index: i32, param_name: &str) -> PropertyInfo;
3817
fn param_metadata(index: i32) -> sys::GDNativeExtensionClassMethodArgumentMetadata;
39-
fn property_info(index: i32, param_name: &str) -> sys::GDNativePropertyInfo;
4018

4119
fn varcall<C: GodotClass>(
4220
instance_ptr: sys::GDExtensionClassInstancePtr,
@@ -74,7 +52,8 @@ pub trait SignatureTuple {
7452
// }
7553
// }
7654
//
77-
use crate::builtin::{FromVariant, StringName, ToVariant, Variant};
55+
use crate::builtin::meta::*;
56+
use crate::builtin::{FromVariant, ToVariant, Variant};
7857
use crate::obj::GodotClass;
7958

8059
macro_rules! impl_signature_for_tuple {
@@ -91,7 +70,7 @@ macro_rules! impl_signature_for_tuple {
9170
type Ret = $R;
9271

9372
#[inline]
94-
fn variant_type(index: i32) -> sys::GDNativeVariantType {
73+
fn variant_type(index: i32) -> sys::VariantType {
9574
match index {
9675
-1 => $R::variant_type(),
9776
$(
@@ -114,7 +93,7 @@ macro_rules! impl_signature_for_tuple {
11493
}
11594

11695
#[inline]
117-
fn property_info(index: i32, param_name: &str) -> sys::GDNativePropertyInfo {
96+
fn property_info(index: i32, param_name: &str) -> PropertyInfo {
11897
match index {
11998
-1 => $R::property_info(param_name),
12099
$(
@@ -208,34 +187,3 @@ impl_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5, P6: 6);
208187
impl_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5, P6: 6, P7: 7);
209188
impl_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5, P6: 6, P7: 7, P8: 8);
210189
impl_signature_for_tuple!(R, P0: 0, P1: 1, P2: 2, P3: 3, P4: 4, P5: 5, P6: 6, P7: 7, P8: 8, P9: 9);
211-
212-
// Re-exported to crate::private
213-
#[doc(hidden)]
214-
pub mod func_callbacks {
215-
use super::*;
216-
217-
pub extern "C" fn get_type<S: SignatureTuple>(
218-
_method_data: *mut std::ffi::c_void,
219-
n: i32,
220-
) -> sys::GDNativeVariantType {
221-
S::variant_type(n)
222-
}
223-
224-
pub extern "C" fn get_info<S: SignatureTuple>(
225-
_method_data: *mut std::ffi::c_void,
226-
n: i32,
227-
ret: *mut sys::GDNativePropertyInfo,
228-
) {
229-
// Return value is the first "argument"
230-
let info = S::property_info(n, "TODO");
231-
unsafe { *ret = info };
232-
}
233-
234-
pub extern "C" fn get_metadata<S: SignatureTuple>(
235-
_method_data: *mut std::ffi::c_void,
236-
n: i32,
237-
) -> sys::GDNativeExtensionClassMethodArgumentMetadata {
238-
// Return value is the first "argument"
239-
S::param_metadata(n)
240-
}
241-
}

godot-core/src/builtin/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ mod vector2;
1818
mod vector3;
1919
mod vector4;
2020

21+
pub mod meta;
22+
2123
pub use arrays::*;
2224
pub use color::*;
2325
pub use others::*;

godot-core/src/builtin/string_name.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ impl StringName {
4343

4444
let boks = Box::new(self.clone());
4545
let ptr = boks.string_sys();
46-
println!("Cloned: '{}' -> '{}'", self,&*boks);
46+
println!("Cloned: '{}' -> '{}'", self, &*boks);
4747
Box::leak(boks);
4848

4949
ptr

godot-core/src/builtin/variant/impls.rs

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
use super::*;
8+
use crate::builtin::meta::VariantMetadata;
89
use crate::builtin::*;
910
use godot_ffi as sys;
1011
use sys::GodotFfi;
@@ -59,8 +60,8 @@ macro_rules! impl_variant_traits {
5960
}
6061

6162
impl VariantMetadata for $T {
62-
fn variant_type() -> sys::GDNativeVariantType {
63-
sys::$variant_type
63+
fn variant_type() -> VariantType {
64+
VariantType::$variant_type
6465
}
6566

6667
$($extra)*
@@ -84,8 +85,8 @@ macro_rules! impl_variant_traits_int {
8485
}
8586

8687
impl VariantMetadata for $T {
87-
fn variant_type() -> sys::GDNativeVariantType {
88-
sys::GDNATIVE_VARIANT_TYPE_INT
88+
fn variant_type() -> VariantType {
89+
VariantType::Int
8990
}
9091

9192
fn param_metadata() -> sys::GDNativeExtensionClassMethodArgumentMetadata {
@@ -111,8 +112,8 @@ macro_rules! impl_variant_traits_float {
111112
}
112113

113114
impl VariantMetadata for $T {
114-
fn variant_type() -> sys::GDNativeVariantType {
115-
sys::GDNATIVE_VARIANT_TYPE_FLOAT
115+
fn variant_type() -> VariantType {
116+
VariantType::Float
116117
}
117118

118119
fn param_metadata() -> sys::GDNativeExtensionClassMethodArgumentMetadata {
@@ -129,30 +130,28 @@ macro_rules! impl_variant_traits_float {
129130
mod impls {
130131
use super::*;
131132

132-
impl_variant_traits!(bool, bool_to_variant, bool_from_variant, GDNATIVE_VARIANT_TYPE_BOOL);
133-
impl_variant_traits!(Vector2, vector2_to_variant, vector2_from_variant, GDNATIVE_VARIANT_TYPE_VECTOR2);
134-
impl_variant_traits!(Vector3, vector3_to_variant, vector3_from_variant, GDNATIVE_VARIANT_TYPE_VECTOR3);
135-
impl_variant_traits!(Vector4, vector4_to_variant, vector4_from_variant, GDNATIVE_VARIANT_TYPE_VECTOR4);
136-
impl_variant_traits!(Vector2i, vector2i_to_variant, vector2i_from_variant, GDNATIVE_VARIANT_TYPE_VECTOR2I);
137-
impl_variant_traits!(Vector3i, vector3i_to_variant, vector3i_from_variant, GDNATIVE_VARIANT_TYPE_VECTOR3I);
138-
impl_variant_traits!(Color, color_to_variant, color_from_variant, GDNATIVE_VARIANT_TYPE_COLOR);
139-
impl_variant_traits!(GodotString, string_to_variant, string_from_variant, GDNATIVE_VARIANT_TYPE_STRING);
140-
impl_variant_traits!(StringName, string_name_to_variant, string_name_from_variant, GDNATIVE_VARIANT_TYPE_STRING_NAME);
133+
impl_variant_traits!(bool, bool_to_variant, bool_from_variant, Bool);
134+
impl_variant_traits!(Vector2, vector2_to_variant, vector2_from_variant, Vector2);
135+
impl_variant_traits!(Vector3, vector3_to_variant, vector3_from_variant, Vector3);
136+
impl_variant_traits!(Vector4, vector4_to_variant, vector4_from_variant, Vector4);
137+
impl_variant_traits!(Vector2i, vector2i_to_variant, vector2i_from_variant, Vector2i);
138+
impl_variant_traits!(Vector3i, vector3i_to_variant, vector3i_from_variant, Vector3i);
139+
impl_variant_traits!(Color, color_to_variant, color_from_variant, Color);
140+
impl_variant_traits!(GodotString, string_to_variant, string_from_variant, String);
141+
impl_variant_traits!(StringName, string_name_to_variant, string_name_from_variant, StringName);
141142

142143

143-
impl_variant_traits!(i64, int_to_variant, int_from_variant, GDNATIVE_VARIANT_TYPE_INT,
144-
GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT64);
144+
impl_variant_traits!(i64, int_to_variant, int_from_variant, Int, GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT64);
145145
impl_variant_traits_int!(i8, GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT8);
146146
impl_variant_traits_int!(i16, GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT16);
147147
impl_variant_traits_int!(i32, GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT32);
148148

149149
impl_variant_traits_int!(u8, GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_UINT8);
150150
impl_variant_traits_int!(u16, GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_UINT16);
151151
impl_variant_traits_int!(u32, GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_UINT32);
152-
// u64 is not supported, because it cannot be represented on GDScript side, and converting to i64 is error-prone.
152+
// u64 is not supported, because it cannot be represented on GDScript side, and implicitly converting to i64 is error-prone.
153153

154-
impl_variant_traits!(f64, float_to_variant, float_from_variant, GDNATIVE_VARIANT_TYPE_FLOAT,
155-
GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_REAL_IS_DOUBLE);
154+
impl_variant_traits!(f64, float_to_variant, float_from_variant, Float, GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_REAL_IS_DOUBLE);
156155
impl_variant_traits_float!(f32, GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_REAL_IS_FLOAT);
157156
}
158157

@@ -167,8 +166,8 @@ impl ToVariant for () {
167166
}
168167

169168
impl VariantMetadata for () {
170-
fn variant_type() -> sys::GDNativeVariantType {
171-
sys::GDNATIVE_VARIANT_TYPE_NIL
169+
fn variant_type() -> VariantType {
170+
VariantType::Nil
172171
}
173172
}
174173

@@ -186,7 +185,7 @@ impl FromVariant for Variant {
186185

187186
// Variant itself
188187
impl VariantMetadata for Variant {
189-
fn variant_type() -> sys::GDNativeVariantType {
190-
sys::GDNATIVE_VARIANT_TYPE_NIL
188+
fn variant_type() -> VariantType {
189+
VariantType::Nil // FIXME is this correct? what else to use? is this called at all?
191190
}
192191
}

0 commit comments

Comments
 (0)