Skip to content

Commit

Permalink
Consolidate Export + Var property hints
Browse files Browse the repository at this point in the history
Provide reasonable defaults where appropriate.
  • Loading branch information
Bromeon committed Aug 4, 2024
1 parent be32f1d commit de92e70
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 31 deletions.
15 changes: 14 additions & 1 deletion godot-core/src/builtin/collections/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -895,9 +895,22 @@ impl<T: ArrayElement> Var for Array<T> {
fn get_property(&self) -> Self::Via {
self.to_godot()
}

fn set_property(&mut self, value: Self::Via) {
*self = FromGodot::from_godot(value)
}

fn property_hint() -> PropertyHintInfo {
// For array #[var], the hint string is "PackedInt32Array", "Node" etc. for typed arrays, and "" for untyped arrays.
if Self::has_variant_t() {
PropertyHintInfo::none()
} else if sys::GdextBuild::since_api("4.2") {
PropertyHintInfo::var_array_element::<T>()
} else {
// Godot 4.1 was missing PropertyHint::ARRAY_TYPE, so we use the type name instead.
PropertyHintInfo::none()
}
}
}

impl<T: ArrayElement> Export for Array<T> {
Expand All @@ -906,7 +919,7 @@ impl<T: ArrayElement> Export for Array<T> {
if Self::has_variant_t() {
PropertyHintInfo::with_type_name::<VariantArray>()
} else {
PropertyHintInfo::with_array_element::<T>()
PropertyHintInfo::export_array_element::<T>()
}
}
}
Expand Down
17 changes: 0 additions & 17 deletions godot-core/src/builtin/collections/dictionary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use godot_ffi as sys;

use crate::builtin::{inner, Variant, VariantArray};
use crate::meta::{FromGodot, ToGodot};
use crate::registry::property::{Export, PropertyHintInfo, Var};
use sys::types::OpaqueDictionary;
use sys::{ffi_methods, interface_fn, GodotFfi};

Expand Down Expand Up @@ -400,22 +399,6 @@ impl Clone for Dictionary {
}
}

impl Var for Dictionary {
fn get_property(&self) -> Self::Via {
self.to_godot()
}

fn set_property(&mut self, value: Self::Via) {
*self = FromGodot::from_godot(value)
}
}

impl Export for Dictionary {
fn default_export_info() -> PropertyHintInfo {
PropertyHintInfo::with_hint_none("Dictionary")
}
}

// ----------------------------------------------------------------------------------------------------------------------------------------------
// Conversion traits

Expand Down
2 changes: 1 addition & 1 deletion godot-core/src/builtin/collections/packed_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ macro_rules! impl_packed_array {
fn default_export_info() -> $crate::registry::property::PropertyHintInfo {
// In 4.3 Godot can (and does) use type hint strings for packed arrays, see https://github.com/godotengine/godot/pull/82952.
if sys::GdextBuild::since_api("4.3") {
$crate::registry::property::PropertyHintInfo::with_array_element::<$Element>()
$crate::registry::property::PropertyHintInfo::export_array_element::<$Element>()
} else {
$crate::registry::property::PropertyHintInfo::with_type_name::<$PackedArray>()
}
Expand Down
3 changes: 3 additions & 0 deletions godot-core/src/meta/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ pub trait GodotType:

#[doc(hidden)]
fn property_hint_info() -> PropertyHintInfo {
// The default implementation is mostly good for builtin types.
//PropertyHintInfo::with_type_name::<Self>()

PropertyHintInfo::none()
}

Expand Down
29 changes: 24 additions & 5 deletions godot-core/src/registry/property.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ pub trait Var: GodotConvert {

/// Specific property hints, only override if they deviate from [`GodotType::property_info`], e.g. for enums/newtypes.
fn property_hint() -> PropertyHintInfo {
// From Godot 4.3 onward, properties are typically exported with "" hint_string. This needs to be manually overridden for types
// that need a hint string, like arrays. See also https://github.com/godotengine/godot/pull/82952 and property_template_test.rs.
// if sys::GdextBuild::since_api("4.3") {
// PropertyHintInfo::with_type_name::<Self::Via>()
// } else {
// Self::Via::property_hint_info()
// }

//PropertyHintInfo::with_hint_none("")
Self::Via::property_hint_info()
}
}
Expand All @@ -50,7 +59,9 @@ pub trait Var: GodotConvert {
)]
pub trait Export: Var {
/// The export info to use for an exported field of this type, if no other export info is specified.
fn default_export_info() -> PropertyHintInfo;
fn default_export_info() -> PropertyHintInfo {
<Self as Var>::property_hint()
}
}

// ----------------------------------------------------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -125,13 +136,19 @@ impl PropertyHintInfo {
}
}

pub fn with_array_element<T: ArrayElement>() -> Self {
pub fn var_array_element<T: ArrayElement>() -> Self {
Self {
hint: PropertyHint::ARRAY_TYPE,
hint_string: GString::from(T::godot_type_name()),
}
}

pub fn export_array_element<T: ArrayElement>() -> Self {
Self {
hint: PropertyHint::TYPE_STRING,
hint_string: GString::from(T::element_type_string()),
}
}

pub fn with_type_name<T: GodotType>() -> Self {
Self::with_hint_none(T::godot_type_name())
}
Expand Down Expand Up @@ -457,8 +474,10 @@ mod export_impls {

impl_property_by_godot_convert!(Color);

// Arrays
// We manually implement `Export`.
// Dictionary: will need to be done manually once they become typed.
impl_property_by_godot_convert!(Dictionary);

// Packed arrays: we manually implement `Export`.
impl_property_by_godot_convert!(PackedByteArray, no_export);
impl_property_by_godot_convert!(PackedInt32Array, no_export);
impl_property_by_godot_convert!(PackedInt64Array, no_export);
Expand Down
6 changes: 1 addition & 5 deletions godot-macros/src/derive/derive_export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@ pub fn derive_export(item: venial::Item) -> ParseResult<TokenStream> {
let GodotConvert { ty_name: name, .. } = GodotConvert::parse_declaration(item)?;

Ok(quote! {
impl ::godot::register::property::Export for #name {
fn default_export_info() -> ::godot::register::property::PropertyHintInfo {
<#name as ::godot::register::property::Var>::property_hint()
}
}
impl ::godot::register::property::Export for #name {}
})
}
1 change: 0 additions & 1 deletion godot-macros/src/derive/derive_var.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ pub fn derive_var(item: venial::Item) -> ParseResult<TokenStream> {
fn property_hint() -> ::godot::register::property::PropertyHintInfo {
#property_hint_impl
}

}
})
}
Expand Down
2 changes: 1 addition & 1 deletion itest/rust/src/object_tests/property_template_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ fn property_template_test(ctx: &TestContext) {

if rust_prop != property {
errors.push(format!(
"mismatch in property {name}, GDScript: {property:?}, Rust: {rust_prop:?}"
"mismatch in property {name}:\n GDScript: {property:?}\n Rust: {rust_prop:?}"
));
}
}
Expand Down

0 comments on commit de92e70

Please sign in to comment.