mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-26 06:16:43 +08:00
style(csharp): 统一代码格式化规范并优化方法实现
- 调整注释格式统一使用4个空格缩进 - 重新排列字段声明顺序提升代码可读性 - 将简单属性访问器改为表达式主体语法 - 优化AudioManagerSystem中音量设置逻辑 - 移除AbstractAssetCatalogSystem中多余空行 - 重构日志类中方法实现为表达式主体形式 - 统一空行分隔符保持代码结构一致性 - 优化方法内部逻辑表达式简化代码 - [no tag]
This commit is contained in:
parent
378690a42c
commit
017870421e
@ -156,10 +156,7 @@ public abstract class Architecture(
|
||||
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);
|
||||
|
||||
@ -368,7 +365,9 @@ public abstract class Architecture(
|
||||
Container.RegisterPlurality(system);
|
||||
_allSystems.Add(system);
|
||||
if (!_mInited)
|
||||
{
|
||||
_mSystems.Add(system);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Debug($"Immediately initializing system: {typeof(TSystem).Name}");
|
||||
@ -400,7 +399,9 @@ public abstract class Architecture(
|
||||
Container.RegisterPlurality(model);
|
||||
|
||||
if (!_mInited)
|
||||
{
|
||||
_mModels.Add(model);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Debug($"Immediately initializing model: {typeof(TModel).Name}");
|
||||
|
||||
@ -6,20 +6,20 @@ namespace GFramework.Core.architecture;
|
||||
/// 默认架构配置类,实现IArchitectureConfiguration接口
|
||||
/// 提供日志工厂、日志级别和架构选项的默认配置
|
||||
/// </summary>
|
||||
public class ArchitectureConfiguration: IArchitectureConfiguration
|
||||
public class ArchitectureConfiguration : IArchitectureConfiguration
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取或设置日志工厂实例
|
||||
/// 默认使用控制台日志工厂
|
||||
/// </summary>
|
||||
public ILoggerFactory LoggerFactory { get; set; } = new ConsoleLoggerFactory();
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置日志级别
|
||||
/// 默认设置为Info级别
|
||||
/// </summary>
|
||||
public LogLevel LogLevel { get; set; } = LogLevel.Info;
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置日志工厂实例
|
||||
/// 默认使用控制台日志工厂
|
||||
/// </summary>
|
||||
public ILoggerFactory LoggerFactory { get; set; } = new ConsoleLoggerFactory();
|
||||
|
||||
/// <summary>
|
||||
/// 获取或设置架构选项
|
||||
/// 默认创建新的ArchitectureOptions实例
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
|
||||
using System.Collections.Immutable;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace GFramework.Core.architecture;
|
||||
|
||||
|
||||
@ -8,13 +8,13 @@ public sealed class ArchitectureOptions(
|
||||
bool allowLateRegistration = false
|
||||
)
|
||||
{
|
||||
/// <summary>
|
||||
/// 严格阶段验证开关,当设置为true时启用严格的阶段验证机制
|
||||
/// </summary>
|
||||
public bool StrictPhaseValidation = strictPhaseValidation;
|
||||
|
||||
/// <summary>
|
||||
/// 允许延迟注册开关,当设置为true时允许在初始化完成后进行组件注册
|
||||
/// </summary>
|
||||
public bool AllowLateRegistration = allowLateRegistration;
|
||||
|
||||
/// <summary>
|
||||
/// 严格阶段验证开关,当设置为true时启用严格的阶段验证机制
|
||||
/// </summary>
|
||||
public bool StrictPhaseValidation = strictPhaseValidation;
|
||||
}
|
||||
@ -13,6 +13,7 @@ public enum ArchitecturePhase
|
||||
/// 无效阶段,表示未定义的阶段
|
||||
/// </summary>
|
||||
None = 0,
|
||||
|
||||
/// <summary>
|
||||
/// 模型初始化之前阶段
|
||||
/// </summary>
|
||||
@ -37,13 +38,14 @@ public enum ArchitecturePhase
|
||||
/// 就绪阶段,完成冻结和事件处理后的最终状态
|
||||
/// </summary>
|
||||
Ready,
|
||||
|
||||
/// <summary>
|
||||
/// 正在销毁中 暂时不使用
|
||||
/// </summary>
|
||||
Destroying,
|
||||
|
||||
/// <summary>
|
||||
/// 已销毁 暂时不使用
|
||||
/// </summary>
|
||||
Destroyed
|
||||
|
||||
}
|
||||
@ -11,6 +11,21 @@ public class ArchitectureRuntime(IArchitectureContext context) : IArchitectureRu
|
||||
{
|
||||
private readonly IArchitectureContext _context = context ?? throw new ArgumentNullException(nameof(context));
|
||||
|
||||
#region Query Execution
|
||||
|
||||
/// <summary>
|
||||
/// 发起一次查询请求并获得其结果
|
||||
/// </summary>
|
||||
/// <typeparam name="TResult">查询结果的数据类型</typeparam>
|
||||
/// <param name="query">要发起的查询对象</param>
|
||||
/// <returns>查询得到的结果数据</returns>
|
||||
public TResult SendQuery<TResult>(IQuery<TResult> query)
|
||||
{
|
||||
return _context.SendQuery(query);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Command Execution
|
||||
|
||||
/// <summary>
|
||||
@ -36,21 +51,6 @@ public class ArchitectureRuntime(IArchitectureContext context) : IArchitectureRu
|
||||
|
||||
#endregion
|
||||
|
||||
#region Query Execution
|
||||
|
||||
/// <summary>
|
||||
/// 发起一次查询请求并获得其结果
|
||||
/// </summary>
|
||||
/// <typeparam name="TResult">查询结果的数据类型</typeparam>
|
||||
/// <param name="query">要发起的查询对象</param>
|
||||
/// <returns>查询得到的结果数据</returns>
|
||||
public TResult SendQuery<TResult>(IQuery<TResult> query)
|
||||
{
|
||||
return _context.SendQuery(query);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Event Management
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
|
||||
using GFramework.Core.events;
|
||||
using GFramework.Core.events;
|
||||
using GFramework.Core.ioc;
|
||||
|
||||
namespace GFramework.Core.architecture;
|
||||
|
||||
public class ArchitectureServices: IArchitectureServices
|
||||
public class ArchitectureServices : IArchitectureServices
|
||||
{
|
||||
public IIocContainer Container { get; } = new IocContainer();
|
||||
public ITypeEventSystem TypeEventSystem { get; } = new TypeEventSystem();
|
||||
|
||||
@ -1,8 +1,4 @@
|
||||
using GFramework.Core.architecture;
|
||||
using GFramework.Core.command;
|
||||
using GFramework.Core.events;
|
||||
using GFramework.Core.model;
|
||||
using GFramework.Core.query;
|
||||
using GFramework.Core.model;
|
||||
using GFramework.Core.system;
|
||||
using GFramework.Core.utility;
|
||||
|
||||
@ -12,8 +8,18 @@ namespace GFramework.Core.architecture;
|
||||
/// 架构接口,专注于生命周期管理,包括系统、模型、工具的注册和获取
|
||||
/// 业务操作通过 ArchitectureRuntime 提供
|
||||
/// </summary>
|
||||
public interface IArchitecture: IAsyncInitializable
|
||||
public interface IArchitecture : IAsyncInitializable
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取架构上下文
|
||||
/// </summary>
|
||||
IArchitectureContext Context { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取架构运行时实例
|
||||
/// </summary>
|
||||
IArchitectureRuntime Runtime { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 初始化方法,用于执行对象的初始化操作
|
||||
/// </summary>
|
||||
@ -62,14 +68,4 @@ public interface IArchitecture: IAsyncInitializable
|
||||
/// </summary>
|
||||
/// <param name="hook">生命周期钩子实例</param>
|
||||
void RegisterLifecycleHook(IArchitectureLifecycle hook);
|
||||
|
||||
/// <summary>
|
||||
/// 获取架构上下文
|
||||
/// </summary>
|
||||
IArchitectureContext Context { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取架构运行时实例
|
||||
/// </summary>
|
||||
IArchitectureRuntime Runtime { get; }
|
||||
}
|
||||
@ -17,4 +17,3 @@ public interface IArchitectureExtensible : IArchitecture
|
||||
/// <param name="hook">要注册的架构生命周期钩子实例</param>
|
||||
void RegisterLifecycleHook(IArchitectureLifecycle hook);
|
||||
}
|
||||
|
||||
|
||||
@ -12,4 +12,3 @@ public interface IArchitectureLifecycle
|
||||
/// <param name="architecture">相关的架构实例</param>
|
||||
void OnPhase(ArchitecturePhase phase, IArchitecture architecture);
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
|
||||
namespace GFramework.Core.architecture;
|
||||
namespace GFramework.Core.architecture;
|
||||
|
||||
/// <summary>
|
||||
/// 架构模块接口,继承自架构生命周期接口。
|
||||
|
||||
@ -11,4 +11,3 @@ public interface IArchitecturePhaseAware
|
||||
/// <param name="phase">架构阶段枚举值,表示当前所处的架构阶段</param>
|
||||
void OnArchitecturePhase(ArchitecturePhase phase);
|
||||
}
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ namespace GFramework.Core.command;
|
||||
/// 命令接口,定义了无返回值命令的基本契约
|
||||
/// 该接口继承了多个框架能力接口,使命令可以访问架构、系统、模型、工具,并能够发送事件、命令和查询
|
||||
/// </summary>
|
||||
public interface ICommand: IContextAware
|
||||
public interface ICommand : IContextAware
|
||||
{
|
||||
/// <summary>
|
||||
/// 执行命令的核心方法
|
||||
@ -20,7 +20,7 @@ public interface ICommand: IContextAware
|
||||
/// 该接口继承了多个框架能力接口,使命令可以访问架构、系统、模型、工具,并能够发送事件、命令和查询
|
||||
/// </summary>
|
||||
/// <typeparam name="TResult">命令执行后返回的结果类型</typeparam>
|
||||
public interface ICommand<out TResult>: IContextAware
|
||||
public interface ICommand<out TResult> : IContextAware
|
||||
{
|
||||
/// <summary>
|
||||
/// 执行命令的核心方法
|
||||
|
||||
@ -11,7 +11,10 @@ public class TypeEventSystem : ITypeEventSystem
|
||||
/// 发送事件,自动创建事件实例
|
||||
/// </summary>
|
||||
/// <typeparam name="T">事件类型,必须具有无参构造函数</typeparam>
|
||||
public void Send<T>() where T : new() => _mEvents.GetEvent<EasyEvent<T>>().Trigger(new T());
|
||||
public void Send<T>() where T : new()
|
||||
{
|
||||
_mEvents.GetEvent<EasyEvent<T>>().Trigger(new T());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送指定的事件实例
|
||||
@ -29,12 +32,18 @@ public class TypeEventSystem : ITypeEventSystem
|
||||
/// <typeparam name="T">事件类型</typeparam>
|
||||
/// <param name="onEvent">事件处理回调函数</param>
|
||||
/// <returns>反注册接口,用于注销事件监听</returns>
|
||||
public IUnRegister Register<T>(Action<T> onEvent) => _mEvents.GetOrAddEvent<EasyEvent<T>>().Register(onEvent);
|
||||
public IUnRegister Register<T>(Action<T> onEvent)
|
||||
{
|
||||
return _mEvents.GetOrAddEvent<EasyEvent<T>>().Register(onEvent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注销事件监听器
|
||||
/// </summary>
|
||||
/// <typeparam name="T">事件类型</typeparam>
|
||||
/// <param name="onEvent">要注销的事件处理回调函数</param>
|
||||
public void UnRegister<T>(Action<T> onEvent) => _mEvents.GetEvent<EasyEvent<T>>().UnRegister(onEvent);
|
||||
public void UnRegister<T>(Action<T> onEvent)
|
||||
{
|
||||
_mEvents.GetEvent<EasyEvent<T>>().UnRegister(onEvent);
|
||||
}
|
||||
}
|
||||
@ -16,10 +16,21 @@ public abstract class AbstractLogger(
|
||||
/// 获取日志器的名称
|
||||
/// </summary>
|
||||
/// <returns>日志器名称</returns>
|
||||
public string Name() => _name;
|
||||
public string Name()
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 平台输出入口,由具体实现负责真正的日志写入。
|
||||
/// </summary>
|
||||
/// <param name="level">日志级别</param>
|
||||
/// <param name="message">日志消息</param>
|
||||
/// <param name="exception">异常对象(可为null)</param>
|
||||
protected abstract void Write(LogLevel level, string message, Exception? exception);
|
||||
|
||||
#region Level Checks
|
||||
|
||||
/// <summary>
|
||||
@ -27,43 +38,64 @@ public abstract class AbstractLogger(
|
||||
/// </summary>
|
||||
/// <param name="level">要检查的日志级别</param>
|
||||
/// <returns>如果指定级别大于等于最小级别则返回true,否则返回false</returns>
|
||||
protected bool IsEnabled(LogLevel level) => level >= minLevel;
|
||||
protected bool IsEnabled(LogLevel level)
|
||||
{
|
||||
return level >= minLevel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查Trace级别日志是否启用
|
||||
/// </summary>
|
||||
/// <returns>如果Trace级别启用返回true,否则返回false</returns>
|
||||
public bool IsTraceEnabled() => IsEnabled(LogLevel.Trace);
|
||||
public bool IsTraceEnabled()
|
||||
{
|
||||
return IsEnabled(LogLevel.Trace);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查Debug级别日志是否启用
|
||||
/// </summary>
|
||||
/// <returns>如果Debug级别启用返回true,否则返回false</returns>
|
||||
public bool IsDebugEnabled() => IsEnabled(LogLevel.Debug);
|
||||
public bool IsDebugEnabled()
|
||||
{
|
||||
return IsEnabled(LogLevel.Debug);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查Info级别日志是否启用
|
||||
/// </summary>
|
||||
/// <returns>如果Info级别启用返回true,否则返回false</returns>
|
||||
public bool IsInfoEnabled() => IsEnabled(LogLevel.Info);
|
||||
public bool IsInfoEnabled()
|
||||
{
|
||||
return IsEnabled(LogLevel.Info);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查Warning级别日志是否启用
|
||||
/// </summary>
|
||||
/// <returns>如果Warning级别启用返回true,否则返回false</returns>
|
||||
public bool IsWarnEnabled() => IsEnabled(LogLevel.Warning);
|
||||
public bool IsWarnEnabled()
|
||||
{
|
||||
return IsEnabled(LogLevel.Warning);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查Error级别日志是否启用
|
||||
/// </summary>
|
||||
/// <returns>如果Error级别启用返回true,否则返回false</returns>
|
||||
public bool IsErrorEnabled() => IsEnabled(LogLevel.Error);
|
||||
public bool IsErrorEnabled()
|
||||
{
|
||||
return IsEnabled(LogLevel.Error);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查Fatal级别日志是否启用
|
||||
/// </summary>
|
||||
/// <returns>如果Fatal级别启用返回true,否则返回false</returns>
|
||||
public bool IsFatalEnabled() => IsEnabled(LogLevel.Fatal);
|
||||
public bool IsFatalEnabled()
|
||||
{
|
||||
return IsEnabled(LogLevel.Fatal);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -73,14 +105,20 @@ public abstract class AbstractLogger(
|
||||
/// 记录Trace级别日志
|
||||
/// </summary>
|
||||
/// <param name="msg">日志消息</param>
|
||||
public void Trace(string msg) => Log(LogLevel.Trace, msg);
|
||||
public void Trace(string msg)
|
||||
{
|
||||
Log(LogLevel.Trace, msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录Trace级别日志(带格式化参数)
|
||||
/// </summary>
|
||||
/// <param name="format">格式化字符串</param>
|
||||
/// <param name="arg">格式化参数</param>
|
||||
public void Trace(string format, object arg) => Log(LogLevel.Trace, format, arg);
|
||||
public void Trace(string format, object arg)
|
||||
{
|
||||
Log(LogLevel.Trace, format, arg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录Trace级别日志(带两个格式化参数)
|
||||
@ -88,21 +126,30 @@ public abstract class AbstractLogger(
|
||||
/// <param name="format">格式化字符串</param>
|
||||
/// <param name="arg1">第一个格式化参数</param>
|
||||
/// <param name="arg2">第二个格式化参数</param>
|
||||
public void Trace(string format, object arg1, object arg2) => Log(LogLevel.Trace, format, arg1, arg2);
|
||||
public void Trace(string format, object arg1, object arg2)
|
||||
{
|
||||
Log(LogLevel.Trace, format, arg1, arg2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录Trace级别日志(带多个格式化参数)
|
||||
/// </summary>
|
||||
/// <param name="format">格式化字符串</param>
|
||||
/// <param name="arguments">格式化参数数组</param>
|
||||
public void Trace(string format, params object[] arguments) => Log(LogLevel.Trace, format, arguments);
|
||||
public void Trace(string format, params object[] arguments)
|
||||
{
|
||||
Log(LogLevel.Trace, format, arguments);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录Trace级别日志(带异常信息)
|
||||
/// </summary>
|
||||
/// <param name="msg">日志消息</param>
|
||||
/// <param name="t">异常对象</param>
|
||||
public void Trace(string msg, Exception t) => Log(LogLevel.Trace, msg, t);
|
||||
public void Trace(string msg, Exception t)
|
||||
{
|
||||
Log(LogLevel.Trace, msg, t);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -112,14 +159,20 @@ public abstract class AbstractLogger(
|
||||
/// 记录Debug级别日志
|
||||
/// </summary>
|
||||
/// <param name="msg">日志消息</param>
|
||||
public void Debug(string msg) => Log(LogLevel.Debug, msg);
|
||||
public void Debug(string msg)
|
||||
{
|
||||
Log(LogLevel.Debug, msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录Debug级别日志(带格式化参数)
|
||||
/// </summary>
|
||||
/// <param name="format">格式化字符串</param>
|
||||
/// <param name="arg">格式化参数</param>
|
||||
public void Debug(string format, object arg) => Log(LogLevel.Debug, format, arg);
|
||||
public void Debug(string format, object arg)
|
||||
{
|
||||
Log(LogLevel.Debug, format, arg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录Debug级别日志(带两个格式化参数)
|
||||
@ -127,21 +180,30 @@ public abstract class AbstractLogger(
|
||||
/// <param name="format">格式化字符串</param>
|
||||
/// <param name="arg1">第一个格式化参数</param>
|
||||
/// <param name="arg2">第二个格式化参数</param>
|
||||
public void Debug(string format, object arg1, object arg2) => Log(LogLevel.Debug, format, arg1, arg2);
|
||||
public void Debug(string format, object arg1, object arg2)
|
||||
{
|
||||
Log(LogLevel.Debug, format, arg1, arg2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录Debug级别日志(带多个格式化参数)
|
||||
/// </summary>
|
||||
/// <param name="format">格式化字符串</param>
|
||||
/// <param name="arguments">格式化参数数组</param>
|
||||
public void Debug(string format, params object[] arguments) => Log(LogLevel.Debug, format, arguments);
|
||||
public void Debug(string format, params object[] arguments)
|
||||
{
|
||||
Log(LogLevel.Debug, format, arguments);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录Debug级别日志(带异常信息)
|
||||
/// </summary>
|
||||
/// <param name="msg">日志消息</param>
|
||||
/// <param name="t">异常对象</param>
|
||||
public void Debug(string msg, Exception t) => Log(LogLevel.Debug, msg, t);
|
||||
public void Debug(string msg, Exception t)
|
||||
{
|
||||
Log(LogLevel.Debug, msg, t);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -151,14 +213,20 @@ public abstract class AbstractLogger(
|
||||
/// 记录Info级别日志
|
||||
/// </summary>
|
||||
/// <param name="msg">日志消息</param>
|
||||
public void Info(string msg) => Log(LogLevel.Info, msg);
|
||||
public void Info(string msg)
|
||||
{
|
||||
Log(LogLevel.Info, msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录Info级别日志(带格式化参数)
|
||||
/// </summary>
|
||||
/// <param name="format">格式化字符串</param>
|
||||
/// <param name="arg">格式化参数</param>
|
||||
public void Info(string format, object arg) => Log(LogLevel.Info, format, arg);
|
||||
public void Info(string format, object arg)
|
||||
{
|
||||
Log(LogLevel.Info, format, arg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录Info级别日志(带两个格式化参数)
|
||||
@ -166,21 +234,30 @@ public abstract class AbstractLogger(
|
||||
/// <param name="format">格式化字符串</param>
|
||||
/// <param name="arg1">第一个格式化参数</param>
|
||||
/// <param name="arg2">第二个格式化参数</param>
|
||||
public void Info(string format, object arg1, object arg2) => Log(LogLevel.Info, format, arg1, arg2);
|
||||
public void Info(string format, object arg1, object arg2)
|
||||
{
|
||||
Log(LogLevel.Info, format, arg1, arg2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录Info级别日志(带多个格式化参数)
|
||||
/// </summary>
|
||||
/// <param name="format">格式化字符串</param>
|
||||
/// <param name="arguments">格式化参数数组</param>
|
||||
public void Info(string format, params object[] arguments) => Log(LogLevel.Info, format, arguments);
|
||||
public void Info(string format, params object[] arguments)
|
||||
{
|
||||
Log(LogLevel.Info, format, arguments);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录Info级别日志(带异常信息)
|
||||
/// </summary>
|
||||
/// <param name="msg">日志消息</param>
|
||||
/// <param name="t">异常对象</param>
|
||||
public void Info(string msg, Exception t) => Log(LogLevel.Info, msg, t);
|
||||
public void Info(string msg, Exception t)
|
||||
{
|
||||
Log(LogLevel.Info, msg, t);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -190,14 +267,20 @@ public abstract class AbstractLogger(
|
||||
/// 记录Warning级别日志
|
||||
/// </summary>
|
||||
/// <param name="msg">日志消息</param>
|
||||
public void Warn(string msg) => Log(LogLevel.Warning, msg);
|
||||
public void Warn(string msg)
|
||||
{
|
||||
Log(LogLevel.Warning, msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录Warning级别日志(带格式化参数)
|
||||
/// </summary>
|
||||
/// <param name="format">格式化字符串</param>
|
||||
/// <param name="arg">格式化参数</param>
|
||||
public void Warn(string format, object arg) => Log(LogLevel.Warning, format, arg);
|
||||
public void Warn(string format, object arg)
|
||||
{
|
||||
Log(LogLevel.Warning, format, arg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录Warning级别日志(带两个格式化参数)
|
||||
@ -205,21 +288,30 @@ public abstract class AbstractLogger(
|
||||
/// <param name="format">格式化字符串</param>
|
||||
/// <param name="arg1">第一个格式化参数</param>
|
||||
/// <param name="arg2">第二个格式化参数</param>
|
||||
public void Warn(string format, object arg1, object arg2) => Log(LogLevel.Warning, format, arg1, arg2);
|
||||
public void Warn(string format, object arg1, object arg2)
|
||||
{
|
||||
Log(LogLevel.Warning, format, arg1, arg2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录Warning级别日志(带多个格式化参数)
|
||||
/// </summary>
|
||||
/// <param name="format">格式化字符串</param>
|
||||
/// <param name="arguments">格式化参数数组</param>
|
||||
public void Warn(string format, params object[] arguments) => Log(LogLevel.Warning, format, arguments);
|
||||
public void Warn(string format, params object[] arguments)
|
||||
{
|
||||
Log(LogLevel.Warning, format, arguments);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录Warning级别日志(带异常信息)
|
||||
/// </summary>
|
||||
/// <param name="msg">日志消息</param>
|
||||
/// <param name="t">异常对象</param>
|
||||
public void Warn(string msg, Exception t) => Log(LogLevel.Warning, msg, t);
|
||||
public void Warn(string msg, Exception t)
|
||||
{
|
||||
Log(LogLevel.Warning, msg, t);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -229,14 +321,20 @@ public abstract class AbstractLogger(
|
||||
/// 记录Error级别日志
|
||||
/// </summary>
|
||||
/// <param name="msg">日志消息</param>
|
||||
public void Error(string msg) => Log(LogLevel.Error, msg);
|
||||
public void Error(string msg)
|
||||
{
|
||||
Log(LogLevel.Error, msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录Error级别日志(带格式化参数)
|
||||
/// </summary>
|
||||
/// <param name="format">格式化字符串</param>
|
||||
/// <param name="arg">格式化参数</param>
|
||||
public void Error(string format, object arg) => Log(LogLevel.Error, format, arg);
|
||||
public void Error(string format, object arg)
|
||||
{
|
||||
Log(LogLevel.Error, format, arg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录Error级别日志(带两个格式化参数)
|
||||
@ -244,21 +342,30 @@ public abstract class AbstractLogger(
|
||||
/// <param name="format">格式化字符串</param>
|
||||
/// <param name="arg1">第一个格式化参数</param>
|
||||
/// <param name="arg2">第二个格式化参数</param>
|
||||
public void Error(string format, object arg1, object arg2) => Log(LogLevel.Error, format, arg1, arg2);
|
||||
public void Error(string format, object arg1, object arg2)
|
||||
{
|
||||
Log(LogLevel.Error, format, arg1, arg2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录Error级别日志(带多个格式化参数)
|
||||
/// </summary>
|
||||
/// <param name="format">格式化字符串</param>
|
||||
/// <param name="arguments">格式化参数数组</param>
|
||||
public void Error(string format, params object[] arguments) => Log(LogLevel.Error, format, arguments);
|
||||
public void Error(string format, params object[] arguments)
|
||||
{
|
||||
Log(LogLevel.Error, format, arguments);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录Error级别日志(带异常信息)
|
||||
/// </summary>
|
||||
/// <param name="msg">日志消息</param>
|
||||
/// <param name="t">异常对象</param>
|
||||
public void Error(string msg, Exception t) => Log(LogLevel.Error, msg, t);
|
||||
public void Error(string msg, Exception t)
|
||||
{
|
||||
Log(LogLevel.Error, msg, t);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -268,14 +375,20 @@ public abstract class AbstractLogger(
|
||||
/// 记录Fatal级别日志
|
||||
/// </summary>
|
||||
/// <param name="msg">日志消息</param>
|
||||
public void Fatal(string msg) => Log(LogLevel.Fatal, msg);
|
||||
public void Fatal(string msg)
|
||||
{
|
||||
Log(LogLevel.Fatal, msg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录Fatal级别日志(带格式化参数)
|
||||
/// </summary>
|
||||
/// <param name="format">格式化字符串</param>
|
||||
/// <param name="arg">格式化参数</param>
|
||||
public void Fatal(string format, object arg) => Log(LogLevel.Fatal, format, arg);
|
||||
public void Fatal(string format, object arg)
|
||||
{
|
||||
Log(LogLevel.Fatal, format, arg);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录Fatal级别日志(带两个格式化参数)
|
||||
@ -283,21 +396,30 @@ public abstract class AbstractLogger(
|
||||
/// <param name="format">格式化字符串</param>
|
||||
/// <param name="arg1">第一个格式化参数</param>
|
||||
/// <param name="arg2">第二个格式化参数</param>
|
||||
public void Fatal(string format, object arg1, object arg2) => Log(LogLevel.Fatal, format, arg1, arg2);
|
||||
public void Fatal(string format, object arg1, object arg2)
|
||||
{
|
||||
Log(LogLevel.Fatal, format, arg1, arg2);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录Fatal级别日志(带多个格式化参数)
|
||||
/// </summary>
|
||||
/// <param name="format">格式化字符串</param>
|
||||
/// <param name="arguments">格式化参数数组</param>
|
||||
public void Fatal(string format, params object[] arguments) => Log(LogLevel.Fatal, format, arguments);
|
||||
public void Fatal(string format, params object[] arguments)
|
||||
{
|
||||
Log(LogLevel.Fatal, format, arguments);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记录Fatal级别日志(带异常信息)
|
||||
/// </summary>
|
||||
/// <param name="msg">日志消息</param>
|
||||
/// <param name="t">异常对象</param>
|
||||
public void Fatal(string msg, Exception t) => Log(LogLevel.Fatal, msg, t);
|
||||
public void Fatal(string msg, Exception t)
|
||||
{
|
||||
Log(LogLevel.Fatal, msg, t);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@ -339,12 +461,4 @@ public abstract class AbstractLogger(
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 平台输出入口,由具体实现负责真正的日志写入。
|
||||
/// </summary>
|
||||
/// <param name="level">日志级别</param>
|
||||
/// <param name="message">日志消息</param>
|
||||
/// <param name="exception">异常对象(可为null)</param>
|
||||
protected abstract void Write(LogLevel level, string message, Exception? exception);
|
||||
}
|
||||
@ -9,8 +9,8 @@ public sealed class ConsoleLogger(
|
||||
TextWriter? writer = null,
|
||||
bool useColors = true) : AbstractLogger(name ?? ILogger.RootLoggerName, minLevel)
|
||||
{
|
||||
private readonly TextWriter _writer = writer ?? Console.Out;
|
||||
private readonly bool _useColors = useColors && writer == Console.Out;
|
||||
private readonly TextWriter _writer = writer ?? Console.Out;
|
||||
|
||||
/// <summary>
|
||||
/// 写入日志消息到控制台
|
||||
@ -25,22 +25,16 @@ public sealed class ConsoleLogger(
|
||||
var log = $"[{timestamp}] {levelStr} [{Name()}] {message}";
|
||||
|
||||
// 添加异常信息到日志
|
||||
if (exception != null)
|
||||
{
|
||||
log += Environment.NewLine + exception;
|
||||
}
|
||||
if (exception != null) log += Environment.NewLine + exception;
|
||||
|
||||
if (_useColors)
|
||||
{
|
||||
WriteColored(level, log);
|
||||
}
|
||||
else
|
||||
{
|
||||
_writer.WriteLine(log);
|
||||
}
|
||||
}
|
||||
|
||||
#region Internal Core
|
||||
|
||||
/// <summary>
|
||||
/// 以指定颜色写入日志消息
|
||||
/// </summary>
|
||||
@ -65,7 +59,9 @@ public sealed class ConsoleLogger(
|
||||
/// </summary>
|
||||
/// <param name="level">日志级别</param>
|
||||
/// <returns>控制台颜色</returns>
|
||||
private static ConsoleColor GetColor(LogLevel level) => level switch
|
||||
private static ConsoleColor GetColor(LogLevel level)
|
||||
{
|
||||
return level switch
|
||||
{
|
||||
LogLevel.Trace => ConsoleColor.DarkGray,
|
||||
LogLevel.Debug => ConsoleColor.Cyan,
|
||||
@ -75,6 +71,7 @@ public sealed class ConsoleLogger(
|
||||
LogLevel.Fatal => ConsoleColor.Magenta,
|
||||
_ => ConsoleColor.White
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@ -9,22 +9,27 @@ public enum LogLevel
|
||||
/// 跟踪级别,用于详细的程序执行流程信息
|
||||
/// </summary>
|
||||
Trace,
|
||||
|
||||
/// <summary>
|
||||
/// 调试级别,用于调试过程中的详细信息
|
||||
/// </summary>
|
||||
Debug,
|
||||
|
||||
/// <summary>
|
||||
/// 信息级别,用于一般性的程序运行信息
|
||||
/// </summary>
|
||||
Info,
|
||||
|
||||
/// <summary>
|
||||
/// 警告级别,用于表示可能的问题或异常情况
|
||||
/// </summary>
|
||||
Warning,
|
||||
|
||||
/// <summary>
|
||||
/// 错误级别,用于表示错误但程序仍可继续运行的情况
|
||||
/// </summary>
|
||||
Error,
|
||||
|
||||
/// <summary>
|
||||
/// 致命级别,用于表示严重的错误导致程序无法继续运行
|
||||
/// </summary>
|
||||
|
||||
@ -17,6 +17,5 @@ internal sealed class NoopLogger(
|
||||
/// <param name="exception">异常信息</param>
|
||||
protected override void Write(LogLevel level, string message, Exception? exception)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@ -3,7 +3,7 @@
|
||||
/// <summary>
|
||||
/// 无操作日志工厂实现,用于提供空的日志记录功能
|
||||
/// </summary>
|
||||
public class NoopLoggerFactory: ILoggerFactory
|
||||
public class NoopLoggerFactory : ILoggerFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取指定名称的无操作日志记录器
|
||||
|
||||
@ -2,7 +2,8 @@
|
||||
|
||||
## 概述
|
||||
|
||||
GFramework.Core 提供了一个灵活、可配置的日志系统,支持多级别、多类别和多种输出方式的日志记录。默认日志级别为 `Info`,确保框架的关键操作都能被记录下来。
|
||||
GFramework.Core 提供了一个灵活、可配置的日志系统,支持多级别、多类别和多种输出方式的日志记录。默认日志级别为 `Info`
|
||||
,确保框架的关键操作都能被记录下来。
|
||||
|
||||
## 主要特性
|
||||
|
||||
@ -241,27 +242,32 @@ paymentLogger.Info("支付成功", new { OrderId = "ORD_789", TransactionId = "t
|
||||
GFramework.Core 在以下关键位置自动添加了日志记录:
|
||||
|
||||
### 架构模块 (Architecture)
|
||||
|
||||
- 架构初始化流程
|
||||
- 组件注册和初始化
|
||||
- 生命周期阶段变更
|
||||
- 模块安装和卸载
|
||||
|
||||
### IOC容器 (IOC)
|
||||
|
||||
- 对象注册和获取
|
||||
- 容器冻结操作
|
||||
- 重复注册检测
|
||||
|
||||
### 事件系统 (Event)
|
||||
|
||||
- 事件发送和接收
|
||||
- 事件处理器注册和注销
|
||||
|
||||
### 系统模块 (System)
|
||||
|
||||
- 系统初始化和销毁
|
||||
- 组件生命周期管理
|
||||
|
||||
## 输出格式
|
||||
|
||||
### 控制台输出示例
|
||||
|
||||
```
|
||||
[2025-12-23 12:34:56.789] INFO Architecture Architecture initialized
|
||||
[2025-12-23 12:34:56.790] INFO Architecture Initializing 3 systems
|
||||
@ -271,6 +277,7 @@ GFramework.Core 在以下关键位置自动添加了日志记录:
|
||||
```
|
||||
|
||||
### 日志输出级别颜色
|
||||
|
||||
- **Trace**: 灰色
|
||||
- **Debug**: 青色
|
||||
- **Info**: 白色
|
||||
@ -331,6 +338,7 @@ GFramework.Core 在以下关键位置自动添加了日志记录:
|
||||
## 配置建议
|
||||
|
||||
### 开发环境
|
||||
|
||||
```csharp
|
||||
Log.Configure(
|
||||
minLevel: LogLevel.Debug,
|
||||
@ -341,6 +349,7 @@ Log.Configure(
|
||||
```
|
||||
|
||||
### 生产环境
|
||||
|
||||
```csharp
|
||||
var config = new LogConfig
|
||||
{
|
||||
|
||||
@ -12,6 +12,14 @@ public abstract class AbstractModel : IModel
|
||||
/// </summary>
|
||||
protected IArchitecture Architecture;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化模型,调用抽象方法OnInit执行具体初始化逻辑
|
||||
/// </summary>
|
||||
void IModel.Init()
|
||||
{
|
||||
OnInit();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取模型所属的架构实例
|
||||
/// </summary>
|
||||
@ -30,14 +38,6 @@ public abstract class AbstractModel : IModel
|
||||
Architecture = architecture;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化模型,调用抽象方法OnInit执行具体初始化逻辑
|
||||
/// </summary>
|
||||
void IModel.Init()
|
||||
{
|
||||
OnInit();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 抽象初始化方法,由子类实现具体的初始化逻辑
|
||||
/// </summary>
|
||||
|
||||
@ -1,8 +1,4 @@
|
||||
using GFramework.Core.events;
|
||||
using GFramework.Core.rule;
|
||||
using GFramework.Core.utility;
|
||||
|
||||
namespace GFramework.Core.model;
|
||||
namespace GFramework.Core.model;
|
||||
|
||||
/// <summary>
|
||||
/// 模型接口,定义了模型的基本行为和功能
|
||||
|
||||
@ -6,7 +6,7 @@ namespace GFramework.Core.query;
|
||||
/// 抽象查询类,提供查询操作的基础实现
|
||||
/// </summary>
|
||||
/// <typeparam name="T">查询结果的类型</typeparam>
|
||||
public abstract class AbstractQuery<T> :ContextAwareBase, IQuery<T>
|
||||
public abstract class AbstractQuery<T> : ContextAwareBase, IQuery<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// 执行查询操作
|
||||
|
||||
@ -6,7 +6,7 @@ namespace GFramework.Core.query;
|
||||
/// 查询接口,定义了执行查询操作的契约
|
||||
/// </summary>
|
||||
/// <typeparam name="TResult">查询结果的类型</typeparam>
|
||||
public interface IQuery<out TResult>:IContextAware
|
||||
public interface IQuery<out TResult> : IContextAware
|
||||
{
|
||||
/// <summary>
|
||||
/// 执行查询操作并返回结果
|
||||
|
||||
@ -25,5 +25,7 @@ public abstract class ContextAwareBase : IContextAware
|
||||
/// <summary>
|
||||
/// 当上下文准备就绪时调用的虚方法,子类可以重写此方法来执行上下文相关的初始化逻辑
|
||||
/// </summary>
|
||||
protected virtual void OnContextReady() { }
|
||||
protected virtual void OnContextReady()
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -6,11 +6,10 @@ namespace GFramework.Core.utility;
|
||||
/// 上下文工具接口,继承自IUtility和IContextAware接口
|
||||
/// 提供具有上下文感知能力的工具功能
|
||||
/// </summary>
|
||||
public interface IContextUtility:IUtility,IContextAware
|
||||
public interface IContextUtility : IUtility, IContextAware
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化上下文工具
|
||||
/// </summary>
|
||||
void Init();
|
||||
}
|
||||
|
||||
|
||||
@ -7,6 +7,6 @@
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\GFramework.Core\GFramework.Core.csproj" />
|
||||
<ProjectReference Include="..\GFramework.Core\GFramework.Core.csproj"/>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@ -5,18 +5,18 @@ namespace GFramework.Game.assets;
|
||||
/// <summary>
|
||||
/// 资源目录系统抽象基类,用于管理和注册游戏中的场景和资源。
|
||||
/// 提供了统一的接口来注册和查询不同类型的资产(如游戏单元、模板、普通资源)。
|
||||
/// 子类需要实现 <see cref="RegisterAssets"/> 方法以完成具体资产的注册逻辑。
|
||||
/// 子类需要实现 <see cref="RegisterAssets" /> 方法以完成具体资产的注册逻辑。
|
||||
/// </summary>
|
||||
public abstract class AbstractAssetCatalogSystem : AbstractSystem, IAssetCatalogSystem
|
||||
{
|
||||
private readonly Dictionary<string, AssetCatalog.SceneUnitId> _sceneUnits = new();
|
||||
private readonly Dictionary<string, AssetCatalog.ScenePageId> _scenePages = new();
|
||||
private readonly Dictionary<string, AssetCatalog.AssetId> _assets = new();
|
||||
private readonly Dictionary<string, AssetCatalog.ScenePageId> _scenePages = new();
|
||||
private readonly Dictionary<string, AssetCatalog.SceneUnitId> _sceneUnits = new();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 系统初始化时调用,用于触发资产注册流程。
|
||||
/// 此方法会调用抽象方法 <see cref="RegisterAssets"/>,由子类提供实际注册逻辑。
|
||||
/// 此方法会调用抽象方法 <see cref="RegisterAssets" />,由子类提供实际注册逻辑。
|
||||
/// </summary>
|
||||
protected override void OnInit()
|
||||
{
|
||||
@ -31,7 +31,6 @@ public abstract class AbstractAssetCatalogSystem : AbstractSystem, IAssetCatalog
|
||||
|
||||
#region Register(内部 or Module 使用)
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 注册场景单元到资产目录中
|
||||
/// </summary>
|
||||
@ -107,7 +106,7 @@ public abstract class AbstractAssetCatalogSystem : AbstractSystem, IAssetCatalog
|
||||
/// </summary>
|
||||
/// <param name="mapping">包含键与ID映射关系的对象。</param>
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// 当映射ID不是 <see cref="AssetCatalog.AssetId"/> 类型或键重复时抛出异常。
|
||||
/// 当映射ID不是 <see cref="AssetCatalog.AssetId" /> 类型或键重复时抛出异常。
|
||||
/// </exception>
|
||||
public void RegisterAsset(AssetCatalog.AssetCatalogMapping mapping)
|
||||
{
|
||||
@ -117,6 +116,7 @@ public abstract class AbstractAssetCatalogSystem : AbstractSystem, IAssetCatalog
|
||||
if (!_assets.TryAdd(mapping.Key, assetId))
|
||||
throw new InvalidOperationException($"Asset key duplicated: {mapping.Key}");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Query(对外)
|
||||
@ -126,14 +126,20 @@ public abstract class AbstractAssetCatalogSystem : AbstractSystem, IAssetCatalog
|
||||
/// </summary>
|
||||
/// <param name="key">用于查找场景单元的键值</param>
|
||||
/// <returns>返回与指定键对应的场景单元标识符</returns>
|
||||
public AssetCatalog.SceneUnitId GetSceneUnit(string key) => _sceneUnits[key];
|
||||
public AssetCatalog.SceneUnitId GetSceneUnit(string key)
|
||||
{
|
||||
return _sceneUnits[key];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据指定的键获取场景页面标识符
|
||||
/// </summary>
|
||||
/// <param name="key">用于查找场景页面的键值</param>
|
||||
/// <returns>返回与指定键对应的场景页面标识符</returns>
|
||||
public AssetCatalog.ScenePageId GetScenePage(string key) => _scenePages[key];
|
||||
public AssetCatalog.ScenePageId GetScenePage(string key)
|
||||
{
|
||||
return _scenePages[key];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定键对应的通用资源ID。
|
||||
@ -141,27 +147,40 @@ public abstract class AbstractAssetCatalogSystem : AbstractSystem, IAssetCatalog
|
||||
/// <param name="key">要查找的通用资源键。</param>
|
||||
/// <returns>对应的通用资源ID。</returns>
|
||||
/// <exception cref="KeyNotFoundException">如果未找到指定键则抛出异常。</exception>
|
||||
public AssetCatalog.AssetId GetAsset(string key) => _assets[key];
|
||||
public AssetCatalog.AssetId GetAsset(string key)
|
||||
{
|
||||
return _assets[key];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在指定键的场景单元
|
||||
/// </summary>
|
||||
/// <param name="key">用于查找场景单元的键值</param>
|
||||
/// <returns>存在返回true,否则返回false</returns>
|
||||
public bool HasSceneUnit(string key) => _sceneUnits.ContainsKey(key);
|
||||
public bool HasSceneUnit(string key)
|
||||
{
|
||||
return _sceneUnits.ContainsKey(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否存在指定键的场景页面
|
||||
/// </summary>
|
||||
/// <param name="key">用于查找场景页面的键值</param>
|
||||
/// <returns>存在返回true,否则返回false</returns>
|
||||
public bool HasScenePage(string key) => _scenePages.ContainsKey(key);
|
||||
public bool HasScenePage(string key)
|
||||
{
|
||||
return _scenePages.ContainsKey(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断是否存在指定键的通用资源。
|
||||
/// </summary>
|
||||
/// <param name="key">要检查的通用资源键。</param>
|
||||
/// <returns>若存在返回 true,否则返回 false。</returns>
|
||||
public bool HasAsset(string key) => _assets.ContainsKey(key);
|
||||
public bool HasAsset(string key)
|
||||
{
|
||||
return _assets.ContainsKey(key);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@ -42,6 +42,4 @@ public static class AssetCatalog
|
||||
/// </summary>
|
||||
/// <param name="Path">资源路径</param>
|
||||
public readonly record struct AssetId(string Path) : IAssetId;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -94,5 +94,4 @@ public interface IAssetCatalogSystem : ISystem
|
||||
/// <param name="key">用于查找资源的键值</param>
|
||||
/// <returns>存在返回true,否则返回false</returns>
|
||||
bool HasAsset(string key);
|
||||
|
||||
}
|
||||
@ -23,4 +23,3 @@ public interface IResourceFactorySystem : ISystem
|
||||
/// <returns>返回一个创建T类型实例的函数委托</returns>
|
||||
Func<T> GetFactory<T>(AssetCatalog.AssetCatalogMapping mapping);
|
||||
}
|
||||
|
||||
|
||||
@ -15,11 +15,6 @@ public static class ResourceFactory
|
||||
/// </summary>
|
||||
bool Preload { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 执行与该条目关联的工厂方法
|
||||
/// </summary>
|
||||
void ExecuteFactory();
|
||||
|
||||
/// <summary>
|
||||
/// 获取资源类型
|
||||
/// </summary>
|
||||
@ -29,6 +24,11 @@ public static class ResourceFactory
|
||||
/// 获取资源键值
|
||||
/// </summary>
|
||||
string Key { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 执行与该条目关联的工厂方法
|
||||
/// </summary>
|
||||
void ExecuteFactory();
|
||||
}
|
||||
|
||||
|
||||
@ -51,7 +51,10 @@ public static class ResourceFactory
|
||||
/// <summary>
|
||||
/// 执行工厂函数以创建资源实例
|
||||
/// </summary>
|
||||
public void ExecuteFactory() => Factory();
|
||||
public void ExecuteFactory()
|
||||
{
|
||||
Factory();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取资源的类型
|
||||
@ -105,9 +108,7 @@ public static class ResourceFactory
|
||||
|
||||
if (_factories.TryGetValue(dictKey, out var entry)
|
||||
&& entry is Entry<T> typed)
|
||||
{
|
||||
return typed.Factory;
|
||||
}
|
||||
|
||||
throw new InvalidOperationException(
|
||||
$"Factory not registered: {typeof(T).Name} with key '{key}'");
|
||||
@ -120,11 +121,8 @@ public static class ResourceFactory
|
||||
{
|
||||
// 遍历所有已注册的工厂
|
||||
foreach (var entry in _factories.Values.Where(entry => entry.Preload))
|
||||
{
|
||||
// 执行其工厂方法进行预加载
|
||||
entry.ExecuteFactory();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,44 +0,0 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace GFramework.Godot.SourceGenerators.logging;
|
||||
|
||||
/// <summary>
|
||||
/// 提供诊断描述符的静态类,用于GFramework日志生成器的编译时检查
|
||||
/// </summary>
|
||||
internal static class GodotLoggerDiagnostics
|
||||
{
|
||||
/// <summary>
|
||||
/// 诊断描述符:标识使用[GodotLog]特性的类必须声明为partial
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// ID: GFLOG001
|
||||
/// 严重性: Error
|
||||
/// 分类: GFramework.Godot.Logging
|
||||
/// </remarks>
|
||||
public static readonly DiagnosticDescriptor MustBePartial =
|
||||
new(
|
||||
id: "GFLOG001",
|
||||
title: "Class must be partial",
|
||||
messageFormat: "Class '{0}' must be declared as partial to use [GodotLog]",
|
||||
category: "GFramework.Godot.Logging",
|
||||
DiagnosticSeverity.Error,
|
||||
isEnabledByDefault: true
|
||||
);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 诊断描述符:标识GodotLogAttribute无法在指定类上生成Logger
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// ID: GFW_LOG001
|
||||
/// 严重性: Warning
|
||||
/// 分类: GFramework.Godot.Logging
|
||||
/// </remarks>
|
||||
public static readonly DiagnosticDescriptor LogAttributeInvalid = new(
|
||||
id: "GFW_LOG001",
|
||||
title: "GodotLogAttribute cannot generate Logger",
|
||||
messageFormat: "GodotLogAttribute on class '{0}' is ineffective: {1}",
|
||||
category: "GFramework.Godot.Logging",
|
||||
DiagnosticSeverity.Warning,
|
||||
isEnabledByDefault: true);
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace GFramework.Godot.SourceGenerators.logging;
|
||||
|
||||
/// <summary>
|
||||
/// 提供诊断描述符的静态类,用于GFramework日志生成器的编译时检查
|
||||
/// </summary>
|
||||
internal static class GodotLoggerDiagnostics
|
||||
{
|
||||
/// <summary>
|
||||
/// 诊断描述符:标识使用[GodotLog]特性的类必须声明为partial
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// ID: GFLOG001
|
||||
/// 严重性: Error
|
||||
/// 分类: GFramework.Godot.Logging
|
||||
/// </remarks>
|
||||
public static readonly DiagnosticDescriptor MustBePartial =
|
||||
new(
|
||||
"GFLOG001",
|
||||
"Class must be partial",
|
||||
"Class '{0}' must be declared as partial to use [GodotLog]",
|
||||
"GFramework.Godot.Logging",
|
||||
DiagnosticSeverity.Error,
|
||||
true
|
||||
);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 诊断描述符:标识GodotLogAttribute无法在指定类上生成Logger
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// ID: GFW_LOG001
|
||||
/// 严重性: Warning
|
||||
/// 分类: GFramework.Godot.Logging
|
||||
/// </remarks>
|
||||
public static readonly DiagnosticDescriptor LogAttributeInvalid = new(
|
||||
"GFW_LOG001",
|
||||
"GodotLogAttribute cannot generate Logger",
|
||||
"GodotLogAttribute on class '{0}' is ineffective: {1}",
|
||||
"GFramework.Godot.Logging",
|
||||
DiagnosticSeverity.Warning,
|
||||
true);
|
||||
}
|
||||
@ -14,7 +14,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\GFramework.Game\GFramework.Game.csproj" />
|
||||
<ProjectReference Include="..\GFramework.Game\GFramework.Game.csproj"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@ -9,9 +9,8 @@ namespace GFramework.Godot.architecture;
|
||||
/// 抽象架构类,为特定类型的架构提供基础实现框架。
|
||||
/// 此类负责管理架构的初始化、生命周期绑定以及扩展模块的安装与销毁。
|
||||
/// </summary>
|
||||
public abstract class AbstractArchitecture: Architecture
|
||||
public abstract class AbstractArchitecture : Architecture
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 架构锚点节点的唯一标识名称
|
||||
/// 用于在Godot场景树中创建和查找架构锚点节点
|
||||
@ -30,18 +29,18 @@ public abstract class AbstractArchitecture: Architecture
|
||||
/// </summary>
|
||||
private ArchitectureAnchor? _anchor;
|
||||
|
||||
/// <summary>
|
||||
/// 获取架构根节点。如果尚未初始化或已被销毁,则抛出异常。
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException">当架构未准备就绪时抛出。</exception>
|
||||
protected Node ArchitectureRoot => _anchor ?? throw new InvalidOperationException("Architecture root not ready");
|
||||
|
||||
/// <summary>
|
||||
/// 标记架构是否已被销毁的状态标志
|
||||
/// 用于防止架构被重复销毁,确保资源清理只执行一次
|
||||
/// </summary>
|
||||
private bool _destroyed;
|
||||
|
||||
/// <summary>
|
||||
/// 获取架构根节点。如果尚未初始化或已被销毁,则抛出异常。
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException">当架构未准备就绪时抛出。</exception>
|
||||
protected Node ArchitectureRoot => _anchor ?? throw new InvalidOperationException("Architecture root not ready");
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 初始化架构,按顺序注册模型、系统和工具。
|
||||
@ -111,7 +110,6 @@ public abstract class AbstractArchitecture: Architecture
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 销毁架构及其相关资源。
|
||||
/// 调用所有已安装扩展的OnDetach方法,并清空扩展列表。
|
||||
|
||||
@ -6,7 +6,7 @@ namespace GFramework.Godot.architecture;
|
||||
/// <summary>
|
||||
/// 抽象的Godot模块基类,用于定义Godot框架中的模块行为
|
||||
/// </summary>
|
||||
public abstract class AbstractGodotModule: IGodotModule
|
||||
public abstract class AbstractGodotModule : IGodotModule
|
||||
{
|
||||
/// <summary>
|
||||
/// 当架构阶段发生变化时调用此方法
|
||||
@ -15,7 +15,6 @@ public abstract class AbstractGodotModule: IGodotModule
|
||||
/// <param name="arch">架构实例</param>
|
||||
public virtual void OnPhase(ArchitecturePhase phase, IArchitecture arch)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -24,7 +23,6 @@ public abstract class AbstractGodotModule: IGodotModule
|
||||
/// <param name="phase">当前的架构阶段</param>
|
||||
public virtual void OnArchitecturePhase(ArchitecturePhase phase)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -44,7 +42,6 @@ public abstract class AbstractGodotModule: IGodotModule
|
||||
/// <param name="architecture">被附加到的架构实例</param>
|
||||
public virtual void OnAttach(Architecture architecture)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -52,6 +49,5 @@ public abstract class AbstractGodotModule: IGodotModule
|
||||
/// </summary>
|
||||
public virtual void OnDetach()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@ -9,6 +9,7 @@ namespace GFramework.Godot.architecture;
|
||||
public partial class ArchitectureAnchor : Node
|
||||
{
|
||||
private Action? _onExit;
|
||||
|
||||
/// <summary>
|
||||
/// 绑定节点退出时的回调动作
|
||||
/// </summary>
|
||||
@ -16,10 +17,8 @@ public partial class ArchitectureAnchor : Node
|
||||
public void Bind(Action onExit)
|
||||
{
|
||||
if (_onExit != null)
|
||||
{
|
||||
GD.PushWarning(
|
||||
$"{nameof(ArchitectureAnchor)} already bound. Rebinding will override previous callback.");
|
||||
}
|
||||
_onExit = onExit;
|
||||
}
|
||||
|
||||
@ -34,4 +33,3 @@ public partial class ArchitectureAnchor : Node
|
||||
callback?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -12,21 +12,9 @@ namespace GFramework.Godot.assets;
|
||||
/// </summary>
|
||||
public abstract class AbstractResourceFactorySystem : AbstractSystem, IResourceFactorySystem, IArchitectureLifecycle
|
||||
{
|
||||
private IAssetCatalogSystem? _assetCatalogSystem;
|
||||
private ResourceFactory.Registry? _registry;
|
||||
private IResourceLoadSystem? _resourceLoadSystem;
|
||||
private IAssetCatalogSystem? _assetCatalogSystem;
|
||||
|
||||
/// <summary>
|
||||
/// 系统初始化方法,在系统启动时执行一次。
|
||||
/// 初始化资源注册表,并获取依赖的资源加载系统和资产目录系统。
|
||||
/// 最后执行所有已注册资源的预加载操作。
|
||||
/// </summary>
|
||||
protected override void OnInit()
|
||||
{
|
||||
_registry = new ResourceFactory.Registry();
|
||||
_resourceLoadSystem = Context.GetSystem<IResourceLoadSystem>();
|
||||
_assetCatalogSystem = Context.GetSystem<IAssetCatalogSystem>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 架构阶段回调,在架构就绪时注册和预加载资源
|
||||
@ -44,11 +32,6 @@ public abstract class AbstractResourceFactorySystem : AbstractSystem, IResourceF
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册系统所需的各种资源类型。由子类实现具体注册逻辑。
|
||||
/// </summary>
|
||||
protected abstract void RegisterResources();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 根据指定的键获取资源工厂函数。
|
||||
@ -56,7 +39,10 @@ public abstract class AbstractResourceFactorySystem : AbstractSystem, IResourceF
|
||||
/// <typeparam name="T">资源类型</typeparam>
|
||||
/// <param name="key">资源键</param>
|
||||
/// <returns>返回创建指定类型资源的工厂函数</returns>
|
||||
public Func<T> GetFactory<T>(string key) => _registry!.ResolveFactory<T>(key);
|
||||
public Func<T> GetFactory<T>(string key)
|
||||
{
|
||||
return _registry!.ResolveFactory<T>(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据资产目录映射信息获取资源工厂函数。
|
||||
@ -64,12 +50,31 @@ public abstract class AbstractResourceFactorySystem : AbstractSystem, IResourceF
|
||||
/// <typeparam name="T">资源类型</typeparam>
|
||||
/// <param name="mapping">资产目录映射信息</param>
|
||||
/// <returns>返回创建指定类型资源的工厂函数</returns>
|
||||
public Func<T> GetFactory<T>(AssetCatalog.AssetCatalogMapping mapping) => _registry!.ResolveFactory<T>(mapping.Key);
|
||||
public Func<T> GetFactory<T>(AssetCatalog.AssetCatalogMapping mapping)
|
||||
{
|
||||
return _registry!.ResolveFactory<T>(mapping.Key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 系统初始化方法,在系统启动时执行一次。
|
||||
/// 初始化资源注册表,并获取依赖的资源加载系统和资产目录系统。
|
||||
/// 最后执行所有已注册资源的预加载操作。
|
||||
/// </summary>
|
||||
protected override void OnInit()
|
||||
{
|
||||
_registry = new ResourceFactory.Registry();
|
||||
_resourceLoadSystem = Context.GetSystem<IResourceLoadSystem>();
|
||||
_assetCatalogSystem = Context.GetSystem<IAssetCatalogSystem>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 注册系统所需的各种资源类型。由子类实现具体注册逻辑。
|
||||
/// </summary>
|
||||
protected abstract void RegisterResources();
|
||||
|
||||
|
||||
#region Register Helpers(声明式)
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 注册场景单元到资源管理系统中
|
||||
/// </summary>
|
||||
@ -131,6 +136,5 @@ public abstract class AbstractResourceFactorySystem : AbstractSystem, IResourceF
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
@ -16,9 +16,9 @@ public class ResourceLoadSystem : AbstractSystem, IResourceLoadSystem
|
||||
private readonly Dictionary<string, Resource> _loadedResources = new();
|
||||
|
||||
/// <summary>
|
||||
/// 场景懒加载器缓存,键为场景路径,值为延迟加载的PackedScene对象。
|
||||
/// 资源获取/复制工厂委托缓存,键为资源路径,值为获取或复制资源的Func委托。
|
||||
/// </summary>
|
||||
private readonly Dictionary<string, Lazy<PackedScene>> _sceneLoaders = new();
|
||||
private readonly Dictionary<string, Delegate> _resourceFactories = new();
|
||||
|
||||
/// <summary>
|
||||
/// 场景实例化工厂委托缓存,键为场景路径,值为创建该场景实例的Func委托。
|
||||
@ -26,66 +26,9 @@ public class ResourceLoadSystem : AbstractSystem, IResourceLoadSystem
|
||||
private readonly Dictionary<string, Delegate> _sceneFactories = new();
|
||||
|
||||
/// <summary>
|
||||
/// 资源获取/复制工厂委托缓存,键为资源路径,值为获取或复制资源的Func委托。
|
||||
/// 场景懒加载器缓存,键为场景路径,值为延迟加载的PackedScene对象。
|
||||
/// </summary>
|
||||
private readonly Dictionary<string, Delegate> _resourceFactories = new();
|
||||
|
||||
/// <summary>
|
||||
/// 初始化方法,在系统初始化时打印日志信息。
|
||||
/// </summary>
|
||||
protected override void OnInit()
|
||||
{
|
||||
}
|
||||
|
||||
#region 基础加载
|
||||
|
||||
/// <summary>
|
||||
/// 加载指定类型的资源并进行缓存。如果资源已经加载过则直接从缓存中返回。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要加载的资源类型,必须继承自Resource。</typeparam>
|
||||
/// <param name="path">资源在项目中的相对路径。</param>
|
||||
/// <returns>成功加载的资源对象;若路径无效或加载失败则返回null。</returns>
|
||||
public T? LoadResource<T>(string path) where T : Resource
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
return null;
|
||||
|
||||
if (_loadedResources.TryGetValue(path, out var cached))
|
||||
return cached as T;
|
||||
|
||||
var res = GD.Load<T>(path);
|
||||
if (res == null)
|
||||
{
|
||||
GD.PrintErr($"[ResourceLoadSystem] Load failed: {path}");
|
||||
return null;
|
||||
}
|
||||
|
||||
_loadedResources[path] = res;
|
||||
return res;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取一个场景的懒加载器,用于按需加载PackedScene资源。
|
||||
/// 若对应路径尚未注册加载器,则会自动创建一个新的Lazy实例。
|
||||
/// </summary>
|
||||
/// <param name="path">场景文件的相对路径。</param>
|
||||
/// <returns>表示该场景懒加载逻辑的Lazy<PackedScene>对象。</returns>
|
||||
public Lazy<PackedScene> GetSceneLoader(string path)
|
||||
{
|
||||
if (_sceneLoaders.TryGetValue(path, out var loader))
|
||||
return loader;
|
||||
|
||||
loader = new Lazy<PackedScene>(() =>
|
||||
{
|
||||
var scene = LoadResource<PackedScene>(path);
|
||||
return scene ?? throw new InvalidOperationException($"Failed to load scene: {path}");
|
||||
});
|
||||
|
||||
_sceneLoaders[path] = loader;
|
||||
return loader;
|
||||
}
|
||||
|
||||
#endregion
|
||||
private readonly Dictionary<string, Lazy<PackedScene>> _sceneLoaders = new();
|
||||
|
||||
/// <summary>
|
||||
/// 根据给定路径加载场景,并创建其节点实例。
|
||||
@ -159,6 +102,64 @@ public class ResourceLoadSystem : AbstractSystem, IResourceLoadSystem
|
||||
_resourceFactories[path] = factory;
|
||||
return factory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化方法,在系统初始化时打印日志信息。
|
||||
/// </summary>
|
||||
protected override void OnInit()
|
||||
{
|
||||
}
|
||||
|
||||
#region 基础加载
|
||||
|
||||
/// <summary>
|
||||
/// 加载指定类型的资源并进行缓存。如果资源已经加载过则直接从缓存中返回。
|
||||
/// </summary>
|
||||
/// <typeparam name="T">要加载的资源类型,必须继承自Resource。</typeparam>
|
||||
/// <param name="path">资源在项目中的相对路径。</param>
|
||||
/// <returns>成功加载的资源对象;若路径无效或加载失败则返回null。</returns>
|
||||
public T? LoadResource<T>(string path) where T : Resource
|
||||
{
|
||||
if (string.IsNullOrEmpty(path))
|
||||
return null;
|
||||
|
||||
if (_loadedResources.TryGetValue(path, out var cached))
|
||||
return cached as T;
|
||||
|
||||
var res = GD.Load<T>(path);
|
||||
if (res == null)
|
||||
{
|
||||
GD.PrintErr($"[ResourceLoadSystem] Load failed: {path}");
|
||||
return null;
|
||||
}
|
||||
|
||||
_loadedResources[path] = res;
|
||||
return res;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取一个场景的懒加载器,用于按需加载PackedScene资源。
|
||||
/// 若对应路径尚未注册加载器,则会自动创建一个新的Lazy实例。
|
||||
/// </summary>
|
||||
/// <param name="path">场景文件的相对路径。</param>
|
||||
/// <returns>表示该场景懒加载逻辑的Lazy<PackedScene>对象。</returns>
|
||||
public Lazy<PackedScene> GetSceneLoader(string path)
|
||||
{
|
||||
if (_sceneLoaders.TryGetValue(path, out var loader))
|
||||
return loader;
|
||||
|
||||
loader = new Lazy<PackedScene>(() =>
|
||||
{
|
||||
var scene = LoadResource<PackedScene>(path);
|
||||
return scene ?? throw new InvalidOperationException($"Failed to load scene: {path}");
|
||||
});
|
||||
|
||||
_sceneLoaders[path] = loader;
|
||||
return loader;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 缓存管理
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -252,10 +252,8 @@ public static class NodeExtensions
|
||||
public static T OfType<T>(this Node? node) where T : Node
|
||||
{
|
||||
// 检查节点是否有效且类型匹配
|
||||
if (node.IsValidNode()&& node is T t)
|
||||
if (node.IsValidNode() && node is T t)
|
||||
return t;
|
||||
throw new InvalidCastException($"Cannot cast {node} to {typeof(T)}");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -8,17 +8,14 @@ namespace GFramework.Godot.logging;
|
||||
/// </summary>
|
||||
public sealed class GodotLogger(
|
||||
string? name = null,
|
||||
LogLevel minLevel = LogLevel.Info) : AbstractLogger(name??ILogger.RootLoggerName, minLevel)
|
||||
LogLevel minLevel = LogLevel.Info) : AbstractLogger(name ?? ILogger.RootLoggerName, minLevel)
|
||||
{
|
||||
protected override void Write(LogLevel level, string message, Exception? exception)
|
||||
{
|
||||
var prefix = $"[{level.ToString().ToUpper()}][{Name()}]";
|
||||
|
||||
// 将异常信息追加到日志消息中
|
||||
if (exception != null)
|
||||
{
|
||||
message += "\n" + exception;
|
||||
}
|
||||
if (exception != null) message += "\n" + exception;
|
||||
|
||||
// 根据日志级别选择不同的输出方法
|
||||
switch (level)
|
||||
|
||||
@ -5,7 +5,7 @@ namespace GFramework.Godot.logging;
|
||||
/// <summary>
|
||||
/// Godot日志工厂类,用于创建Godot平台专用的日志记录器实例
|
||||
/// </summary>
|
||||
public class GodotLoggerFactory: ILoggerFactory
|
||||
public class GodotLoggerFactory : ILoggerFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取指定名称的日志记录器实例
|
||||
|
||||
@ -10,24 +10,19 @@ namespace GFramework.Godot.system;
|
||||
public abstract class AbstractAudioManagerSystem : AbstractSystem, IAudioManagerSystem
|
||||
{
|
||||
/// <summary>
|
||||
/// 音频资源加载系统依赖
|
||||
/// 最大同时播放的音效数量
|
||||
/// </summary>
|
||||
protected IResourceLoadSystem? ResourceLoadSystem;
|
||||
protected const int MaxSoundPlayers = 10;
|
||||
|
||||
/// <summary>
|
||||
/// 资源目录系统依赖
|
||||
/// 最大同时播放的3D音效数量
|
||||
/// </summary>
|
||||
protected IAssetCatalogSystem? AssetCatalogSystem;
|
||||
protected const int MaxSound3DPlayers = 5;
|
||||
|
||||
/// <summary>
|
||||
/// 背景音乐播放器
|
||||
/// 可用3D音效播放器队列
|
||||
/// </summary>
|
||||
protected AudioStreamPlayer? MusicPlayer;
|
||||
|
||||
/// <summary>
|
||||
/// 音效播放器列表
|
||||
/// </summary>
|
||||
protected readonly List<AudioStreamPlayer> SoundPlayers = [];
|
||||
protected readonly Queue<AudioStreamPlayer3D> AvailableSound3DPlayers = new();
|
||||
|
||||
/// <summary>
|
||||
/// 可用音效播放器队列
|
||||
@ -40,120 +35,70 @@ public abstract class AbstractAudioManagerSystem : AbstractSystem, IAudioManager
|
||||
protected readonly List<AudioStreamPlayer3D> Sound3DPlayers = [];
|
||||
|
||||
/// <summary>
|
||||
/// 可用3D音效播放器队列
|
||||
/// 音效播放器列表
|
||||
/// </summary>
|
||||
protected readonly Queue<AudioStreamPlayer3D> AvailableSound3DPlayers = new();
|
||||
|
||||
/// <summary>
|
||||
/// 资源工厂系统依赖
|
||||
/// </summary>
|
||||
protected IResourceFactorySystem? ResourceFactorySystem;
|
||||
|
||||
/// <summary>
|
||||
/// 背景音乐音量
|
||||
/// </summary>
|
||||
protected float MusicVolume = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// 音效音量
|
||||
/// </summary>
|
||||
protected float SoundVolume = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// 主音量
|
||||
/// </summary>
|
||||
protected float MasterVolume = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// 特效音量
|
||||
/// </summary>
|
||||
protected float SfxVolume = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// 语音音量
|
||||
/// </summary>
|
||||
protected float VoiceVolume = 1.0f;
|
||||
protected readonly List<AudioStreamPlayer> SoundPlayers = [];
|
||||
|
||||
/// <summary>
|
||||
/// 环境音量
|
||||
/// </summary>
|
||||
protected float AmbientVolume = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// 资源目录系统依赖
|
||||
/// </summary>
|
||||
protected IAssetCatalogSystem? AssetCatalogSystem;
|
||||
|
||||
/// <summary>
|
||||
/// 主音量
|
||||
/// </summary>
|
||||
protected float MasterVolume = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// 音乐淡入淡出动画
|
||||
/// </summary>
|
||||
protected Tween? MusicFadeTween;
|
||||
|
||||
/// <summary>
|
||||
/// 最大同时播放的音效数量
|
||||
/// 背景音乐播放器
|
||||
/// </summary>
|
||||
protected const int MaxSoundPlayers = 10;
|
||||
protected AudioStreamPlayer? MusicPlayer;
|
||||
|
||||
/// <summary>
|
||||
/// 最大同时播放的3D音效数量
|
||||
/// 背景音乐音量
|
||||
/// </summary>
|
||||
protected const int MaxSound3DPlayers = 5;
|
||||
protected float MusicVolume = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// 资源工厂系统依赖
|
||||
/// </summary>
|
||||
protected IResourceFactorySystem? ResourceFactorySystem;
|
||||
|
||||
/// <summary>
|
||||
/// 音频资源加载系统依赖
|
||||
/// </summary>
|
||||
protected IResourceLoadSystem? ResourceLoadSystem;
|
||||
|
||||
/// <summary>
|
||||
/// 特效音量
|
||||
/// </summary>
|
||||
protected float SfxVolume = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// 音效音量
|
||||
/// </summary>
|
||||
protected float SoundVolume = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// 语音音量
|
||||
/// </summary>
|
||||
protected float VoiceVolume = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// 所有者节点的抽象属性
|
||||
/// </summary>
|
||||
protected abstract Node Owner { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 系统初始化方法
|
||||
/// </summary>
|
||||
protected override void OnInit()
|
||||
{
|
||||
// 获取依赖的系统
|
||||
ResourceLoadSystem = Context.GetSystem<IResourceLoadSystem>();
|
||||
AssetCatalogSystem = Context.GetSystem<IAssetCatalogSystem>();
|
||||
ResourceFactorySystem = Context.GetSystem<IResourceFactorySystem>();
|
||||
|
||||
// 初始化背景音乐播放器
|
||||
MusicPlayer = new AudioStreamPlayer();
|
||||
Owner.AddChild(MusicPlayer);
|
||||
|
||||
// 预创建音效播放器池
|
||||
for (var i = 0; i < MaxSoundPlayers; i++)
|
||||
{
|
||||
var soundPlayer = new AudioStreamPlayer();
|
||||
Owner.AddChild(soundPlayer);
|
||||
soundPlayer.Finished += () => OnSoundFinished(soundPlayer);
|
||||
SoundPlayers.Add(soundPlayer);
|
||||
AvailableSoundPlayers.Enqueue(soundPlayer);
|
||||
}
|
||||
|
||||
// 预创建3D音效播放器池
|
||||
for (var i = 0; i < MaxSound3DPlayers; i++)
|
||||
{
|
||||
var sound3DPlayer = new AudioStreamPlayer3D();
|
||||
Owner.AddChild(sound3DPlayer);
|
||||
sound3DPlayer.Finished += () => OnSound3DFinished(sound3DPlayer);
|
||||
Sound3DPlayers.Add(sound3DPlayer);
|
||||
AvailableSound3DPlayers.Enqueue(sound3DPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当音效播放完成时的回调
|
||||
/// </summary>
|
||||
/// <param name="player">完成播放的音频播放器</param>
|
||||
private void OnSoundFinished(AudioStreamPlayer player)
|
||||
{
|
||||
// 将播放器放回可用队列
|
||||
AvailableSoundPlayers.Enqueue(player);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当3D音效播放完成时的回调
|
||||
/// </summary>
|
||||
/// <param name="player">完成播放的3D音频播放器</param>
|
||||
private void OnSound3DFinished(AudioStreamPlayer3D player)
|
||||
{
|
||||
// 将播放器放回可用队列
|
||||
AvailableSound3DPlayers.Enqueue(player);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 播放背景音乐
|
||||
/// </summary>
|
||||
@ -173,17 +118,6 @@ public abstract class AbstractAudioManagerSystem : AbstractSystem, IAudioManager
|
||||
MusicPlayer.Play();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过资源ID播放背景音乐
|
||||
/// </summary>
|
||||
/// <param name="musicId">音乐资源ID</param>
|
||||
/// <param name="volume">音量大小,范围0-1</param>
|
||||
/// <param name="loop">是否循环播放</param>
|
||||
public virtual void PlayMusic(AssetCatalog.AssetId musicId, float volume = 1.0f, bool loop = true)
|
||||
{
|
||||
PlayMusic(musicId.Path, volume, loop);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 播放音效
|
||||
/// </summary>
|
||||
@ -260,17 +194,6 @@ public abstract class AbstractAudioManagerSystem : AbstractSystem, IAudioManager
|
||||
player.Play();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过资源ID播放音效
|
||||
/// </summary>
|
||||
/// <param name="soundId">音效资源ID</param>
|
||||
/// <param name="volume">音量大小,范围0-1</param>
|
||||
/// <param name="pitch">音调调整</param>
|
||||
public virtual void PlaySound(AssetCatalog.AssetId soundId, float volume = 1.0f, float pitch = 1.0f)
|
||||
{
|
||||
PlaySound(soundId.Path, volume, pitch);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 播放3D音效
|
||||
/// </summary>
|
||||
@ -324,10 +247,7 @@ public abstract class AbstractAudioManagerSystem : AbstractSystem, IAudioManager
|
||||
public virtual void SetMusicVolume(float volume)
|
||||
{
|
||||
MusicVolume = volume;
|
||||
if (MusicPlayer != null)
|
||||
{
|
||||
MusicPlayer.VolumeDb = LinearToDb(MusicVolume * MasterVolume);
|
||||
}
|
||||
if (MusicPlayer != null) MusicPlayer.VolumeDb = LinearToDb(MusicVolume * MasterVolume);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -366,10 +286,7 @@ public abstract class AbstractAudioManagerSystem : AbstractSystem, IAudioManager
|
||||
MasterVolume = volume;
|
||||
|
||||
// 更新音乐音量
|
||||
if (MusicPlayer != null)
|
||||
{
|
||||
MusicPlayer.VolumeDb = LinearToDb(MusicVolume * MasterVolume);
|
||||
}
|
||||
if (MusicPlayer != null) MusicPlayer.VolumeDb = LinearToDb(MusicVolume * MasterVolume);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -507,6 +424,83 @@ public abstract class AbstractAudioManagerSystem : AbstractSystem, IAudioManager
|
||||
// 可以通过AudioEffectReverb实现
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 系统初始化方法
|
||||
/// </summary>
|
||||
protected override void OnInit()
|
||||
{
|
||||
// 获取依赖的系统
|
||||
ResourceLoadSystem = Context.GetSystem<IResourceLoadSystem>();
|
||||
AssetCatalogSystem = Context.GetSystem<IAssetCatalogSystem>();
|
||||
ResourceFactorySystem = Context.GetSystem<IResourceFactorySystem>();
|
||||
|
||||
// 初始化背景音乐播放器
|
||||
MusicPlayer = new AudioStreamPlayer();
|
||||
Owner.AddChild(MusicPlayer);
|
||||
|
||||
// 预创建音效播放器池
|
||||
for (var i = 0; i < MaxSoundPlayers; i++)
|
||||
{
|
||||
var soundPlayer = new AudioStreamPlayer();
|
||||
Owner.AddChild(soundPlayer);
|
||||
soundPlayer.Finished += () => OnSoundFinished(soundPlayer);
|
||||
SoundPlayers.Add(soundPlayer);
|
||||
AvailableSoundPlayers.Enqueue(soundPlayer);
|
||||
}
|
||||
|
||||
// 预创建3D音效播放器池
|
||||
for (var i = 0; i < MaxSound3DPlayers; i++)
|
||||
{
|
||||
var sound3DPlayer = new AudioStreamPlayer3D();
|
||||
Owner.AddChild(sound3DPlayer);
|
||||
sound3DPlayer.Finished += () => OnSound3DFinished(sound3DPlayer);
|
||||
Sound3DPlayers.Add(sound3DPlayer);
|
||||
AvailableSound3DPlayers.Enqueue(sound3DPlayer);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当音效播放完成时的回调
|
||||
/// </summary>
|
||||
/// <param name="player">完成播放的音频播放器</param>
|
||||
private void OnSoundFinished(AudioStreamPlayer player)
|
||||
{
|
||||
// 将播放器放回可用队列
|
||||
AvailableSoundPlayers.Enqueue(player);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当3D音效播放完成时的回调
|
||||
/// </summary>
|
||||
/// <param name="player">完成播放的3D音频播放器</param>
|
||||
private void OnSound3DFinished(AudioStreamPlayer3D player)
|
||||
{
|
||||
// 将播放器放回可用队列
|
||||
AvailableSound3DPlayers.Enqueue(player);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过资源ID播放背景音乐
|
||||
/// </summary>
|
||||
/// <param name="musicId">音乐资源ID</param>
|
||||
/// <param name="volume">音量大小,范围0-1</param>
|
||||
/// <param name="loop">是否循环播放</param>
|
||||
public virtual void PlayMusic(AssetCatalog.AssetId musicId, float volume = 1.0f, bool loop = true)
|
||||
{
|
||||
PlayMusic(musicId.Path, volume, loop);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过资源ID播放音效
|
||||
/// </summary>
|
||||
/// <param name="soundId">音效资源ID</param>
|
||||
/// <param name="volume">音量大小,范围0-1</param>
|
||||
/// <param name="pitch">音调调整</param>
|
||||
public virtual void PlaySound(AssetCatalog.AssetId soundId, float volume = 1.0f, float pitch = 1.0f)
|
||||
{
|
||||
PlaySound(soundId.Path, volume, pitch);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将线性音量值转换为分贝值
|
||||
/// </summary>
|
||||
@ -539,16 +533,10 @@ public abstract class AbstractAudioManagerSystem : AbstractSystem, IAudioManager
|
||||
MusicPlayer?.QueueFree();
|
||||
|
||||
// 清理音效播放器池
|
||||
foreach (var player in SoundPlayers)
|
||||
{
|
||||
player.QueueFree();
|
||||
}
|
||||
foreach (var player in SoundPlayers) player.QueueFree();
|
||||
|
||||
// 清理3D音效播放器池
|
||||
foreach (var player in Sound3DPlayers)
|
||||
{
|
||||
player.QueueFree();
|
||||
}
|
||||
foreach (var player in Sound3DPlayers) player.QueueFree();
|
||||
|
||||
SoundPlayers.Clear();
|
||||
AvailableSoundPlayers.Clear();
|
||||
|
||||
@ -6,6 +6,6 @@
|
||||
<LangVersion>10</LangVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.14.0" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Common" Version="4.14.0"/>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
using System;
|
||||
|
||||
namespace GFramework.SourceGenerators.Attributes.enums
|
||||
namespace GFramework.SourceGenerators.Attributes.enums;
|
||||
|
||||
/// <summary>
|
||||
/// 标注在 enum 上,Source Generator 会为该 enum 生成扩展方法。
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Enum)]
|
||||
public sealed class GenerateEnumExtensionsAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// 标注在 enum 上,Source Generator 会为该 enum 生成扩展方法。
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Enum)]
|
||||
public sealed class GenerateEnumExtensionsAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否为每个枚举项生成单独的 IsXXX 方法(默认 true)。
|
||||
/// </summary>
|
||||
@ -17,5 +17,4 @@ namespace GFramework.SourceGenerators.Attributes.enums
|
||||
/// 是否生成一个 IsIn(params T[]) 方法以简化多值判断(默认 true)。
|
||||
/// </summary>
|
||||
public bool GenerateIsInMethod { get; set; } = true;
|
||||
}
|
||||
}
|
||||
@ -1,37 +0,0 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace GFramework.SourceGenerators.logging;
|
||||
|
||||
/// <summary>
|
||||
/// 提供诊断描述符的静态类,用于GFramework日志生成器的编译时检查
|
||||
/// </summary>
|
||||
internal static class LoggerDiagnostics
|
||||
{
|
||||
/// <summary>
|
||||
/// 定义诊断描述符:要求使用[Log]特性的类必须声明为partial
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 当类使用[Log]特性但未声明为partial时,编译器将报告此错误
|
||||
/// </remarks>
|
||||
public static readonly DiagnosticDescriptor MustBePartial =
|
||||
new(
|
||||
id: "GFLOG001",
|
||||
title: "Class must be partial",
|
||||
messageFormat: "Class '{0}' must be declared partial to use [Log]",
|
||||
category: "GFramework.Logging",
|
||||
DiagnosticSeverity.Error,
|
||||
isEnabledByDefault: true
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// 定义诊断描述符:LogAttribute无法生成Logger的错误情况
|
||||
/// </summary>
|
||||
public static readonly DiagnosticDescriptor LogAttributeInvalid =
|
||||
new(
|
||||
id: "GFW_LOG001",
|
||||
title: "LogAttribute cannot generate Logger",
|
||||
messageFormat: "LogAttribute on class '{0}' is ineffective: {1}",
|
||||
category: "GFramework.Godot.Logging",
|
||||
DiagnosticSeverity.Warning,
|
||||
isEnabledByDefault: true);
|
||||
}
|
||||
37
GFramework.SourceGenerators/logging/LoggerDiagnostic.cs
Normal file
37
GFramework.SourceGenerators/logging/LoggerDiagnostic.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace GFramework.SourceGenerators.logging;
|
||||
|
||||
/// <summary>
|
||||
/// 提供诊断描述符的静态类,用于GFramework日志生成器的编译时检查
|
||||
/// </summary>
|
||||
internal static class LoggerDiagnostics
|
||||
{
|
||||
/// <summary>
|
||||
/// 定义诊断描述符:要求使用[Log]特性的类必须声明为partial
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 当类使用[Log]特性但未声明为partial时,编译器将报告此错误
|
||||
/// </remarks>
|
||||
public static readonly DiagnosticDescriptor MustBePartial =
|
||||
new(
|
||||
"GFLOG001",
|
||||
"Class must be partial",
|
||||
"Class '{0}' must be declared partial to use [Log]",
|
||||
"GFramework.Logging",
|
||||
DiagnosticSeverity.Error,
|
||||
true
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// 定义诊断描述符:LogAttribute无法生成Logger的错误情况
|
||||
/// </summary>
|
||||
public static readonly DiagnosticDescriptor LogAttributeInvalid =
|
||||
new(
|
||||
"GFW_LOG001",
|
||||
"LogAttribute cannot generate Logger",
|
||||
"LogAttribute on class '{0}' is ineffective: {1}",
|
||||
"GFramework.Godot.Logging",
|
||||
DiagnosticSeverity.Warning,
|
||||
true);
|
||||
}
|
||||
@ -160,7 +160,7 @@ public sealed class LoggerGenerator : IIncrementalGenerator
|
||||
|
||||
sb.AppendLine($" public partial class {className}");
|
||||
sb.AppendLine(" {");
|
||||
sb.AppendLine($" /// <summary>Auto-generated logger</summary>");
|
||||
sb.AppendLine(" /// <summary>Auto-generated logger</summary>");
|
||||
sb.AppendLine(
|
||||
$" {access} {staticKeyword}readonly ILogger {fieldName} = " +
|
||||
$"new ConsoleLoggerFactory().GetLogger(\"{name}\");");
|
||||
|
||||
@ -20,10 +20,10 @@
|
||||
|
||||
<!-- 排除不需要参与打包/编译的目录 -->
|
||||
<ItemGroup>
|
||||
<None Include="README.md" Pack="true" PackagePath="" />
|
||||
<None Remove="GFramework.Core\**" />
|
||||
<None Remove="GFramework.Game\**" />
|
||||
<None Remove="GFramework.Godot\**" />
|
||||
<None Include="README.md" Pack="true" PackagePath=""/>
|
||||
<None Remove="GFramework.Core\**"/>
|
||||
<None Remove="GFramework.Game\**"/>
|
||||
<None Remove="GFramework.Godot\**"/>
|
||||
<None Update="GFramework.SourceGenerators\bin\Debug\netstandard2.0\GFramework.Generator.Attributes.dll">
|
||||
<Link>GFramework.SorceGenerators\bin\Debug\netstandard2.0\GFramework.Generator.Attributes.dll</Link>
|
||||
</None>
|
||||
@ -47,13 +47,13 @@
|
||||
</ItemGroup>
|
||||
<!-- 聚合核心模块 -->
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="GFramework.Core\GFramework.Core.csproj" />
|
||||
<ProjectReference Include="GFramework.Game\GFramework.Game.csproj" />
|
||||
<ProjectReference Include="GFramework.Core\GFramework.Core.csproj"/>
|
||||
<ProjectReference Include="GFramework.Game\GFramework.Game.csproj"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Remove="GFramework.Core\**" />
|
||||
<Compile Remove="GFramework.Game\**" />
|
||||
<Compile Remove="GFramework.Godot\**" />
|
||||
<Compile Remove="GFramework.Core\**"/>
|
||||
<Compile Remove="GFramework.Game\**"/>
|
||||
<Compile Remove="GFramework.Godot\**"/>
|
||||
<Compile Update="GFramework.SourceGenerators\enums\EnumExtensionsGenerator.cs">
|
||||
<Link>GFramework.SorceGenerators\enums\EnumExtensionsGenerator.cs</Link>
|
||||
</Compile>
|
||||
@ -70,9 +70,9 @@
|
||||
<Compile Remove="GFramework.SourceGenerators.Attributes\**"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Remove="GFramework.Core\**" />
|
||||
<EmbeddedResource Remove="GFramework.Game\**" />
|
||||
<EmbeddedResource Remove="GFramework.Godot\**" />
|
||||
<EmbeddedResource Remove="GFramework.Core\**"/>
|
||||
<EmbeddedResource Remove="GFramework.Game\**"/>
|
||||
<EmbeddedResource Remove="GFramework.Godot\**"/>
|
||||
<EmbeddedResource Remove="GFramework.Godot.SourceGenerators\**"/>
|
||||
<EmbeddedResource Remove="GFramework.Godot.SourceGenerators.Attributes\**"/>
|
||||
<EmbeddedResource Remove="GFramework.SorceGenerators\**"/>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user