diff --git a/GFramework.Core.Abstractions/architecture/IArchitectureConfiguration.cs b/GFramework.Core.Abstractions/architecture/IArchitectureConfiguration.cs index 51f3b1b..3504e47 100644 --- a/GFramework.Core.Abstractions/architecture/IArchitectureConfiguration.cs +++ b/GFramework.Core.Abstractions/architecture/IArchitectureConfiguration.cs @@ -1,4 +1,4 @@ -using GFramework.Core.Abstractions.logging; +using GFramework.Core.Abstractions.properties; namespace GFramework.Core.Abstractions.architecture; @@ -8,12 +8,12 @@ namespace GFramework.Core.Abstractions.architecture; public interface IArchitectureConfiguration { /// - /// 获取或设置日志工厂,用于创建日志记录器实例 + /// 获取或设置日志选项,包含日志相关的配置参数 /// - ILoggerFactory LoggerFactory { get; set; } + LoggerProperties LoggerProperties { get; set; } /// /// 获取或设置架构选项,包含架构相关的配置参数 /// - ArchitectureOptions Options { get; set; } + ArchitectureProperties ArchitectureProperties { get; set; } } \ No newline at end of file diff --git a/GFramework.Core.Abstractions/architecture/IArchitectureContext.cs b/GFramework.Core.Abstractions/architecture/IArchitectureContext.cs index 57f50b6..aa2451c 100644 --- a/GFramework.Core.Abstractions/architecture/IArchitectureContext.cs +++ b/GFramework.Core.Abstractions/architecture/IArchitectureContext.cs @@ -1,7 +1,6 @@ using System; using GFramework.Core.Abstractions.command; using GFramework.Core.Abstractions.events; -using GFramework.Core.Abstractions.logging; using GFramework.Core.Abstractions.model; using GFramework.Core.Abstractions.query; using GFramework.Core.Abstractions.system; @@ -14,11 +13,6 @@ namespace GFramework.Core.Abstractions.architecture; /// public interface IArchitectureContext { - /// - /// 获取日志工厂 - /// - ILoggerFactory LoggerFactory { get; } - /// /// 获取指定类型的系统实例 /// diff --git a/GFramework.Core.Abstractions/logging/ILoggerFactoryProvider.cs b/GFramework.Core.Abstractions/logging/ILoggerFactoryProvider.cs index 8471658..a6bcd3e 100644 --- a/GFramework.Core.Abstractions/logging/ILoggerFactoryProvider.cs +++ b/GFramework.Core.Abstractions/logging/ILoggerFactoryProvider.cs @@ -5,11 +5,15 @@ /// public interface ILoggerFactoryProvider { + /// + /// 获取或设置日志记录器的最小日志级别,低于此级别的日志将被忽略 + /// + public LogLevel MinLevel { get; set; } + /// /// 创建一个日志记录器实例 /// /// 日志记录器的名称,用于标识特定的日志源 - /// 日志记录器的最小日志级别,低于此级别的日志消息将被忽略 /// 配置了指定名称和最小日志级别的ILogger实例 - ILogger CreateLogger(string name, LogLevel minLevel); + ILogger CreateLogger(string name); } \ No newline at end of file diff --git a/GFramework.Core.Abstractions/architecture/ArchitectureOptions.cs b/GFramework.Core.Abstractions/properties/ArchitectureProperties.cs similarity index 54% rename from GFramework.Core.Abstractions/architecture/ArchitectureOptions.cs rename to GFramework.Core.Abstractions/properties/ArchitectureProperties.cs index 769645b..6895d4a 100644 --- a/GFramework.Core.Abstractions/architecture/ArchitectureOptions.cs +++ b/GFramework.Core.Abstractions/properties/ArchitectureProperties.cs @@ -1,20 +1,17 @@ -namespace GFramework.Core.Abstractions.architecture; +namespace GFramework.Core.Abstractions.properties; /// /// 架构选项配置类,用于定义架构行为的相关配置选项 /// -public sealed class ArchitectureOptions( - bool strictPhaseValidation = true, - bool allowLateRegistration = false -) +public sealed class ArchitectureProperties { /// /// 允许延迟注册开关,当设置为true时允许在初始化完成后进行组件注册 /// - public bool AllowLateRegistration { get; } = allowLateRegistration; + public bool AllowLateRegistration { get; set; } /// /// 严格阶段验证开关,当设置为true时启用严格的阶段验证机制 /// - public bool StrictPhaseValidation { get; } = strictPhaseValidation; + public bool StrictPhaseValidation { get; set; } } \ No newline at end of file diff --git a/GFramework.Core.Abstractions/properties/LoggerProperties.cs b/GFramework.Core.Abstractions/properties/LoggerProperties.cs new file mode 100644 index 0000000..a6364c4 --- /dev/null +++ b/GFramework.Core.Abstractions/properties/LoggerProperties.cs @@ -0,0 +1,15 @@ +using GFramework.Core.Abstractions.logging; + +namespace GFramework.Core.Abstractions.properties; + +/// +/// 日志配置选项类,用于配置日志系统的相关参数 +/// +public sealed class LoggerProperties +{ + /// + /// 获取或设置日志工厂提供程序 + /// 可为空,用于提供自定义的日志工厂实现 + /// + public ILoggerFactoryProvider LoggerFactoryProvider { get; set; } = null!; +} \ No newline at end of file diff --git a/GFramework.Core/architecture/Architecture.cs b/GFramework.Core/architecture/Architecture.cs index 09a7097..e540040 100644 --- a/GFramework.Core/architecture/Architecture.cs +++ b/GFramework.Core/architecture/Architecture.cs @@ -7,6 +7,7 @@ using GFramework.Core.Abstractions.model; using GFramework.Core.Abstractions.system; using GFramework.Core.Abstractions.utility; using GFramework.Core.events; +using GFramework.Core.logging; namespace GFramework.Core.architecture; @@ -70,7 +71,8 @@ public abstract class Architecture( /// 要安装的模块 public void InstallModule(IArchitectureModule module) { - var logger = Configuration.LoggerFactory.GetLogger(nameof(Architecture)); + var logger = + LoggerFactoryResolver.Provider.CreateLogger(nameof(GetType)); logger.Debug($"Installing module: {module.GetType().Name}"); RegisterLifecycleHook(module); Container.RegisterPlurality(module); @@ -132,28 +134,27 @@ public abstract class Architecture( /// 当阶段转换不被允许时抛出异常 private void EnterPhase(ArchitecturePhase next) { - var logger = Configuration.LoggerFactory.GetLogger(nameof(Architecture)); - if (Configuration.Options.StrictPhaseValidation && + if (Configuration.ArchitectureProperties.StrictPhaseValidation && (!ArchitectureConstants.PhaseTransitions.TryGetValue(CurrentPhase, out var allowed) || !allowed.Contains(next))) { // 验证阶段转换是否合法 var errorMsg = $"Invalid phase transition: {CurrentPhase} -> {next}"; - logger.Fatal(errorMsg); + _logger.Fatal(errorMsg); throw new InvalidOperationException(errorMsg); } var previousPhase = CurrentPhase; CurrentPhase = next; - if (previousPhase != next) logger.Info($"Architecture phase changed: {previousPhase} -> {next}"); + if (previousPhase != next) _logger.Info($"Architecture phase changed: {previousPhase} -> {next}"); NotifyPhase(next); // 通知所有架构阶段感知对象阶段变更 foreach (var obj in Container.GetAll()) { - logger.Debug($"Notifying phase-aware object {obj.GetType().Name} of phase change to {next}"); + _logger.Debug($"Notifying phase-aware object {obj.GetType().Name} of phase change to {next}"); obj.OnArchitecturePhase(next); } } @@ -174,7 +175,7 @@ public abstract class Architecture( /// 生命周期钩子实例 public void RegisterLifecycleHook(IArchitectureLifecycle hook) { - if (CurrentPhase >= ArchitecturePhase.Ready && !Configuration.Options.AllowLateRegistration) + if (CurrentPhase >= ArchitecturePhase.Ready && !Configuration.ArchitectureProperties.AllowLateRegistration) throw new InvalidOperationException( "Cannot register lifecycle hook after architecture is Ready"); _lifecycleHooks.Add(hook); @@ -195,25 +196,23 @@ public abstract class Architecture( /// public virtual void Destroy() { - var logger = Configuration.LoggerFactory.GetLogger(nameof(Architecture)); - // 检查当前阶段,如果已经处于销毁或已销毁状态则直接返回 if (CurrentPhase >= ArchitecturePhase.Destroying) { - logger.Warn("Architecture destroy called but already in destroying/destroyed state"); + _logger.Warn("Architecture destroy called but already in destroying/destroyed state"); return; } // 进入销毁阶段并发送销毁开始事件 - logger.Info("Starting architecture destruction"); + _logger.Info("Starting architecture destruction"); EnterPhase(ArchitecturePhase.Destroying); TypeEventSystem.Send(new ArchitectureEvents.ArchitectureDestroyingEvent()); // 销毁所有系统组件并清空系统列表 - logger.Info($"Destroying {_allSystems.Count} systems"); + _logger.Info($"Destroying {_allSystems.Count} systems"); foreach (var system in _allSystems) { - logger.Debug($"Destroying system: {system.GetType().Name}"); + _logger.Debug($"Destroying system: {system.GetType().Name}"); system.Destroy(); } @@ -222,7 +221,7 @@ public abstract class Architecture( // 进入已销毁阶段并发送销毁完成事件 EnterPhase(ArchitecturePhase.Destroyed); TypeEventSystem.Send(new ArchitectureEvents.ArchitectureDestroyedEvent()); - logger.Info("Architecture destruction completed"); + _logger.Info("Architecture destruction completed"); } #endregion @@ -231,8 +230,10 @@ public abstract class Architecture( public void Initialize() { - _logger = Configuration.LoggerFactory.GetLogger(GetType().Name); - _context ??= new ArchitectureContext(Container, TypeEventSystem, Configuration.LoggerFactory); + // 设置日志工厂提供程序,用于创建日志记录器 + LoggerFactoryResolver.Provider = Configuration.LoggerProperties.LoggerFactoryProvider; + _logger = LoggerFactoryResolver.Provider.CreateLogger(GetType().Name); + _context ??= new ArchitectureContext(Container, TypeEventSystem, Configuration.LoggerProperties); GameContext.Bind(GetType(), _context); // 创建架构运行时实例 Runtime = new ArchitectureRuntime(_context); @@ -284,8 +285,11 @@ public abstract class Architecture( public async Task InitializeAsync() { - _logger = Configuration.LoggerFactory.GetLogger(GetType().Name); - _context ??= new ArchitectureContext(Container, TypeEventSystem, Configuration.LoggerFactory); + // 设置日志工厂提供程序,用于创建日志记录器 + LoggerFactoryResolver.Provider = Configuration.LoggerProperties.LoggerFactoryProvider; + // 创建日志记录器 + _logger = LoggerFactoryResolver.Provider.CreateLogger(GetType().Name); + _context ??= new ArchitectureContext(Container, TypeEventSystem, Configuration.LoggerProperties); GameContext.Bind(GetType(), _context); // 创建架构运行时实例 Runtime = new ArchitectureRuntime(_context); @@ -347,7 +351,7 @@ public abstract class Architecture( /// 要注册的系统实例 public void RegisterSystem(TSystem system) where TSystem : ISystem { - if (CurrentPhase >= ArchitecturePhase.Ready && !Configuration.Options.AllowLateRegistration) + if (CurrentPhase >= ArchitecturePhase.Ready && !Configuration.ArchitectureProperties.AllowLateRegistration) { const string errorMsg = "Cannot register system after Architecture is Ready"; _logger.Error(errorMsg); @@ -379,7 +383,7 @@ public abstract class Architecture( /// 要注册的模型实例 public void RegisterModel(TModel model) where TModel : IModel { - if (CurrentPhase >= ArchitecturePhase.Ready && !Configuration.Options.AllowLateRegistration) + if (CurrentPhase >= ArchitecturePhase.Ready && !Configuration.ArchitectureProperties.AllowLateRegistration) { var errorMsg = "Cannot register model after Architecture is Ready"; _logger.Error(errorMsg); diff --git a/GFramework.Core/architecture/ArchitectureConfiguration.cs b/GFramework.Core/architecture/ArchitectureConfiguration.cs index 2cfb976..b699383 100644 --- a/GFramework.Core/architecture/ArchitectureConfiguration.cs +++ b/GFramework.Core/architecture/ArchitectureConfiguration.cs @@ -1,5 +1,6 @@ using GFramework.Core.Abstractions.architecture; using GFramework.Core.Abstractions.logging; +using GFramework.Core.Abstractions.properties; using GFramework.Core.logging; namespace GFramework.Core.architecture; @@ -8,23 +9,27 @@ namespace GFramework.Core.architecture; /// 默认架构配置类,实现IArchitectureConfiguration接口 /// 提供日志工厂、日志级别和架构选项的默认配置 /// -public class ArchitectureConfiguration : IArchitectureConfiguration +public sealed class ArchitectureConfiguration : IArchitectureConfiguration { /// - /// 获取或设置日志级别 - /// 默认设置为Info级别 + /// 获取或设置日志选项 + /// 默认配置为Info级别日志,使用控制台日志工厂提供程序 /// - public LogLevel LogLevel { get; set; } = LogLevel.Info; - - /// - /// 获取或设置日志工厂实例 - /// 默认使用控制台日志工厂 - /// - public ILoggerFactory LoggerFactory { get; set; } = new ConsoleLoggerFactory(); + public LoggerProperties LoggerProperties { get; set; } = new() + { + LoggerFactoryProvider = new ConsoleLoggerFactoryProvider() + { + MinLevel = LogLevel.Info + } + }; /// /// 获取或设置架构选项 /// 默认创建新的ArchitectureOptions实例 /// - public ArchitectureOptions Options { get; set; } = new(); + public ArchitectureProperties ArchitectureProperties { get; set; } = new() + { + AllowLateRegistration = false, + StrictPhaseValidation = true + }; } \ No newline at end of file diff --git a/GFramework.Core/architecture/ArchitectureContext.cs b/GFramework.Core/architecture/ArchitectureContext.cs index 3b6472d..afd7274 100644 --- a/GFramework.Core/architecture/ArchitectureContext.cs +++ b/GFramework.Core/architecture/ArchitectureContext.cs @@ -2,12 +2,11 @@ using GFramework.Core.Abstractions.command; using GFramework.Core.Abstractions.events; using GFramework.Core.Abstractions.ioc; -using GFramework.Core.Abstractions.logging; using GFramework.Core.Abstractions.model; +using GFramework.Core.Abstractions.properties; using GFramework.Core.Abstractions.query; using GFramework.Core.Abstractions.system; using GFramework.Core.Abstractions.utility; -using GFramework.Core.logging; namespace GFramework.Core.architecture; @@ -17,7 +16,7 @@ namespace GFramework.Core.architecture; public class ArchitectureContext( IIocContainer container, ITypeEventSystem typeEventSystem, - ILoggerFactory? loggerFactory) + LoggerProperties loggerProperties) : IArchitectureContext { private readonly IIocContainer _container = container ?? throw new ArgumentNullException(nameof(container)); @@ -27,8 +26,6 @@ public class ArchitectureContext( internal IArchitectureRuntime Runtime { get; set; } = null!; - public ILoggerFactory LoggerFactory { get; } = loggerFactory ?? new NoopLoggerFactory(); - #region Query Execution /// diff --git a/GFramework.Core/ioc/IocContainer.cs b/GFramework.Core/ioc/IocContainer.cs index 6501b5f..ff667f8 100644 --- a/GFramework.Core/ioc/IocContainer.cs +++ b/GFramework.Core/ioc/IocContainer.cs @@ -1,6 +1,7 @@ using GFramework.Core.Abstractions.ioc; using GFramework.Core.Abstractions.logging; using GFramework.Core.Abstractions.system; +using GFramework.Core.logging; using GFramework.Core.rule; namespace GFramework.Core.ioc; @@ -54,7 +55,8 @@ public class IocContainer : ContextAwareBase, IIocContainer protected override void OnContextReady() { - _logger = Context.LoggerFactory.GetLogger(nameof(IocContainer)); + _logger = + LoggerFactoryResolver.Provider.CreateLogger(nameof(GetType)); } /// diff --git a/GFramework.Core/logging/ConsoleLoggerFactoryProvider.cs b/GFramework.Core/logging/ConsoleLoggerFactoryProvider.cs index 5da073e..c73bbc6 100644 --- a/GFramework.Core/logging/ConsoleLoggerFactoryProvider.cs +++ b/GFramework.Core/logging/ConsoleLoggerFactoryProvider.cs @@ -7,12 +7,16 @@ namespace GFramework.Core.logging; /// public sealed class ConsoleLoggerFactoryProvider : ILoggerFactoryProvider { + /// + /// 获取或设置日志记录器的最小日志级别,低于此级别的日志将被忽略 + /// + public LogLevel MinLevel { get; set; } = LogLevel.Info; + /// /// 创建一个日志记录器实例 /// /// 日志记录器的名称,用于标识特定的日志源 - /// 日志记录器的最小日志级别,低于此级别的日志消息将被忽略 /// 配置了指定名称和最小日志级别的ILogger实例 - public ILogger CreateLogger(string name, LogLevel minLevel) - => new ConsoleLoggerFactory().GetLogger(name, minLevel); + public ILogger CreateLogger(string name) + => new ConsoleLoggerFactory().GetLogger(name, MinLevel); } \ No newline at end of file diff --git a/GFramework.Core/logging/LoggerFactoryResolver.cs b/GFramework.Core/logging/LoggerFactoryResolver.cs index 5cabcf0..4dd5f7a 100644 --- a/GFramework.Core/logging/LoggerFactoryResolver.cs +++ b/GFramework.Core/logging/LoggerFactoryResolver.cs @@ -15,4 +15,12 @@ public static class LoggerFactoryResolver /// public static ILoggerFactoryProvider Provider { get; set; } = new ConsoleLoggerFactoryProvider(); + + /// + /// 获取或设置日志记录的最小级别 + /// + /// + /// 日志级别枚举值,默认为Info级别 + /// + public static LogLevel MinLevel { get; set; } = LogLevel.Info; } \ No newline at end of file diff --git a/GFramework.Core/rule/ContextAwareBase.cs b/GFramework.Core/rule/ContextAwareBase.cs index aca31d0..b436bda 100644 --- a/GFramework.Core/rule/ContextAwareBase.cs +++ b/GFramework.Core/rule/ContextAwareBase.cs @@ -11,7 +11,7 @@ public abstract class ContextAwareBase : IContextAware /// /// 获取当前实例的架构上下文 /// - protected IArchitectureContext Context { get; private set; } = null!; + protected IArchitectureContext Context { get; set; } = null!; /// /// 设置架构上下文的实现方法,由框架调用 diff --git a/GFramework.Core/system/AbstractSystem.cs b/GFramework.Core/system/AbstractSystem.cs index 5415d08..1a15bdb 100644 --- a/GFramework.Core/system/AbstractSystem.cs +++ b/GFramework.Core/system/AbstractSystem.cs @@ -1,6 +1,7 @@ using GFramework.Core.Abstractions.enums; using GFramework.Core.Abstractions.logging; using GFramework.Core.Abstractions.system; +using GFramework.Core.logging; using GFramework.Core.rule; namespace GFramework.Core.system; @@ -18,7 +19,7 @@ public abstract class AbstractSystem : ContextAwareBase, ISystem /// void ISystem.Init() { - _logger = Context.LoggerFactory.GetLogger(nameof(AbstractSystem)); + _logger = LoggerFactoryResolver.Provider.CreateLogger(nameof(GetType)); _logger.Debug($"Initializing system: {GetType().Name}"); OnInit(); diff --git a/GFramework.Core/utility/AbstractContextUtility.cs b/GFramework.Core/utility/AbstractContextUtility.cs index a068eb8..cfe456d 100644 --- a/GFramework.Core/utility/AbstractContextUtility.cs +++ b/GFramework.Core/utility/AbstractContextUtility.cs @@ -1,5 +1,6 @@ using GFramework.Core.Abstractions.logging; using GFramework.Core.Abstractions.utility; +using GFramework.Core.logging; using GFramework.Core.rule; namespace GFramework.Core.utility; @@ -18,7 +19,7 @@ public abstract class AbstractContextUtility : ContextAwareBase, IContextUtility void IContextUtility.Init() { // 获取上下文中的日志记录器 - Logger = Context.LoggerFactory.GetLogger(nameof(AbstractContextUtility)); + Logger = LoggerFactoryResolver.Provider.CreateLogger(nameof(GetType)); Logger.Debug($"Initializing Context Utility: {GetType().Name}"); // 执行子类实现的初始化逻辑 diff --git a/GFramework.Godot.SourceGenerators.Abstractions/GFramework.Godot.SourceGenerators.Abstractions.csproj b/GFramework.Godot.SourceGenerators.Abstractions/GFramework.Godot.SourceGenerators.Abstractions.csproj index 7acd9a3..477e9bc 100644 --- a/GFramework.Godot.SourceGenerators.Abstractions/GFramework.Godot.SourceGenerators.Abstractions.csproj +++ b/GFramework.Godot.SourceGenerators.Abstractions/GFramework.Godot.SourceGenerators.Abstractions.csproj @@ -15,4 +15,7 @@ + + + diff --git a/GFramework.Godot.SourceGenerators.Abstractions/logging/GodotLogAttribute.cs b/GFramework.Godot.SourceGenerators.Abstractions/logging/GodotLogAttribute.cs deleted file mode 100644 index 2de1603..0000000 --- a/GFramework.Godot.SourceGenerators.Abstractions/logging/GodotLogAttribute.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; - -namespace GFramework.Godot.SourceGenerators.Abstractions.logging; - -/// -/// Godot日志特性,用于在类上标记以自动生成日志字段 -/// -[AttributeUsage(AttributeTargets.Class, Inherited = false)] -public sealed class GodotLogAttribute : Attribute -{ - /// - /// 初始化 GodotLogAttribute 类的新实例 - /// - public GodotLogAttribute() - { - } - - /// - /// 初始化 GodotLogAttribute 类的新实例 - /// - /// 日志分类名 - public GodotLogAttribute(string? name) - { - Name = name; - } - - /// 日志分类名(默认使用类名) - public string? Name { get; set; } - - /// 生成字段名 - public string FieldName { get; set; } = "Logger"; - - /// 是否生成 static 字段 - public bool IsStatic { get; set; } = true; - - /// 访问修饰符 - public string AccessModifier { get; set; } = "private"; -} \ No newline at end of file diff --git a/GFramework.Godot.SourceGenerators/AnalyzerReleases.Shipped.md b/GFramework.Godot.SourceGenerators/AnalyzerReleases.Shipped.md deleted file mode 100644 index 60b59dd..0000000 --- a/GFramework.Godot.SourceGenerators/AnalyzerReleases.Shipped.md +++ /dev/null @@ -1,3 +0,0 @@ -; Shipped analyzer releases -; https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md - diff --git a/GFramework.Godot.SourceGenerators/AnalyzerReleases.Unshipped.md b/GFramework.Godot.SourceGenerators/AnalyzerReleases.Unshipped.md deleted file mode 100644 index 58de45e..0000000 --- a/GFramework.Godot.SourceGenerators/AnalyzerReleases.Unshipped.md +++ /dev/null @@ -1,8 +0,0 @@ -; Unshipped analyzer release -; https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md - -### New Rules - - Rule ID | Category | Severity | Notes -----------------------|--------------------------|----------|------------------------ - GF_Godot_Logging_001 | GFramework.Godot.Logging | Warning | GodotLoggerDiagnostics \ No newline at end of file diff --git a/GFramework.Godot.SourceGenerators/GFramework.Godot.SourceGenerators.csproj b/GFramework.Godot.SourceGenerators/GFramework.Godot.SourceGenerators.csproj index b24d6d2..c62c5dd 100644 --- a/GFramework.Godot.SourceGenerators/GFramework.Godot.SourceGenerators.csproj +++ b/GFramework.Godot.SourceGenerators/GFramework.Godot.SourceGenerators.csproj @@ -59,4 +59,12 @@ + + + + + + + + diff --git a/GFramework.Godot.SourceGenerators/diagnostics/GodotLoggerDiagnostic.cs b/GFramework.Godot.SourceGenerators/diagnostics/GodotLoggerDiagnostic.cs deleted file mode 100644 index 77608b6..0000000 --- a/GFramework.Godot.SourceGenerators/diagnostics/GodotLoggerDiagnostic.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Microsoft.CodeAnalysis; - -namespace GFramework.Godot.SourceGenerators.diagnostics; - -/// -/// 提供诊断描述符的静态类,用于GFramework日志生成器的编译时检查 -/// -internal static class GodotLoggerDiagnostics -{ - /// - /// 诊断描述符:标识GodotLogAttribute无法在指定类上生成Logger - /// - /// - /// ID: GFW_LOG001 - /// 严重性: Warning - /// 分类: GFramework.Godot.Logging - /// - public static readonly DiagnosticDescriptor LogAttributeInvalid = new( - "GF_Godot_Logging_001", - "GodotLogAttribute cannot generate Logger", - "GodotLogAttribute on class '{0}' is ineffective: {1}", - "GFramework.Godot.Logging", - DiagnosticSeverity.Warning, - true); -} \ No newline at end of file diff --git a/GFramework.Godot.SourceGenerators/logging/GodotLoggerGenerator.cs b/GFramework.Godot.SourceGenerators/logging/GodotLoggerGenerator.cs deleted file mode 100644 index 684d3f9..0000000 --- a/GFramework.Godot.SourceGenerators/logging/GodotLoggerGenerator.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System; -using System.Linq; -using System.Text; -using GFramework.Godot.SourceGenerators.Abstractions.logging; -using GFramework.SourceGenerators.Common.constants; -using GFramework.SourceGenerators.Common.generator; -using Microsoft.CodeAnalysis; - -namespace GFramework.Godot.SourceGenerators.logging; - -/// -/// 日志生成器,用于为标记了GodotLogAttribute的类自动生成日志字段 -/// -[Generator] -public sealed class GodotLoggerGenerator : TypeAttributeClassGeneratorBase -{ - protected override Type AttributeType => typeof(GodotLogAttribute); - - - protected override string AttributeShortNameWithoutSuffix => "GodotLog"; - - /// - /// 生成源代码 - /// - /// 源生产上下文 - /// 编译对象 - /// 命名类型符号 - /// 属性数据 - /// 生成的源代码字符串 - protected override string Generate( - SourceProductionContext context, - Compilation compilation, - INamedTypeSymbol symbol, - AttributeData attr) - { - var ns = symbol.ContainingNamespace.IsGlobalNamespace - ? null - : symbol.ContainingNamespace.ToDisplayString(); - var className = symbol.Name; - - // 解析构造函数参数 - var name = className; - if (attr.ConstructorArguments.Length > 0 && attr.ConstructorArguments[0].Value is string s && - !string.IsNullOrWhiteSpace(s)) - { - name = s; - } - - // 解析命名参数 - var fieldName = GetNamedArg(attr, "FieldName")?.ToString() ?? "_log"; - var access = GetNamedArg(attr, "AccessModifier")?.ToString() ?? "private"; - var isStatic = GetNamedArg(attr, "IsStatic") is not bool b || b; - var staticKeyword = isStatic ? "static " : ""; - - var sb = new StringBuilder(); - sb.AppendLine("// "); - sb.AppendLine($"using {PathContests.CoreAbstractionsNamespace}.logging;"); - sb.AppendLine($"using {PathContests.GodotNamespace}.logging;"); - sb.AppendLine(); - - if (ns is not null) - { - sb.AppendLine($"namespace {ns}"); - sb.AppendLine("{"); - } - - sb.AppendLine($" public partial class {className}"); - sb.AppendLine(" {"); - sb.AppendLine(" /// Auto-generated logger"); - sb.AppendLine( - $" {access} {staticKeyword}readonly ILogger {fieldName} = new GodotLoggerFactory().GetLogger(\"{name}\");"); - sb.AppendLine(" }"); - - if (ns is not null) - sb.AppendLine("}"); - - return sb.ToString(); - } - - /// - /// 获取生成文件的提示名称 - /// - /// 类型符号 - /// 生成文件的提示名称 - protected override string GetHintName(INamedTypeSymbol symbol) - => $"{symbol.Name}.Logger.g.cs"; - - /// - /// 获取属性的命名参数值 - /// - /// 属性数据 - /// 参数名称 - /// 参数值 - private static object? GetNamedArg(AttributeData attr, string name) - => attr.NamedArguments.FirstOrDefault(kv => kv.Key == name).Value.Value; -} \ No newline at end of file diff --git a/GFramework.Godot/logging/GodotLoggerFactoryProvider.cs b/GFramework.Godot/logging/GodotLoggerFactoryProvider.cs index 13b629f..95c2932 100644 --- a/GFramework.Godot/logging/GodotLoggerFactoryProvider.cs +++ b/GFramework.Godot/logging/GodotLoggerFactoryProvider.cs @@ -8,11 +8,14 @@ namespace GFramework.Godot.logging; public sealed class GodotLoggerFactoryProvider : ILoggerFactoryProvider { /// - /// 创建指定名称和最小日志级别的日志记录器 + /// 获取或设置最小日志级别 + /// + public LogLevel MinLevel { get; set; } + + /// + /// 创建指定名称的日志记录器实例 /// /// 日志记录器的名称 - /// 日志记录器的最小日志级别 - /// 返回配置好的Godot日志记录器实例 - public ILogger CreateLogger(string name, LogLevel minLevel) - => new GodotLoggerFactory().GetLogger(name, minLevel); + /// 返回配置了最小日志级别的Godot日志记录器实例 + public ILogger CreateLogger(string name) => new GodotLoggerFactory().GetLogger(name, MinLevel); } \ No newline at end of file diff --git a/GFramework.SourceGenerators.Abstractions/logging/LogAttribute.cs b/GFramework.SourceGenerators.Abstractions/logging/LogAttribute.cs index 890401f..52e7325 100644 --- a/GFramework.SourceGenerators.Abstractions/logging/LogAttribute.cs +++ b/GFramework.SourceGenerators.Abstractions/logging/LogAttribute.cs @@ -1,6 +1,5 @@ #nullable enable using System; -using GFramework.Core.Abstractions.logging; namespace GFramework.SourceGenerators.Abstractions.logging; @@ -38,7 +37,4 @@ public sealed class LogAttribute : Attribute /// 访问修饰符 public string AccessModifier { get; set; } = "private"; - - /// 最小日志级别 - public LogLevel MinLevel { get; set; } = LogLevel.Info; } \ No newline at end of file diff --git a/GFramework.SourceGenerators/logging/LoggerGenerator.cs b/GFramework.SourceGenerators/logging/LoggerGenerator.cs index add02af..0317635 100644 --- a/GFramework.SourceGenerators/logging/LoggerGenerator.cs +++ b/GFramework.SourceGenerators/logging/LoggerGenerator.cs @@ -92,7 +92,7 @@ public sealed class LoggerGenerator : TypeAttributeClassGeneratorBase sb.AppendLine("{"); sb.AppendLine(" /// Auto-generated logger"); sb.AppendLine( - $" {access} {staticKeyword}readonly ILogger {fieldName} = new ConsoleLoggerFactory().GetLogger(\"{name}\");"); + $" {access} {staticKeyword}readonly ILogger {fieldName} = LoggerFactoryResolver.Provider.CreateLogger(\"{name}\");"); sb.AppendLine("}"); return sb.ToString().TrimEnd();