1
This commit is contained in:
113
Src/Core/Localization/ILocalizationService.cs
Normal file
113
Src/Core/Localization/ILocalizationService.cs
Normal file
@@ -0,0 +1,113 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using BITKit;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Net.BITKit.Localization
|
||||
{
|
||||
/// <summary>
|
||||
/// 本地化
|
||||
/// </summary>
|
||||
public interface ILocalizationService
|
||||
{
|
||||
public string Prefix { get; }
|
||||
/// <summary>
|
||||
/// 当前语言
|
||||
/// </summary>
|
||||
public string CurrentLanguage { get; }
|
||||
/// <summary>
|
||||
/// 更改回调,通常在此检查并下载语言包
|
||||
/// </summary>
|
||||
public event Func<string,string,UniTask> OnLanguageChangeAsync;
|
||||
/// <summary>
|
||||
/// 语言更改完成回调,UI和World执行更新
|
||||
/// </summary>
|
||||
public event Action<string,string> OnLanguageChanged;
|
||||
/// <summary>
|
||||
/// 获取翻译文本,返回无复制的引用
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="language">语言,默认为当前CultureInfo.Name</param>
|
||||
/// <returns></returns>
|
||||
public string GetLocalizedString(string key,string language=null);
|
||||
public UniTask ChangeLanguageAsync(string newLanguage);
|
||||
public IDictionary<string, IDictionary<string, string>> LocalizedStrings { get; }
|
||||
}
|
||||
|
||||
public class LocalizationService : ILocalizationService,IDisposable
|
||||
{
|
||||
private static LocalizationService _singleton;
|
||||
public string Prefix => "#";
|
||||
private char _prefix = '#';
|
||||
public string CurrentLanguage { get; private set; }
|
||||
|
||||
public event Func<string, string, UniTask> OnLanguageChangeAsync;
|
||||
public event Action<string, string> OnLanguageChanged;
|
||||
|
||||
private readonly ILogger<LocalizationService> _logger;
|
||||
|
||||
public IDictionary<string, IDictionary<string, string>> LocalizedStrings { get; } =
|
||||
new Dictionary<string, IDictionary<string, string>>();
|
||||
|
||||
private readonly ValidHandle _isBusy = new();
|
||||
|
||||
private readonly HashSet<string> _untranslatedKeys = new();
|
||||
|
||||
public LocalizationService(ILogger<LocalizationService> logger)
|
||||
{
|
||||
if (_singleton is not null)
|
||||
{
|
||||
logger.LogError("LocalizationService can only be one singleton");
|
||||
return;
|
||||
}
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
|
||||
public string GetLocalizedString(string key, string language = null)
|
||||
{
|
||||
language ??= CurrentLanguage; // 默认使用当前语言
|
||||
|
||||
if (key[0] != _prefix)
|
||||
{
|
||||
key = _prefix + key;
|
||||
}
|
||||
if (LocalizedStrings.TryGetValue(language, out var langDict) && langDict.TryGetValue(key, out var value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
_untranslatedKeys.Add(key);
|
||||
return key.Replace(Prefix,string.Empty).Replace("_"," "); // 如果找不到翻译,就返回 key 本身(常见策略)
|
||||
}
|
||||
public async UniTask ChangeLanguageAsync(string newLanguage)
|
||||
{
|
||||
if (CurrentLanguage == newLanguage) return;
|
||||
var oldLanguage = CurrentLanguage;
|
||||
CurrentLanguage = newLanguage;
|
||||
|
||||
await _isBusy;
|
||||
using var _ = _isBusy.GetHandle();
|
||||
|
||||
#if UNITY_5_3_OR_NEWER
|
||||
await UniTask.SwitchToMainThread();
|
||||
#endif
|
||||
|
||||
await OnLanguageChangeAsync.UniTaskFunc(oldLanguage, newLanguage);
|
||||
|
||||
// 触发同步事件(例如更新 UI)
|
||||
OnLanguageChanged?.Invoke(oldLanguage, newLanguage);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_isBusy?.Dispose();
|
||||
_singleton = null;
|
||||
_logger.LogInformation("Untranslated keys:\n"+string.Join("\n", _untranslatedKeys));
|
||||
_untranslatedKeys.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user