| | |
| | | public class BattleCacheManager |
| | | { |
| | | /// <summary> |
| | | /// 资源引用信息 |
| | | /// 资源引用信息(战场 + 角色维度) |
| | | /// </summary> |
| | | private class ResourceReference |
| | | { |
| | | public BattleResCache.CachedResource CachedResource; |
| | | public HashSet<string> OwnerIds = new HashSet<string>(); // 使用该资源的角色ID集合 |
| | | // 记录哪些战场的哪些角色在使用这个资源 |
| | | // Key: battleGuid, Value: ownerIds |
| | | public Dictionary<string, HashSet<string>> BattlefieldOwners = new Dictionary<string, HashSet<string>>(); |
| | | |
| | | public int RefCount => OwnerIds.Count; |
| | | |
| | | public void AddOwner(string ownerId) |
| | | public int RefCount |
| | | { |
| | | OwnerIds.Add(ownerId); |
| | | } |
| | | |
| | | public void RemoveOwner(string ownerId) |
| | | get |
| | | { |
| | | OwnerIds.Remove(ownerId); |
| | | int count = 0; |
| | | foreach (var owners in BattlefieldOwners.Values) |
| | | { |
| | | count += owners.Count; |
| | | } |
| | | return count; |
| | | } |
| | | } |
| | | |
| | | // ===== 红队资源:全局共享,按引用计数管理 ===== |
| | | private static Dictionary<string, ResourceReference> globalRedTeamSpineCache = |
| | | /// <summary> |
| | | /// 添加战场+角色的引用 |
| | | /// </summary> |
| | | public void AddBattlefieldOwner(string battleGuid, string ownerId) |
| | | { |
| | | if (!BattlefieldOwners.ContainsKey(battleGuid)) |
| | | { |
| | | BattlefieldOwners[battleGuid] = new HashSet<string>(); |
| | | } |
| | | BattlefieldOwners[battleGuid].Add(ownerId); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 移除整个战场的所有引用 |
| | | /// </summary> |
| | | public void RemoveBattlefield(string battleGuid) |
| | | { |
| | | BattlefieldOwners.Remove(battleGuid); |
| | | } |
| | | } |
| | | |
| | | // ===== 全局统一资源池(不再区分红蓝队)===== |
| | | private static Dictionary<string, ResourceReference> globalSpineCache = |
| | | new Dictionary<string, ResourceReference>(); |
| | | |
| | | private static Dictionary<string, ResourceReference> globalRedTeamAudioCache = |
| | | private static Dictionary<string, ResourceReference> globalAudioCache = |
| | | new Dictionary<string, ResourceReference>(); |
| | | |
| | | // ===== 蓝队资源:按战场GUID隔离 ===== |
| | | private static Dictionary<string, Dictionary<string, BattleResCache.CachedResource>> blueTeamSpineCacheDict = |
| | | new Dictionary<string, Dictionary<string, BattleResCache.CachedResource>>(); |
| | | |
| | | private static Dictionary<string, Dictionary<string, BattleResCache.CachedResource>> blueTeamAudioCacheDict = |
| | | new Dictionary<string, Dictionary<string, BattleResCache.CachedResource>>(); |
| | | |
| | | // 需要添加的字段 |
| | | private static Dictionary<string, HashSet<string>> battlefieldRedTeamOwners = |
| | | new Dictionary<string, HashSet<string>>(); // <battleGuid, ownerIds> |
| | | |
| | | /// <summary> |
| | | /// 获取Spine缓存(红队全局,蓝队按战场隔离) |
| | | /// 注册战场资源需求(红队+蓝队一起注册) |
| | | /// </summary> |
| | | public Dictionary<string, BattleResCache.CachedResource> GetSpineCache(bool isPersistent, string battleGuid = "") |
| | | public void RegisterBattlefieldResources(string battleGuid, |
| | | List<BattleResCache.ResourceIdentifier> spineResources, |
| | | List<BattleResCache.ResourceIdentifier> audioResources) |
| | | { |
| | | if (isPersistent) |
| | | { |
| | | // 红队:将引用字典转换为普通缓存字典(兼容加载器) |
| | | var cache = new Dictionary<string, BattleResCache.CachedResource>(); |
| | | foreach (var kvp in globalRedTeamSpineCache) |
| | | { |
| | | cache[kvp.Key] = kvp.Value.CachedResource; |
| | | } |
| | | return cache; |
| | | } |
| | | else |
| | | { |
| | | // 蓝队:返回战场专属缓存 |
| | | if (!blueTeamSpineCacheDict.ContainsKey(battleGuid)) |
| | | { |
| | | blueTeamSpineCacheDict[battleGuid] = new Dictionary<string, BattleResCache.CachedResource>(); |
| | | } |
| | | return blueTeamSpineCacheDict[battleGuid]; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取音频缓存(红队全局,蓝队按战场隔离) |
| | | /// </summary> |
| | | public Dictionary<string, BattleResCache.CachedResource> GetAudioCache(bool isPersistent, string battleGuid = "") |
| | | { |
| | | if (isPersistent) |
| | | { |
| | | // 红队:将引用字典转换为普通缓存字典 |
| | | var cache = new Dictionary<string, BattleResCache.CachedResource>(); |
| | | foreach (var kvp in globalRedTeamAudioCache) |
| | | { |
| | | cache[kvp.Key] = kvp.Value.CachedResource; |
| | | } |
| | | return cache; |
| | | } |
| | | else |
| | | { |
| | | // 蓝队:返回战场专属缓存 |
| | | if (!blueTeamAudioCacheDict.ContainsKey(battleGuid)) |
| | | { |
| | | blueTeamAudioCacheDict[battleGuid] = new Dictionary<string, BattleResCache.CachedResource>(); |
| | | } |
| | | return blueTeamAudioCacheDict[battleGuid]; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 添加红队资源引用(由加载器调用) |
| | | /// </summary> |
| | | public void AddRedTeamSpineReference(string key, BattleResCache.CachedResource resource, string ownerId) |
| | | { |
| | | if (!globalRedTeamSpineCache.ContainsKey(key)) |
| | | { |
| | | globalRedTeamSpineCache[key] = new ResourceReference |
| | | { |
| | | CachedResource = resource |
| | | }; |
| | | } |
| | | globalRedTeamSpineCache[key].AddOwner(ownerId); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 添加红队音频引用 |
| | | /// </summary> |
| | | public void AddRedTeamAudioReference(string key, BattleResCache.CachedResource resource, string ownerId) |
| | | { |
| | | if (!globalRedTeamAudioCache.ContainsKey(key)) |
| | | { |
| | | globalRedTeamAudioCache[key] = new ResourceReference |
| | | { |
| | | CachedResource = resource |
| | | }; |
| | | } |
| | | globalRedTeamAudioCache[key].AddOwner(ownerId); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取Spine资源(未命中时自动加载并缓存) |
| | | /// </summary> |
| | | public SkeletonDataAsset GetSpineResource(string directory, string assetName, string battleGuid = "", bool autoLoadIfMissing = true) |
| | | { |
| | | string key = $"{directory}/{assetName}"; |
| | | |
| | | // 优先从红队全局缓存查找 |
| | | if (globalRedTeamSpineCache.TryGetValue(key, out var redRef)) |
| | | { |
| | | return redRef.CachedResource.Asset as SkeletonDataAsset; |
| | | } |
| | | |
| | | // 再从蓝队战场专属缓存查找 |
| | | if (!string.IsNullOrEmpty(battleGuid) && blueTeamSpineCacheDict.TryGetValue(battleGuid, out var blueCache)) |
| | | { |
| | | if (blueCache.TryGetValue(key, out var blueRes)) |
| | | { |
| | | return blueRes.Asset as SkeletonDataAsset; |
| | | } |
| | | } |
| | | |
| | | // ===== 缓存未命中时自动加载 ===== |
| | | if (autoLoadIfMissing) |
| | | { |
| | | Debug.LogWarning($"BattleCacheManager: Spine cache miss for {key}, loading on-demand..."); |
| | | |
| | | SkeletonDataAsset asset = ResManager.Instance.LoadAsset<SkeletonDataAsset>(directory, assetName); |
| | | |
| | | if (asset != null) |
| | | { |
| | | var identifier = new BattleResCache.ResourceIdentifier |
| | | { |
| | | Directory = directory, |
| | | AssetName = assetName, |
| | | Type = BattleResCache.ResourceType.Spine, |
| | | IsPersistent = string.IsNullOrEmpty(battleGuid) |
| | | }; |
| | | |
| | | var cachedRes = new BattleResCache.CachedResource(identifier, asset, identifier.IsPersistent); |
| | | |
| | | if (string.IsNullOrEmpty(battleGuid)) |
| | | { |
| | | // 红队:添加引用(未知所有者,用特殊标识) |
| | | AddRedTeamSpineReference(key, cachedRes, "OnDemand"); |
| | | Debug.Log($"BattleCacheManager: Added to global red cache: {key}"); |
| | | } |
| | | else |
| | | { |
| | | // 蓝队:直接加入战场缓存 |
| | | if (!blueTeamSpineCacheDict.ContainsKey(battleGuid)) |
| | | { |
| | | blueTeamSpineCacheDict[battleGuid] = new Dictionary<string, BattleResCache.CachedResource>(); |
| | | } |
| | | blueTeamSpineCacheDict[battleGuid][key] = cachedRes; |
| | | Debug.Log($"BattleCacheManager: Added to blue cache (BF={battleGuid}): {key}"); |
| | | } |
| | | |
| | | return asset; |
| | | } |
| | | } |
| | | |
| | | return null; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取音频资源(未命中时自动加载并缓存) |
| | | /// </summary> |
| | | public AudioClip GetAudioResource(string directory, string assetName, string battleGuid = "", bool autoLoadIfMissing = true) |
| | | { |
| | | string key = $"{directory}/{assetName}"; |
| | | |
| | | // 优先从红队全局缓存查找 |
| | | if (globalRedTeamAudioCache.TryGetValue(key, out var redRef)) |
| | | { |
| | | return redRef.CachedResource.Asset as AudioClip; |
| | | } |
| | | |
| | | // 再从蓝队战场专属缓存查找 |
| | | if (!string.IsNullOrEmpty(battleGuid) && blueTeamAudioCacheDict.TryGetValue(battleGuid, out var blueCache)) |
| | | { |
| | | if (blueCache.TryGetValue(key, out var blueRes)) |
| | | { |
| | | return blueRes.Asset as AudioClip; |
| | | } |
| | | } |
| | | |
| | | // ===== 缓存未命中时自动加载 ===== |
| | | if (autoLoadIfMissing) |
| | | { |
| | | Debug.LogWarning($"BattleCacheManager: Audio cache miss for {key}, loading on-demand..."); |
| | | |
| | | AudioClip asset = ResManager.Instance.LoadAsset<AudioClip>(directory, assetName, false); |
| | | |
| | | if (asset != null) |
| | | { |
| | | var identifier = new BattleResCache.ResourceIdentifier |
| | | { |
| | | Directory = directory, |
| | | AssetName = assetName, |
| | | Type = BattleResCache.ResourceType.Audio, |
| | | IsPersistent = string.IsNullOrEmpty(battleGuid) |
| | | }; |
| | | |
| | | var cachedRes = new BattleResCache.CachedResource(identifier, asset, identifier.IsPersistent); |
| | | |
| | | if (string.IsNullOrEmpty(battleGuid)) |
| | | { |
| | | // 红队:添加引用 |
| | | AddRedTeamAudioReference(key, cachedRes, "OnDemand"); |
| | | Debug.Log($"BattleCacheManager: Added to global red audio cache: {key}"); |
| | | } |
| | | else |
| | | { |
| | | // 蓝队:直接加入战场缓存 |
| | | if (!blueTeamAudioCacheDict.ContainsKey(battleGuid)) |
| | | { |
| | | blueTeamAudioCacheDict[battleGuid] = new Dictionary<string, BattleResCache.CachedResource>(); |
| | | } |
| | | blueTeamAudioCacheDict[battleGuid][key] = cachedRes; |
| | | Debug.Log($"BattleCacheManager: Added to blue audio cache (BF={battleGuid}): {key}"); |
| | | } |
| | | |
| | | return asset; |
| | | } |
| | | } |
| | | |
| | | return null; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 移除指定角色的红队资源引用 |
| | | /// </summary> |
| | | public void RemoveRedTeamReferences(List<string> ownerIds) |
| | | { |
| | | if (ownerIds == null || ownerIds.Count == 0) |
| | | return; |
| | | |
| | | int removedSpineCount = 0; |
| | | int removedAudioCount = 0; |
| | | |
| | | // 处理Spine资源 |
| | | var spineKeysToRemove = new List<string>(); |
| | | foreach (var kvp in globalRedTeamSpineCache) |
| | | { |
| | | foreach (var ownerId in ownerIds) |
| | | { |
| | | kvp.Value.RemoveOwner(ownerId); |
| | | } |
| | | |
| | | // 如果没有引用了,标记删除 |
| | | if (kvp.Value.RefCount == 0) |
| | | { |
| | | spineKeysToRemove.Add(kvp.Key); |
| | | } |
| | | } |
| | | |
| | | foreach (var key in spineKeysToRemove) |
| | | { |
| | | var resource = globalRedTeamSpineCache[key].CachedResource; |
| | | ResManager.Instance.UnloadAsset( |
| | | resource.Identifier.Directory.ToLower(), |
| | | resource.Identifier.AssetName.ToLower() |
| | | ); |
| | | globalRedTeamSpineCache.Remove(key); |
| | | removedSpineCount++; |
| | | } |
| | | |
| | | // 处理音频资源 |
| | | var audioKeysToRemove = new List<string>(); |
| | | foreach (var kvp in globalRedTeamAudioCache) |
| | | { |
| | | foreach (var ownerId in ownerIds) |
| | | { |
| | | kvp.Value.RemoveOwner(ownerId); |
| | | } |
| | | |
| | | if (kvp.Value.RefCount == 0) |
| | | { |
| | | audioKeysToRemove.Add(kvp.Key); |
| | | } |
| | | } |
| | | |
| | | foreach (var key in audioKeysToRemove) |
| | | { |
| | | var resource = globalRedTeamAudioCache[key].CachedResource; |
| | | ResManager.Instance.UnloadAsset( |
| | | resource.Identifier.Directory.ToLower(), |
| | | resource.Identifier.AssetName.ToLower() |
| | | ); |
| | | globalRedTeamAudioCache.Remove(key); |
| | | removedAudioCount++; |
| | | } |
| | | |
| | | Debug.Log($"BattleCacheManager: Removed {ownerIds.Count} owner(s), freed {removedSpineCount} spine + {removedAudioCount} audio resources"); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 清空指定战场的蓝队缓存 |
| | | /// </summary> |
| | | public void ClearBlueTeamCache(string battleGuid) |
| | | { |
| | | if (blueTeamSpineCacheDict.ContainsKey(battleGuid)) |
| | | { |
| | | blueTeamSpineCacheDict.Remove(battleGuid); |
| | | } |
| | | |
| | | if (blueTeamAudioCacheDict.ContainsKey(battleGuid)) |
| | | { |
| | | blueTeamAudioCacheDict.Remove(battleGuid); |
| | | } |
| | | |
| | | Debug.Log($"BattleCacheManager: Cleared blue team cache for battlefield {battleGuid}"); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 清空红队全局缓存(玩家重置阵容时调用) |
| | | /// </summary> |
| | | public void ClearRedTeamCache() |
| | | { |
| | | globalRedTeamSpineCache.Clear(); |
| | | globalRedTeamAudioCache.Clear(); |
| | | Debug.Log("BattleCacheManager: Cleared red team global cache"); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取缓存统计信息 |
| | | /// </summary> |
| | | public string GetCacheStats(string battleGuid = "") |
| | | { |
| | | int blueSpineCount = blueTeamSpineCacheDict.ContainsKey(battleGuid) ? blueTeamSpineCacheDict[battleGuid].Count : 0; |
| | | int blueAudioCount = blueTeamAudioCacheDict.ContainsKey(battleGuid) ? blueTeamAudioCacheDict[battleGuid].Count : 0; |
| | | |
| | | return $"Red Spine: {globalRedTeamSpineCache.Count}, Red Audio: {globalRedTeamAudioCache.Count}, " + |
| | | $"Blue Spine (BF={battleGuid}): {blueSpineCount}, Blue Audio (BF={battleGuid}): {blueAudioCount}"; |
| | | } |
| | | |
| | | // ========== BattleCacheManager.cs 新增方法 ========== |
| | | |
| | | /// <summary> |
| | | /// 记录战场的红队资源需求(增加引用) |
| | | /// </summary> |
| | | public void RegisterBattlefieldRedTeam(string battleGuid, List<BattleResCache.ResourceIdentifier> spineResources, List<BattleResCache.ResourceIdentifier> audioResources) |
| | | { |
| | | // 记录这个战场使用的红队资源的OwnerIds |
| | | var ownerIds = new HashSet<string>(); |
| | | |
| | | // 注册Spine资源 |
| | | foreach (var res in spineResources) |
| | | { |
| | | if (!string.IsNullOrEmpty(res.OwnerId)) |
| | | if (string.IsNullOrEmpty(res.OwnerId)) |
| | | continue; |
| | | |
| | | string key = res.GetKey(); |
| | | |
| | | if (!globalSpineCache.ContainsKey(key)) |
| | | { |
| | | ownerIds.Add(res.OwnerId); |
| | | } |
| | | globalSpineCache[key] = new ResourceReference |
| | | { |
| | | CachedResource = new BattleResCache.CachedResource(res, null, false) |
| | | }; |
| | | } |
| | | |
| | | globalSpineCache[key].AddBattlefieldOwner(battleGuid, res.OwnerId); |
| | | } |
| | | |
| | | // 注册Audio资源 |
| | | foreach (var res in audioResources) |
| | | { |
| | | if (!string.IsNullOrEmpty(res.OwnerId)) |
| | | if (string.IsNullOrEmpty(res.OwnerId)) |
| | | continue; |
| | | |
| | | string key = res.GetKey(); |
| | | |
| | | if (!globalAudioCache.ContainsKey(key)) |
| | | { |
| | | ownerIds.Add(res.OwnerId); |
| | | } |
| | | globalAudioCache[key] = new ResourceReference |
| | | { |
| | | CachedResource = new BattleResCache.CachedResource(res, null, false) |
| | | }; |
| | | } |
| | | |
| | | if (!battlefieldRedTeamOwners.ContainsKey(battleGuid)) |
| | | { |
| | | battlefieldRedTeamOwners[battleGuid] = ownerIds; |
| | | globalAudioCache[key].AddBattlefieldOwner(battleGuid, res.OwnerId); |
| | | } |
| | | |
| | | Debug.Log($"BattleCacheManager: Registered battlefield {battleGuid} - Spine: {spineResources.Count}, Audio: {audioResources.Count}"); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 注销战场的红队资源需求(减少引用) |
| | | /// 注销战场(卸载该战场的所有资源引用) |
| | | /// </summary> |
| | | public void UnregisterBattlefieldRedTeam(string battleGuid) |
| | | { |
| | | if (!battlefieldRedTeamOwners.ContainsKey(battleGuid)) |
| | | return; |
| | | |
| | | var ownerIds = battlefieldRedTeamOwners[battleGuid]; |
| | | |
| | | // 从所有红队资源中移除这些OwnerIds的引用 |
| | | RemoveOwnersFromRedTeamCache(ownerIds); |
| | | |
| | | battlefieldRedTeamOwners.Remove(battleGuid); |
| | | } |
| | | |
| | | private void RemoveOwnersFromRedTeamCache(HashSet<string> ownerIds) |
| | | public void UnregisterBattlefield(string battleGuid) |
| | | { |
| | | // 处理Spine资源 |
| | | var spineKeysToRemove = new List<string>(); |
| | | foreach (var kvp in globalRedTeamSpineCache) |
| | | foreach (var kvp in globalSpineCache) |
| | | { |
| | | foreach (var ownerId in ownerIds) |
| | | { |
| | | kvp.Value.RemoveOwner(ownerId); |
| | | } |
| | | kvp.Value.RemoveBattlefield(battleGuid); |
| | | |
| | | // 引用计数为0时真正卸载 |
| | | if (kvp.Value.RefCount == 0) |
| | | { |
| | | spineKeysToRemove.Add(kvp.Key); |
| | |
| | | |
| | | foreach (var key in spineKeysToRemove) |
| | | { |
| | | var res = globalRedTeamSpineCache[key]; |
| | | ResManager.Instance.UnloadAsset(res.CachedResource.Identifier.Directory, res.CachedResource.Identifier.AssetName); |
| | | globalRedTeamSpineCache.Remove(key); |
| | | Debug.Log($"BattleCacheManager: Unloaded red team spine (refCount=0): {key}"); |
| | | var res = globalSpineCache[key]; |
| | | if (res.CachedResource.Asset != null) |
| | | { |
| | | ResManager.Instance.UnloadAsset( |
| | | res.CachedResource.Identifier.Directory, |
| | | res.CachedResource.Identifier.AssetName |
| | | ); |
| | | } |
| | | globalSpineCache.Remove(key); |
| | | Debug.Log($"BattleCacheManager: Unloaded spine (refCount=0): {key}"); |
| | | } |
| | | |
| | | // 处理Audio资源 |
| | | var audioKeysToRemove = new List<string>(); |
| | | foreach (var kvp in globalRedTeamAudioCache) |
| | | foreach (var kvp in globalAudioCache) |
| | | { |
| | | foreach (var ownerId in ownerIds) |
| | | { |
| | | kvp.Value.RemoveOwner(ownerId); |
| | | } |
| | | kvp.Value.RemoveBattlefield(battleGuid); |
| | | |
| | | if (kvp.Value.RefCount == 0) |
| | | { |
| | |
| | | |
| | | foreach (var key in audioKeysToRemove) |
| | | { |
| | | var res = globalRedTeamAudioCache[key]; |
| | | ResManager.Instance.UnloadAsset(res.CachedResource.Identifier.Directory, res.CachedResource.Identifier.AssetName); |
| | | globalRedTeamAudioCache.Remove(key); |
| | | Debug.Log($"BattleCacheManager: Unloaded red team audio (refCount=0): {key}"); |
| | | var res = globalAudioCache[key]; |
| | | if (res.CachedResource.Asset != null) |
| | | { |
| | | ResManager.Instance.UnloadAsset( |
| | | res.CachedResource.Identifier.Directory, |
| | | res.CachedResource.Identifier.AssetName |
| | | ); |
| | | } |
| | | globalAudioCache.Remove(key); |
| | | Debug.Log($"BattleCacheManager: Unloaded audio (refCount=0): {key}"); |
| | | } |
| | | |
| | | Debug.Log($"BattleCacheManager: Unregistered battlefield {battleGuid}"); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取或加载Spine资源 |
| | | /// </summary> |
| | | public SkeletonDataAsset GetSpineResource(string directory, string assetName, string battleGuid = "") |
| | | { |
| | | string key = $"{directory}/{assetName}"; |
| | | |
| | | if (globalSpineCache.TryGetValue(key, out var refInfo)) |
| | | { |
| | | return refInfo.CachedResource.Asset as SkeletonDataAsset; |
| | | } |
| | | |
| | | // 自动加载 |
| | | Debug.LogWarning($"BattleCacheManager: Spine cache miss for {key}, loading on-demand..."); |
| | | var asset = ResManager.Instance.LoadAsset<SkeletonDataAsset>(directory, assetName); |
| | | |
| | | if (asset != null) |
| | | { |
| | | var identifier = new BattleResCache.ResourceIdentifier |
| | | { |
| | | Directory = directory, |
| | | AssetName = assetName, |
| | | Type = BattleResCache.ResourceType.Spine |
| | | }; |
| | | |
| | | globalSpineCache[key] = new ResourceReference |
| | | { |
| | | CachedResource = new BattleResCache.CachedResource(identifier, asset, false) |
| | | }; |
| | | } |
| | | |
| | | return asset; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取或加载Audio资源 |
| | | /// </summary> |
| | | public AudioClip GetAudioResource(string directory, string assetName, string battleGuid = "") |
| | | { |
| | | string key = $"{directory}/{assetName}"; |
| | | |
| | | if (globalAudioCache.TryGetValue(key, out var refInfo)) |
| | | { |
| | | return refInfo.CachedResource.Asset as AudioClip; |
| | | } |
| | | |
| | | // 自动加载 |
| | | Debug.LogWarning($"BattleCacheManager: Audio cache miss for {key}, loading on-demand..."); |
| | | var asset = ResManager.Instance.LoadAsset<AudioClip>(directory, assetName, false); |
| | | |
| | | if (asset != null) |
| | | { |
| | | var identifier = new BattleResCache.ResourceIdentifier |
| | | { |
| | | Directory = directory, |
| | | AssetName = assetName, |
| | | Type = BattleResCache.ResourceType.Audio |
| | | }; |
| | | |
| | | globalAudioCache[key] = new ResourceReference |
| | | { |
| | | CachedResource = new BattleResCache.CachedResource(identifier, asset, false) |
| | | }; |
| | | } |
| | | |
| | | return asset; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 更新已加载资源的引用(由加载器调用) |
| | | /// </summary> |
| | | public void UpdateResourceReference(string key, BattleResCache.CachedResource resource, string battleGuid, string ownerId) |
| | | { |
| | | if (resource.Identifier.Type == BattleResCache.ResourceType.Spine) |
| | | { |
| | | if (globalSpineCache.ContainsKey(key)) |
| | | { |
| | | globalSpineCache[key].CachedResource = resource; |
| | | } |
| | | } |
| | | else if (resource.Identifier.Type == BattleResCache.ResourceType.Audio) |
| | | { |
| | | if (globalAudioCache.ContainsKey(key)) |
| | | { |
| | | globalAudioCache[key].CachedResource = resource; |
| | | } |
| | | } |
| | | } |
| | | |
| | | public string GetCacheStats(string battleGuid = "") |
| | | { |
| | | int spineTotal = globalSpineCache.Count; |
| | | int audioTotal = globalAudioCache.Count; |
| | | |
| | | return $"Spine: {spineTotal}, Audio: {audioTotal}"; |
| | | } |
| | | } |