Skip to content

Commit 71f55d3

Browse files
committed
Replace Var::Intermediate with GodotConvert::Via
1 parent bfc3a98 commit 71f55d3

File tree

11 files changed

+202
-149
lines changed

11 files changed

+202
-149
lines changed

godot-core/src/builtin/array.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -762,14 +762,12 @@ impl TypeStringHint for VariantArray {
762762
}
763763

764764
impl<T: GodotType> Var for Array<T> {
765-
type Intermediate = Self;
766-
767-
fn get_property(&self) -> Self::Intermediate {
768-
self.clone()
765+
fn get_property(&self) -> Self::Via {
766+
self.to_godot()
769767
}
770768

771-
fn set_property(&mut self, value: Self::Intermediate) {
772-
*self = value;
769+
fn set_property(&mut self, value: Self::Via) {
770+
*self = FromGodot::from_godot(value)
773771
}
774772

775773
#[cfg(since_api = "4.2")]

godot-core/src/builtin/dictionary.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -341,14 +341,12 @@ impl Clone for Dictionary {
341341
}
342342

343343
impl Var for Dictionary {
344-
type Intermediate = Self;
345-
346-
fn get_property(&self) -> Self::Intermediate {
347-
self.clone()
344+
fn get_property(&self) -> Self::Via {
345+
self.to_godot()
348346
}
349347

350-
fn set_property(&mut self, value: Self::Intermediate) {
351-
*self = value;
348+
fn set_property(&mut self, value: Self::Via) {
349+
*self = FromGodot::from_godot(value)
352350
}
353351
}
354352

godot-core/src/obj/gd.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -656,15 +656,15 @@ impl<T: GodotClass> TypeStringHint for Gd<T> {
656656
}
657657
}
658658

659+
// TODO: Do we even want to implement `Var` and `Export` for `Gd<T>`? You basically always want to use `Option<Gd<T>>` because the editor
660+
// may otherwise try to set the object to a null value.
659661
impl<T: GodotClass> Var for Gd<T> {
660-
type Intermediate = Self;
661-
662-
fn get_property(&self) -> Self {
663-
self.clone()
662+
fn get_property(&self) -> Self::Via {
663+
self.to_godot()
664664
}
665665

666-
fn set_property(&mut self, value: Self) {
667-
*self = value;
666+
fn set_property(&mut self, value: Self::Via) {
667+
*self = FromGodot::from_godot(value)
668668
}
669669
}
670670

godot-core/src/obj/onready.rs

+7-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
66
*/
77

8+
use crate::builtin::meta::GodotConvert;
89
use crate::property::{PropertyHintInfo, Var};
910
use std::mem;
1011

@@ -190,15 +191,17 @@ impl<T> std::ops::DerefMut for OnReady<T> {
190191
}
191192
}
192193

193-
impl<T: Var> Var for OnReady<T> {
194-
type Intermediate = T::Intermediate;
194+
impl<T: GodotConvert> GodotConvert for OnReady<T> {
195+
type Via = T::Via;
196+
}
195197

196-
fn get_property(&self) -> Self::Intermediate {
198+
impl<T: Var> Var for OnReady<T> {
199+
fn get_property(&self) -> Self::Via {
197200
let deref: &T = self;
198201
deref.get_property()
199202
}
200203

201-
fn set_property(&mut self, value: Self::Intermediate) {
204+
fn set_property(&mut self, value: Self::Via) {
202205
let deref: &mut T = self;
203206
deref.set_property(value);
204207
}

godot-core/src/property.rs

+72-82
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
//! Registration support for property types.
99
10+
use crate::builtin::meta::{FromGodot, GodotConvert, ToGodot};
1011
use crate::builtin::GString;
1112
use crate::engine::global::PropertyHint;
1213

@@ -17,11 +18,12 @@ use crate::engine::global::PropertyHint;
1718
///
1819
/// This creates a copy of the value, according to copy semantics provided by `Clone`. For example, `Array`, `Dictionary` and `Gd` are
1920
/// returned by shared reference instead of copying the actual data.
20-
pub trait Var {
21-
type Intermediate;
22-
23-
fn get_property(&self) -> Self::Intermediate;
24-
fn set_property(&mut self, value: Self::Intermediate);
21+
///
22+
/// This does not require [`FromGodot`] or [`ToGodot`], so that something can be used as a property even if it can't be used in function
23+
/// arguments/return types.
24+
pub trait Var: GodotConvert {
25+
fn get_property(&self) -> Self::Via;
26+
fn set_property(&mut self, value: Self::Via);
2527

2628
fn property_hint() -> PropertyHintInfo {
2729
PropertyHintInfo::with_hint_none("")
@@ -59,21 +61,20 @@ impl<T: TypeStringHint> TypeStringHint for Option<T> {
5961

6062
impl<T> Var for Option<T>
6163
where
62-
T: Var + From<<T as Var>::Intermediate>,
64+
T: Var + FromGodot,
65+
Option<T>: GodotConvert<Via = Option<T::Via>>,
6366
{
64-
type Intermediate = Option<T::Intermediate>;
65-
66-
fn get_property(&self) -> Self::Intermediate {
67+
fn get_property(&self) -> Self::Via {
6768
self.as_ref().map(Var::get_property)
6869
}
6970

70-
fn set_property(&mut self, value: Self::Intermediate) {
71+
fn set_property(&mut self, value: Self::Via) {
7172
match value {
7273
Some(value) => {
7374
if let Some(current_value) = self {
7475
current_value.set_property(value)
7576
} else {
76-
*self = Some(T::from(value))
77+
*self = Some(FromGodot::from_godot(value))
7778
}
7879
}
7980
None => *self = None,
@@ -83,7 +84,8 @@ where
8384

8485
impl<T> Export for Option<T>
8586
where
86-
T: Export + From<<T as Var>::Intermediate>,
87+
T: Export,
88+
Option<T>: Var,
8789
{
8890
fn default_export_info() -> PropertyHintInfo {
8991
T::default_export_info()
@@ -314,39 +316,26 @@ mod export_impls {
314316
use crate::builtin::*;
315317
use godot_ffi as sys;
316318

317-
macro_rules! impl_property_by_clone {
318-
($Ty:ty => $variant_type:ident, no_export) => {
319-
impl_property_by_clone!(@property $Ty => $variant_type);
320-
impl_property_by_clone!(@type_string_hint $Ty, $variant_type);
321-
};
322-
323-
($Ty:ty => $variant_type:ident, no_export; $type_string_name:ident) => {
324-
impl_property_by_clone!(@property $Ty => $variant_type);
325-
impl_property_by_clone!(@type_string_hint $Ty, $type_string_name);
326-
};
327-
328-
($Ty:ty => $variant_type:ident) => {
329-
impl_property_by_clone!(@property $Ty => $variant_type);
330-
impl_property_by_clone!(@export $Ty);
331-
impl_property_by_clone!(@type_string_hint $Ty, $variant_type);
319+
macro_rules! impl_property_by_godot_convert {
320+
($Ty:ty, no_export) => {
321+
impl_property_by_godot_convert!(@property $Ty);
322+
impl_property_by_godot_convert!(@type_string_hint $Ty);
332323
};
333324

334-
($Ty:ty => $variant_type:ident; $type_string_name:ident) => {
335-
impl_property_by_clone!(@property $Ty => $variant_type);
336-
impl_property_by_clone!(@export $Ty);
337-
impl_property_by_clone!(@type_string_hint $Ty, $type_string_name);
325+
($Ty:ty) => {
326+
impl_property_by_godot_convert!(@property $Ty);
327+
impl_property_by_godot_convert!(@export $Ty);
328+
impl_property_by_godot_convert!(@type_string_hint $Ty);
338329
};
339330

340-
(@property $Ty:ty => $variant_type:ident) => {
331+
(@property $Ty:ty) => {
341332
impl Var for $Ty {
342-
type Intermediate = Self;
343-
344-
fn get_property(&self) -> Self {
345-
self.clone()
333+
fn get_property(&self) -> Self::Via {
334+
self.to_godot()
346335
}
347336

348-
fn set_property(&mut self, value: Self) {
349-
*self = value;
337+
fn set_property(&mut self, value: Self::Via) {
338+
*self = FromGodot::from_godot(value);
350339
}
351340
}
352341
};
@@ -359,82 +348,83 @@ mod export_impls {
359348
}
360349
};
361350

362-
(@type_string_hint $Ty:ty, $type_string_name:ident) => {
351+
(@type_string_hint $Ty:ty) => {
363352
impl TypeStringHint for $Ty {
364353
fn type_string() -> String {
365354
use sys::GodotFfi;
366355
let variant_type = <$Ty as $crate::builtin::meta::GodotType>::Ffi::variant_type();
367-
format!("{}:{}", variant_type as i32, stringify!($type_string_name))
356+
let type_name = <$Ty as $crate::builtin::meta::GodotType>::godot_type_name();
357+
format!("{}:{}", variant_type as i32, type_name)
368358
}
369359
}
370360
}
371361
}
372362

373363
// Bounding Boxes
374-
impl_property_by_clone!(Aabb => Aabb; AABB);
375-
impl_property_by_clone!(Rect2 => Rect2);
376-
impl_property_by_clone!(Rect2i => Rect2i);
364+
impl_property_by_godot_convert!(Aabb);
365+
impl_property_by_godot_convert!(Rect2);
366+
impl_property_by_godot_convert!(Rect2i);
377367

378368
// Matrices
379-
impl_property_by_clone!(Basis => Basis);
380-
impl_property_by_clone!(Transform2D => Transform2D);
381-
impl_property_by_clone!(Transform3D => Transform3D);
382-
impl_property_by_clone!(Projection => Projection);
369+
impl_property_by_godot_convert!(Basis);
370+
impl_property_by_godot_convert!(Transform2D);
371+
impl_property_by_godot_convert!(Transform3D);
372+
impl_property_by_godot_convert!(Projection);
383373

384374
// Vectors
385-
impl_property_by_clone!(Vector2 => Vector2);
386-
impl_property_by_clone!(Vector2i => Vector2i);
387-
impl_property_by_clone!(Vector3 => Vector3);
388-
impl_property_by_clone!(Vector3i => Vector3i);
389-
impl_property_by_clone!(Vector4 => Vector4);
390-
impl_property_by_clone!(Vector4i => Vector4i);
375+
impl_property_by_godot_convert!(Vector2);
376+
impl_property_by_godot_convert!(Vector2i);
377+
impl_property_by_godot_convert!(Vector3);
378+
impl_property_by_godot_convert!(Vector3i);
379+
impl_property_by_godot_convert!(Vector4);
380+
impl_property_by_godot_convert!(Vector4i);
391381

392382
// Misc Math
393-
impl_property_by_clone!(Quaternion => Quaternion);
394-
impl_property_by_clone!(Plane => Plane);
383+
impl_property_by_godot_convert!(Quaternion);
384+
impl_property_by_godot_convert!(Plane);
395385

396386
// Stringy Types
397-
impl_property_by_clone!(GString => String);
398-
impl_property_by_clone!(StringName => StringName);
399-
impl_property_by_clone!(NodePath => NodePath);
387+
impl_property_by_godot_convert!(GString);
388+
impl_property_by_godot_convert!(StringName);
389+
impl_property_by_godot_convert!(NodePath);
400390

401-
impl_property_by_clone!(Color => Color);
391+
impl_property_by_godot_convert!(Color);
402392

403393
// Arrays
404-
impl_property_by_clone!(PackedByteArray => PackedByteArray);
405-
impl_property_by_clone!(PackedInt32Array => PackedInt32Array);
406-
impl_property_by_clone!(PackedInt64Array => PackedInt64Array);
407-
impl_property_by_clone!(PackedFloat32Array => PackedFloat32Array);
408-
impl_property_by_clone!(PackedFloat64Array => PackedFloat64Array);
409-
impl_property_by_clone!(PackedStringArray => PackedStringArray);
410-
impl_property_by_clone!(PackedVector2Array => PackedVector2Array);
411-
impl_property_by_clone!(PackedVector3Array => PackedVector3Array);
412-
impl_property_by_clone!(PackedColorArray => PackedColorArray);
394+
impl_property_by_godot_convert!(PackedByteArray);
395+
impl_property_by_godot_convert!(PackedInt32Array);
396+
impl_property_by_godot_convert!(PackedInt64Array);
397+
impl_property_by_godot_convert!(PackedFloat32Array);
398+
impl_property_by_godot_convert!(PackedFloat64Array);
399+
impl_property_by_godot_convert!(PackedStringArray);
400+
impl_property_by_godot_convert!(PackedVector2Array);
401+
impl_property_by_godot_convert!(PackedVector3Array);
402+
impl_property_by_godot_convert!(PackedColorArray);
413403

414404
// Primitives
415-
impl_property_by_clone!(f64 => Float; float);
416-
impl_property_by_clone!(i64 => Int; int);
417-
impl_property_by_clone!(bool => Bool; bool);
405+
impl_property_by_godot_convert!(f64);
406+
impl_property_by_godot_convert!(i64);
407+
impl_property_by_godot_convert!(bool);
418408

419409
// Godot uses f64 internally for floats, and if Godot tries to pass an invalid f32 into a rust property
420410
// then the property will just round the value or become inf.
421-
impl_property_by_clone!(f32 => Float; float);
411+
impl_property_by_godot_convert!(f32);
422412

423413
// Godot uses i64 internally for integers, and if Godot tries to pass an invalid integer into a property
424414
// accepting one of the below values then rust will panic. In the editor this will appear as the property
425415
// failing to be set to a value and an error printed in the console. During runtime this will crash the
426416
// program and print the panic from rust stating that the property cannot store the value.
427-
impl_property_by_clone!(i32 => Int; int);
428-
impl_property_by_clone!(i16 => Int; int);
429-
impl_property_by_clone!(i8 => Int; int);
430-
impl_property_by_clone!(u32 => Int; int);
431-
impl_property_by_clone!(u16 => Int; int);
432-
impl_property_by_clone!(u8 => Int; int);
417+
impl_property_by_godot_convert!(i32);
418+
impl_property_by_godot_convert!(i16);
419+
impl_property_by_godot_convert!(i8);
420+
impl_property_by_godot_convert!(u32);
421+
impl_property_by_godot_convert!(u16);
422+
impl_property_by_godot_convert!(u8);
433423

434424
// Callables and Signals are useless when exported to the editor, so we only need to make them available as
435425
// properties.
436-
impl_property_by_clone!(Callable => Callable, no_export);
437-
impl_property_by_clone!(Signal => Signal, no_export);
426+
impl_property_by_godot_convert!(Callable, no_export);
427+
impl_property_by_godot_convert!(Signal, no_export);
438428

439429
// RIDs when exported act slightly weird. They are largely read-only, however you can reset them to their
440430
// default value. This seems to me very unintuitive. Since if we are storing an RID we would likely not
@@ -443,7 +433,7 @@ mod export_impls {
443433
//
444434
// Additionally, RIDs aren't persistent, and can sometimes behave a bit weirdly when passed from the
445435
// editor to the runtime.
446-
impl_property_by_clone!(Rid => Rid, no_export; RID);
436+
impl_property_by_godot_convert!(Rid, no_export);
447437

448-
// impl_property_by_clone!(Signal => Signal);
438+
// impl_property_by_godot_convert!(Signal);
449439
}

godot-macros/src/class/data_models/field_var.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -168,15 +168,15 @@ impl GetterSetterImpl {
168168
match kind {
169169
GetSet::Get => {
170170
signature = quote! {
171-
fn #function_name(&self) -> <#field_type as ::godot::register::property::Var>::Intermediate
171+
fn #function_name(&self) -> <#field_type as ::godot::builtin::meta::GodotConvert>::Via
172172
};
173173
function_body = quote! {
174174
<#field_type as ::godot::register::property::Var>::get_property(&self.#field_name)
175175
};
176176
}
177177
GetSet::Set => {
178178
signature = quote! {
179-
fn #function_name(&mut self, #field_name: <#field_type as ::godot::register::property::Var>::Intermediate)
179+
fn #function_name(&mut self, #field_name: <#field_type as ::godot::builtin::meta::GodotConvert>::Via)
180180
};
181181
function_body = quote! {
182182
<#field_type as ::godot::register::property::Var>::set_property(&mut self.#field_name, #field_name);

godot-macros/src/derive/derive_godot_convert.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use proc_macro2::TokenStream;
99
use quote::quote;
1010
use venial::Declaration;
1111

12-
use crate::util::{decl_get_info, DeclInfo};
12+
use crate::util::{decl_get_info, via_type, DeclInfo};
1313
use crate::ParseResult;
1414

1515
pub fn derive_godot_convert(decl: Declaration) -> ParseResult<TokenStream> {
@@ -22,9 +22,11 @@ pub fn derive_godot_convert(decl: Declaration) -> ParseResult<TokenStream> {
2222

2323
let gen = generic_params.as_ref().map(|x| x.as_inline_args());
2424

25+
let via_type = via_type(&decl)?;
26+
2527
Ok(quote! {
2628
impl #generic_params ::godot::builtin::meta::GodotConvert for #name #gen #where_ {
27-
type Via = ::godot::builtin::Variant;
29+
type Via = #via_type;
2830
}
2931
})
3032
}

0 commit comments

Comments
 (0)