Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Array<T> registered without element type #836

Merged
merged 1 commit into from
Aug 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 14 additions & 12 deletions godot-core/src/builtin/collections/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -906,18 +906,6 @@ impl<T: ArrayElement> Var for Array<T> {
fn set_property(&mut self, value: Self::Via) {
*self = FromGodot::from_godot(value)
}

#[cfg(since_api = "4.2")]
fn property_hint() -> PropertyHintInfo {
if T::Ffi::variant_type() == VariantType::NIL {
return PropertyHintInfo::with_hint_none("");
}

PropertyHintInfo {
hint: crate::global::PropertyHint::ARRAY_TYPE,
hint_string: T::godot_type_name().into(),
}
}
}

impl<T: ArrayElement + TypeStringHint> Export for Array<T> {
Expand Down Expand Up @@ -983,6 +971,20 @@ impl<T: ArrayElement> GodotType for Array<T> {
fn godot_type_name() -> String {
"Array".to_string()
}

#[cfg(since_api = "4.2")]
fn property_hint_info() -> PropertyHintInfo {
// Array<Variant>, aka untyped array, has no hints.
if T::Ffi::variant_type() == VariantType::NIL {
return PropertyHintInfo::none();
}

// Typed arrays use type hint.
PropertyHintInfo {
hint: crate::global::PropertyHint::ARRAY_TYPE,
hint_string: T::godot_type_name().into(),
}
}
}

impl<T: ArrayElement> GodotFfiVariant for Array<T> {
Expand Down
5 changes: 2 additions & 3 deletions godot-core/src/builtin/variant/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use crate::builtin::*;
use crate::global;
use crate::meta::error::{ConvertError, FromVariantError};
use crate::meta::{ArrayElement, GodotFfiVariant, GodotType, PropertyInfo};
use crate::registry::property::PropertyHintInfo;
use godot_ffi as sys;

// For godot-cpp, see https://github.com/godotengine/godot-cpp/blob/master/include/godot_cpp/core/type_info.hpp.

// ----------------------------------------------------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -212,8 +212,7 @@ impl GodotType for Variant {
variant_type: Self::variant_type(),
class_name: Self::class_name(),
property_name: StringName::from(property_name),
hint: global::PropertyHint::NONE,
hint_string: GString::new(),
hint_info: PropertyHintInfo::none(),
usage: global::PropertyUsageFlags::DEFAULT | global::PropertyUsageFlags::NIL_IS_VARIANT,
}
}
Expand Down
6 changes: 5 additions & 1 deletion godot-core/src/meta/godot_convert/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ use crate::meta::{
ToGodot,
};
use crate::registry::method::MethodParamOrReturnInfo;
use crate::registry::property::PropertyHintInfo;
use godot_ffi as sys;

// The following ToGodot/FromGodot/Convert impls are auto-generated for each engine type, co-located with their definitions:
// - enum
// - const/mut pointer to native struct
Expand Down Expand Up @@ -64,6 +64,10 @@ where
T::property_info(property_name)
}

fn property_hint_info() -> PropertyHintInfo {
T::property_hint_info()
}

fn argument_info(property_name: &str) -> MethodParamOrReturnInfo {
T::argument_info(property_name)
}
Expand Down
37 changes: 17 additions & 20 deletions godot-core/src/meta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,12 @@ pub struct PropertyInfo {
/// The name of this property in Godot.
pub property_name: StringName,

/// How the property is meant to be edited. See also [`PropertyHint`] in the Godot docs.
/// Additional type information for this property, e.g. about array types or enum values. Split into `hint` and `hint_string` members.
///
/// See also [`PropertyHint`] in the Godot docs.
///
/// [`PropertyHint`]: https://docs.godotengine.org/en/latest/classes/class_%40globalscope.html#enum-globalscope-propertyhint
pub hint: PropertyHint,

/// Extra information passed to Godot for this property, what this means depends on the `hint` value.
pub hint_string: GString,
pub hint_info: PropertyHintInfo,

/// How this property should be used. See [`PropertyUsageFlags`] in Godot for the meaning.
///
Expand Down Expand Up @@ -148,13 +147,7 @@ impl PropertyInfo {
/// ));
/// ```
pub fn with_hint_info(self, hint_info: PropertyHintInfo) -> Self {
let PropertyHintInfo { hint, hint_string } = hint_info;

Self {
hint,
hint_string,
..self
}
Self { hint_info, ..self }
}

/// Create a new `PropertyInfo` representing a group in Godot.
Expand All @@ -166,8 +159,10 @@ impl PropertyInfo {
variant_type: VariantType::NIL,
class_name: ClassName::none(),
property_name: group_name.into(),
hint: PropertyHint::NONE,
hint_string: group_prefix.into(),
hint_info: PropertyHintInfo {
hint: PropertyHint::NONE,
hint_string: group_prefix.into(),
},
usage: PropertyUsageFlags::GROUP,
}
}
Expand All @@ -181,8 +176,10 @@ impl PropertyInfo {
variant_type: VariantType::NIL,
class_name: ClassName::none(),
property_name: subgroup_name.into(),
hint: PropertyHint::NONE,
hint_string: subgroup_prefix.into(),
hint_info: PropertyHintInfo {
hint: PropertyHint::NONE,
hint_string: subgroup_prefix.into(),
},
usage: PropertyUsageFlags::SUBGROUP,
}
}
Expand All @@ -196,8 +193,8 @@ impl PropertyInfo {
type_: self.variant_type.sys(),
name: sys::SysPtr::force_mut(self.property_name.string_sys()),
class_name: sys::SysPtr::force_mut(self.class_name.string_sys()),
hint: u32::try_from(self.hint.ord()).expect("hint.ord()"),
hint_string: sys::SysPtr::force_mut(self.hint_string.string_sys()),
hint: u32::try_from(self.hint_info.hint.ord()).expect("hint.ord()"),
hint_string: sys::SysPtr::force_mut(self.hint_info.hint_string.string_sys()),
usage: u32::try_from(self.usage.ord()).expect("usage.ord()"),
}
}
Expand Down Expand Up @@ -228,8 +225,8 @@ impl PropertyInfo {
type_: self.variant_type.sys(),
name: self.property_name.into_owned_string_sys(),
class_name: sys::SysPtr::force_mut(self.class_name.string_sys()),
hint: u32::try_from(self.hint.ord()).expect("hint.ord()"),
hint_string: self.hint_string.into_owned_string_sys(),
hint: u32::try_from(self.hint_info.hint.ord()).expect("hint.ord()"),
hint_string: self.hint_info.hint_string.into_owned_string_sys(),
usage: u32::try_from(self.usage.ord()).expect("usage.ord()"),
}
}
Expand Down
13 changes: 9 additions & 4 deletions godot-core/src/meta/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@

use godot_ffi as sys;

use crate::builtin::{GString, StringName, Variant};
use crate::global::{PropertyHint, PropertyUsageFlags};
use crate::builtin::{StringName, Variant};
use crate::global::PropertyUsageFlags;
use crate::meta::error::ConvertError;
use crate::meta::{sealed, ClassName, FromGodot, GodotConvert, PropertyInfo, ToGodot};
use crate::registry::method::MethodParamOrReturnInfo;

// Re-export sys traits in this module, so all are in one place.
use crate::registry::property::PropertyHintInfo;
pub use sys::{GodotFfi, GodotNullableFfi};

/// Conversion of [`GodotFfi`] types to/from [`Variant`].
Expand Down Expand Up @@ -73,12 +74,16 @@ pub trait GodotType:
variant_type: Self::Ffi::variant_type(),
class_name: Self::class_name(),
property_name: StringName::from(property_name),
hint: PropertyHint::NONE,
hint_string: GString::new(),
hint_info: Self::property_hint_info(),
usage: PropertyUsageFlags::DEFAULT,
}
}

#[doc(hidden)]
fn property_hint_info() -> PropertyHintInfo {
PropertyHintInfo::none()
}

#[doc(hidden)]
fn argument_info(property_name: &str) -> MethodParamOrReturnInfo {
MethodParamOrReturnInfo::new(Self::property_info(property_name), Self::param_metadata())
Expand Down
5 changes: 2 additions & 3 deletions godot-core/src/obj/gd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,9 +374,8 @@ impl<T: GodotClass> Gd<T> {

/// **Downcast:** try to convert into a smart pointer to a derived class.
///
/// If `T`'s dynamic type is not `Derived` or one of its subclasses, `None` is returned
/// and the reference is dropped. Otherwise, `Some` is returned and the ownership is moved
/// to the returned value.
/// If `T`'s dynamic type is not `Derived` or one of its subclasses, `Err(self)` is returned, meaning you can reuse the original
/// object for further casts.
pub fn try_cast<Derived>(self) -> Result<Gd<Derived>, Self>
where
Derived: GodotClass + Inherits<T>,
Expand Down
6 changes: 1 addition & 5 deletions godot-core/src/obj/onready.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::builtin::NodePath;
use crate::classes::Node;
use crate::meta::GodotConvert;
use crate::obj::{Gd, GodotClass, Inherits};
use crate::registry::property::{PropertyHintInfo, Var};
use crate::registry::property::Var;
use std::mem;

/// Ergonomic late-initialization container with `ready()` support.
Expand Down Expand Up @@ -267,10 +267,6 @@ impl<T: Var> Var for OnReady<T> {
let deref: &mut T = self;
deref.set_property(value);
}

fn property_hint() -> PropertyHintInfo {
T::property_hint()
}
}

// ----------------------------------------------------------------------------------------------------------------------------------------------
Expand Down
11 changes: 10 additions & 1 deletion godot-core/src/registry/property.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ pub trait Var: GodotConvert {
fn get_property(&self) -> Self::Via;
fn set_property(&mut self, value: Self::Via);

/// Specific property hints, only override if they deviate from [`GodotType::property_info`], e.g. for enums/newtypes.
fn property_hint() -> PropertyHintInfo {
PropertyHintInfo::with_hint_none("")
Self::Via::property_hint_info()
}
}

Expand Down Expand Up @@ -119,6 +120,14 @@ pub struct PropertyHintInfo {
}

impl PropertyHintInfo {
/// Create a new `PropertyHintInfo` with a property hint of [`PROPERTY_HINT_NONE`](PropertyHint::NONE), and no hint string.
pub fn none() -> Self {
Self {
hint: PropertyHint::NONE,
hint_string: GString::new(),
}
}

/// Create a new `PropertyHintInfo` with a property hint of [`PROPERTY_HINT_NONE`](PropertyHint::NONE).
///
/// Starting with Godot version 4.3, the hint string will always be the empty string. Before that, the hint string is set to
Expand Down
6 changes: 4 additions & 2 deletions godot-macros/src/class/data_models/property.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,10 @@ pub fn make_property_impl(class_name: &Ident, fields: &Fields) -> TokenStream {
variant_type: #field_variant_type,
class_name: #field_class_name,
property_name: #field_name.into(),
hint,
hint_string,
hint_info: ::godot::register::property::PropertyHintInfo {
hint,
hint_string,
},
usage,
};

Expand Down
4 changes: 2 additions & 2 deletions itest/rust/src/object_tests/get_property_list_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ fn property_dict_eq_property_info(dict: &Dictionary, info: &PropertyInfo) -> boo
dict.get("name").unwrap().to::<GString>().to_string() == info.property_name.to_string()
&& dict.get("class_name").unwrap().to::<StringName>() == info.class_name.to_string_name()
&& dict.get("type").unwrap().to::<VariantType>() == info.variant_type
&& dict.get("hint").unwrap().to::<PropertyHint>() == info.hint
&& dict.get("hint_string").unwrap().to::<GString>() == info.hint_string
&& dict.get("hint").unwrap().to::<PropertyHint>() == info.hint_info.hint
&& dict.get("hint_string").unwrap().to::<GString>() == info.hint_info.hint_string
&& dict.get("usage").unwrap().to::<PropertyUsageFlags>() == info.usage
}

Expand Down
Loading