92 lines
3.1 KiB
C#
92 lines
3.1 KiB
C#
using System.Text;
|
|
|
|
using Microsoft.CodeAnalysis;
|
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|
using Microsoft.CodeAnalysis.Text;
|
|
|
|
namespace MfGames.Nitride.Generators;
|
|
|
|
/// <summary>
|
|
/// Implements a source generator that creates the additional properties
|
|
/// and methods for a singleton component including the constructor and
|
|
/// instance methods, along with extension methods for adding them to entities.
|
|
/// </summary>
|
|
[Generator]
|
|
public class SingletonComponentSourceGenerator
|
|
: ClassAttributeSourceGeneratorBase<SingletonComponentSyntaxReceiver>
|
|
{
|
|
protected override SingletonComponentSyntaxReceiver CreateSyntaxReceiver(
|
|
GeneratorInitializationContext context)
|
|
{
|
|
return new SingletonComponentSyntaxReceiver(context);
|
|
}
|
|
|
|
protected override void GenerateClassFile(
|
|
GeneratorExecutionContext context,
|
|
ClassAttributeReference unit)
|
|
{
|
|
// Pull out some fields.
|
|
ClassDeclarationSyntax cds = unit.ClassDeclaration;
|
|
|
|
// Create the partial class.
|
|
StringBuilder buffer = new();
|
|
buffer.AppendLine("#nullable enable");
|
|
|
|
// Copy the using statements from the file.
|
|
foreach (UsingDirectiveSyntax? uds in unit.UsingDirectiveList)
|
|
{
|
|
buffer.AppendLine(uds.ToString());
|
|
}
|
|
|
|
buffer.AppendLine();
|
|
|
|
// Create the namespace.
|
|
SyntaxToken cls = cds.Identifier;
|
|
|
|
buffer.AppendLine(
|
|
string.Join(
|
|
"\n",
|
|
$"using MfGames.Gallium;",
|
|
$"",
|
|
$"namespace {unit.Namespace}",
|
|
$"{{",
|
|
$" public partial class {cls}",
|
|
$" {{",
|
|
$" static {cls}()",
|
|
$" {{",
|
|
$" Instance = new {cls}();",
|
|
$" }}",
|
|
$"",
|
|
$" private {cls}()",
|
|
$" {{",
|
|
$" }}",
|
|
$"",
|
|
$" public static {cls} Instance {{ get; }}",
|
|
$" }}",
|
|
$"",
|
|
$" public static class {cls}Extensions",
|
|
$" {{",
|
|
$" public static bool Has{cls}(this Entity entity)",
|
|
$" {{",
|
|
$" return entity.Has<{cls}>();",
|
|
$" }}",
|
|
$"",
|
|
$" public static Entity Remove{cls}(this Entity entity)",
|
|
$" {{",
|
|
$" return entity.Remove<{cls}>();",
|
|
$" }}",
|
|
$"",
|
|
$" public static Entity Set{cls}(this Entity entity)",
|
|
$" {{",
|
|
$" return entity.Set({cls}.Instance);",
|
|
$" }}",
|
|
$" }}",
|
|
$"}}",
|
|
""));
|
|
|
|
// Create the source text and write out the file.
|
|
var sourceText = SourceText.From(buffer.ToString(), Encoding.UTF8);
|
|
context.AddSource(cls + ".Generated.cs", sourceText);
|
|
}
|
|
}
|