Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace GFramework.Core.Abstractions.Localization;

/// <summary>
/// 本地化格式化器接口
/// </summary>
public interface ILocalizationFormatter
{
/// <summary>
/// 格式化器名称
/// </summary>
string Name { get; }

/// <summary>
/// 尝试格式化值
/// </summary>
/// <param name="format">格式字符串</param>
/// <param name="value">要格式化的值</param>
/// <param name="provider">格式提供者</param>
/// <param name="result">格式化结果</param>
/// <returns>是否成功格式化</returns>
bool TryFormat(string format, object value, IFormatProvider? provider, out string result);
}
89 changes: 89 additions & 0 deletions GFramework.Core.Abstractions/Localization/ILocalizationManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using System.Globalization;
using GFramework.Core.Abstractions.Systems;

namespace GFramework.Core.Abstractions.Localization;

/// <summary>
/// 本地化管理器接口
/// </summary>
public interface ILocalizationManager : ISystem
{
/// <summary>
/// 当前语言代码
/// </summary>
string CurrentLanguage { get; }

/// <summary>
/// 当前文化信息
/// </summary>
CultureInfo CurrentCulture { get; }

/// <summary>
/// 可用语言列表
/// </summary>
IReadOnlyList<string> AvailableLanguages { get; }

/// <summary>
/// 设置当前语言
/// </summary>
/// <param name="languageCode">语言代码</param>
void SetLanguage(string languageCode);

/// <summary>
/// 获取本地化表
/// </summary>
/// <param name="tableName">表名</param>
/// <returns>本地化表</returns>
ILocalizationTable GetTable(string tableName);

/// <summary>
/// 获取本地化文本
/// </summary>
/// <param name="table">表名</param>
/// <param name="key">键名</param>
/// <returns>本地化文本</returns>
string GetText(string table, string key);

/// <summary>
/// 获取本地化字符串(支持变量和格式化)
/// </summary>
/// <param name="table">表名</param>
/// <param name="key">键名</param>
/// <returns>本地化字符串</returns>
ILocalizationString GetString(string table, string key);

/// <summary>
/// 尝试获取本地化文本
/// </summary>
/// <param name="table">表名</param>
/// <param name="key">键名</param>
/// <param name="text">输出文本</param>
/// <returns>是否成功获取</returns>
bool TryGetText(string table, string key, out string text);

/// <summary>
/// 注册格式化器
/// </summary>
/// <param name="name">格式化器名称</param>
/// <param name="formatter">格式化器实例</param>
void RegisterFormatter(string name, ILocalizationFormatter formatter);

/// <summary>
/// 获取格式化器
/// </summary>
/// <param name="name">格式化器名称</param>
/// <returns>格式化器实例,如果不存在则返回 null</returns>
ILocalizationFormatter? GetFormatter(string name);

/// <summary>
/// 订阅语言变化事件
/// </summary>
/// <param name="callback">回调函数</param>
void SubscribeToLanguageChange(Action<string> callback);

/// <summary>
/// 取消订阅语言变化事件
/// </summary>
/// <param name="callback">回调函数</param>
void UnsubscribeFromLanguageChange(Action<string> callback);
}
50 changes: 50 additions & 0 deletions GFramework.Core.Abstractions/Localization/ILocalizationString.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
namespace GFramework.Core.Abstractions.Localization;

/// <summary>
/// 本地化字符串接口(支持变量和格式化)
/// </summary>
public interface ILocalizationString
{
/// <summary>
/// 表名
/// </summary>
string Table { get; }

/// <summary>
/// 键名
/// </summary>
string Key { get; }

/// <summary>
/// 添加变量
/// </summary>
/// <param name="name">变量名</param>
/// <param name="value">变量值</param>
/// <returns>当前实例(支持链式调用)</returns>
ILocalizationString WithVariable(string name, object value);

/// <summary>
/// 批量添加变量
/// </summary>
/// <param name="variables">变量数组</param>
/// <returns>当前实例(支持链式调用)</returns>
ILocalizationString WithVariables(params (string name, object value)[] variables);

/// <summary>
/// 格式化并返回最终文本
/// </summary>
/// <returns>格式化后的文本</returns>
string Format();

/// <summary>
/// 获取原始文本(不进行格式化)
/// </summary>
/// <returns>原始文本</returns>
string GetRaw();

/// <summary>
/// 检查键是否存在
/// </summary>
/// <returns>是否存在</returns>
bool Exists();
}
48 changes: 48 additions & 0 deletions GFramework.Core.Abstractions/Localization/ILocalizationTable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
namespace GFramework.Core.Abstractions.Localization;

/// <summary>
/// 本地化表接口
/// </summary>
public interface ILocalizationTable
{
/// <summary>
/// 表名
/// </summary>
string Name { get; }

/// <summary>
/// 语言代码
/// </summary>
string Language { get; }

/// <summary>
/// 回退表(当前表中找不到键时使用)
/// </summary>
ILocalizationTable? Fallback { get; }

/// <summary>
/// 获取原始文本(不进行格式化)
/// </summary>
/// <param name="key">键名</param>
/// <returns>原始文本</returns>
string GetRawText(string key);

/// <summary>
/// 检查是否包含指定键
/// </summary>
/// <param name="key">键名</param>
/// <returns>是否包含</returns>
bool ContainsKey(string key);

/// <summary>
/// 获取所有键
/// </summary>
/// <returns>键集合</returns>
IEnumerable<string> GetKeys();

/// <summary>
/// 合并覆盖数据
/// </summary>
/// <param name="overrides">覆盖数据</param>
void Merge(IReadOnlyDictionary<string, string> overrides);
}
37 changes: 37 additions & 0 deletions GFramework.Core.Abstractions/Localization/LocalizationConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
namespace GFramework.Core.Abstractions.Localization;

/// <summary>
/// 本地化配置
/// </summary>
public class LocalizationConfig
{
/// <summary>
/// 默认语言代码
/// </summary>
public string DefaultLanguage { get; set; } = "eng";

/// <summary>
/// 回退语言代码(当目标语言缺少键时使用)
/// </summary>
public string FallbackLanguage { get; set; } = "eng";

/// <summary>
/// 本地化文件路径(Godot 资源路径)
/// </summary>
public string LocalizationPath { get; set; } = "res://localization";

/// <summary>
/// 用户覆盖文件路径(用于热更新和自定义翻译)
/// </summary>
public string OverridePath { get; set; } = "user://localization_override";

/// <summary>
/// 是否启用热重载(监视覆盖文件变化)
/// </summary>
public bool EnableHotReload { get; set; } = true;

/// <summary>
/// 是否在加载时验证本地化文件
/// </summary>
public bool ValidateOnLoad { get; set; } = true;
}
31 changes: 31 additions & 0 deletions GFramework.Core.Abstractions/Localization/LocalizationException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
namespace GFramework.Core.Abstractions.Localization;

/// <summary>
/// 本地化异常基类
/// </summary>
public class LocalizationException : Exception
{
/// <summary>
/// 初始化本地化异常
/// </summary>
public LocalizationException()
{
}

/// <summary>
/// 初始化本地化异常
/// </summary>
/// <param name="message">异常消息</param>
public LocalizationException(string message) : base(message)
{
}

/// <summary>
/// 初始化本地化异常
/// </summary>
/// <param name="message">异常消息</param>
/// <param name="innerException">内部异常</param>
public LocalizationException(string message, Exception innerException) : base(message, innerException)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace GFramework.Core.Abstractions.Localization;

/// <summary>
/// 本地化键未找到异常
/// </summary>
public class LocalizationKeyNotFoundException : LocalizationException
{
/// <summary>
/// 初始化键未找到异常
/// </summary>
/// <param name="tableName">表名</param>
/// <param name="key">键名</param>
public LocalizationKeyNotFoundException(string tableName, string key)
: base($"Localization key '{key}' not found in table '{tableName}'")
{
TableName = tableName;
Key = key;
}

/// <summary>
/// 表名
/// </summary>
public string TableName { get; }

/// <summary>
/// 键名
/// </summary>
public string Key { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace GFramework.Core.Abstractions.Localization;

/// <summary>
/// 本地化表未找到异常
/// </summary>
public class LocalizationTableNotFoundException : LocalizationException
{
/// <summary>
/// 初始化表未找到异常
/// </summary>
/// <param name="tableName">表名</param>
public LocalizationTableNotFoundException(string tableName)
: base($"Localization table '{tableName}' not found")
{
TableName = tableName;
}

/// <summary>
/// 表名
/// </summary>
public string TableName { get; }
}
Loading
Loading