Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
319 changes: 205 additions & 114 deletions derive/src/attribute_ops.rs

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions derive/src/impl_attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ pub fn godot_script_impl(
name: stringify!(#arg_name),
ty: #arg_type,
class_name: <<#arg_rust_type as #godot_types::meta::GodotConvert>::Via as #godot_types::meta::GodotType>::class_id(),
exported: false,
usage: #godot_types::global::PropertyUsageFlags::NONE,
hint: #property_hints::NONE,
hint_string: String::new(),
description: "",
Expand Down Expand Up @@ -135,7 +135,7 @@ pub fn godot_script_impl(
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(),
exported: false,
usage: #godot_types::global::PropertyUsageFlags::NONE,
hint: #property_hints::NONE,
hint_string: String::new(),
description: "",
Expand Down
37 changes: 25 additions & 12 deletions derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ mod enums;
mod impl_attribute;
mod type_paths;

use attribute_ops::{FieldOpts, GodotScriptOpts};
use darling::{util::SpannedValue, FromAttributes, FromDeriveInput, FromMeta};
use itertools::Itertools;
use proc_macro2::TokenStream;
use quote::{quote, quote_spanned, ToTokens};
use syn::{parse_macro_input, spanned::Spanned, DeriveInput, Ident, Type};
use type_paths::{godot_types, property_hints, string_name_ty, variant_ty};

use crate::attribute_ops::{FieldExportOps, FieldSignalOps, PropertyOpts};
use crate::attribute_ops::{
ExportMetadata, FieldExportOps, FieldOpts, FieldSignalOps, GodotScriptOpts, PropertyOpts,
};
use crate::type_paths::{godot_types, property_hints, property_usage, string_name_ty, variant_ty};

#[proc_macro_derive(GodotScript, attributes(export, script, prop, signal))]
pub fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
Expand Down Expand Up @@ -383,6 +384,7 @@ fn derive_field_metadata(
) -> Result<TokenStream, TokenStream> {
let godot_types = godot_types();
let property_hint_ty = property_hints();
let property_usage_ty = property_usage();
let name = field
.ident
.as_ref()
Expand All @@ -392,19 +394,30 @@ fn derive_field_metadata(
let rust_ty = &field.ty;
let ty = rust_to_variant_type(&field.ty)?;

let (hint, hint_string) = is_exported
let ExportMetadata {
field: _,
usage,
hint,
hint_string,
} = is_exported
.then(|| {
let ops =
FieldExportOps::from_attributes(&field.attrs).map_err(|err| err.write_errors())?;
let span = field
.attrs
.iter()
.find(|attr| attr.path().is_ident("export"))
.expect("FieldExportOps already succeded")
.span();

ops.hint(&field.ty)
ops.to_export_meta(&field.ty, span)
})
.transpose()?
.unwrap_or_else(|| {
(
quote_spanned!(field.span()=> #property_hint_ty::NONE),
quote_spanned!(field.span()=> String::new()),
)
.unwrap_or_else(|| ExportMetadata {
field: "",
usage: quote_spanned!(field.span() => #property_usage_ty::SCRIPT_VARIABLE),
hint: quote_spanned!(field.span()=> #property_hint_ty::NONE),
hint_string: quote_spanned!(field.span()=> String::new()),
});

let description = get_field_description(field);
Expand All @@ -413,7 +426,7 @@ fn derive_field_metadata(
name: #name,
ty: #ty,
class_name: <<#rust_ty as #godot_types::meta::GodotConvert>::Via as #godot_types::meta::GodotType>::class_id(),
exported: #is_exported,
usage: #usage,
hint: #hint,
hint_string: #hint_string,
description: concat!(#description),
Expand Down Expand Up @@ -530,7 +543,7 @@ fn extract_ident_from_type(impl_target: &syn::Type) -> Result<Ident, TokenStream
Type::Macro(_) => Err(compile_error("Macro types are not supported!", impl_target)),
Type::Never(_) => Err(compile_error("Never type is not supported!", impl_target)),
Type::Paren(_) => Err(compile_error("Unsupported type!", impl_target)),
Type::Path(ref path) => Ok(path.path.segments.last().unwrap().ident.clone()),
Type::Path(path) => Ok(path.path.segments.last().unwrap().ident.clone()),
Type::Ptr(_) => Err(compile_error(
"Pointer types are not supported!",
impl_target,
Expand Down
12 changes: 12 additions & 0 deletions derive/src/type_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,40 @@
use proc_macro2::TokenStream;
use quote::quote;

#[inline]
pub fn godot_types() -> TokenStream {
quote!(::godot_rust_script::godot)
}

#[inline]
pub fn property_hints() -> TokenStream {
let godot_types = godot_types();

quote!(#godot_types::global::PropertyHint)
}

#[inline]
pub fn property_usage() -> TokenStream {
let godot_types = godot_types();

quote!(#godot_types::global::PropertyUsageFlags)
}

#[inline]
pub fn variant_ty() -> TokenStream {
let godot_types = godot_types();

quote!(#godot_types::prelude::Variant)
}

#[inline]
pub fn string_name_ty() -> TokenStream {
let godot_types = godot_types();

quote!(#godot_types::prelude::StringName)
}

#[inline]
pub fn convert_error_ty() -> TokenStream {
let godot_types = godot_types();

Expand Down
4 changes: 2 additions & 2 deletions rust-script/src/interface/signals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use godot::builtin::{
Callable, Dictionary, GString, NodePath, StringName, Variant, Vector2, Vector3, Vector4,
};
use godot::classes::Object;
use godot::global::{Error, PropertyHint};
use godot::global::{Error, PropertyHint, PropertyUsageFlags};
use godot::meta::{ByValue, GodotConvert, GodotType, ToGodot};
use godot::obj::{Gd, GodotClass};

Expand Down Expand Up @@ -113,7 +113,7 @@ macro_rules! signal_argument_desc {
name: $name,
ty: <<<$type as GodotConvert>::Via as GodotType>::Ffi as godot::sys::GodotFfi>::VARIANT_TYPE.variant_as_nil(),
class_name: <<$type as GodotConvert>::Via as GodotType>::class_id(),
exported: false,
usage: PropertyUsageFlags::NONE,
hint: PropertyHint::NONE,
hint_string: String::new(),
description: "",
Expand Down
8 changes: 2 additions & 6 deletions rust-script/src/static_script_registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ pub struct RustScriptPropDesc {
pub name: &'static str,
pub ty: VariantType,
pub class_name: ClassId,
pub exported: bool,
pub usage: PropertyUsageFlags,
pub hint: PropertyHint,
pub hint_string: String,
pub description: &'static str,
Expand All @@ -96,11 +96,7 @@ impl RustScriptPropDesc {
variant_type: self.ty,
class_name: self.class_name,
property_name: self.name,
usage: if self.exported {
(PropertyUsageFlags::EDITOR | PropertyUsageFlags::STORAGE).ord()
} else {
PropertyUsageFlags::NONE.ord()
},
usage: self.usage.ord(),
hint: self.hint.ord(),
hint_string: self.hint_string.clone(),
description: self.description,
Expand Down
6 changes: 4 additions & 2 deletions rust-script/tests/script_derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use godot::builtin::{Array, GString};
use godot::classes::{Node, Node3D};
use godot::global::PropertyHint;
use godot::obj::{Gd, NewAlloc};
use godot_rust_script::{
godot_script_impl, CastToScript, Context, GodotScript, GodotScriptEnum, OnEditor, RsRef,
Expand Down Expand Up @@ -58,14 +59,15 @@ struct TestScript {
#[export(range(min = 0.0, max = 10.0))]
pub int_range: u32,

#[export]
#[export(storage)]
pub custom_enum: ScriptEnum,

#[export]
pub script_ref_opt: Option<RsRef<TestScript>>,

#[export]
#[export(custom(hint = PropertyHint::NODE_TYPE, hint_string = ""))]
pub script_ref: OnEditor<RsRef<TestScript>>,

base: Gd<<Self as GodotScript>::Base>,
}

Expand Down
Loading