update diagnostic system

优化了Debugger窗口的显示页面
pull/497/head
何冠峰 2025-02-22 14:14:05 +08:00
parent 82c57c382f
commit f6244885be
13 changed files with 282 additions and 79 deletions

View File

@ -272,7 +272,7 @@ namespace YooAsset.Editor
packageData.ProviderInfos.Sort();
foreach (var providerInfo in packageData.ProviderInfos)
{
providerInfo.DependBundleInfos.Sort();
providerInfo.DependBundles.Sort();
}
}

View File

@ -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<ITableData>(providerInfo.DependBundleInfos.Count);
foreach (var dependBundleInfo in providerInfo.DependBundleInfos)
var sourceDatas = new List<ITableData>(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);

View File

@ -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<ITableData> _sourceDatas;
@ -44,20 +49,25 @@ namespace YooAsset.Editor
_root.style.flexGrow = 1f;
// 资源包列表
_bundleTableView = _root.Q<TableView>("TopTableView");
_bundleTableView = _root.Q<TableView>("BundleTableView");
_bundleTableView.SelectionChangedEvent = OnBundleTableViewSelectionChanged;
CreateBundleTableViewColumns();
// 使用列表
_usingTableView = _root.Q<TableView>("BottomTableView");
_usingTableView = _root.Q<TableView>("UsingTableView");
CreateUsingTableViewColumns();
// 引用列表
_referenceTableView = _root.Q<TableView>("ReferenceTableView");
CreateReferenceTableViewColumns();
#if UNITY_2020_3_OR_NEWER
var topGroup = _root.Q<VisualElement>("TopGroup");
var bottomGroup = _root.Q<VisualElement>("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);
}
}
/// <summary>
/// 填充页面数据
@ -280,30 +363,22 @@ namespace YooAsset.Editor
// 清空旧数据
_bundleTableView.ClearAll(false, true);
_usingTableView.ClearAll(false, true);
_referenceTableView.ClearAll(false, true);
// 填充数据源
_sourceDatas = new List<ITableData>(1000);
foreach (var packageData in debugReport.PackageDatas)
{
var tempDic = new HashSet<string>();
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();
}
/// <summary>
@ -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<ITableData>(1000);
foreach (var packageData in _debugReport.PackageDatas)
// 填充UsingTableView
{
if (packageData.PackageName != bundleTableData.PackageName)
continue;
var sourceDatas = new List<ITableData>(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<ITableData>(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();
}
}
}

View File

@ -1,8 +1,9 @@
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
<ui:VisualElement name="TopGroup" style="flex-grow: 1; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); margin-left: 0; margin-right: 0; margin-top: 2px; margin-bottom: 1px; display: flex;">
<YooAsset.Editor.TableView name="TopTableView" />
<YooAsset.Editor.TableView name="BundleTableView" />
</ui:VisualElement>
<ui:VisualElement name="BottomGroup" style="height: 200px; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); margin-left: 0; margin-right: 0; margin-top: 1px; margin-bottom: 1px; display: flex;">
<YooAsset.Editor.TableView name="BottomTableView" />
<ui:VisualElement name="BottomGroup" style="height: 400px; border-left-width: 1px; border-right-width: 1px; border-top-width: 1px; border-bottom-width: 1px; border-left-color: rgb(0, 0, 0); border-right-color: rgb(0, 0, 0); border-top-color: rgb(0, 0, 0); border-bottom-color: rgb(0, 0, 0); margin-left: 0; margin-right: 0; margin-top: 1px; margin-bottom: 1px; display: flex;">
<YooAsset.Editor.TableView name="UsingTableView" />
<YooAsset.Editor.TableView name="ReferenceTableView" />
</ui:VisualElement>
</ui:UXML>

View File

@ -22,6 +22,11 @@ namespace YooAsset
/// </summary>
public EOperationStatus Status;
/// <summary>
/// 谁引用了该资源包
/// </summary>
public List<string> ReferenceBundles;
public int CompareTo(DebugBundleInfo other)
{
return Compare(this, other);

View File

@ -17,5 +17,44 @@ namespace YooAsset
/// 调试数据列表
/// </summary>
public List<DebugProviderInfo> ProviderInfos = new List<DebugProviderInfo>(1000);
/// <summary>
/// 调试数据列表
/// </summary>
public List<DebugBundleInfo> BundleInfos = new List<DebugBundleInfo>(1000);
[NonSerialized]
public Dictionary<string, DebugBundleInfo> BundleInfoDic = new Dictionary<string, DebugBundleInfo>();
private bool _isParse = false;
/// <summary>
/// 获取调试资源包信息类
/// </summary>
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;
}
}
}
}

View File

@ -45,7 +45,7 @@ namespace YooAsset
/// <summary>
/// 依赖的资源包列表
/// </summary>
public List<DebugBundleInfo> DependBundleInfos;
public List<string> DependBundles;
public int CompareTo(DebugProviderInfo other)
{

View File

@ -22,7 +22,6 @@ namespace YooAsset
/// </summary>
public List<DebugPackageData> PackageDatas = new List<DebugPackageData>(10);
/// <summary>
/// 序列化
/// </summary>

View File

@ -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<LoadBundleFileOperation>(_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
}
}
}
/// <summary>
/// 说明:资源包之间会有深层的依赖链表,需要多次迭代才可以在单帧内卸载!
/// </summary>
private void LoopUnloadUnused()
{
var removeList = new List<LoadBundleFileOperation>(_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);
}
}
}
}

View File

@ -286,7 +286,7 @@ namespace YooAsset
return status;
}
#region 调试信息相关
#region 调试信息
/// <summary>
/// 出生的场景
/// </summary>
@ -341,16 +341,15 @@ namespace YooAsset
/// <summary>
/// 获取资源包的调试信息列表
/// </summary>
internal void GetBundleDebugInfos(List<DebugBundleInfo> output)
internal List<string> GetDebugDependBundles()
{
List<string> result = new List<string>(_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
}

View File

@ -360,7 +360,15 @@ namespace YooAsset
}
#region 调试信息
internal List<DebugProviderInfo> GetDebugReportInfos()
internal DebugPackageData GetDebugPackageData()
{
DebugPackageData data = new DebugPackageData();
data.PackageName = PackageName;
data.ProviderInfos = GetDebugProviderInfos();
data.BundleInfos = GetDebugBundleInfos();
return data;
}
internal List<DebugProviderInfo> GetDebugProviderInfos()
{
List<DebugProviderInfo> result = new List<DebugProviderInfo>(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<DebugBundleInfo>();
provider.GetBundleDebugInfos(providerInfo.DependBundleInfos);
providerInfo.DependBundles = provider.GetDebugDependBundles();
result.Add(providerInfo);
}
return result;
}
internal List<DebugBundleInfo> GetDebugBundleInfos()
{
List<DebugBundleInfo> result = new List<DebugBundleInfo>(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<string> FilterReferenceBundles(PackageBundle packageBundle)
{
// 注意:引用的资源包不一定在内存中,所以需要过滤
var referenceBundles = packageBundle.GetDebugReferenceBundles();
List<string> result = new List<string>(referenceBundles.Count);
foreach (var bundleName in referenceBundles)
{
if (LoaderDic.ContainsKey(bundleName))
result.Add(bundleName);
}
return result;
}
#endregion
}
}

View File

@ -120,6 +120,7 @@ namespace YooAsset
/// </summary>
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<string> _debugReferenceBundles;
public List<string> GetDebugReferenceBundles()
{
if (_debugReferenceBundles == null)
{
_debugReferenceBundles = new List<string>(ReferenceBundleIDs.Count);
foreach (int bundleID in ReferenceBundleIDs)
{
var packageBundle = _mainfest.BundleList[bundleID];
_debugReferenceBundles.Add(packageBundle.BundleName);
}
}
return _debugReferenceBundles;
}
#endregion
}
}

View File

@ -339,10 +339,11 @@ namespace YooAsset
/// 回收不再使用的资源
/// 说明:卸载引用计数为零的资源
/// </summary>
public UnloadUnusedAssetsOperation UnloadUnusedAssetsAsync()
/// <param name="loopCount">循环迭代次数</param>
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
}