From 9668c27e2dba126de4f83d8752743102ffe07c2b Mon Sep 17 00:00:00 2001 From: hzhang Date: Mon, 3 Mar 2025 11:08:24 +0000 Subject: [PATCH] add: MessageBus --- src/AssetProcessGenerator.cs | 35 ++++++++++++++++++++ src/Generators/PoloniumFactoryGenerator.cs | 5 +-- src/Generators/SendMessageMethodGenerator.cs | 31 +++++++++++++++++ 3 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 src/Generators/SendMessageMethodGenerator.cs diff --git a/src/AssetProcessGenerator.cs b/src/AssetProcessGenerator.cs index 34ff108..66c9cbc 100644 --- a/src/AssetProcessGenerator.cs +++ b/src/AssetProcessGenerator.cs @@ -113,6 +113,41 @@ public abstract class AssetProcessGenerator : ISourceGenerator } } + protected IEnumerable GetClassesWithInterface(GeneratorExecutionContext context, INamedTypeSymbol? ifc, bool direct = true) + { + if(context.SyntaxReceiver is not ClassSyntaxReceiver receiver) + yield break; + Compilation compilation = context.Compilation; + foreach (ClassDeclarationSyntax? declaration in receiver.Classes) + { + SemanticModel model = compilation.GetSemanticModel(declaration.SyntaxTree); + INamedTypeSymbol? sClassSymbol = model.GetDeclaredSymbol(declaration) as INamedTypeSymbol; + string filePath = declaration.SyntaxTree.FilePath; + string className = Path.GetFileNameWithoutExtension(filePath); + bool interfaceFound = false; + if (sClassSymbol is null) + yield break; + if (direct) + interfaceFound = sClassSymbol.Interfaces.Any(i => SymbolEqualityComparer.Default.Equals(i, ifc)); + else + interfaceFound = sClassSymbol.AllInterfaces.Any(i => SymbolEqualityComparer.Default.Equals(i, ifc)); + + if (interfaceFound) + { + yield return new ClassInfo + { + DeclarationSyntax = declaration, + ClassName = className, + ClassFullName = sClassSymbol.ToDisplayString(), + Path = filePath, + Symbol = sClassSymbol, + Namespace = sClassSymbol.ContainingNamespace.ToDisplayString() + }; + } + + } + } + protected static bool HasAttribute(INamedTypeSymbol? type, INamedTypeSymbol? attr) { if (type is null) diff --git a/src/Generators/PoloniumFactoryGenerator.cs b/src/Generators/PoloniumFactoryGenerator.cs index 3c2615b..5edaae6 100644 --- a/src/Generators/PoloniumFactoryGenerator.cs +++ b/src/Generators/PoloniumFactoryGenerator.cs @@ -16,6 +16,7 @@ public class PoloniumFactoryGenerator : AssetProcessGenerator .AppendLine("using Polonium.Attributes;") .AppendLine("using Polonium.Interfaces;") .AppendLine("using Polonium.Resources;") + .AppendLine("using Polonium.MessageManager;") .AppendLine("[AutoRegister]") .AppendLine("public class PoloniumFactoryRegister") .AppendLine("{") @@ -25,10 +26,10 @@ public class PoloniumFactoryGenerator : AssetProcessGenerator .AppendLine(" }") .AppendLine(" public class PoloniumFactory : IPoloniumFactory") .AppendLine(" {") - .AppendLine(" public SignalHeader CreateSignalHeader()") + .AppendLine(" public MessageHeader CreateMessageHeader()") .AppendLine(" {"); Compilation compilation = context.Compilation; - INamedTypeSymbol? signalHeader = compilation.GetTypeByMetadataName("Polonium.Resources.SignalHeader"); + INamedTypeSymbol? signalHeader = compilation.GetTypeByMetadataName("Polonium.MessageManager.MessageHeader"); bool founded = false; foreach (ClassDeclarationSyntax cls in receiver.Classes) diff --git a/src/Generators/SendMessageMethodGenerator.cs b/src/Generators/SendMessageMethodGenerator.cs new file mode 100644 index 0000000..1440992 --- /dev/null +++ b/src/Generators/SendMessageMethodGenerator.cs @@ -0,0 +1,31 @@ +using System.Text; +using Microsoft.CodeAnalysis; + +namespace Polonium.Generators.Generators; +[Generator] +public class SendMessageMethodGenerator : AssetProcessGenerator +{ + public override void Execute(GeneratorExecutionContext context) + { + if (context.SyntaxReceiver is not ClassSyntaxReceiver receiver) + return; + Compilation compilation = context.Compilation; + INamedTypeSymbol? ifc = compilation.GetTypeByMetadataName("Polonium.Interfaces.IMessageClient"); + foreach (ClassInfo cls in GetClassesWithInterface(context, ifc)) + { + StringBuilder sb = new(); + sb + .AppendLine("using Polonium.Interfaces;") + .AppendLine("using System;") + .AppendLine("using Polonium.Resources;") + .AppendLine("using Polonium.MessageManager;") + .AppendLine($"namespace {cls.Namespace};") + .AppendLine($"public partial class {cls.ClassName}") + .AppendLine("{") + .AppendLine(" public event IMessageClient.MessageSentEventHandler MessageSent;") + .AppendLine(" public void SendMessage(PoloniumMessage msg) => MessageSent?.Invoke(msg); ") + .AppendLine("}"); + context.AddSource($"{cls.ClassName}_MessageClient.g.cs", sb.ToString()); + } + } +} \ No newline at end of file