WuhuIslandTesting/Library/PackageCache/com.unity.addressables@1.21.12/Editor/Diagnostics/Profiler/AddressablesProfilerDetailsDataInspector.cs
2025-01-07 02:06:59 +01:00

420 lines
18 KiB
C#

#if ENABLE_ADDRESSABLE_PROFILER && UNITY_2022_2_OR_NEWER
using System.Collections.Generic;
using System.Text;
using UnityEditor.AddressableAssets.Build.Layout;
using UnityEditor.AddressableAssets.GUI;
using UnityEditor.AddressableAssets.GUIElements;
using UnityEditor.AddressableAssets.Settings;
using UnityEngine;
using UnityEngine.ResourceManagement.Profiling;
using UnityEngine.ResourceManagement.Util;
using UnityEngine.UIElements;
using Object = UnityEngine.Object;
namespace UnityEditor.AddressableAssets.Diagnostics
{
internal class AddressablesProfilerDetailsDataInspector
{
private ContentDataTreeView m_ReferencesTree = new ContentDataTreeView();
private ContentData m_SelectionSource;
private HelpDisplayManager m_HelpManager = new HelpDisplayManager();
private InspectorPane m_Elements;
private Stack<LabeledLabel> m_InformationLabelsCache = new Stack<LabeledLabel>();
public AddressablesProfilerDetailsDataInspector(InspectorPane rootView)
{
m_Elements = rootView;
}
public void Initialise(MultiColumnTreeView mainProfilerAssetTree)
{
m_HelpManager.Initialise(m_Elements, mainProfilerAssetTree);
m_Elements.ReferencesTypeSelection.Clicked += ReferencesRibbonOnClicked;
m_ReferencesTree.Initialise(m_Elements.ReferencesTree, mainProfilerAssetTree);
m_Elements.SelectInEditor.clicked += SelectInEditorOnClicked;
m_Elements.SelectInGroups.clicked += SelectInGroupsOnClicked;
m_Elements.SelectedAsset.Wrap = true;
SetSourceContent(null);
}
public void SetSourceContent(ContentData source)
{
m_Elements.SelectInEditor.SetEnabled(false);
m_Elements.SelectInGroups.SetEnabled(false);
m_SelectionSource = source;
m_Elements.PreviewImage.image = null;
m_HelpManager.Clear();
if (source == null)
{
m_Elements.MainContainer.visible = false;
return;
}
RemoveLabels(m_Elements.SelectionDetailsFoldout);
m_Elements.MainContainer.visible = true;
if (source is BundleData bundleData)
SetSourceBundle(bundleData);
else if (source is GroupData groupData)
SetSourceGroup(groupData);
else if (source is AssetData assetData)
SetSourceAsset(assetData);
else if (source is ObjectData objectData)
SetSourceObject(objectData);
else
m_Elements.MainContainer.visible = false;
m_HelpManager.HideIfEmpty();
SetInfoFoldoutsVisibility();
}
private LabeledLabel AddLabel(string label, string text, VisualElement parent)
{
LabeledLabel lbl = null;
if (m_InformationLabelsCache.Count > 0)
{
lbl = m_InformationLabelsCache.Pop();
lbl.Label = label;
lbl.Text = text;
}
else
lbl = new LabeledLabel(label, text, true);
parent.Add(lbl);
return lbl;
}
private void RemoveLabels(VisualElement parent)
{
List<VisualElement> toRemove = new List<VisualElement>();
foreach (VisualElement child in parent.Children())
{
if (child is LabeledLabel)
toRemove.Add(child);
}
foreach (VisualElement element in toRemove)
{
parent.Remove(element);
if (element is LabeledLabel l)
m_InformationLabelsCache.Push(l);
}
}
private void SetInfoFoldoutsVisibility()
{
if (m_Elements.SelectionDetailsFoldout.childCount == 0)
ProfilerGUIUtilities.Hide(m_Elements.SelectionDetailsFoldout);
else
ProfilerGUIUtilities.Show(m_Elements.SelectionDetailsFoldout);
}
private void SetSourceGroup(GroupData groupData)
{
m_Elements.SelectedAsset.SetContent(groupData);
AddLabel("Name", groupData.m_ReportGroup.Name, m_Elements.SelectionDetailsFoldout);
AddLabel("GUID", groupData.m_ReportGroup.Guid, m_Elements.SelectionDetailsFoldout);
AddLabel("Packing Mode", groupData.m_ReportGroup.PackingMode, m_Elements.SelectionDetailsFoldout);
AddLabel("Bundle Count", groupData.m_ReportGroup.Bundles.Count.ToString(), m_Elements.SelectionDetailsFoldout);
ProfilerGUIUtilities.Hide(m_Elements.ReferencesFoldout);
ProfilerGUIUtilities.Hide(m_Elements.PreviewFoldout);
}
private void SetSourceBundle(BundleData bundleData)
{
m_Elements.SelectedAsset.SetContent(bundleData);
// basic
AddLabel("Source", bundleData.Source.ToString(), m_Elements.SelectionDetailsFoldout);
AddLabel("Load Path", bundleData.ReportBundle.LoadPath, m_Elements.SelectionDetailsFoldout);
AddLabel("Compression", bundleData.ReportBundle.Compression + " (at build)", m_Elements.SelectionDetailsFoldout);
// addressables group
AddLabel("Group", bundleData.ReportBundle.Group.Name, m_Elements.SelectionDetailsFoldout);
AddLabel("Provider", bundleData.ReportBundle.Provider, m_Elements.SelectionDetailsFoldout);
AddLabel("Hash", bundleData.ReportBundle.Hash.ToString(), m_Elements.SelectionDetailsFoldout);
AddLabel("CRC", bundleData.ReportBundle.CRC.ToString(), m_Elements.SelectionDetailsFoldout);
ProfilerGUIUtilities.Show(m_Elements.ReferencesFoldout);
ReferencesRibbonOnClicked(m_Elements.ReferencesTypeSelection.m_CurrentOption);
ProfilerGUIUtilities.Hide(m_Elements.PreviewFoldout);
if (bundleData.Children.Count > 0)
{
List<ContentData> addressedAssetsInBundle = new List<ContentData>(bundleData.Children.Count);
foreach (ContentData childAsset in bundleData.Children)
{
if (childAsset.AddressableHandles > 0)
addressedAssetsInBundle.Add(childAsset);
}
m_HelpManager.MakeHelp(ProfilerStrings.BundleWithLoadedAddressableContent, addressedAssetsInBundle);
}
if (bundleData.ReferencesToThis.Count > 0)
{
HashSet<ContentData> referencingAssets = new HashSet<ContentData>();
HashSet<ContentData> bundlesReferencingWithoutLoadingReferencingAsset = new HashSet<ContentData>();
foreach (ContentData bundleReferencingThis in bundleData.ReferencesToThis)
{
bool hasLoadedAssetReferencing = false;
// find children referencing this
foreach (ContentData assetInReferencingBundle in bundleReferencingThis.Children)
{
foreach (ContentData other in assetInReferencingBundle.ThisReferencesOther)
{
if (other.Parent == bundleData)
{
referencingAssets.Add(assetInReferencingBundle);
hasLoadedAssetReferencing = true;
break;
}
}
}
if (!hasLoadedAssetReferencing)
bundlesReferencingWithoutLoadingReferencingAsset.Add(bundleReferencingThis);
}
if (referencingAssets.Count > 0)
{
m_HelpManager.MakeHelp(ProfilerStrings.BundleReferencingWithDependencies, new List<ContentData>(referencingAssets), "editor/building-content/AssetDependencies.html", "Learn more: About Dependencies");
}
if (bundlesReferencingWithoutLoadingReferencingAsset.Count > 0)
{
m_HelpManager.MakeHelp(ProfilerStrings.BundleReferencingWithNoLoadedDependencies, new List<ContentData>(bundlesReferencingWithoutLoadingReferencingAsset), "editor/building-content/AssetDependencies.html", "Learn more: About Dependencies");
}
}
if (bundleData.Source == BundleSource.Local)
{
if (bundleData.CheckSumEnabled)
m_HelpManager.MakeHelp(ProfilerStrings.LocalBundleUsingCRC, new List<ContentData>(), "editor/groups/ContentPackingAndLoadingSchema.html#assetbundle-crc", "Learn more: About CRC");
}
else if (bundleData.Source == BundleSource.Cache)
{
if (bundleData.CheckSumEnabled)
m_HelpManager.MakeHelp(ProfilerStrings.CachedBundleUsingCRC, new List<ContentData>(), "editor/groups/ContentPackingAndLoadingSchema.html#assetbundle-crc", "Learn more: About CRC");
}
else if (bundleData.Source == BundleSource.Download)
{
#if ENABLE_CACHING
if (!bundleData.CachingEnabled)
m_HelpManager.MakeHelp(ProfilerStrings.DownloadWithoutCaching);
#else
if (bundleData.CachingEnabled)
m_HelpManager.MakeHelp(ProfilerStrings.DownloadWithoutCachingEnabled);
#endif
if (bundleData.CachingEnabled && !bundleData.CheckSumEnabled)
m_HelpManager.MakeHelp(ProfilerStrings.DownloadWithoutCRC, new List<ContentData>(), "editor/groups/ContentPackingAndLoadingSchema.html#assetbundle-crc", "Learn more: About CRC");
}
}
private void SetSourceAsset(AssetData assetData)
{
m_Elements.SelectedAsset.SetContent(assetData);
AddLabel("AssetPath", assetData.AssetPath, m_Elements.SelectionDetailsFoldout);
AddLabel("GUID", assetData.AssetGuid, m_Elements.SelectionDetailsFoldout);
AddLabel("Asset Type", assetData.MainAssetType.ToString(), m_Elements.SelectionDetailsFoldout);
if (assetData.ReportExplicitData != null)
{
AddLabel("Address", assetData.ReportExplicitData.AddressableName, m_Elements.SelectionDetailsFoldout);
ContentData parent = assetData.Parent;
while (parent != null)
{
if (parent is GroupData g)
{
AddLabel("Group Name", g.m_ReportGroup.Name, m_Elements.SelectionDetailsFoldout);
break;
}
parent = parent.Parent;
}
if (assetData.ReportExplicitData.Labels.Length > 0)
{
StringBuilder labels = new StringBuilder(assetData.ReportExplicitData.Labels[0]);
for (int i = 1; i < assetData.ReportExplicitData.Labels.Length; ++i)
labels.Append($", {assetData.ReportExplicitData.Labels[i]}");
AddLabel("Labels", labels.ToString(), m_Elements.SelectionDetailsFoldout);
}
AddLabel("Asset Hash", assetData.ReportExplicitData.AssetHash.ToString(), m_Elements.SelectionDetailsFoldout);
AddLabel("Internal Id", assetData.ReportExplicitData.InternalId, m_Elements.SelectionDetailsFoldout);
}
else if (assetData.ReportImplicitData != null)
{
AddLabel("Inclusion", "Implicit", m_Elements.SelectionDetailsFoldout);
}
if (assetData.Status == ContentStatus.None)
ProfilerGUIUtilities.Hide(m_Elements.ReferencesFoldout);
else
{
ProfilerGUIUtilities.Show(m_Elements.ReferencesFoldout);
ReferencesRibbonOnClicked(m_Elements.ReferencesTypeSelection.m_CurrentOption);
}
if (assetData.AddressableHandles > 0)
m_HelpManager.MakeHelp(ProfilerStrings.LoadedAssetText);
if (assetData.Status == ContentStatus.None)
m_HelpManager.MakeHelp(ProfilerStrings.NotLoadedAssetHelpText);
if (assetData.ReferencesToThis.Count > 0)
{
// get root addressable assets
Queue<ContentData> refQueue = new Queue<ContentData>(assetData.ReferencesToThis);
HashSet<ContentData> addressedContentReferencingSelection = new HashSet<ContentData>();
while (refQueue.Count > 0)
{
ContentData referencingContent = refQueue.Dequeue();
if (referencingContent.AddressableHandles > 0)
addressedContentReferencingSelection.Add(referencingContent);
foreach (ContentData innerRef in referencingContent.ReferencesToThis)
refQueue.Enqueue(innerRef);
}
Stack<ContentData> stack = new Stack<ContentData>();
List<ContentData[]> addressableStacks = new List<ContentData[]>();
foreach (ContentData refTo in assetData.ReferencesToThis)
ProcessReference(refTo, stack, addressableStacks);
m_HelpManager.MakeHelp(ProfilerStrings.ReferencedAssetText, addressableStacks);
// m_HelpManager.MakeHelp(ProfilerStrings.ReferencedAssetText, new List<ContentData>(addressedContentReferencingSelection));
}
DisplayAssetPreview(assetData);
AddressableAssetSettings settings = AddressableAssetSettingsDefaultObject.Settings;
if (settings != null && settings.FindAssetEntry(assetData.AssetGuid) != null)
m_Elements.SelectInGroups.SetEnabled(true);
}
private void ProcessReference(ContentData processing, in Stack<ContentData> stack, in List<ContentData[]> addressableStacks)
{
stack.Push(processing);
if (processing.AddressableHandles > 0)
addressableStacks.Add(stack.ToArray());
foreach (ContentData refTo in processing.ReferencesToThis)
ProcessReference(refTo, stack, addressableStacks);
stack.Pop();
}
private void DisplayAssetPreview(AssetData assetData)
{
string path = AssetDatabase.GUIDToAssetPath(assetData.AssetGuid);
if (!string.IsNullOrEmpty(path))
{
m_Elements.SelectInEditor.SetEnabled(true);
var obj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(path);
if (obj != null)
{
var editor = UnityEditor.Editor.CreateEditor(obj);
Texture2D preview = editor.RenderStaticPreview(path, new Object[] { obj }, 256, 256);
Object.DestroyImmediate(editor);
if (preview != null)
m_Elements.PreviewImage.image = preview;
}
}
m_Elements.PreviewFoldout.style.display =
new StyleEnum<DisplayStyle>(m_Elements.PreviewImage.image == null ? DisplayStyle.None : DisplayStyle.Flex);
}
private void SetSourceObject(ObjectData objectData)
{
m_Elements.SelectedAsset.SetContent(objectData);
bool sceneObject = false;
if (objectData.Parent is AssetData assetData)
{
if (assetData.MainAssetType == AssetType.Scene)
sceneObject = true;
}
if (sceneObject && objectData.AssetType != AssetType.SceneObject)
{
m_HelpManager.MakeHelp("This indicates that the scene contains this object type, but no other data is available.");
ProfilerGUIUtilities.Hide(m_Elements.ReferencesFoldout);
}
else
{
ProfilerGUIUtilities.Show(m_Elements.ReferencesFoldout);
ReferencesRibbonOnClicked(m_Elements.ReferencesTypeSelection.m_CurrentOption);
}
ProfilerGUIUtilities.Hide(m_Elements.PreviewFoldout);
AddLabel("Object Type", objectData.AssetType.ToString(), m_Elements.SelectionDetailsFoldout);
if (objectData.AssetType == AssetType.Component)
AddLabel("Component", objectData.ComponentName, m_Elements.SelectionDetailsFoldout);
}
private void ReferencesRibbonOnClicked(int optionValue)
{
if (m_SelectionSource == null)
{
m_Elements.ReferencedByButton.text = "Referenced By (0)";
m_Elements.ReferencesToButton.text = "References To (0)";
m_ReferencesTree.SetSource(new List<ContentData>());
return;
}
m_ReferencesTree.SetSource(optionValue == 0 ? m_SelectionSource.ThisReferencesOther : m_SelectionSource.ReferencesToThis);
m_Elements.ReferencedByButton.text = $"Referenced By ({m_SelectionSource.ReferencesToThis.Count})";
m_Elements.ReferencesToButton.text = $"References To ({m_SelectionSource.ThisReferencesOther.Count})";
}
private void SelectInEditorOnClicked()
{
var assetData = m_SelectionSource as AssetData;
if (assetData == null)
return;
string path = assetData.ReportExplicitData != null ? assetData.ReportExplicitData.AssetPath :
assetData.ReportImplicitData != null ? assetData.ReportImplicitData.AssetPath : null;
if (string.IsNullOrEmpty(path))
return;
var obj = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(path);
if (obj == null)
return;
EditorGUIUtility.PingObject(obj);
Selection.activeObject = obj;
}
private void SelectInGroupsOnClicked()
{
var assetData = m_SelectionSource as AssetData;
if (assetData == null)
return;
AddressableAssetSettings settings = AddressableAssetSettingsDefaultObject.Settings;
if (settings == null)
return;
AddressableAssetEntry entry = settings.FindAssetEntry(assetData.AssetGuid);
if (entry == null)
return;
AddressableAssetsWindow.Init();
var window = EditorWindow.GetWindow<AddressableAssetsWindow>();
List<AddressableAssetEntry> entries = new List<AddressableAssetEntry>(){entry};
window.SelectAssetsInGroupEditor(entries);
}
}
}
#endif