Godot.Sharp.Extended/ActionGenerator.cs
2025-09-26 03:13:44 -05:00

71 lines
No EOL
2.1 KiB
C#

using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Text;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Text;
namespace Godot.Sharp.Extended.Generators;
[Generator]
public class ActionGenerator : IIncrementalGenerator
{
public void Initialize(IncrementalGeneratorInitializationContext context)
{
var projectFile = context.AdditionalTextsProvider
.Where(file => file.Path.EndsWith("project.godot"))
.Select((file, token) => file.GetText())
.Collect();
context.RegisterSourceOutput(projectFile, GenerateCode);
}
private void GenerateCode(SourceProductionContext ctx, ImmutableArray<SourceText> texts)
{
var memberCode = new StringBuilder();
foreach (var text in texts)
{
if (text == null) continue;
var content = text.ToString();
var inputs = GetActions(content);
var fields = inputs.Select(keyData => $$"""\tpublic static StringName {{keyData.ToPascalCase()}} = "{{keyData}}";""");
foreach (var field in fields) memberCode.AppendLine(field);
}
var code = $$"""
// <auto-generated />
using System;
using Godot;
namespace Godot.Sharp.Extended;
public partial class Actions
{
{{memberCode}}
}
""";
ctx.AddSource("Godot.Sharp.Extended.Actions.g.cs", SourceText.From(code, Encoding.UTF8));
}
public List<string> GetActions(string content)
{
var results = new List<string>();
var inputSection = false;
foreach (var line in content.Split(['\n']))
{
if (line.Equals("[input]"))
inputSection = true;
else if (line.StartsWith("[") && inputSection) break;
if (!inputSection) continue;
var kv = line.Split(['='], 2);
if (kv.Length == 2) results.Add(kv[0].Trim());
}
return results;
}
}