7
7
8
8
//! Registration support for property types.
9
9
10
+ use crate :: builtin:: meta:: { FromGodot , GodotConvert , ToGodot } ;
10
11
use crate :: builtin:: GString ;
11
12
use crate :: engine:: global:: PropertyHint ;
12
13
@@ -17,11 +18,12 @@ use crate::engine::global::PropertyHint;
17
18
///
18
19
/// This creates a copy of the value, according to copy semantics provided by `Clone`. For example, `Array`, `Dictionary` and `Gd` are
19
20
/// 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 ) ;
25
27
26
28
fn property_hint ( ) -> PropertyHintInfo {
27
29
PropertyHintInfo :: with_hint_none ( "" )
@@ -59,21 +61,20 @@ impl<T: TypeStringHint> TypeStringHint for Option<T> {
59
61
60
62
impl < T > Var for Option < T >
61
63
where
62
- T : Var + From < <T as Var >:: Intermediate > ,
64
+ T : Var + FromGodot ,
65
+ Option < T > : GodotConvert < Via = Option < T :: Via > > ,
63
66
{
64
- type Intermediate = Option < T :: Intermediate > ;
65
-
66
- fn get_property ( & self ) -> Self :: Intermediate {
67
+ fn get_property ( & self ) -> Self :: Via {
67
68
self . as_ref ( ) . map ( Var :: get_property)
68
69
}
69
70
70
- fn set_property ( & mut self , value : Self :: Intermediate ) {
71
+ fn set_property ( & mut self , value : Self :: Via ) {
71
72
match value {
72
73
Some ( value) => {
73
74
if let Some ( current_value) = self {
74
75
current_value. set_property ( value)
75
76
} else {
76
- * self = Some ( T :: from ( value) )
77
+ * self = Some ( FromGodot :: from_godot ( value) )
77
78
}
78
79
}
79
80
None => * self = None ,
83
84
84
85
impl < T > Export for Option < T >
85
86
where
86
- T : Export + From < <T as Var >:: Intermediate > ,
87
+ T : Export ,
88
+ Option < T > : Var ,
87
89
{
88
90
fn default_export_info ( ) -> PropertyHintInfo {
89
91
T :: default_export_info ( )
@@ -314,39 +316,26 @@ mod export_impls {
314
316
use crate :: builtin:: * ;
315
317
use godot_ffi as sys;
316
318
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) ;
332
323
} ;
333
324
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) ;
338
329
} ;
339
330
340
- ( @property $Ty: ty => $variant_type : ident ) => {
331
+ ( @property $Ty: ty) => {
341
332
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( )
346
335
}
347
336
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) ;
350
339
}
351
340
}
352
341
} ;
@@ -359,82 +348,83 @@ mod export_impls {
359
348
}
360
349
} ;
361
350
362
- ( @type_string_hint $Ty: ty, $type_string_name : ident ) => {
351
+ ( @type_string_hint $Ty: ty) => {
363
352
impl TypeStringHint for $Ty {
364
353
fn type_string( ) -> String {
365
354
use sys:: GodotFfi ;
366
355
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)
368
358
}
369
359
}
370
360
}
371
361
}
372
362
373
363
// 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 ) ;
377
367
378
368
// 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 ) ;
383
373
384
374
// 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 ) ;
391
381
392
382
// 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 ) ;
395
385
396
386
// 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 ) ;
400
390
401
- impl_property_by_clone ! ( Color => Color ) ;
391
+ impl_property_by_godot_convert ! ( Color ) ;
402
392
403
393
// 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 ) ;
413
403
414
404
// 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 ) ;
418
408
419
409
// Godot uses f64 internally for floats, and if Godot tries to pass an invalid f32 into a rust property
420
410
// 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 ) ;
422
412
423
413
// Godot uses i64 internally for integers, and if Godot tries to pass an invalid integer into a property
424
414
// accepting one of the below values then rust will panic. In the editor this will appear as the property
425
415
// failing to be set to a value and an error printed in the console. During runtime this will crash the
426
416
// 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 ) ;
433
423
434
424
// Callables and Signals are useless when exported to the editor, so we only need to make them available as
435
425
// 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) ;
438
428
439
429
// RIDs when exported act slightly weird. They are largely read-only, however you can reset them to their
440
430
// 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 {
443
433
//
444
434
// Additionally, RIDs aren't persistent, and can sometimes behave a bit weirdly when passed from the
445
435
// editor to the runtime.
446
- impl_property_by_clone ! ( Rid => Rid , no_export; RID ) ;
436
+ impl_property_by_godot_convert ! ( Rid , no_export) ;
447
437
448
- // impl_property_by_clone!(Signal => Signal);
438
+ // impl_property_by_godot_convert!( Signal);
449
439
}
0 commit comments