diff --git a/derive/src/impl_attribute.rs b/derive/src/impl_attribute.rs index 68e9438..3eb3bc7 100644 --- a/derive/src/impl_attribute.rs +++ b/derive/src/impl_attribute.rs @@ -112,9 +112,9 @@ pub fn godot_script_impl( }; let method_flag = if is_static { - quote!(#godot_types::global::MethodFlags::STATIC) + quote!(.with_flags(#godot_types::global::MethodFlags::STATIC)) } else { - quote!(#godot_types::global::MethodFlags::NORMAL) + TokenStream::new() }; let description = fnc.attrs.iter() @@ -128,32 +128,38 @@ pub fn godot_script_impl( let metadata = quote_spanned! { fnc.span() => - ::godot_rust_script::private_export::RustScriptMethodDesc { - name: #fn_name_str, - arguments: Box::new([#args_meta]), - return_type: ::godot_rust_script::private_export::RustScriptPropDesc { - name: #fn_name_str, - ty: #fn_return_ty, - class_name: <<#fn_return_ty_rust as #godot_types::meta::GodotConvert>::Via as #godot_types::meta::GodotType>::class_id(), - usage: #godot_types::global::PropertyUsageFlags::NONE, - hint: #property_hints::NONE, - hint_string: String::new(), - description: "", - }, - flags: #method_flag, - description: concat!(#description), - }, + methods.add_method( + ::godot_rust_script::private_export::RustScriptMethodDesc::builder( + #fn_name_str, + Box::new([#args_meta]), + ::godot_rust_script::private_export::RustScriptPropDesc { + name: #fn_name_str, + ty: #fn_return_ty, + class_name: <<#fn_return_ty_rust as #godot_types::meta::GodotConvert>::Via as #godot_types::meta::GodotType>::class_id(), + usage: #godot_types::global::PropertyUsageFlags::NONE, + hint: #property_hints::NONE, + hint_string: String::new(), + description: "", + }, + ) + .with_description(concat!(#description)) + #method_flag + ); }; Ok((dispatch, metadata)) }) .collect(); - let (method_dispatch, method_metadata): (TokenStream, TokenStream) = match result { - Ok(r) => r.into_iter().unzip(), + let method_list = match result { + Ok(r) => r, Err(err) => return err, }; + let method_count = method_list.len(); + let (method_dispatch, method_metadata): (TokenStream, TokenStream) = + method_list.into_iter().unzip(); + let trait_impl = quote_spanned! { current_type.span() => impl ::godot_rust_script::GodotScriptImpl for #current_type { @@ -173,9 +179,10 @@ pub fn godot_script_impl( let metadata = quote! { ::godot_rust_script::register_script_methods!( #current_type, - vec![ + #method_count, + methods => { #method_metadata - ] + } ); }; diff --git a/rust-script/src/interface.rs b/rust-script/src/interface.rs index e2f0bed..f7187d4 100644 --- a/rust-script/src/interface.rs +++ b/rust-script/src/interface.rs @@ -213,7 +213,7 @@ impl + Inherits> CastToScript fo /// Script property access indirection /// -/// gdext uses this kind of indirection to allow conversion of the actual property value into a godot compatible type when accessing the +/// Gdext uses this kind of indirection to allow conversion of the actual property value into a Godot compatible type when accessing the /// property from the engine. This Trait separates the `::godot::prelude::Var` trait into it's get and set components for more granular /// requirements on the property types. pub trait GetScriptProperty: GodotConvert { @@ -222,7 +222,7 @@ pub trait GetScriptProperty: GodotConvert { /// Script property write indirection /// -/// gdext uses this kind of indirection to allow conversion of the actual property value from a godot compatible type when setting the +/// Gdext uses this kind of indirection to allow conversion of the actual property value from a Godot compatible type when setting the /// property from the engine. This Trait separates the `::godot::prelude::Var` trait into it's get and set components for more granular /// requirements on the property types. pub trait SetScriptProperty: GodotConvert { diff --git a/rust-script/src/runtime/metadata.rs b/rust-script/src/runtime/metadata.rs index 03985ba..810a092 100644 --- a/rust-script/src/runtime/metadata.rs +++ b/rust-script/src/runtime/metadata.rs @@ -140,8 +140,8 @@ pub struct Documented { description: &'static str, } -impl From for Documented { - fn from(value: crate::static_script_registry::RustScriptPropertyInfo) -> Self { +impl From for Documented { + fn from(value: crate::static_script_registry::RustScriptPropDesc) -> Self { Self { description: value.description, inner: (&value).into(), @@ -149,17 +149,17 @@ impl From for Documented< } } -impl From for Documented { - fn from(value: crate::static_script_registry::RustScriptMethodInfo) -> Self { +impl From for Documented { + fn from(value: crate::static_script_registry::RustScriptMethodDesc) -> Self { Self { description: value.description, - inner: (&value).into(), + inner: value.into(), } } } -impl From for Documented { - fn from(value: crate::static_script_registry::RustScriptSignalInfo) -> Self { +impl From for Documented { + fn from(value: crate::static_script_registry::RustScriptSignalDesc) -> Self { Self { description: value.description, inner: (&value).into(), diff --git a/rust-script/src/runtime/rust_script.rs b/rust-script/src/runtime/rust_script.rs index 0cdc09e..cfcd8e0 100644 --- a/rust-script/src/runtime/rust_script.rs +++ b/rust-script/src/runtime/rust_script.rs @@ -20,7 +20,7 @@ use godot::prelude::{ }; use crate::apply::Apply; -use crate::static_script_registry::RustScriptPropertyInfo; +use crate::private_export::RustScriptPropDesc; use super::rust_script_instance::GodotScriptObject; use super::{ @@ -39,7 +39,7 @@ pub(crate) struct RustScript { #[var(get = get_class_name, set = set_class_name, usage_flags = [STORAGE])] class_name: GString, - /// dummy property that stores the onwer ids when the extension gets reloaded by the engine. + /// Dummy property that stores the owner ids when the extension gets reloaded by the engine. #[var( get = owner_ids, set = set_owner_ids, usage_flags = [STORAGE])] #[allow(dead_code)] owner_ids: Array, @@ -94,7 +94,7 @@ impl RustScript { #[func] fn set_owner_ids(&mut self, ids: Array) { if ids.is_empty() { - // ignore empty owners list from engine + // Ignore empty owners list from engine return; } @@ -133,7 +133,7 @@ impl RustScript { base.call("_init", &[]); } - fn map_property_info_list(&self, f: impl Fn(&RustScriptPropertyInfo) -> R) -> Vec { + fn map_property_info_list(&self, f: impl Fn(&RustScriptPropDesc) -> R) -> Vec { let reg = SCRIPT_REGISTRY.read().expect("unable to obtain read lock"); reg.get(&self.str_class_name()) @@ -218,44 +218,48 @@ impl IScriptExtension for RustScript { } fn has_property_default_value(&self, _property: StringName) -> bool { - // default values are currently not exposed + // Default values are currently not exposed false } fn get_property_default_value(&self, #[expect(unused)] property: StringName) -> Variant { - // default values are currently not exposed + // Default values are currently not exposed Variant::nil() } fn get_script_signal_list(&self) -> Array { - let Some(script) = RustScriptLanguage::script_meta_data(&self.str_class_name()) else { - godot_error!( - "RustScript class {} does not exist in compiled dynamic library!", - self.str_class_name() - ); - return Array::new(); - }; + RustScriptLanguage::with_script_metadata(&self.str_class_name(), |script_data| { + let Some(script) = script_data else { + godot_error!( + "RustScript class {} does not exist in compiled dynamic library!", + self.str_class_name() + ); + return Array::new(); + }; - script - .signals() - .iter() - .map(|signal| MethodInfo::from(signal).to_dict()) - .collect() + script + .signals() + .iter() + .map(|signal| MethodInfo::from(signal).to_dict()) + .collect() + }) } fn has_script_signal(&self, name: StringName) -> bool { - let Some(script) = RustScriptLanguage::script_meta_data(&self.str_class_name()) else { - godot_error!( - "RustScript class {} does not exist in compiled dynamic library!", - self.str_class_name() - ); - return false; - }; + RustScriptLanguage::with_script_metadata(&self.str_class_name(), |script_data| { + let Some(script) = script_data else { + godot_error!( + "RustScript class {} does not exist in compiled dynamic library!", + self.str_class_name() + ); + return false; + }; - script - .signals() - .iter() - .any(|signal| signal.name == name.to_string()) + script + .signals() + .iter() + .any(|signal| signal.name == name.to_string()) + }) } fn update_exports(&mut self) {} @@ -268,7 +272,7 @@ impl IScriptExtension for RustScript { class .methods() .iter() - .map(|method| MethodInfo::from(method).to_dict()) + .map(|method| MethodInfo::from(method.clone()).to_dict()) .collect() }) .unwrap_or_default() @@ -295,7 +299,7 @@ impl IScriptExtension for RustScript { class .methods() .iter() - .any(|method| method.method_name == method_name.to_string()) + .any(|method| method.name == method_name.to_string()) }) } @@ -310,8 +314,8 @@ impl IScriptExtension for RustScript { class .methods() .iter() - .find(|method| method.method_name == method_name.to_string()) - .map(|method| MethodInfo::from(method).to_dict()) + .find(|method| method.name == method_name.to_string()) + .map(|method| MethodInfo::from(method.clone()).to_dict()) }) .unwrap_or_default() } @@ -386,10 +390,10 @@ impl IScriptExtension for RustScript { true } - // godot script reload hook + // Godot script reload hook fn reload( &mut self, - // before 4.4 the engine does not correctly pass the keep_state flag + // Before 4.4 the engine does not correctly pass the keep_state flag #[cfg_attr(before_api = "4.4", expect(unused_variables))] keep_state: bool, ) -> godot::global::Error { #[cfg(before_api = "4.4")] @@ -398,7 +402,9 @@ impl IScriptExtension for RustScript { let owners = self.owners.borrow().clone(); let exported_properties_list = if keep_state { self.map_property_info_list(|prop| { - (prop.usage & PropertyUsageFlags::EDITOR.ord() != 0).then_some(prop.property_name) + (prop.usage.ord() & PropertyUsageFlags::EDITOR.ord() + != PropertyUsageFlags::NONE.ord()) + .then_some(prop.name) }) } else { Vec::with_capacity(0) @@ -427,7 +433,7 @@ impl IScriptExtension for RustScript { Vec::with_capacity(0) }; - // clear script to destroy script instance. + // Clear script to destroy script instance. object.set_script(Option::<&Gd