diff --git a/Assets/YooAsset/Editor/AssetBundleDebugger/AssetBundleDebuggerWindow.cs b/Assets/YooAsset/Editor/AssetBundleDebugger/AssetBundleDebuggerWindow.cs index 09a064b8..3b20b2a3 100644 --- a/Assets/YooAsset/Editor/AssetBundleDebugger/AssetBundleDebuggerWindow.cs +++ b/Assets/YooAsset/Editor/AssetBundleDebugger/AssetBundleDebuggerWindow.cs @@ -272,7 +272,7 @@ namespace YooAsset.Editor packageData.ProviderInfos.Sort(); foreach (var providerInfo in packageData.ProviderInfos) { - providerInfo.DependBundleInfos.Sort(); + providerInfo.DependBundles.Sort(); } } diff --git a/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerAssetListViewer.cs b/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerAssetListViewer.cs index 9eb3e1f6..6d5df657 100644 --- a/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerAssetListViewer.cs +++ b/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerAssetListViewer.cs @@ -13,6 +13,7 @@ namespace YooAsset.Editor { private class ProviderTableData : DefaultTableData { + public DebugPackageData PackageData; public DebugProviderInfo ProviderInfo; } private class DependTableData : DefaultTableData @@ -205,7 +206,7 @@ namespace YooAsset.Editor { StyleColor textColor; var providerTableData = data as ProviderTableData; - if(providerTableData.ProviderInfo.Status == EOperationStatus.Failed.ToString()) + if (providerTableData.ProviderInfo.Status == EOperationStatus.Failed.ToString()) textColor = new StyleColor(Color.yellow); else textColor = new StyleColor(Color.white); @@ -309,6 +310,7 @@ namespace YooAsset.Editor foreach (var providerInfo in packageData.ProviderInfos) { var rowData = new ProviderTableData(); + rowData.PackageData = packageData; rowData.ProviderInfo = providerInfo; rowData.AddAssetPathCell("PackageName", packageData.PackageName); rowData.AddStringValueCell("AssetPath", providerInfo.AssetPath); @@ -368,12 +370,14 @@ namespace YooAsset.Editor private void OnProviderTableViewSelectionChanged(ITableData data) { var providerTableData = data as ProviderTableData; + DebugPackageData packageData = providerTableData.PackageData; DebugProviderInfo providerInfo = providerTableData.ProviderInfo; // 填充依赖数据 - var sourceDatas = new List(providerInfo.DependBundleInfos.Count); - foreach (var dependBundleInfo in providerInfo.DependBundleInfos) + var sourceDatas = new List(providerInfo.DependBundles.Count); + foreach (var bundleName in providerInfo.DependBundles) { + var dependBundleInfo = packageData.GetBundleInfo(bundleName); var rowData = new DependTableData(); rowData.BundleInfo = dependBundleInfo; rowData.AddStringValueCell("DependBundles", dependBundleInfo.BundleName); diff --git a/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerBundleListViewer.cs b/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerBundleListViewer.cs index 878025eb..21902767 100644 --- a/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerBundleListViewer.cs +++ b/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerBundleListViewer.cs @@ -13,19 +13,24 @@ namespace YooAsset.Editor { private class BundleTableData : DefaultTableData { - public string PackageName; + public DebugPackageData PackageData; public DebugBundleInfo BundleInfo; } private class UsingTableData : DefaultTableData { public DebugProviderInfo ProviderInfo; } + private class ReferenceTableData : DefaultTableData + { + public DebugBundleInfo BundleInfo; + } private VisualTreeAsset _visualAsset; private TemplateContainer _root; private TableView _bundleTableView; private TableView _usingTableView; + private TableView _referenceTableView; private DebugReport _debugReport; private List _sourceDatas; @@ -44,20 +49,25 @@ namespace YooAsset.Editor _root.style.flexGrow = 1f; // 资源包列表 - _bundleTableView = _root.Q("TopTableView"); + _bundleTableView = _root.Q("BundleTableView"); _bundleTableView.SelectionChangedEvent = OnBundleTableViewSelectionChanged; CreateBundleTableViewColumns(); // 使用列表 - _usingTableView = _root.Q("BottomTableView"); + _usingTableView = _root.Q("UsingTableView"); CreateUsingTableViewColumns(); + // 引用列表 + _referenceTableView = _root.Q("ReferenceTableView"); + CreateReferenceTableViewColumns(); + #if UNITY_2020_3_OR_NEWER var topGroup = _root.Q("TopGroup"); var bottomGroup = _root.Q("BottomGroup"); topGroup.style.minHeight = 100; bottomGroup.style.minHeight = 100f; PanelSplitView.SplitVerticalPanel(_root, topGroup, bottomGroup); + PanelSplitView.SplitVerticalPanel(bottomGroup, _usingTableView, _referenceTableView); #endif } private void CreateBundleTableViewColumns() @@ -269,6 +279,79 @@ namespace YooAsset.Editor _usingTableView.AddColumn(column); } } + private void CreateReferenceTableViewColumns() + { + // BundleName + { + var columnStyle = new ColumnStyle(600, 500, 1000); + columnStyle.Stretchable = true; + columnStyle.Searchable = true; + columnStyle.Sortable = true; + var column = new TableColumn("ReferenceBundle", "Reference Bundle", columnStyle); + column.MakeCell = () => + { + var label = new Label(); + label.style.unityTextAlign = TextAnchor.MiddleLeft; + return label; + }; + column.BindCell = (VisualElement element, ITableData data, ITableCell cell) => + { + var infoLabel = element as Label; + infoLabel.text = (string)cell.GetDisplayObject(); + }; + _referenceTableView.AddColumn(column); + } + + // RefCount + { + var columnStyle = new ColumnStyle(100); + columnStyle.Stretchable = false; + columnStyle.Searchable = false; + columnStyle.Sortable = true; + var column = new TableColumn("RefCount", "Ref Count", columnStyle); + column.MakeCell = () => + { + var label = new Label(); + label.style.unityTextAlign = TextAnchor.MiddleLeft; + return label; + }; + column.BindCell = (VisualElement element, ITableData data, ITableCell cell) => + { + var infoLabel = element as Label; + infoLabel.text = (string)cell.GetDisplayObject(); + }; + _referenceTableView.AddColumn(column); + } + + // Status + { + var columnStyle = new ColumnStyle(100); + columnStyle.Stretchable = false; + columnStyle.Searchable = false; + columnStyle.Sortable = true; + var column = new TableColumn("Status", "Status", columnStyle); + column.MakeCell = () => + { + var label = new Label(); + label.style.unityTextAlign = TextAnchor.MiddleLeft; + return label; + }; + column.BindCell = (VisualElement element, ITableData data, ITableCell cell) => + { + StyleColor textColor; + var feferenceTableData = data as ReferenceTableData; + if (feferenceTableData.BundleInfo.Status == EOperationStatus.Failed) + textColor = new StyleColor(Color.yellow); + else + textColor = new StyleColor(Color.white); + + var infoLabel = element as Label; + infoLabel.text = (string)cell.GetDisplayObject(); + infoLabel.style.color = textColor; + }; + _referenceTableView.AddColumn(column); + } + } /// /// 填充页面数据 @@ -280,30 +363,22 @@ namespace YooAsset.Editor // 清空旧数据 _bundleTableView.ClearAll(false, true); _usingTableView.ClearAll(false, true); + _referenceTableView.ClearAll(false, true); // 填充数据源 _sourceDatas = new List(1000); foreach (var packageData in debugReport.PackageDatas) { - var tempDic = new HashSet(); - foreach (var providerInfo in packageData.ProviderInfos) + foreach (var bundleInfo in packageData.BundleInfos) { - foreach (var bundleInfo in providerInfo.DependBundleInfos) - { - if (tempDic.Contains(bundleInfo.BundleName) == false) - { - tempDic.Add(bundleInfo.BundleName); - - var rowData = new BundleTableData(); - rowData.PackageName = packageData.PackageName; - rowData.BundleInfo = bundleInfo; - rowData.AddAssetPathCell("PackageName", packageData.PackageName); - rowData.AddStringValueCell("BundleName", bundleInfo.BundleName); - rowData.AddLongValueCell("RefCount", bundleInfo.RefCount); - rowData.AddStringValueCell("Status", bundleInfo.Status.ToString()); - _sourceDatas.Add(rowData); - } - } + var rowData = new BundleTableData(); + rowData.PackageData = packageData; + rowData.BundleInfo = bundleInfo; + rowData.AddAssetPathCell("PackageName", packageData.PackageName); + rowData.AddStringValueCell("BundleName", bundleInfo.BundleName); + rowData.AddLongValueCell("RefCount", bundleInfo.RefCount); + rowData.AddStringValueCell("Status", bundleInfo.Status.ToString()); + _sourceDatas.Add(rowData); } } _bundleTableView.itemsSource = _sourceDatas; @@ -322,6 +397,8 @@ namespace YooAsset.Editor _bundleTableView.RebuildView(); _usingTableView.ClearAll(false, true); _usingTableView.RebuildView(); + _referenceTableView.ClearAll(false, true); + _referenceTableView.RebuildView(); } /// @@ -355,19 +432,17 @@ namespace YooAsset.Editor private void OnBundleTableViewSelectionChanged(ITableData data) { var bundleTableData = data as BundleTableData; + var packageData = bundleTableData.PackageData; + var selectBundleInfo = bundleTableData.BundleInfo; - // 填充依赖数据 - var sourceDatas = new List(1000); - foreach (var packageData in _debugReport.PackageDatas) + // 填充UsingTableView { - if (packageData.PackageName != bundleTableData.PackageName) - continue; - + var sourceDatas = new List(1000); foreach (var providerInfo in packageData.ProviderInfos) { - foreach (var bundleInfo in providerInfo.DependBundleInfos) + foreach (var dependBundleName in providerInfo.DependBundles) { - if (bundleInfo.BundleName == bundleTableData.BundleInfo.BundleName) + if (dependBundleName == selectBundleInfo.BundleName) { var rowData = new UsingTableData(); rowData.ProviderInfo = providerInfo; @@ -381,9 +456,26 @@ namespace YooAsset.Editor } } } + _usingTableView.itemsSource = sourceDatas; + _usingTableView.RebuildView(); + } + + // 填充ReferenceTableView + { + var sourceDatas = new List(1000); + foreach (string referenceBundleName in selectBundleInfo.ReferenceBundles) + { + var bundleInfo = packageData.GetBundleInfo(referenceBundleName); + var rowData = new ReferenceTableData(); + rowData.BundleInfo = bundleInfo; + rowData.AddStringValueCell("BundleName", bundleInfo.BundleName); + rowData.AddLongValueCell("RefCount", bundleInfo.RefCount); + rowData.AddStringValueCell("Status", bundleInfo.Status.ToString()); + sourceDatas.Add(rowData); + } + _referenceTableView.itemsSource = sourceDatas; + _referenceTableView.RebuildView(); } - _usingTableView.itemsSource = sourceDatas; - _usingTableView.RebuildView(); } } } diff --git a/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerBundleListViewer.uxml b/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerBundleListViewer.uxml index 761e5558..5fb8c22d 100644 --- a/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerBundleListViewer.uxml +++ b/Assets/YooAsset/Editor/AssetBundleDebugger/VisualViewers/DebuggerBundleListViewer.uxml @@ -1,8 +1,9 @@ - + - - + + + diff --git a/Assets/YooAsset/Runtime/DiagnosticSystem/DebugBundleInfo.cs b/Assets/YooAsset/Runtime/DiagnosticSystem/DebugBundleInfo.cs index 1a9c66d1..685dc4e3 100644 --- a/Assets/YooAsset/Runtime/DiagnosticSystem/DebugBundleInfo.cs +++ b/Assets/YooAsset/Runtime/DiagnosticSystem/DebugBundleInfo.cs @@ -22,6 +22,11 @@ namespace YooAsset /// public EOperationStatus Status; + /// + /// 谁引用了该资源包 + /// + public List ReferenceBundles; + public int CompareTo(DebugBundleInfo other) { return Compare(this, other); diff --git a/Assets/YooAsset/Runtime/DiagnosticSystem/DebugPackageData.cs b/Assets/YooAsset/Runtime/DiagnosticSystem/DebugPackageData.cs index dd01afef..e2a28761 100644 --- a/Assets/YooAsset/Runtime/DiagnosticSystem/DebugPackageData.cs +++ b/Assets/YooAsset/Runtime/DiagnosticSystem/DebugPackageData.cs @@ -17,5 +17,44 @@ namespace YooAsset /// 调试数据列表 /// public List ProviderInfos = new List(1000); + + /// + /// 调试数据列表 + /// + public List BundleInfos = new List(1000); + + + [NonSerialized] + public Dictionary BundleInfoDic = new Dictionary(); + private bool _isParse = false; + + /// + /// 获取调试资源包信息类 + /// + public DebugBundleInfo GetBundleInfo(string bundleName) + { + // 解析数据 + if (_isParse == false) + { + _isParse = true; + foreach (var bundleInfo in BundleInfos) + { + if (BundleInfoDic.ContainsKey(bundleInfo.BundleName) == false) + { + BundleInfoDic.Add(bundleInfo.BundleName, bundleInfo); + } + } + } + + if (BundleInfoDic.TryGetValue(bundleName, out DebugBundleInfo value)) + { + return value; + } + else + { + UnityEngine.Debug.LogError($"Can not found {nameof(DebugBundleInfo)} : {bundleName}"); + return null; + } + } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/DiagnosticSystem/DebugProviderInfo.cs b/Assets/YooAsset/Runtime/DiagnosticSystem/DebugProviderInfo.cs index f609a0c4..f6531d94 100644 --- a/Assets/YooAsset/Runtime/DiagnosticSystem/DebugProviderInfo.cs +++ b/Assets/YooAsset/Runtime/DiagnosticSystem/DebugProviderInfo.cs @@ -45,7 +45,7 @@ namespace YooAsset /// /// 依赖的资源包列表 /// - public List DependBundleInfos; + public List DependBundles; public int CompareTo(DebugProviderInfo other) { diff --git a/Assets/YooAsset/Runtime/DiagnosticSystem/DebugReport.cs b/Assets/YooAsset/Runtime/DiagnosticSystem/DebugReport.cs index 1a3a7487..ab59bee8 100644 --- a/Assets/YooAsset/Runtime/DiagnosticSystem/DebugReport.cs +++ b/Assets/YooAsset/Runtime/DiagnosticSystem/DebugReport.cs @@ -22,7 +22,6 @@ namespace YooAsset /// public List PackageDatas = new List(10); - /// /// 序列化 /// diff --git a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadUnusedAssetsOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadUnusedAssetsOperation.cs index 62e1a935..630d53e8 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadUnusedAssetsOperation.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Operation/UnloadUnusedAssetsOperation.cs @@ -14,11 +14,13 @@ namespace YooAsset } private readonly ResourceManager _resManager; + private readonly int _loopCount; private ESteps _steps = ESteps.None; - internal UnloadUnusedAssetsOperation(ResourceManager resourceManager) + internal UnloadUnusedAssetsOperation(ResourceManager resourceManager, int loopCount) { _resManager = resourceManager; + _loopCount = loopCount; } internal override void InternalOnStart() { @@ -31,29 +33,9 @@ namespace YooAsset if (_steps == ESteps.UnloadUnused) { - var removeList = new List(_resManager.LoaderDic.Count); - - // 注意:优先销毁资源提供者 - foreach (var loader in _resManager.LoaderDic.Values) + for (int i = 0; i < _loopCount; i++) { - loader.TryDestroyProviders(); - } - - // 获取销毁列表 - foreach (var loader in _resManager.LoaderDic.Values) - { - if (loader.CanDestroyLoader()) - { - removeList.Add(loader); - } - } - - // 销毁文件加载器 - foreach (var loader in removeList) - { - string bundleName = loader.LoadBundleInfo.Bundle.BundleName; - loader.DestroyLoader(); - _resManager.LoaderDic.Remove(bundleName); + LoopUnloadUnused(); } _steps = ESteps.Done; @@ -71,5 +53,36 @@ namespace YooAsset } } } + + /// + /// 说明:资源包之间会有深层的依赖链表,需要多次迭代才可以在单帧内卸载! + /// + private void LoopUnloadUnused() + { + var removeList = new List(_resManager.LoaderDic.Count); + + // 注意:优先销毁资源提供者 + foreach (var loader in _resManager.LoaderDic.Values) + { + loader.TryDestroyProviders(); + } + + // 获取销毁列表 + foreach (var loader in _resManager.LoaderDic.Values) + { + if (loader.CanDestroyLoader()) + { + removeList.Add(loader); + } + } + + // 销毁文件加载器 + foreach (var loader in removeList) + { + string bundleName = loader.LoadBundleInfo.Bundle.BundleName; + loader.DestroyLoader(); + _resManager.LoaderDic.Remove(bundleName); + } + } } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderOperation.cs b/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderOperation.cs index 725e2769..837cdbe3 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderOperation.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/Provider/ProviderOperation.cs @@ -286,7 +286,7 @@ namespace YooAsset return status; } - #region 调试信息相关 + #region 调试信息 /// /// 出生的场景 /// @@ -341,16 +341,15 @@ namespace YooAsset /// /// 获取资源包的调试信息列表 /// - internal void GetBundleDebugInfos(List output) + internal List GetDebugDependBundles() { + List result = new List(_bundleLoaders.Count); foreach (var bundleLoader in _bundleLoaders) { - var bundleInfo = new DebugBundleInfo(); - bundleInfo.BundleName = bundleLoader.LoadBundleInfo.Bundle.BundleName; - bundleInfo.RefCount = bundleLoader.RefCount; - bundleInfo.Status = bundleLoader.Status; - output.Add(bundleInfo); + var packageBundle = bundleLoader.LoadBundleInfo.Bundle; + result.Add(packageBundle.BundleName); } + return result; } #endregion } diff --git a/Assets/YooAsset/Runtime/ResourceManager/ResourceManager.cs b/Assets/YooAsset/Runtime/ResourceManager/ResourceManager.cs index 8535784a..26b0a7d3 100644 --- a/Assets/YooAsset/Runtime/ResourceManager/ResourceManager.cs +++ b/Assets/YooAsset/Runtime/ResourceManager/ResourceManager.cs @@ -360,7 +360,15 @@ namespace YooAsset } #region 调试信息 - internal List GetDebugReportInfos() + internal DebugPackageData GetDebugPackageData() + { + DebugPackageData data = new DebugPackageData(); + data.PackageName = PackageName; + data.ProviderInfos = GetDebugProviderInfos(); + data.BundleInfos = GetDebugBundleInfos(); + return data; + } + internal List GetDebugProviderInfos() { List result = new List(ProviderDic.Count); foreach (var provider in ProviderDic.Values) @@ -372,12 +380,38 @@ namespace YooAsset providerInfo.LoadingTime = provider.LoadingTime; providerInfo.RefCount = provider.RefCount; providerInfo.Status = provider.Status.ToString(); - providerInfo.DependBundleInfos = new List(); - provider.GetBundleDebugInfos(providerInfo.DependBundleInfos); + providerInfo.DependBundles = provider.GetDebugDependBundles(); result.Add(providerInfo); } return result; } + internal List GetDebugBundleInfos() + { + List result = new List(LoaderDic.Values.Count); + foreach (var bundleLoader in LoaderDic.Values) + { + var packageBundle = bundleLoader.LoadBundleInfo.Bundle; + var bundleInfo = new DebugBundleInfo(); + bundleInfo.BundleName = packageBundle.BundleName; + bundleInfo.RefCount = bundleLoader.RefCount; + bundleInfo.Status = bundleLoader.Status; + bundleInfo.ReferenceBundles = FilterReferenceBundles(packageBundle); + result.Add(bundleInfo); + } + return result; + } + internal List FilterReferenceBundles(PackageBundle packageBundle) + { + // 注意:引用的资源包不一定在内存中,所以需要过滤 + var referenceBundles = packageBundle.GetDebugReferenceBundles(); + List result = new List(referenceBundles.Count); + foreach (var bundleName in referenceBundles) + { + if (LoaderDic.ContainsKey(bundleName)) + result.Add(bundleName); + } + return result; + } #endregion } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/PackageBundle.cs b/Assets/YooAsset/Runtime/ResourcePackage/PackageBundle.cs index 03cc8a7e..89d36857 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/PackageBundle.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/PackageBundle.cs @@ -120,6 +120,7 @@ namespace YooAsset /// public void InitBundle(PackageManifest manifest) { + _mainfest = manifest; _bundleType = manifest.BuildBundleType; _fileExtension = ManifestTools.GetRemoteBundleFileExtension(BundleName); _fileName = ManifestTools.GetRemoteBundleFileName(manifest.OutputNameStyle, BundleName, _fileExtension, FileHash); @@ -177,5 +178,23 @@ namespace YooAsset return false; } + + #region 调试信息 + private PackageManifest _mainfest; + private List _debugReferenceBundles; + public List GetDebugReferenceBundles() + { + if (_debugReferenceBundles == null) + { + _debugReferenceBundles = new List(ReferenceBundleIDs.Count); + foreach (int bundleID in ReferenceBundleIDs) + { + var packageBundle = _mainfest.BundleList[bundleID]; + _debugReferenceBundles.Add(packageBundle.BundleName); + } + } + return _debugReferenceBundles; + } + #endregion } } \ No newline at end of file diff --git a/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs b/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs index 591444b8..997561a2 100644 --- a/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs +++ b/Assets/YooAsset/Runtime/ResourcePackage/ResourcePackage.cs @@ -339,10 +339,11 @@ namespace YooAsset /// 回收不再使用的资源 /// 说明:卸载引用计数为零的资源 /// - public UnloadUnusedAssetsOperation UnloadUnusedAssetsAsync() + /// 循环迭代次数 + public UnloadUnusedAssetsOperation UnloadUnusedAssetsAsync(int loopCount = 10) { DebugCheckInitialize(); - var operation = new UnloadUnusedAssetsOperation(_resourceManager); + var operation = new UnloadUnusedAssetsOperation(_resourceManager, loopCount); OperationSystem.StartOperation(PackageName, operation); return operation; } @@ -1146,10 +1147,7 @@ namespace YooAsset #region 调试信息 internal DebugPackageData GetDebugPackageData() { - DebugPackageData data = new DebugPackageData(); - data.PackageName = PackageName; - data.ProviderInfos = _resourceManager.GetDebugReportInfos(); - return data; + return _resourceManager.GetDebugPackageData(); } #endregion }