From 431a28fe190fe78aa9f265b444d816442c5f7427 Mon Sep 17 00:00:00 2001 From: Zae Date: Tue, 23 Aug 2022 01:23:45 +0800 Subject: C#: Add grouping attributes for properties. --- .../Godot.SourceGenerators/GodotClasses.cs | 3 ++ .../ScriptPropertiesGenerator.cs | 49 ++++++++++++++++++++++ .../Core/Attributes/ExportCategoryAttribute.cs | 22 ++++++++++ .../Core/Attributes/ExportGroupAttribute.cs | 25 +++++++++++ .../Core/Attributes/ExportSubgroupAttribute.cs | 25 +++++++++++ .../glue/GodotSharp/GodotSharp/GodotSharp.csproj | 3 ++ 6 files changed, 127 insertions(+) create mode 100644 modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportCategoryAttribute.cs create mode 100644 modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportGroupAttribute.cs create mode 100644 modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportSubgroupAttribute.cs diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs index 9ba8bb89b8..e899440e10 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/GodotClasses.cs @@ -5,6 +5,9 @@ namespace Godot.SourceGenerators public const string Object = "Godot.Object"; public const string AssemblyHasScriptsAttr = "Godot.AssemblyHasScriptsAttribute"; public const string ExportAttr = "Godot.ExportAttribute"; + public const string ExportCategoryAttr = "Godot.ExportCategoryAttribute"; + public const string ExportGroupAttr = "Godot.ExportGroupAttribute"; + public const string ExportSubgroupAttr = "Godot.ExportSubgroupAttribute"; public const string SignalAttr = "Godot.SignalAttribute"; public const string GodotClassNameAttr = "Godot.GodotClassName"; public const string SystemFlagsAttr = "System.FlagsAttribute"; diff --git a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs index 12a369fd72..b4db3fda62 100644 --- a/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs +++ b/modules/mono/editor/Godot.NET.Sdk/Godot.SourceGenerators/ScriptPropertiesGenerator.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.CodeAnalysis; @@ -226,6 +227,9 @@ namespace Godot.SourceGenerators foreach (var property in godotClassProperties) { + foreach (var groupingInfo in DetermineGroupingPropertyInfo(property.PropertySymbol)) + AppendGroupingPropertyInfo(source, groupingInfo); + var propertyInfo = DeterminePropertyInfo(context, typeCache, property.PropertySymbol, property.Type); @@ -237,6 +241,10 @@ namespace Godot.SourceGenerators foreach (var field in godotClassFields) { + + foreach (var groupingInfo in DetermineGroupingPropertyInfo(field.FieldSymbol)) + AppendGroupingPropertyInfo(source, groupingInfo); + var propertyInfo = DeterminePropertyInfo(context, typeCache, field.FieldSymbol, field.Type); @@ -321,6 +329,21 @@ namespace Godot.SourceGenerators .Append(" }\n"); } + private static void AppendGroupingPropertyInfo(StringBuilder source, PropertyInfo propertyInfo) + { + source.Append(" properties.Add(new(type: (Godot.Variant.Type)") + .Append((int)VariantType.Nil) + .Append(", name: \"") + .Append(propertyInfo.Name) + .Append("\", hint: (Godot.PropertyHint)") + .Append((int)PropertyHint.None) + .Append(", hintString: \"") + .Append(propertyInfo.HintString) + .Append("\", usage: (Godot.PropertyUsageFlags)") + .Append((int)propertyInfo.Usage) + .Append(", exported: true));\n"); + } + private static void AppendPropertyInfo(StringBuilder source, PropertyInfo propertyInfo) { source.Append(" properties.Add(new(type: (Godot.Variant.Type)") @@ -338,6 +361,32 @@ namespace Godot.SourceGenerators .Append("));\n"); } + private static IEnumerable DetermineGroupingPropertyInfo(ISymbol memberSymbol) + { + foreach (var attr in memberSymbol.GetAttributes()) + { + PropertyUsageFlags? propertyUsage = attr.AttributeClass?.ToString() switch + { + GodotClasses.ExportCategoryAttr => PropertyUsageFlags.Category, + GodotClasses.ExportGroupAttr => PropertyUsageFlags.Group, + GodotClasses.ExportSubgroupAttr => PropertyUsageFlags.Subgroup, + _ => null + }; + + if (propertyUsage is null) + continue; + + if (attr.ConstructorArguments.Length > 0 && attr.ConstructorArguments[0].Value is string name) + { + string? hintString = null; + if (propertyUsage != PropertyUsageFlags.Category && attr.ConstructorArguments.Length > 1) + hintString = attr.ConstructorArguments[1].Value?.ToString(); + + yield return new PropertyInfo(VariantType.Nil, name, PropertyHint.None, hintString, propertyUsage.Value, true); + } + } + } + private static PropertyInfo? DeterminePropertyInfo( GeneratorExecutionContext context, MarshalUtils.TypeCache typeCache, diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportCategoryAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportCategoryAttribute.cs new file mode 100644 index 0000000000..101e56f8d3 --- /dev/null +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportCategoryAttribute.cs @@ -0,0 +1,22 @@ +using System; + +namespace Godot +{ + /// + /// Define a new category for the following exported properties. This helps to organize properties in the Inspector dock. + /// + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] + public sealed class ExportCategoryAttribute : Attribute + { + private string name; + + /// + /// Define a new category for the following exported properties. + /// + /// The name of the category. + public ExportCategoryAttribute(string name) + { + this.name = name; + } + } +} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportGroupAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportGroupAttribute.cs new file mode 100644 index 0000000000..3bd532cec1 --- /dev/null +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportGroupAttribute.cs @@ -0,0 +1,25 @@ +using System; + +namespace Godot +{ + /// + /// Define a new group for the following exported properties. This helps to organize properties in the Inspector dock. + /// + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] + public sealed class ExportGroupAttribute : Attribute + { + private string name; + private string prefix; + + /// + /// Define a new group for the following exported properties. + /// + /// The name of the group. + /// If provided, the group would make group to only consider properties that have this prefix. + public ExportGroupAttribute(string name, string prefix = "") + { + this.name = name; + this.prefix = prefix; + } + } +} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportSubgroupAttribute.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportSubgroupAttribute.cs new file mode 100644 index 0000000000..2ae6eb0b68 --- /dev/null +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Attributes/ExportSubgroupAttribute.cs @@ -0,0 +1,25 @@ +using System; + +namespace Godot +{ + /// + /// Define a new subgroup for the following exported properties. This helps to organize properties in the Inspector dock. + /// + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)] + public sealed class ExportSubgroupAttribute : Attribute + { + private string name; + private string prefix; + + /// + /// Define a new subgroup for the following exported properties. This helps to organize properties in the Inspector dock. + /// + /// The name of the subgroup. + /// If provided, the subgroup would make group to only consider properties that have this prefix. + public ExportSubgroupAttribute(string name, string prefix = "") + { + this.name = name; + this.prefix = prefix; + } + } +} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj index 111920ecf6..f0d6748b73 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj +++ b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj @@ -53,6 +53,9 @@ + + + -- cgit v1.2.3