using UnityEngine;
using System.Collections.Generic;
using Spine.Unity;
public class BattleCacheManager
{
///
/// 资源引用信息(战场 + 角色维度)
///
private class ResourceReference
{
public BattleResCache.CachedResource CachedResource;
// 记录哪些战场的哪些角色在使用这个资源
// Key: battleGuid, Value: ownerIds
public Dictionary> BattlefieldOwners = new Dictionary>();
public int RefCount
{
get
{
int count = 0;
foreach (var owners in BattlefieldOwners.Values)
{
count += owners.Count;
}
return count;
}
}
///
/// 添加战场+角色的引用
///
public void AddBattlefieldOwner(string battleGuid, string ownerId)
{
if (!BattlefieldOwners.ContainsKey(battleGuid))
{
BattlefieldOwners[battleGuid] = new HashSet();
}
BattlefieldOwners[battleGuid].Add(ownerId);
}
///
/// 移除整个战场的所有引用
///
public void RemoveBattlefield(string battleGuid)
{
BattlefieldOwners.Remove(battleGuid);
}
}
// ===== 全局统一资源池(不再区分红蓝队)=====
private static Dictionary globalSpineCache =
new Dictionary();
private static Dictionary globalAudioCache =
new Dictionary();
///
/// 注册战场资源需求(红队+蓝队一起注册)
///
public void RegisterBattlefieldResources(string battleGuid,
List spineResources,
List audioResources)
{
// 注册Spine资源
foreach (var res in spineResources)
{
if (string.IsNullOrEmpty(res.OwnerId))
continue;
string key = res.GetKey();
if (!globalSpineCache.ContainsKey(key))
{
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))
continue;
string key = res.GetKey();
if (!globalAudioCache.ContainsKey(key))
{
globalAudioCache[key] = new ResourceReference
{
CachedResource = new BattleResCache.CachedResource(res, null, false)
};
}
globalAudioCache[key].AddBattlefieldOwner(battleGuid, res.OwnerId);
}
Debug.Log($"BattleCacheManager: Registered battlefield {battleGuid} - Spine: {spineResources.Count}, Audio: {audioResources.Count}");
}
///
/// 注销战场(卸载该战场的所有资源引用)
///
public void UnregisterBattlefield(string battleGuid)
{
// 处理Spine资源
var spineKeysToRemove = new List();
foreach (var kvp in globalSpineCache)
{
kvp.Value.RemoveBattlefield(battleGuid);
if (kvp.Value.RefCount == 0)
{
spineKeysToRemove.Add(kvp.Key);
}
}
foreach (var key in spineKeysToRemove)
{
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();
foreach (var kvp in globalAudioCache)
{
kvp.Value.RemoveBattlefield(battleGuid);
if (kvp.Value.RefCount == 0)
{
audioKeysToRemove.Add(kvp.Key);
}
}
foreach (var key in audioKeysToRemove)
{
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}");
}
///
/// 获取或加载Spine资源
///
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(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;
}
///
/// 获取或加载Audio资源
///
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(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;
}
///
/// 更新已加载资源的引用(由加载器调用)
///
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}";
}
}