From 5e4c574228c7cfadab0931a798d43b085bfb8844 Mon Sep 17 00:00:00 2001
From: yyl <yyl>
Date: 星期五, 26 十二月 2025 18:30:13 +0800
Subject: [PATCH] 125 战斗 休息状态 未加载/被清空预加载资源的问题

---
 Main/System/Battle/BattleResources/BattleCacheManager.cs |  198 +++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 189 insertions(+), 9 deletions(-)

diff --git a/Main/System/Battle/BattleResources/BattleCacheManager.cs b/Main/System/Battle/BattleResources/BattleCacheManager.cs
index 79682a6..1217833 100644
--- a/Main/System/Battle/BattleResources/BattleCacheManager.cs
+++ b/Main/System/Battle/BattleResources/BattleCacheManager.cs
@@ -72,9 +72,10 @@
             
             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)
                 };
             }
             
@@ -91,9 +92,10 @@
             
             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)
                 };
             }
             
@@ -106,7 +108,9 @@
     /// <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>();
@@ -116,7 +120,15 @@
             
             if (kvp.Value.RefCount == 0)
             {
-                spineKeysToRemove.Add(kvp.Key);
+                // 浠呭湪闈炲父椹绘垨琚己鍒跺嵏杞芥椂鎵嶇湡姝gЩ闄よ祫婧�
+                if (forceUnloadPersistent || kvp.Value.CachedResource.CanUnload())
+                {
+                    spineKeysToRemove.Add(kvp.Key);
+                }
+                else
+                {
+                    Debug.Log($"BattleCacheManager: Skipped unloading persistent spine resource: {kvp.Key}");
+                }
             }
         }
         
@@ -142,7 +154,15 @@
             
             if (kvp.Value.RefCount == 0)
             {
-                audioKeysToRemove.Add(kvp.Key);
+                // 浠呭湪闈炲父椹绘垨琚己鍒跺嵏杞芥椂鎵嶇湡姝gЩ闄よ祫婧�
+                if (forceUnloadPersistent || kvp.Value.CachedResource.CanUnload())
+                {
+                    audioKeysToRemove.Add(kvp.Key);
+                }
+                else
+                {
+                    Debug.Log($"BattleCacheManager: Skipped unloading persistent audio resource: {kvp.Key}");
+                }
             }
         }
         
@@ -185,12 +205,13 @@
             {
                 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)
             };
         }
         
@@ -219,12 +240,13 @@
             {
                 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)
             };
         }
         
@@ -236,6 +258,9 @@
     /// </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))
@@ -259,6 +284,161 @@
         
         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

--
Gitblit v1.8.0