| | |
| | | |
| | | if (!globalSpineCache.ContainsKey(key)) |
| | | { |
| | | // 把 ResourceIdentifier 的 IsPersistent 传递给 CachedResource |
| | | globalSpineCache[key] = new ResourceReference |
| | | { |
| | | CachedResource = new BattleResCache.CachedResource(res, null, false) |
| | | CachedResource = new BattleResCache.CachedResource(res, null, res.IsPersistent) |
| | | }; |
| | | } |
| | | |
| | |
| | | |
| | | if (!globalAudioCache.ContainsKey(key)) |
| | | { |
| | | // 把 ResourceIdentifier 的 IsPersistent 传递给 CachedResource |
| | | globalAudioCache[key] = new ResourceReference |
| | | { |
| | | CachedResource = new BattleResCache.CachedResource(res, null, false) |
| | | CachedResource = new BattleResCache.CachedResource(res, null, res.IsPersistent) |
| | | }; |
| | | } |
| | | |
| | |
| | | /// <summary> |
| | | /// 注销战场(卸载该战场的所有资源引用) |
| | | /// </summary> |
| | | public void UnregisterBattlefield(string battleGuid) |
| | | /// <param name="battleGuid">战场GUID</param> |
| | | /// <param name="forceUnloadPersistent">是否强制卸载常驻(红队)资源,默认为 false</param> |
| | | public void UnregisterBattlefield(string battleGuid, bool forceUnloadPersistent = false) |
| | | { |
| | | // 处理Spine资源 |
| | | var spineKeysToRemove = new List<string>(); |
| | |
| | | |
| | | if (kvp.Value.RefCount == 0) |
| | | { |
| | | spineKeysToRemove.Add(kvp.Key); |
| | | // 仅在非常驻或被强制卸载时才真正移除资源 |
| | | if (forceUnloadPersistent || kvp.Value.CachedResource.CanUnload()) |
| | | { |
| | | spineKeysToRemove.Add(kvp.Key); |
| | | } |
| | | else |
| | | { |
| | | Debug.Log($"BattleCacheManager: Skipped unloading persistent spine resource: {kvp.Key}"); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | if (kvp.Value.RefCount == 0) |
| | | { |
| | | audioKeysToRemove.Add(kvp.Key); |
| | | // 仅在非常驻或被强制卸载时才真正移除资源 |
| | | if (forceUnloadPersistent || kvp.Value.CachedResource.CanUnload()) |
| | | { |
| | | audioKeysToRemove.Add(kvp.Key); |
| | | } |
| | | else |
| | | { |
| | | Debug.Log($"BattleCacheManager: Skipped unloading persistent audio resource: {kvp.Key}"); |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | { |
| | | Directory = directory, |
| | | AssetName = assetName, |
| | | Type = BattleResCache.ResourceType.Spine |
| | | Type = BattleResCache.ResourceType.Spine, |
| | | IsPersistent = false // on-demand 加载的默认非常驻 |
| | | }; |
| | | |
| | | globalSpineCache[key] = new ResourceReference |
| | | { |
| | | CachedResource = new BattleResCache.CachedResource(identifier, asset, false) |
| | | CachedResource = new BattleResCache.CachedResource(identifier, asset, identifier.IsPersistent) |
| | | }; |
| | | } |
| | | |
| | |
| | | { |
| | | Directory = directory, |
| | | AssetName = assetName, |
| | | Type = BattleResCache.ResourceType.Audio |
| | | Type = BattleResCache.ResourceType.Audio, |
| | | IsPersistent = false // on-demand 加载的默认非常驻 |
| | | }; |
| | | |
| | | globalAudioCache[key] = new ResourceReference |
| | | { |
| | | CachedResource = new BattleResCache.CachedResource(identifier, asset, false) |
| | | CachedResource = new BattleResCache.CachedResource(identifier, asset, identifier.IsPersistent) |
| | | }; |
| | | } |
| | | |
| | |
| | | /// </summary> |
| | | public void UpdateResourceReference(string key, BattleResCache.CachedResource resource, string battleGuid, string ownerId) |
| | | { |
| | | // 确保 CachedResource 的 IsPersistent 与 Identifier 一致 |
| | | resource.IsPersistent = resource.Identifier.IsPersistent; |
| | | |
| | | if (resource.Identifier.Type == BattleResCache.ResourceType.Spine) |
| | | { |
| | | if (globalSpineCache.ContainsKey(key)) |
| | |
| | | |
| | | return $"Spine: {spineTotal}, Audio: {audioTotal}"; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取已注册到某个战场的所有 OwnerId(可选择只返回常驻资源的 owner) |
| | | /// </summary> |
| | | public HashSet<string> GetRegisteredOwners(string battleGuid, bool onlyPersistent = false) |
| | | { |
| | | var owners = new HashSet<string>(); |
| | | |
| | | foreach (var kvp in globalSpineCache) |
| | | { |
| | | if (!kvp.Value.BattlefieldOwners.ContainsKey(battleGuid)) |
| | | continue; |
| | | |
| | | if (onlyPersistent && kvp.Value.CachedResource.IsPersistent == false) |
| | | continue; |
| | | |
| | | foreach (var owner in kvp.Value.BattlefieldOwners[battleGuid]) |
| | | owners.Add(owner); |
| | | } |
| | | |
| | | foreach (var kvp in globalAudioCache) |
| | | { |
| | | if (!kvp.Value.BattlefieldOwners.ContainsKey(battleGuid)) |
| | | continue; |
| | | |
| | | if (onlyPersistent && kvp.Value.CachedResource.IsPersistent == false) |
| | | continue; |
| | | |
| | | foreach (var owner in kvp.Value.BattlefieldOwners[battleGuid]) |
| | | owners.Add(owner); |
| | | } |
| | | |
| | | return owners; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 仅注销战场中指定的 owner(按 owner granularity 移除),仅卸载因此变为无人引用的资源 |
| | | /// </summary> |
| | | /// <param name="battleGuid">战场 GUID</param> |
| | | /// <param name="ownersToRemove">要移除的 OwnerId 集合</param> |
| | | public void UnregisterBattlefieldOwners(string battleGuid, HashSet<string> ownersToRemove) |
| | | { |
| | | if (ownersToRemove == null || ownersToRemove.Count == 0) |
| | | { |
| | | Debug.Log($"BattleCacheManager: UnregisterBattlefieldOwners called with empty owners for {battleGuid}"); |
| | | return; |
| | | } |
| | | |
| | | var spineKeysToRemove = new List<string>(); |
| | | foreach (var kvp in globalSpineCache) |
| | | { |
| | | if (!kvp.Value.BattlefieldOwners.ContainsKey(battleGuid)) |
| | | continue; |
| | | |
| | | var owners = kvp.Value.BattlefieldOwners[battleGuid]; |
| | | bool changed = false; |
| | | foreach (var owner in ownersToRemove) |
| | | { |
| | | if (owners.Contains(owner)) |
| | | { |
| | | owners.Remove(owner); |
| | | changed = true; |
| | | } |
| | | } |
| | | |
| | | if (owners.Count == 0) |
| | | kvp.Value.BattlefieldOwners.Remove(battleGuid); |
| | | |
| | | // 如果全局引用数为0,说明没有任何战场/角色在使用这个资源,安全卸载 |
| | | if (kvp.Value.RefCount == 0) |
| | | { |
| | | spineKeysToRemove.Add(kvp.Key); |
| | | } |
| | | else if (changed) |
| | | { |
| | | Debug.Log($"BattleCacheManager: Updated spine owners for {kvp.Key} after removing owners for {battleGuid}"); |
| | | } |
| | | } |
| | | |
| | | 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 (no owners left): {key}"); |
| | | } |
| | | |
| | | var audioKeysToRemove = new List<string>(); |
| | | foreach (var kvp in globalAudioCache) |
| | | { |
| | | if (!kvp.Value.BattlefieldOwners.ContainsKey(battleGuid)) |
| | | continue; |
| | | |
| | | var owners = kvp.Value.BattlefieldOwners[battleGuid]; |
| | | bool changed = false; |
| | | foreach (var owner in ownersToRemove) |
| | | { |
| | | if (owners.Contains(owner)) |
| | | { |
| | | owners.Remove(owner); |
| | | changed = true; |
| | | } |
| | | } |
| | | |
| | | if (owners.Count == 0) |
| | | kvp.Value.BattlefieldOwners.Remove(battleGuid); |
| | | |
| | | if (kvp.Value.RefCount == 0) |
| | | { |
| | | audioKeysToRemove.Add(kvp.Key); |
| | | } |
| | | else if (changed) |
| | | { |
| | | Debug.Log($"BattleCacheManager: Updated audio owners for {kvp.Key} after removing owners for {battleGuid}"); |
| | | } |
| | | } |
| | | |
| | | 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 (no owners left): {key}"); |
| | | } |
| | | |
| | | Debug.Log($"BattleCacheManager: Unregistered specific owners for battlefield {battleGuid}. Removed owners: {ownersToRemove.Count}"); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 判断该战场是否已注册(有任意资源引用) |
| | | /// </summary> |
| | | public bool HasBattleRegistered(string battleGuid) |
| | | { |
| | | foreach (var kvp in globalSpineCache) |
| | | { |
| | | if (kvp.Value.BattlefieldOwners.ContainsKey(battleGuid)) return true; |
| | | } |
| | | foreach (var kvp in globalAudioCache) |
| | | { |
| | | if (kvp.Value.BattlefieldOwners.ContainsKey(battleGuid)) return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | // ===== 编辑器调试接口 ===== |
| | | #if UNITY_EDITOR |