MeowmentDesign/Assets/Scripts/Config/ConfigManager.cs
2026-02-01 15:37:46 +08:00

209 lines
7.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.IO;
using CrazyMaple;
using Thrift;
using Thrift.Protocol;
using Thrift.Transport;
using Thrift.Transport.Client;
using UnityEngine;
namespace Byway.Config
{
/// <summary>
/// 配置管理器 - 按需加载模式
/// 自动生成于: 2026-01-13 14:32:35
/// </summary>
public class ConfigManager
{
private static ConfigManager _instance;
public static ConfigManager Instance
{
get
{
if (_instance == null)
{
_instance = new ConfigManager();
}
return _instance;
}
}
// 配置文件根目录AssetBundle 路径)
private const string CONFIG_ROOT = "Assets/Design_SubModule/ConfigData";
// 缓存已加载的配置
private Dictionary<Type, object> _configCache = new Dictionary<Type, object>();
// 缓存AllConfigs实例
private Byway.Thrift.Data.AllConfigs _allConfigs = null;
// 标记AllConfigs是否已经加载完成
private bool _allConfigsLoaded = false;
private ConfigManager() { }
/// <summary>
/// 获取配置数据只从AllConfigs获取必须先调用PreloadAllConfigs
/// </summary>
public T GetConfig<T>() where T : class, TBase, new()
{
Type type = typeof(T);
string typeName = type.Name;
// 先查缓存(缓存命中时不打印日志,减少冗余输出)
if (_configCache.TryGetValue(type, out object cached))
{
return cached as T;
}
// 检查AllConfigs是否已加载
if (!_allConfigsLoaded)
{
Debug.LogError($"[ConfigManager] 配置尚未加载完成,请先调用 PreloadAllConfigs() 并等待完成!配置类型: {typeName}");
return null;
}
// 从 AllConfigs 获取
if (_allConfigs != null)
{
T config = GetConfigFromAllConfigs<T>();
if (config != null)
{
_configCache[type] = config;
Debug.Log($"[ConfigManager] 首次加载配置: {typeName}");
return config;
}
}
else
{
Debug.LogError($"[ConfigManager] AllConfigs 为 null配置类型: {typeName}");
}
Debug.LogError($"[ConfigManager] 无法获取配置: {typeName}");
return null;
}
/// <summary>
/// 从 AllConfigs 中获取指定类型的配置
/// </summary>
private T GetConfigFromAllConfigs<T>() where T : class, TBase, new()
{
if (_allConfigs == null)
return null;
string typeName = typeof(T).Name;
// 使用反射获取 AllConfigs 中对应的属性(而不是字段)
var property = typeof(Byway.Thrift.Data.AllConfigs).GetProperty(typeName);
if (property != null)
{
var value = property.GetValue(_allConfigs) as T;
if (value != null)
{
return value;
}
}
Debug.LogWarning($"[ConfigManager] AllConfigs 中未找到配置: {typeName}");
return null;
}
/// <summary>
/// 预加载所有配置(启动时调用)- 只加载AllConfig.bytes
/// </summary>
public void PreloadAllConfigs(Action onComplete = null)
{
var startTime = System.Diagnostics.Stopwatch.StartNew();
try
{
string fileName = "AllConfigs.bytes";
string assetPath = Path.Combine(CONFIG_ROOT, fileName).Replace("\\", "/");
Debug.Log($"[ConfigManager] 开始加载 AllConfigs.bytes, 路径: {assetPath}");
// 直接使用 GameEntry.Resource.LoadAsset 确保正确加载 TextAsset
var callbacks = new GameFramework.Resource.LoadAssetCallbacks(
(assetName, asset, duration, userData) =>
{
// 加载成功
TextAsset textAsset = asset as TextAsset;
if (textAsset == null)
{
startTime.Stop();
Debug.LogError($"[ConfigManager] AllConfigs 加载失败: 资源类型错误,实际类型: {asset?.GetType().Name}");
_allConfigsLoaded = false;
onComplete?.Invoke();
return;
}
Debug.Log($"[ConfigManager] AllConfigs.bytes 加载成功, 文件大小: {textAsset.bytes.Length} bytes");
try
{
_allConfigs = new Byway.Thrift.Data.AllConfigs();
// 使用 Thrift 反序列化
using (var transport = new TMemoryBufferTransport(textAsset.bytes, new TConfiguration()))
{
using (var protocol = new TBinaryProtocol(transport))
{
_allConfigs.ReadAsync(protocol, System.Threading.CancellationToken.None).GetAwaiter().GetResult();
}
}
startTime.Stop();
Debug.Log($"[ConfigManager] AllConfigs 加载完成!耗时: {startTime.ElapsedMilliseconds} ms ({startTime.Elapsed.TotalSeconds:F3} 秒)");
_allConfigsLoaded = true;
}
catch (Exception ex)
{
startTime.Stop();
Debug.LogError($"[ConfigManager] AllConfigs 反序列化失败,耗时: {startTime.ElapsedMilliseconds} ms错误: {ex.Message}\n{ex.StackTrace}");
_allConfigsLoaded = false;
}
finally
{
onComplete?.Invoke();
}
},
(assetName, status, errorMessage, userData) =>
{
// 加载失败
startTime.Stop();
Debug.LogError($"[ConfigManager] AllConfigs 加载失败, 路径: {assetName}, 状态: {status}, 错误: {errorMessage}");
_allConfigsLoaded = false;
onComplete?.Invoke();
},
(assetName, dependencyAssetName, loadedCount, totalCount, userData) =>
{
// 依赖资源加载
Debug.Log($"[ConfigManager] 加载依赖资源: {dependencyAssetName} ({loadedCount}/{totalCount})");
}
);
GameEntry.Resource.LoadAsset(assetPath, callbacks);
}
catch (Exception ex)
{
startTime.Stop();
Debug.LogError($"[ConfigManager] 加载 AllConfigs 失败,错误: {ex.Message}\n{ex.StackTrace}");
_allConfigsLoaded = false;
onComplete?.Invoke();
}
}
/// <summary>
/// 清空所有缓存
/// </summary>
public void ClearCache()
{
_configCache.Clear();
_allConfigs = null;
_allConfigsLoaded = false;
}
}
}