209 lines
7.7 KiB
C#
209 lines
7.7 KiB
C#
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;
|
||
}
|
||
}
|
||
} |