Skip to content

Commit d6c4652

Browse files
committed
Add OnEditor<T>, remove impl<T> Export for Gd<T> and DynGd<T, D>
- Create proper blanket implementation for Godot Types other than Gd<T> - Fix nonsensical bounds - Fix docs examples (don't wrap) - Formatting fixes - Move Gd<T>::export_info to PropertyHintInfo::export_gd.
1 parent f163229 commit d6c4652

File tree

7 files changed

+270
-258
lines changed

7 files changed

+270
-258
lines changed

godot-core/src/builtin/collections/array.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,9 +1086,9 @@ impl<T: ArrayElement> Var for Array<T> {
10861086
}
10871087
}
10881088

1089-
impl<T: Export> Export for Array<T>
1089+
impl<T> Export for Array<T>
10901090
where
1091-
T: ArrayElement,
1091+
T: ArrayElement + Export,
10921092
{
10931093
fn export_hint() -> PropertyHintInfo {
10941094
// If T == Variant, then we return "Array" builtin type hint.
@@ -1103,15 +1103,14 @@ where
11031103
impl<T: GodotClass> Export for Array<Gd<T>>
11041104
where
11051105
T: Bounds<Exportable = bounds::Yes>,
1106-
Gd<T>: ArrayElement,
11071106
{
11081107
fn export_hint() -> PropertyHintInfo {
11091108
PropertyHintInfo::export_array_element::<Gd<T>>()
11101109
}
11111110

11121111
#[doc(hidden)]
11131112
fn as_node_class() -> Option<ClassName> {
1114-
Gd::<T>::as_node_class()
1113+
PropertyHintInfo::object_as_node_class::<T>()
11151114
}
11161115
}
11171116

godot-core/src/meta/property_info.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ use crate::global::{PropertyHint, PropertyUsageFlags};
1010
use crate::meta::{
1111
element_godot_type_name, ArrayElement, ClassName, GodotType, PackedArrayElement,
1212
};
13-
use crate::obj::{EngineBitfield, EngineEnum};
13+
use crate::obj::{bounds, Bounds, EngineBitfield, EngineEnum, GodotClass};
1414
use crate::registry::property::{Export, Var};
15-
use crate::sys;
15+
use crate::{classes, sys};
1616
use godot_ffi::VariantType;
1717

1818
/// Describes a property in Godot.
@@ -302,4 +302,26 @@ impl PropertyHintInfo {
302302
hint_string: GString::from(T::element_type_string()),
303303
}
304304
}
305+
306+
pub fn export_gd<T: GodotClass + Bounds<Exportable = bounds::Yes>>() -> Self {
307+
let hint = if T::inherits::<classes::Resource>() {
308+
PropertyHint::RESOURCE_TYPE
309+
} else if T::inherits::<classes::Node>() {
310+
PropertyHint::NODE_TYPE
311+
} else {
312+
unreachable!("classes not inheriting from Resource or Node should not be exportable")
313+
};
314+
315+
// Godot does this by default too; the hint is needed when the class is a resource/node,
316+
// but doesn't seem to make a difference otherwise.
317+
let hint_string = T::class_name().to_gstring();
318+
319+
Self { hint, hint_string }
320+
}
321+
322+
#[doc(hidden)]
323+
pub fn object_as_node_class<T: GodotClass + Bounds<Exportable = bounds::Yes>>(
324+
) -> Option<ClassName> {
325+
T::inherits::<classes::Node>().then(|| T::class_name())
326+
}
305327
}

godot-core/src/obj/dyn_gd.rs

Lines changed: 3 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -495,22 +495,6 @@ where
495495
}
496496
}
497497

498-
impl<T, D> Export for Option<DynGd<T, D>>
499-
where
500-
T: GodotClass + Bounds<Exportable = bounds::Yes>,
501-
D: ?Sized + 'static,
502-
{
503-
fn export_hint() -> PropertyHintInfo {
504-
PropertyHintInfo {
505-
hint_string: get_dyn_property_hint_string::<D>(),
506-
..Gd::<T>::export_hint()
507-
}
508-
}
509-
fn as_node_class() -> Option<ClassName> {
510-
Gd::<T>::as_node_class()
511-
}
512-
}
513-
514498
#[doc(hidden)]
515499
#[allow(clippy::derivable_impls)]
516500
impl<T, D> Default for OnEditor<DynGd<T, D>>
@@ -522,42 +506,18 @@ where
522506
OnEditor::null()
523507
}
524508
}
525-
526-
impl<T, D> GodotConvert for OnEditor<DynGd<T, D>>
527-
where
528-
T: GodotClass,
529-
D: ?Sized,
530-
{
531-
type Via = Option<<DynGd<T, D> as GodotConvert>::Via>;
532-
}
533-
534-
impl<T, D> Var for OnEditor<DynGd<T, D>>
535-
where
536-
T: GodotClass,
537-
D: ?Sized + 'static,
538-
{
539-
fn get_property(&self) -> Self::Via {
540-
OnEditor::<DynGd<T, D>>::get_property(self)
541-
}
542-
543-
fn set_property(&mut self, value: Self::Via) {
544-
OnEditor::<DynGd<T, D>>::set_property(self, value)
545-
}
546-
}
547-
548-
impl<T, D> Export for OnEditor<DynGd<T, D>>
509+
impl<T, D> Export for Option<DynGd<T, D>>
549510
where
550-
OnEditor<DynGd<T, D>>: Var,
551511
T: GodotClass + Bounds<Exportable = bounds::Yes>,
552512
D: ?Sized + 'static,
553513
{
554514
fn export_hint() -> PropertyHintInfo {
555515
PropertyHintInfo {
556516
hint_string: get_dyn_property_hint_string::<D>(),
557-
..Gd::<T>::export_hint()
517+
..PropertyHintInfo::export_gd::<T>()
558518
}
559519
}
560520
fn as_node_class() -> Option<ClassName> {
561-
Gd::<T>::as_node_class()
521+
PropertyHintInfo::object_as_node_class::<T>()
562522
}
563523
}

godot-core/src/obj/gd.rs

Lines changed: 2 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -545,40 +545,6 @@ impl<T: GodotClass> Gd<T> {
545545
// Do not increment ref-count; assumed to be return value from FFI.
546546
sys::ptr_then(object_ptr, |ptr| Gd::from_obj_sys_weak(ptr))
547547
}
548-
549-
/// Provides `export_hint` to be used in exports with `Option<Gd<T>>` and `OnEditor<Gd<T>>`.
550-
///
551-
/// `Gd<T>` by itself is non-nullable which works badly with Godot editor and might lead to
552-
/// unavoidable memory leaks – thus the need to handle `#[export]` with algebraic types.
553-
///
554-
/// See also: [#892](https://github.com/godot-rust/gdext/issues/892#issuecomment-2628955463)
555-
#[doc(hidden)]
556-
pub(crate) fn export_hint() -> PropertyHintInfo
557-
where
558-
T: Bounds<Exportable = bounds::Yes>,
559-
{
560-
let hint = if T::inherits::<classes::Resource>() {
561-
PropertyHint::RESOURCE_TYPE
562-
} else if T::inherits::<classes::Node>() {
563-
PropertyHint::NODE_TYPE
564-
} else {
565-
unreachable!("classes not inheriting from Resource or Node should not be exportable")
566-
};
567-
568-
// Godot does this by default too; the hint is needed when the class is a resource/node,
569-
// but doesn't seem to make a difference otherwise.
570-
let hint_string = T::class_name().to_gstring();
571-
572-
PropertyHintInfo { hint, hint_string }
573-
}
574-
575-
#[doc(hidden)]
576-
pub(crate) fn as_node_class() -> Option<ClassName>
577-
where
578-
T: Bounds<Exportable = bounds::Yes>,
579-
{
580-
T::inherits::<classes::Node>().then(|| T::class_name())
581-
}
582548
}
583549

584550
/// _The methods in this impl block are only available for objects `T` that are manually managed,
@@ -942,12 +908,12 @@ where
942908
Option<Gd<T>>: Var,
943909
{
944910
fn export_hint() -> PropertyHintInfo {
945-
Gd::<T>::export_hint()
911+
PropertyHintInfo::export_gd::<T>()
946912
}
947913

948914
#[doc(hidden)]
949915
fn as_node_class() -> Option<ClassName> {
950-
Gd::<T>::as_node_class()
916+
PropertyHintInfo::object_as_node_class::<T>()
951917
}
952918
}
953919

@@ -959,43 +925,6 @@ impl<T: GodotClass> Default for OnEditor<Gd<T>> {
959925
}
960926
}
961927

962-
impl<T: GodotClass> GodotConvert for OnEditor<Gd<T>>
963-
where
964-
Gd<T>: GodotConvert,
965-
Option<<Gd<T> as GodotConvert>::Via>: GodotType,
966-
{
967-
type Via = Option<<Gd<T> as GodotConvert>::Via>;
968-
}
969-
970-
impl<T> Var for OnEditor<Gd<T>>
971-
where
972-
T: GodotClass,
973-
OnEditor<Gd<T>>: GodotConvert<Via = Option<<Gd<T> as GodotConvert>::Via>>,
974-
{
975-
fn get_property(&self) -> Self::Via {
976-
OnEditor::<Gd<T>>::get_property(self)
977-
}
978-
979-
fn set_property(&mut self, value: Self::Via) {
980-
OnEditor::<Gd<T>>::set_property(self, value)
981-
}
982-
}
983-
984-
impl<T> Export for OnEditor<Gd<T>>
985-
where
986-
T: GodotClass + Bounds<Exportable = bounds::Yes>,
987-
OnEditor<Gd<T>>: Var,
988-
{
989-
fn export_hint() -> PropertyHintInfo {
990-
Gd::<T>::export_hint()
991-
}
992-
993-
#[doc(hidden)]
994-
fn as_node_class() -> Option<ClassName> {
995-
Gd::<T>::as_node_class()
996-
}
997-
}
998-
999928
impl<T: GodotClass> PartialEq for Gd<T> {
1000929
/// ⚠️ Returns whether two `Gd` pointers point to the same object.
1001930
///

0 commit comments

Comments
 (0)