Skip to content

Commit 6daa678

Browse files
authored
Merge pull request #719 from godot-rust/qol/type-string-duplication
Small code deduplication + docs
2 parents 9afa98d + 66ca72e commit 6daa678

File tree

10 files changed

+46
-42
lines changed

10 files changed

+46
-42
lines changed

godot-core/src/builtin/array.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use godot_ffi as sys;
99

1010
use crate::builtin::*;
11-
use crate::property::{Export, PropertyHintInfo, TypeStringHint, Var};
11+
use crate::property::{builtin_type_string, Export, PropertyHintInfo, TypeStringHint, Var};
1212
use std::fmt;
1313
use std::marker::PhantomData;
1414
use sys::{ffi_methods, interface_fn, GodotFfi};
@@ -834,11 +834,7 @@ impl<T: ArrayElement + TypeStringHint> TypeStringHint for Array<T> {
834834

835835
impl TypeStringHint for VariantArray {
836836
fn type_string() -> String {
837-
if sys::GdextBuild::since_api("4.3") {
838-
format!("{}:", VariantType::Array as i32)
839-
} else {
840-
format!("{}:Array", VariantType::Array as i32)
841-
}
837+
builtin_type_string::<VariantArray>()
842838
}
843839
}
844840

godot-core/src/builtin/dictionary.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ use godot_ffi as sys;
99

1010
use crate::builtin::meta::{FromGodot, ToGodot};
1111
use crate::builtin::{inner, Variant, VariantArray};
12-
use crate::property::{Export, PropertyHintInfo, TypeStringHint, Var};
13-
use std::marker::PhantomData;
14-
use std::{fmt, ptr};
12+
use crate::property::{builtin_type_string, Export, PropertyHintInfo, TypeStringHint, Var};
1513
use sys::types::OpaqueDictionary;
1614
use sys::{ffi_methods, interface_fn, GodotFfi};
1715

16+
use std::marker::PhantomData;
17+
use std::{fmt, ptr};
18+
1819
use super::meta::impl_godot_as_self;
1920

2021
/// Godot's `Dictionary` type.
@@ -330,11 +331,7 @@ impl Var for Dictionary {
330331

331332
impl TypeStringHint for Dictionary {
332333
fn type_string() -> String {
333-
if sys::GdextBuild::since_api("4.3") {
334-
format!("{}:", sys::VariantType::Dictionary as i32)
335-
} else {
336-
format!("{}:Dictionary", sys::VariantType::Dictionary as i32)
337-
}
334+
builtin_type_string::<Dictionary>()
338335
}
339336
}
340337

godot-core/src/builtin/packed_array.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -481,15 +481,16 @@ macro_rules! impl_packed_array {
481481

482482
impl $crate::property::Export for $PackedArray {
483483
fn default_export_info() -> $crate::property::PropertyHintInfo {
484+
// In 4.3 Godot can (and does) use type hint strings for packed arrays, see https://github.com/godotengine/godot/pull/82952.
484485
if sys::GdextBuild::since_api("4.3") {
485-
// In 4.3 Godot can (and does) use type hint strings for packed arrays.
486-
// https://github.com/godotengine/godot/pull/82952
487486
$crate::property::PropertyHintInfo {
488487
hint: $crate::engine::global::PropertyHint::TYPE_STRING,
489488
hint_string: <$Element as $crate::property::TypeStringHint>::type_string().into(),
490489
}
491490
} else {
492-
$crate::property::PropertyHintInfo::with_hint_none(<$PackedArray as $crate::builtin::meta::GodotType>::godot_type_name())
491+
$crate::property::PropertyHintInfo::with_hint_none(
492+
<$PackedArray as $crate::builtin::meta::GodotType>::godot_type_name()
493+
)
493494
}
494495
}
495496
}

godot-core/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ pub mod builtin;
1313
pub mod init;
1414
pub mod log;
1515
pub mod obj;
16-
pub mod property;
1716

1817
#[doc(hidden)]
1918
#[path = "deprecated.rs"]

godot-core/src/obj/bounds.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,16 @@ pub(super) mod private {
6464
///
6565
/// See [`bounds`](crate::obj::bounds) module for how to use this for bounds checking.
6666
///
67+
/// # No manual `impl`
68+
///
6769
/// <div class="warning">
6870
/// <strong>Never</strong> implement this trait manually.
6971
/// </div>
7072
///
7173
/// Most of the time, this trait is covered by [`#[derive(GodotClass)]`](../register/derive.GodotClass.html).
7274
/// If you implement `GodotClass` manually, use the [`implement_godot_bounds!`][crate::implement_godot_bounds] macro.
7375
///
74-
/// There are two reasons to avoid a hand-written `impl Bounds`:
76+
/// There are two reasons to avoid a handwritten `impl Bounds`:
7577
/// - The trait is `unsafe` and it is very easy to get internal bounds wrong. This will lead to immediate UB.
7678
/// - Apart from the documented members, the trait may have undocumented items that may be broken at any time and stand under no SemVer
7779
/// guarantees.

godot-core/src/obj/traits.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ pub unsafe trait Inherits<Base: GodotClass>: GodotClass {}
137137
unsafe impl<T: GodotClass> Inherits<T> for T {}
138138

139139
/// Implemented for all user-defined classes, providing extensions on the raw object to interact with `Gd`.
140+
#[doc(hidden)]
140141
pub trait UserClass: Bounds<Declarer = bounds::DeclUser> {
141142
#[doc(hidden)]
142143
fn __config() -> crate::private::ClassConfig;
@@ -207,15 +208,14 @@ pub trait IndexEnum: EngineEnum {
207208
}
208209
}
209210

210-
/// Trait that's implemented for user-defined classes that provide a `Base<T>` field.
211+
/// Trait that is automatically implemented for user classes containing a `Base<T>` field.
211212
///
212-
/// Gives direct access to the containing `Gd<Self>` from `Self`.
213+
/// Gives direct access to the containing `Gd<Self>` from `self`.
213214
///
214-
/// # Using WithBaseField as a bound
215+
/// # Usage as a bound
215216
///
216-
/// In order to call `self.base()` or `self.base_mut()` within a trait or on a type you define, the type of `Self::Base` must be specified via `WithBaseField<Base = T>`
217-
///
218-
/// E.g.
217+
/// In order to call `base()` or `base_mut()` within a function or on a type you define, you need a `WithBaseField<Base = T>` bound,
218+
/// where `T` is the base class of your type.
219219
///
220220
/// ```no_run
221221
/// # use godot::prelude::*;
@@ -225,6 +225,7 @@ pub trait IndexEnum: EngineEnum {
225225
/// T: WithBaseField<Base = Node3D>,
226226
/// {
227227
/// let base = value.base();
228+
/// let pos = base.get_position();
228229
/// }
229230
/// ```
230231
///

godot-core/src/registry/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use std::{fmt, ptr};
1616
use sys::{interface_fn, Global, GlobalGuard, GlobalLockError};
1717

1818
pub mod callbacks;
19+
pub mod property;
1920

2021
// Needed for class unregistering. The variable is populated during class registering. There is no actual concurrency here, because Godot
2122
// calls register/unregister in the main thread. Mutex is just casual way to ensure safety in this non-performance-critical path.

godot-core/src/property.rs renamed to godot-core/src/registry/property.rs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
1010
use godot_ffi as sys;
1111

12-
use crate::builtin::meta::{FromGodot, GodotConvert, ToGodot};
12+
use crate::builtin::meta::{FromGodot, GodotConvert, GodotType, ToGodot};
1313
use crate::builtin::GString;
1414
use crate::engine::global::PropertyHint;
1515

@@ -123,9 +123,9 @@ impl PropertyHintInfo {
123123
///
124124
/// Starting with Godot version 4.3, the hint string will always be the empty string. Before that, the hint string is set to
125125
/// be `type_name`.
126-
pub fn with_hint_none<S: Into<GString>>(type_name: S) -> Self {
126+
pub fn with_hint_none(type_name: impl Into<GString>) -> Self {
127127
let hint_string = if sys::GdextBuild::since_api("4.3") {
128-
"".into()
128+
GString::new()
129129
} else {
130130
type_name.into()
131131
};
@@ -336,7 +336,6 @@ pub mod export_info_functions {
336336
mod export_impls {
337337
use super::*;
338338
use crate::builtin::*;
339-
use godot_ffi as sys;
340339

341340
macro_rules! impl_property_by_godot_convert {
342341
($Ty:ty, no_export) => {
@@ -373,15 +372,7 @@ mod export_impls {
373372
(@type_string_hint $Ty:ty) => {
374373
impl TypeStringHint for $Ty {
375374
fn type_string() -> String {
376-
use sys::GodotFfi as _;
377-
let variant_type = <$Ty as $crate::builtin::meta::GodotType>::Ffi::variant_type();
378-
379-
if sys::GdextBuild::since_api("4.3") {
380-
format!("{}:", variant_type as i32)
381-
} else {
382-
let type_name = <$Ty as $crate::builtin::meta::GodotType>::godot_type_name();
383-
format!("{}:{}", variant_type as i32, type_name)
384-
}
375+
builtin_type_string::<$Ty>()
385376
}
386377
}
387378
}
@@ -467,3 +458,19 @@ mod export_impls {
467458

468459
// impl_property_by_godot_convert!(Signal);
469460
}
461+
462+
// ----------------------------------------------------------------------------------------------------------------------------------------------
463+
// Crate-local utilities
464+
465+
pub(crate) fn builtin_type_string<T: GodotType>() -> String {
466+
use sys::GodotFfi as _;
467+
468+
let variant_type = T::Ffi::variant_type();
469+
470+
// Godot 4.3 changed representation for type hints, see https://github.com/godotengine/godot/pull/90716.
471+
if sys::GdextBuild::since_api("4.3") {
472+
format!("{}:", variant_type.sys())
473+
} else {
474+
format!("{}:{}", variant_type.sys(), T::godot_type_name())
475+
}
476+
}

itest/rust/src/object_tests/property_template_test.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ fn property_template_test(ctx: &TestContext) {
3333
for property in rust_properties.get_property_list().iter_shared() {
3434
let name = property.get("name").unwrap().to::<String>();
3535

36-
// The format of array-properties in Godot 4.2 changed. This doesn't seem to cause issues if we
37-
// compile against 4.1 and provide the property in the format 4.1 expects but run it with Godot 4.2.
38-
// However this test checks that our output matches that of Godot, and so would fail in this
39-
// circumstance. So here for now, just ignore array properties when we compile for 4.1 but run in 4.2.
36+
// The format of array properties in Godot 4.2 changed. This doesn't seem to cause issues if we
37+
// compile against 4.1 and provide the property in the format 4.1 expects, but run it with Godot 4.2.
38+
// However, this test checks that our output matches that of Godot, and so would fail in this circumstance.
39+
// For now, just ignore array properties when we compile for 4.1 but run in 4.2.
4040
if GdextBuild::since_api("4.2")
4141
&& cfg!(before_api = "4.2")
4242
&& name.starts_with("property_array_")

0 commit comments

Comments
 (0)