64 lines
No EOL
2.2 KiB
C#
64 lines
No EOL
2.2 KiB
C#
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Text;
|
|
using Microsoft.CodeAnalysis;
|
|
using Microsoft.CodeAnalysis.Diagnostics;
|
|
using Microsoft.CodeAnalysis.Text;
|
|
|
|
namespace Godot.Sharp.Extended.Generators;
|
|
|
|
[Generator]
|
|
public class SceneGenerator : IIncrementalGenerator
|
|
{
|
|
public void Initialize(IncrementalGeneratorInitializationContext context)
|
|
{
|
|
var scenes = context.AdditionalTextsProvider
|
|
.Where(text => text.Path.EndsWith(".tscn"));
|
|
|
|
context.RegisterSourceOutput(
|
|
context.CompilationProvider.Combine(scenes.Collect()).Combine(context.AnalyzerConfigOptionsProvider),
|
|
(ctx, t) => GenerateCode(ctx, t.Left.Left, t.Left.Right, t.Right));
|
|
}
|
|
|
|
private void GenerateCode(
|
|
SourceProductionContext context,
|
|
Compilation compilation,
|
|
IEnumerable<AdditionalText> scenes,
|
|
AnalyzerConfigOptionsProvider optionsProvider)
|
|
{
|
|
optionsProvider.GlobalOptions.TryGetValue("build_property.projectdir", out var projectDirectory);
|
|
|
|
var allMethods = new StringBuilder();
|
|
foreach (var scene in scenes)
|
|
{
|
|
var directory = Path.GetDirectoryName(scene.Path);
|
|
var name = Path.GetFileNameWithoutExtension(scene.Path);
|
|
var relativePath = scene.Path.Replace(projectDirectory ?? "", "").Replace("\\", "/");
|
|
allMethods.AppendLine(
|
|
$$"""
|
|
public static T New{{name.ToPascalCase()}}<T>() where T : Node {
|
|
var packedScene = GD.Load<PackedScene>("res://{{relativePath}}");
|
|
return packedScene.Instance<T>();
|
|
}
|
|
""");
|
|
|
|
var code =
|
|
$$"""
|
|
// <auto-generated />
|
|
|
|
using System;
|
|
using Godot;
|
|
|
|
namespace Godot.Sharp.Extended;
|
|
|
|
public class Scenes
|
|
{
|
|
{{allMethods}}
|
|
}
|
|
""";
|
|
|
|
context.AddSource("Godot.Sharp.Extended.Scenes.g.cs", SourceText.From(code, Encoding.UTF8));
|
|
}
|
|
}
|
|
|
|
} |