Skip to content

Commit 1c19ad0

Browse files
committed
Ensure only types that need to be initialized are initialized, but not types that leak when initialized.
1 parent 4b1d208 commit 1c19ad0

File tree

3 files changed

+56
-22
lines changed

3 files changed

+56
-22
lines changed

godot-codegen/src/central_generator.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,15 @@ fn make_build_config(header: &Header) -> TokenStream {
272272
String::from_utf8_lossy(c_str.to_bytes()).to_string()
273273
}
274274
}
275+
276+
/// Version of the Godot engine which loaded gdext via GDExtension binding, as
277+
/// `(major, minor, patch)` triple.
278+
pub fn godot_runtime_version_triple() -> (u8, u8, u8) {
279+
let version = unsafe {
280+
crate::runtime_metadata().godot_version
281+
};
282+
(version.major as u8, version.minor as u8, version.patch as u8)
283+
}
275284
}
276285
}
277286
}

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

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,38 @@ macro_rules! impl_variant_metadata {
2626
}
2727
};
2828
}
29-
29+
// Certain types need to be passed as initialized pointers in their from_variant implementations in 4.0. Because
30+
// 4.0 uses `*ptr = value` to return the type, and some types in c++ override `operator=` in c++ in a way
31+
// that requires the pointer the be initialized. But some other types will cause a memory leak in 4.1 if
32+
// initialized.
33+
//
34+
// Thus we can use `init` to indicate when it must be initialized in 4.0.
3035
macro_rules! impl_variant_traits {
3136
($T:ty, $from_fn:ident, $to_fn:ident, $variant_type:ident) => {
3237
impl_variant_traits!(@@ $T, $from_fn, $to_fn, $variant_type;);
3338
};
3439

35-
($T:ty, $from_fn:ident, $to_fn:ident, $variant_type:ident, $param_metadata:ident) => {
40+
($T:ty, $from_fn:ident, $to_fn:ident, $variant_type:ident, init) => {
41+
impl_variant_traits!(@@ $T, $from_fn, $to_fn, $variant_type, init;);
42+
};
43+
44+
($T:ty, $from_fn:ident, $to_fn:ident, $variant_type:ident, metadata = $param_metadata:ident) => {
3645
impl_variant_traits!(@@ $T, $from_fn, $to_fn, $variant_type;
3746
fn param_metadata() -> sys::GDExtensionClassMethodArgumentMetadata {
3847
sys::$param_metadata
3948
}
4049
);
4150
};
4251

43-
(@@ $T:ty, $from_fn:ident, $to_fn:ident, $variant_type:ident; $($extra:tt)*) => {
52+
($T:ty, $from_fn:ident, $to_fn:ident, $variant_type:ident, init, metadata = $param_metadata:ident) => {
53+
impl_variant_traits!(@@ $T, $from_fn, $to_fn, $variant_type, init;
54+
fn param_metadata() -> sys::GDExtensionClassMethodArgumentMetadata {
55+
sys::$param_metadata
56+
}
57+
);
58+
};
59+
60+
(@@ $T:ty, $from_fn:ident, $to_fn:ident, $variant_type:ident $(, $init:ident)?; $($extra:tt)*) => {
4461
impl ToVariant for $T {
4562
fn to_variant(&self) -> Variant {
4663
let variant = unsafe {
@@ -70,10 +87,7 @@ macro_rules! impl_variant_traits {
7087
//
7188
// This was changed in 4.1.
7289
let result = unsafe {
73-
#[cfg(gdextension_api = "4.0")]
74-
let from_sys_init = Self::from_sys_init_default;
75-
#[cfg(not(gdextension_api = "4.0"))]
76-
let from_sys_init = Self::from_sys_init;
90+
impl_variant_traits!(@@from_sys_init, from_sys_init $(, $init)?);
7791

7892
from_sys_init(|self_ptr| {
7993
let converter = sys::builtin_fn!($to_fn);
@@ -87,6 +101,17 @@ macro_rules! impl_variant_traits {
87101

88102
impl_variant_metadata!($T, $variant_type; $($extra)*);
89103
};
104+
105+
(@@from_sys_init, $from_sys_init:ident, init) => {
106+
#[cfg(gdextension_api = "4.0")]
107+
let $from_sys_init = Self::from_sys_init_default;
108+
#[cfg(not(gdextension_api = "4.0"))]
109+
let $from_sys_init = Self::from_sys_init;
110+
};
111+
112+
(@@from_sys_init, $from_sys_init:ident) => {
113+
let $from_sys_init = Self::from_sys_init;
114+
};
90115
}
91116

92117
macro_rules! impl_variant_traits_int {
@@ -154,28 +179,28 @@ mod impls {
154179
impl_variant_traits!(Aabb, aabb_to_variant, aabb_from_variant, Aabb);
155180
impl_variant_traits!(bool, bool_to_variant, bool_from_variant, Bool);
156181
impl_variant_traits!(Basis, basis_to_variant, basis_from_variant, Basis);
157-
impl_variant_traits!(Callable, callable_to_variant, callable_from_variant, Callable);
182+
impl_variant_traits!(Callable, callable_to_variant, callable_from_variant, Callable, init);
158183
impl_variant_traits!(Vector2, vector2_to_variant, vector2_from_variant, Vector2);
159184
impl_variant_traits!(Vector3, vector3_to_variant, vector3_from_variant, Vector3);
160185
impl_variant_traits!(Vector4, vector4_to_variant, vector4_from_variant, Vector4);
161186
impl_variant_traits!(Vector2i, vector2i_to_variant, vector2i_from_variant, Vector2i);
162187
impl_variant_traits!(Vector3i, vector3i_to_variant, vector3i_from_variant, Vector3i);
163188
impl_variant_traits!(Quaternion, quaternion_to_variant, quaternion_from_variant, Quaternion);
164189
impl_variant_traits!(Color, color_to_variant, color_from_variant, Color);
165-
impl_variant_traits!(GodotString, string_to_variant, string_from_variant, String);
190+
impl_variant_traits!(GodotString, string_to_variant, string_from_variant, String, init);
166191
impl_variant_traits!(StringName, string_name_to_variant, string_name_from_variant, StringName);
167192
impl_variant_traits!(NodePath, node_path_to_variant, node_path_from_variant, NodePath);
168193
// TODO use impl_variant_traits!, as soon as `Default` is available. Also consider auto-generating.
169194
impl_variant_metadata!(Signal, /* signal_to_variant, signal_from_variant, */ Signal);
170-
impl_variant_traits!(PackedByteArray, packed_byte_array_to_variant, packed_byte_array_from_variant, PackedByteArray);
171-
impl_variant_traits!(PackedInt32Array, packed_int32_array_to_variant, packed_int32_array_from_variant, PackedInt32Array);
172-
impl_variant_traits!(PackedInt64Array, packed_int64_array_to_variant, packed_int64_array_from_variant, PackedInt64Array);
173-
impl_variant_traits!(PackedFloat32Array, packed_float32_array_to_variant, packed_float32_array_from_variant, PackedFloat32Array);
174-
impl_variant_traits!(PackedFloat64Array, packed_float64_array_to_variant, packed_float64_array_from_variant, PackedFloat64Array);
175-
impl_variant_traits!(PackedStringArray, packed_string_array_to_variant, packed_string_array_from_variant, PackedStringArray);
176-
impl_variant_traits!(PackedVector2Array, packed_vector2_array_to_variant, packed_vector2_array_from_variant, PackedVector2Array);
177-
impl_variant_traits!(PackedVector3Array, packed_vector3_array_to_variant, packed_vector3_array_from_variant, PackedVector3Array);
178-
impl_variant_traits!(PackedColorArray, packed_color_array_to_variant, packed_color_array_from_variant, PackedColorArray);
195+
impl_variant_traits!(PackedByteArray, packed_byte_array_to_variant, packed_byte_array_from_variant, PackedByteArray, init);
196+
impl_variant_traits!(PackedInt32Array, packed_int32_array_to_variant, packed_int32_array_from_variant, PackedInt32Array, init);
197+
impl_variant_traits!(PackedInt64Array, packed_int64_array_to_variant, packed_int64_array_from_variant, PackedInt64Array, init);
198+
impl_variant_traits!(PackedFloat32Array, packed_float32_array_to_variant, packed_float32_array_from_variant, PackedFloat32Array, init);
199+
impl_variant_traits!(PackedFloat64Array, packed_float64_array_to_variant, packed_float64_array_from_variant, PackedFloat64Array, init);
200+
impl_variant_traits!(PackedStringArray, packed_string_array_to_variant, packed_string_array_from_variant, PackedStringArray, init);
201+
impl_variant_traits!(PackedVector2Array, packed_vector2_array_to_variant, packed_vector2_array_from_variant, PackedVector2Array, init);
202+
impl_variant_traits!(PackedVector3Array, packed_vector3_array_to_variant, packed_vector3_array_from_variant, PackedVector3Array, init);
203+
impl_variant_traits!(PackedColorArray, packed_color_array_to_variant, packed_color_array_from_variant, PackedColorArray, init);
179204
impl_variant_traits!(Plane, plane_to_variant, plane_from_variant, Plane);
180205
impl_variant_traits!(Projection, projection_to_variant, projection_from_variant, Projection);
181206
impl_variant_traits!(Rid, rid_to_variant, rid_from_variant, Rid);
@@ -185,7 +210,7 @@ mod impls {
185210
impl_variant_traits!(Transform3D, transform_3d_to_variant, transform_3d_from_variant, Transform3D);
186211
impl_variant_traits!(Dictionary, dictionary_to_variant, dictionary_from_variant, Dictionary);
187212

188-
impl_variant_traits!(i64, int_to_variant, int_from_variant, Int, GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT64);
213+
impl_variant_traits!(i64, int_to_variant, int_from_variant, Int, metadata = GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT64);
189214
impl_variant_traits_int!(i8, GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT8);
190215
impl_variant_traits_int!(i16, GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT16);
191216
impl_variant_traits_int!(i32, GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_INT32);
@@ -195,7 +220,7 @@ mod impls {
195220
impl_variant_traits_int!(u32, GDEXTENSION_METHOD_ARGUMENT_METADATA_INT_IS_UINT32);
196221
// u64 is not supported, because it cannot be represented on GDScript side, and implicitly converting to i64 is error-prone.
197222

198-
impl_variant_traits!(f64, float_to_variant, float_from_variant, Float, GDEXTENSION_METHOD_ARGUMENT_METADATA_REAL_IS_DOUBLE);
223+
impl_variant_traits!(f64, float_to_variant, float_from_variant, Float, metadata = GDEXTENSION_METHOD_ARGUMENT_METADATA_REAL_IS_DOUBLE);
199224
impl_variant_traits_float!(f32, GDEXTENSION_METHOD_ARGUMENT_METADATA_REAL_IS_FLOAT);
200225
}
201226

godot-core/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,14 +172,14 @@ macro_rules! generate_gdextension_api_version {
172172
//
173173
// This includes all versions we're developing for, including unreleased future versions.
174174
generate_gdextension_api_version!(
175-
(GDEXTENSION_API_VERSION_FULL, gdextension_exact_api) => {
175+
(GDEXTENSION_EXACT_API, gdextension_exact_api) => {
176176
"4.0",
177177
"4.0.1",
178178
"4.0.2",
179179
"4.0.3",
180180
"4.1",
181181
},
182-
(GDEXTENSION_API_VERSION, gdextension_api) => {
182+
(GDEXTENSION_API, gdextension_api) => {
183183
"4.0",
184184
"4.1",
185185
},

0 commit comments

Comments
 (0)