add: Template for Save and config

This commit is contained in:
h z
2025-02-07 02:29:37 +00:00
parent 2812d98d15
commit a52ebfa2f2
6 changed files with 1 additions and 230 deletions

View File

@@ -1,25 +0,0 @@
namespace Polonium.Generators;
using System;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
public struct AssetInfo
{
public INamedTypeSymbol Symbol;
public string Path;
public ClassDeclarationSyntax DeclarationSyntax;
public string ClassName;
public string ClassFullName;
public string GodotPath {
get
{
string rs = Path.Replace("\\", "/").Replace(" ", "%20");
rs = rs.Substring(rs.IndexOf("Assets", StringComparison.Ordinal));
return "res://" + rs;
}
}
public string ScenePath => GodotPath.Replace(".cs", ".tscn");
}

View File

@@ -1,80 +0,0 @@
using System.Collections.Generic;
using System.IO;
using Microsoft.CodeAnalysis;
namespace Polonium.Generators;
public abstract class AssetProcessGenerator : ISourceGenerator
{
public void Initialize(GeneratorInitializationContext context)
{
context.RegisterForSyntaxNotifications(() => new ClassSyntaxReceiver());
}
public abstract void Execute(GeneratorExecutionContext context);
protected IEnumerable<AssetInfo> GetAssetsOfType(GeneratorExecutionContext context, INamedTypeSymbol? t)
{
if (!(context.SyntaxReceiver is ClassSyntaxReceiver receiver))
yield break;
Compilation compilation = context.Compilation;
foreach (var derivedClassDeclaration in receiver.Classes)
{
SemanticModel model = compilation.GetSemanticModel(derivedClassDeclaration.SyntaxTree);
INamedTypeSymbol? derivedClassSymbol = model.GetDeclaredSymbol(derivedClassDeclaration) as INamedTypeSymbol;
string filePath = derivedClassDeclaration.SyntaxTree.FilePath;
string className = Path.GetFileNameWithoutExtension(filePath);
if(derivedClassSymbol == null || !filePath.Contains("Assets"))
continue;
AssetInfo res = new AssetInfo
{
DeclarationSyntax = derivedClassDeclaration,
ClassName = className,
ClassFullName = derivedClassSymbol.ToDisplayString(),
Path = filePath,
Symbol = derivedClassSymbol
};
if (IsDerivedFrom(derivedClassSymbol, t))
{
yield return res;
continue;
}
foreach (INamedTypeSymbol interfaceSymbol in derivedClassSymbol.AllInterfaces)
{
if (SymbolEqualityComparer.Default.Equals(interfaceSymbol, t))
{
yield return res;
break;
}
}
}
}
protected IEnumerable<AssetInfo> GetAssetsOfType(GeneratorExecutionContext context, string t)
{
Compilation compilation = context.Compilation;
INamedTypeSymbol? specificType = compilation.GetTypeByMetadataName(t);
return GetAssetsOfType(context, specificType);
}
protected static bool IsDerivedFrom(INamedTypeSymbol? symbol, INamedTypeSymbol? baseType)
{
if (symbol == null)
return false;
if (baseType == null)
return true;
INamedTypeSymbol? current = symbol.BaseType;
while (current != null)
{
if (SymbolEqualityComparer.Default.Equals(current, baseType))
return true;
current = current.BaseType;
}
return false;
}
}

View File

@@ -1,52 +0,0 @@
using System;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.CodeAnalysis;
namespace Polonium.Generators;
[Generator]
public class AssetRegisterGenerator : AssetProcessGenerator
{
public override void Execute(GeneratorExecutionContext context)
{
if (!(context.SyntaxReceiver is ClassSyntaxReceiver receiver))
return;
Compilation compilation = context.Compilation;
StringBuilder sb = new();
sb
.AppendLine("using System;")
.AppendLine("using Godot;")
.AppendLine("using Polonium.Attributes;")
.AppendLine("[AutoRegister]")
.AppendLine("public static class AssetRegister")
.AppendLine("{")
.AppendLine(" public static void Register()")
.AppendLine(" {");
foreach (var derivedClassDeclaration in receiver.Classes)
{
SemanticModel model = compilation.GetSemanticModel(derivedClassDeclaration.SyntaxTree);
INamedTypeSymbol? symbol = model.GetDeclaredSymbol(derivedClassDeclaration) as INamedTypeSymbol;
string filePath = derivedClassDeclaration.SyntaxTree.FilePath.Replace(".cs", ".tscn");
if(!filePath.Contains("Assets") || symbol == null)
continue;
ImmutableArray<AdditionalText> additionalFiles = context.AdditionalFiles;
if (additionalFiles.Select(y => y.Path).Contains(filePath))
{
string rs = filePath.Replace("\\", "/").Replace(" ", "%20");
rs = rs.Substring(rs.IndexOf("Assets", StringComparison.Ordinal));
string gdPath = "res://" + rs;
string className = Path.GetFileNameWithoutExtension(filePath);
sb
.AppendLine(
$" GlobalRegistry.Asset<{className}>.Scene = ResourceLoader.Load<PackedScene>(\"{gdPath}\");"
);
}
}
sb
.AppendLine(" }")
.AppendLine("}");
context.AddSource("AssetRegistry.g.cs", sb.ToString());
}
}

View File

@@ -1,18 +0,0 @@
using System.Collections.Generic;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
namespace Polonium.Generators;
public class ClassSyntaxReceiver : ISyntaxReceiver
{
public List<ClassDeclarationSyntax> Classes { get; set; } = new ();
public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
{
if (syntaxNode is ClassDeclarationSyntax classDeclaration)
{
Classes.Add(classDeclaration);
}
}
}

View File

@@ -1,54 +0,0 @@
using System.Text;
using Microsoft.CodeAnalysis;
namespace Polonium.Generators;
[Generator]
public class GlobalRegistryGenerator : ISourceGenerator
{
public void Initialize(GeneratorInitializationContext context)
{
}
public void Execute(GeneratorExecutionContext context)
{
StringBuilder sb = new();
sb
.AppendLine("using Godot;")
.AppendLine("using System;")
.AppendLine("using System.Collections.Generic;")
.AppendLine("using System.Linq;")
.AppendLine("using System.Reflection;")
.AppendLine("using Polonium.Attributes;")
.AppendLine("using Polonium;")
.AppendLine("public static partial class GlobalRegistry")
.AppendLine("{")
.AppendLine(" public static void Register()")
.AppendLine(" {")
.AppendLine(" Assembly assembly = Assembly.GetExecutingAssembly();")
.AppendLine(" IEnumerable<Type> registerTypes = Utils.GetLoadableTypes(assembly);")
.AppendLine(" registerTypes = registerTypes.Where(t => t.IsClass && t.GetCustomAttributes(typeof(AutoRegister), false).Any());")
.AppendLine(" foreach(Type t in registerTypes)")
.AppendLine(" {")
.AppendLine(" MethodInfo registerMethod = t.GetMethod(\"Register\", BindingFlags.Static | BindingFlags.Public);")
.AppendLine(" if (registerMethod != null)")
.AppendLine(" registerMethod.Invoke(null, null);")
.AppendLine(" }")
.AppendLine(" }")
.AppendLine(" public static class Asset<T> where T : Node")
.AppendLine(" {")
.AppendLine(" private static readonly Queue<T> Pool = new();")
.AppendLine(" public static PackedScene Scene { get; set; }")
.AppendLine(" public static T Instance => Scene.Instantiate<T>();")
.AppendLine(" public static T Get() => Pool.Count > 0 ? Pool.Dequeue() : Instance;")
.AppendLine(" public static void Return(T obj)")
.AppendLine(" {")
.AppendLine(" if(Pool.Count < 10)")
.AppendLine(" Pool.Enqueue(obj);")
.AppendLine(" else")
.AppendLine(" obj.QueueFree();")
.AppendLine(" }")
.AppendLine(" }")
.AppendLine("}");
context.AddSource("GlobalRegistry.g.cs", sb.ToString());
}
}

View File

@@ -1,2 +1,2 @@
#!/bin/bash
dotnet nuget push "$(ls -t ./bin/Debug/Hangman.SDK.Generators.*.nupkg | head -n 1)" --source hangman-lab
dotnet nuget push "$(ls -t ./bin/Debug/Polonium.Generators.*.nupkg | head -n 1)" --source hangman-lab