Skip to content

Commit 252fc40

Browse files
committed
Support OnEditor in scripts
1 parent 91c1391 commit 252fc40

File tree

6 files changed

+98
-11
lines changed

6 files changed

+98
-11
lines changed

derive/src/enums.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,16 @@ pub fn script_enum_derive(input: proc_macro::TokenStream) -> proc_macro::TokenSt
136136
}
137137
}
138138

139+
impl #godot_types::prelude::Var for #enum_ident {
140+
fn get_property(&self) -> Self::Via {
141+
self.into()
142+
}
143+
144+
fn set_property(&mut self, value: Self::Via) {
145+
*self = #godot_types::meta::FromGodot::try_from_godot(value).unwrap();
146+
}
147+
}
148+
139149
#derive_export
140150
};
141151

derive/src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ fn derive_get_field_dispatch(field: &SpannedValue<FieldOpts>) -> TokenStream {
279279

280280
quote_spanned! {field.ty.span()=>
281281
#[allow(clippy::needless_borrow)]
282-
#field_name => Some(#godot_types::prelude::ToGodot::to_variant(&#accessor)),
282+
#field_name => Some(#godot_types::prelude::ToGodot::to_variant(&::godot_rust_script::GetScriptProperty::get_property(&#accessor))),
283283
}
284284
}
285285

@@ -313,7 +313,9 @@ fn derive_set_field_dispatch(field: &SpannedValue<FieldOpts>) -> TokenStream {
313313

314314
let assignment = match opts.set {
315315
Some(setter) => quote_spanned!(setter.span()=> #setter(self, local_value)),
316-
None => quote_spanned!(field.ty.span() => self.#field_ident = local_value),
316+
None => {
317+
quote_spanned!(field.ty.span() => ::godot_rust_script::SetScriptProperty::set_property(&mut self.#field_ident, local_value))
318+
}
317319
};
318320

319321
quote! {

rust-script/src/interface.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,20 @@ impl<T: GodotScript> ToGodot for RsRef<T> {
135135
}
136136
}
137137

138+
impl<'v, T: GodotScript> ::godot::prelude::Var for RsRef<T>
139+
where
140+
Self: GodotConvert<Via = <Self as ToGodot>::ToVia<'v>>,
141+
Self: 'v,
142+
{
143+
fn get_property(&self) -> Self::Via {
144+
<Self as ToGodot>::to_godot(&self)
145+
}
146+
147+
fn set_property(&mut self, value: Self::Via) {
148+
<Self as FromGodot>::from_godot(value);
149+
}
150+
}
151+
138152
#[derive(thiserror::Error, Debug)]
139153
pub enum GodotScriptCastError {
140154
#[error("Object has no script attached!")]
@@ -196,6 +210,42 @@ impl<T: GodotScript, B: Inherits<T::Base> + Inherits<Object>> CastToScript<T> fo
196210
}
197211
}
198212

213+
/// Script property access indirection
214+
///
215+
/// gdext uses this kind of indirection to allow conversion of the actual property value into a godot compatible type when accessing the
216+
/// property from the engine. This Trait separates the `::godot::prelude::Var` trait into it's get and set components for more granular
217+
/// requirements on the property types.
218+
pub trait GetScriptProperty: GodotConvert {
219+
fn get_property(&self) -> Self::Via;
220+
}
221+
222+
/// Script property write indirection
223+
///
224+
/// gdext uses this kind of indirection to allow conversion of the actual property value from a godot compatible type when setting the
225+
/// property from the engine. This Trait separates the `::godot::prelude::Var` trait into it's get and set components for more granular
226+
/// requirements on the property types.
227+
pub trait SetScriptProperty: GodotConvert {
228+
fn set_property(&mut self, value: Self::Via);
229+
}
230+
231+
impl<T> GetScriptProperty for T
232+
where
233+
T: godot::prelude::Var,
234+
{
235+
fn get_property(&self) -> Self::Via {
236+
T::get_property(self)
237+
}
238+
}
239+
240+
impl<T> SetScriptProperty for T
241+
where
242+
T: godot::prelude::Var,
243+
{
244+
fn set_property(&mut self, value: Self::Via) {
245+
T::set_property(self, value);
246+
}
247+
}
248+
199249
#[macro_export]
200250
macro_rules! define_script_root {
201251
() => {

rust-script/src/interface/export.rs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,16 @@ use godot::builtin::{
1515
};
1616
use godot::classes::{Node, Resource};
1717
use godot::global::PropertyHint;
18-
use godot::meta::{ArrayElement, FromGodot, GodotConvert, GodotType, ToGodot};
19-
use godot::obj::{EngineEnum, Gd};
18+
use godot::meta::{ArrayElement, GodotConvert, GodotType};
19+
use godot::obj::{EngineEnum, Gd, OnEditor};
2020
use godot::prelude::GodotClass;
2121
use godot::sys::GodotFfi;
2222

23+
use crate::{GetScriptProperty, SetScriptProperty};
24+
2325
use super::{GodotScript, RsRef};
2426

25-
pub trait GodotScriptExport: GodotConvert + FromGodot + ToGodot {
27+
pub trait GodotScriptExport: GodotConvert + GetScriptProperty + SetScriptProperty {
2628
fn hint_string(custom_hint: Option<PropertyHint>, custom_string: Option<String>) -> String;
2729

2830
fn hint(custom: Option<PropertyHint>) -> PropertyHint;
@@ -78,11 +80,7 @@ impl<T: GodotScript> GodotScriptExport for RsRef<T> {
7880

7981
impl<T: GodotScriptExport> GodotScriptExport for Option<T>
8082
where
81-
for<'v> T: 'v,
82-
for<'v> <<T as ToGodot>::ToVia<'v> as GodotType>::Ffi: godot::sys::GodotNullableFfi,
83-
for<'f> <<T as GodotConvert>::Via as GodotType>::ToFfi<'f>: godot::sys::GodotNullableFfi,
84-
<<T as GodotConvert>::Via as GodotType>::Ffi: godot::sys::GodotNullableFfi,
85-
for<'v, 'f> <<T as ToGodot>::ToVia<'v> as GodotType>::ToFfi<'f>: godot::sys::GodotNullableFfi,
83+
Self: GodotConvert,
8684
{
8785
fn hint_string(custom_hint: Option<PropertyHint>, custom_string: Option<String>) -> String {
8886
T::hint_string(custom_hint, custom_string)
@@ -113,6 +111,19 @@ impl<T: ArrayElement + GodotScriptExport + GodotType> GodotScriptExport for Arra
113111
}
114112
}
115113

114+
impl<T: GodotScriptExport> GodotScriptExport for OnEditor<T>
115+
where
116+
Self: GodotConvert,
117+
{
118+
fn hint_string(custom_hint: Option<PropertyHint>, custom_string: Option<String>) -> String {
119+
T::hint_string(custom_hint, custom_string)
120+
}
121+
122+
fn hint(custom: Option<PropertyHint>) -> PropertyHint {
123+
T::hint(custom)
124+
}
125+
}
126+
116127
macro_rules! default_export {
117128
($ty:ty) => {
118129
impl GodotScriptExport for $ty {

rust-script/src/interface/signals.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ use godot::obj::{Gd, GodotClass};
1717
use crate::static_script_registry::RustScriptPropDesc;
1818
use crate::{GodotScript, RsRef};
1919

20+
use super::GetScriptProperty;
21+
2022
pub trait SignalArguments {
2123
const COUNT: u8;
2224

@@ -220,3 +222,9 @@ impl<T: SignalArguments> ToGodot for ScriptSignal<T> {
220222
godot::builtin::Signal::from_object_signal(&self.host, self.name)
221223
}
222224
}
225+
226+
impl<T: SignalArguments> GetScriptProperty for ScriptSignal<T> {
227+
fn get_property(&self) -> Self::Via {
228+
self.to_godot()
229+
}
230+
}

rust-script/tests/script_derive.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
use godot::builtin::{Array, GString};
88
use godot::classes::{Node, Node3D};
9-
use godot::obj::{Gd, NewAlloc};
9+
use godot::obj::{Gd, NewAlloc, OnEditor};
1010
use godot_rust_script::{
1111
godot_script_impl, CastToScript, Context, GodotScript, GodotScriptEnum, RsRef, ScriptSignal,
1212
};
@@ -48,6 +48,9 @@ struct TestScript {
4848
#[export(ty = "Decal")]
4949
pub node_prop_2: Option<Gd<Node3D>>,
5050

51+
#[export(ty = "Decal")]
52+
pub node_prop_3: OnEditor<Gd<Node3D>>,
53+
5154
#[export]
5255
pub node_array: Array<Gd<Node3D>>,
5356

@@ -57,6 +60,9 @@ struct TestScript {
5760
#[export]
5861
pub custom_enum: ScriptEnum,
5962

63+
#[export]
64+
pub script_ref: RsRef<TestScript>,
65+
6066
base: Gd<<Self as GodotScript>::Base>,
6167
}
6268

0 commit comments

Comments
 (0)