123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using UnityEditor.AddressableAssets.Build;
- using UnityEditor.AddressableAssets.Build.AnalyzeRules;
- using UnityEditor.AddressableAssets.Settings;
- using UnityEditor.IMGUI.Controls;
- using UnityEngine;
- using Debug = UnityEngine.Debug;
- using Object = UnityEngine.Object;
- namespace UnityEditor.AddressableAssets.GUI
- {
- class AssetSettingsAnalyzeTreeView : TreeView
- {
- private int m_CurrentDepth;
- internal AssetSettingsAnalyzeTreeView(TreeViewState state)
- : base(state)
- {
- showAlternatingRowBackgrounds = true;
- showBorder = true;
- Reload();
- }
- private List<AnalyzeRuleContainerTreeViewItem> GatherAllInheritRuleContainers(TreeViewItem baseContainer)
- {
- List<AnalyzeRuleContainerTreeViewItem> retValue = new List<AnalyzeRuleContainerTreeViewItem>();
- if (!baseContainer.hasChildren)
- return new List<AnalyzeRuleContainerTreeViewItem>();
- foreach (var child in baseContainer.children)
- {
- if (child is AnalyzeRuleContainerTreeViewItem)
- {
- retValue.AddRange(GatherAllInheritRuleContainers(child as AnalyzeRuleContainerTreeViewItem));
- retValue.Add(child as AnalyzeRuleContainerTreeViewItem);
- }
- }
- return retValue;
- }
- private void PerformActionForEntireRuleSelection(Action<AnalyzeRuleContainerTreeViewItem> action)
- {
- List<AnalyzeRuleContainerTreeViewItem> activeSelection = (from id in GetSelection()
- let selection = FindItem(id, rootItem)
- where selection is AnalyzeRuleContainerTreeViewItem
- select selection as AnalyzeRuleContainerTreeViewItem).ToList();
- List<AnalyzeRuleContainerTreeViewItem> inheritSelection = new List<AnalyzeRuleContainerTreeViewItem>();
- foreach (var selected in activeSelection)
- inheritSelection.AddRange(GatherAllInheritRuleContainers(selected));
- List<AnalyzeRuleContainerTreeViewItem> entireSelection = activeSelection.Union(inheritSelection).ToList();
- foreach (AnalyzeRuleContainerTreeViewItem ruleContainer in entireSelection)
- {
- if (ruleContainer.analyzeRule != null)
- {
- action(ruleContainer);
- }
- }
- }
- public void RunAllSelectedRules()
- {
- PerformActionForEntireRuleSelection((ruleContainer) =>
- {
- var results = AnalyzeSystem.RefreshAnalysis(ruleContainer.analyzeRule);
- BuildResults(ruleContainer, results);
- Reload();
- UpdateSelections(GetSelection());
- });
- }
- public void FixAllSelectedRules()
- {
- PerformActionForEntireRuleSelection((ruleContainer) =>
- {
- AnalyzeSystem.FixIssues(ruleContainer.analyzeRule);
- var results = AnalyzeSystem.RefreshAnalysis(ruleContainer.analyzeRule);
- BuildResults(ruleContainer, results);
- Reload();
- UpdateSelections(GetSelection());
- });
- }
- public void ClearAllSelectedRules()
- {
- PerformActionForEntireRuleSelection((ruleContainer) =>
- {
- AnalyzeSystem.ClearAnalysis(ruleContainer.analyzeRule);
- BuildResults(ruleContainer, new List<AnalyzeRule.AnalyzeResult>());
- Reload();
- UpdateSelections(GetSelection());
- });
- }
- public bool SelectionContainsFixableRule { get; private set; }
- public bool SelectionContainsRuleContainer { get; private set; }
- public bool SelectionContainsErrors { get; private set; }
- protected override void SelectionChanged(IList<int> selectedIds)
- {
- UpdateSelections(selectedIds);
- }
- void UpdateSelections(IList<int> selectedIds)
- {
- var allSelectedRuleContainers = (from id in selectedIds
- let ruleContainer = FindItem(id, rootItem) as AnalyzeRuleContainerTreeViewItem
- where ruleContainer != null
- select ruleContainer);
- List<AnalyzeRuleContainerTreeViewItem> allRuleContainers = new List<AnalyzeRuleContainerTreeViewItem>();
- foreach (var ruleContainer in allSelectedRuleContainers)
- {
- allRuleContainers.AddRange(GatherAllInheritRuleContainers(ruleContainer));
- allRuleContainers.Add(ruleContainer);
- }
- allRuleContainers = allRuleContainers.Distinct().ToList();
- SelectionContainsErrors = (from container in allRuleContainers
- from child in container.children
- where child is AnalyzeResultsTreeViewItem && (child as AnalyzeResultsTreeViewItem).IsError
- select child).Any();
- SelectionContainsRuleContainer = allRuleContainers.Any();
- SelectionContainsFixableRule = (from container in allRuleContainers
- where container.analyzeRule.CanFix
- select container).Any();
- }
- protected override void ContextClicked()
- {
- if (SelectionContainsRuleContainer)
- {
- GenericMenu menu = new GenericMenu();
- menu.AddItem(new GUIContent("Run Analyze Rule"), false, RunAllSelectedRules);
- menu.AddItem(new GUIContent("Clear Analyze Results"), false, ClearAllSelectedRules);
- if (SelectionContainsFixableRule && SelectionContainsErrors)
- menu.AddItem(new GUIContent("Fix Analyze Rule"), false, FixAllSelectedRules);
- else
- menu.AddDisabledItem(new GUIContent("Fix Analyze Rule"));
- IList<int> selectedIds = GetSelection();
- if (selectedIds.Count == 1)
- {
- AnalyzeRuleContainerTreeViewItem analyzeRuleContainer = FindItem(selectedIds[0], rootItem) as AnalyzeRuleContainerTreeViewItem;
- if (analyzeRuleContainer != null)
- {
- foreach (var customMenuItem in analyzeRuleContainer.analyzeRule.GetCustomContextMenuItems())
- {
- if(customMenuItem.MenuEnabled)
- menu.AddItem(new GUIContent(customMenuItem.MenuName), customMenuItem.ToggledOn, () => customMenuItem.MenuAction());
- else
- menu.AddDisabledItem(new GUIContent(customMenuItem.MenuName));
- }
- }
- }
- menu.ShowAsContext();
- Repaint();
- }
- else
- {
- var selectedIds = this.GetSelection();
- List<AnalyzeResultsTreeViewItem> items = new List<AnalyzeResultsTreeViewItem>();
- foreach (int id in selectedIds)
- {
- var item = FindItem(id, rootItem) as AnalyzeResultsTreeViewItem;
- if (item != null)
- items.Add(item);
- }
-
- if (items.Count > 0)
- AnalyzeResultsTreeViewItem.ContextClicked(items);
- }
-
- }
- protected override void DoubleClickedItem(int id)
- {
- var item = FindItem(id, rootItem) as AnalyzeResultsTreeViewItem;
- if (item != null)
- item.DoubleClicked();
- }
- protected override TreeViewItem BuildRoot()
- {
- m_CurrentDepth = 0;
- var root = new TreeViewItem(-1, -1);
- root.children = new List<TreeViewItem>();
- string baseName = "Analyze Rules";
- string fixableRules = "Fixable Rules";
- string unfixableRules = "Unfixable Rules";
- AnalyzeSystem.TreeView = this;
- AnalyzeRuleContainerTreeViewItem baseViewItem = new AnalyzeRuleContainerTreeViewItem(baseName.GetHashCode(), m_CurrentDepth, baseName);
- baseViewItem.children = new List<TreeViewItem>();
- baseViewItem.analyzeRule.CanFix = true;
- root.AddChild(baseViewItem);
- m_CurrentDepth++;
- var fixable = new AnalyzeRuleContainerTreeViewItem(fixableRules.GetHashCode(), m_CurrentDepth, fixableRules);
- var unfixable = new AnalyzeRuleContainerTreeViewItem(unfixableRules.GetHashCode(), m_CurrentDepth, unfixableRules);
- fixable.analyzeRule.CanFix = true;
- unfixable.analyzeRule.CanFix = false;
- baseViewItem.AddChild(fixable);
- baseViewItem.AddChild(unfixable);
- m_CurrentDepth++;
- for (int i = 0; i < AnalyzeSystem.Rules.Count; i++)
- {
- AnalyzeRuleContainerTreeViewItem ruleContainer = new AnalyzeRuleContainerTreeViewItem(
- AnalyzeSystem.Rules[i].ruleName.GetHashCode(), m_CurrentDepth, AnalyzeSystem.Rules[i]);
- if (ruleContainer.analyzeRule.CanFix)
- fixable.AddChild(ruleContainer);
- else
- unfixable.AddChild(ruleContainer);
- }
- m_CurrentDepth++;
- int index = 0;
- var ruleContainers = GatherAllInheritRuleContainers(baseViewItem);
- foreach (var ruleContainer in ruleContainers)
- {
- if(ruleContainer == null)
- continue;
- EditorUtility.DisplayProgressBar("Calculating Analyze Results...", ruleContainer.displayName, (index / (float)ruleContainers.Count));
- if (AnalyzeSystem.AnalyzeData.Data.ContainsKey(ruleContainer.analyzeRule.ruleName))
- BuildResults(ruleContainer, AnalyzeSystem.AnalyzeData.Data[ruleContainer.analyzeRule.ruleName]);
- index++;
- }
- EditorUtility.ClearProgressBar();
- return root;
- }
- private readonly Dictionary<int, AnalyzeResultsTreeViewItem> hashToAnalyzeResults = new Dictionary<int, AnalyzeResultsTreeViewItem>();
- void BuildResults(TreeViewItem root, List<AnalyzeRule.AnalyzeResult> ruleResults)
- {
- hashToAnalyzeResults.Clear();
- int updateFrequency = Mathf.Max(ruleResults.Count / 10, 1);
- for (int index=0; index < ruleResults.Count; ++index)
- {
- var result = ruleResults[index];
- if (index == 0 || index % updateFrequency == 0)
- EditorUtility.DisplayProgressBar("Building Results Tree...", result.resultName, (float)index / hashToAnalyzeResults.Keys.Count);
-
- var resPath = result.resultName.Split(AnalyzeRule.kDelimiter);
- string name = string.Empty;
- TreeViewItem parent = root;
-
- for (int i = 0; i < resPath.Length; i++)
- {
- name += resPath[i];
- int hash = name.GetHashCode();
- if (!hashToAnalyzeResults.ContainsKey(hash))
- {
- AnalyzeResultsTreeViewItem item = new AnalyzeResultsTreeViewItem(hash, i + m_CurrentDepth, resPath[i], result.severity, result);
- hashToAnalyzeResults.Add(item.id, item);
- parent.AddChild(item);
- parent = item;
- }
- else
- {
- var targetItem = hashToAnalyzeResults[hash];
- targetItem.results.Add(result);
- parent = targetItem;
- }
- }
- }
- EditorUtility.ClearProgressBar();
- List<TreeViewItem> allTreeViewItems = new List<TreeViewItem>();
- allTreeViewItems.Add(root);
- allTreeViewItems.AddRange(root.children);
- foreach (var node in allTreeViewItems)
- (node as AnalyzeTreeViewItemBase)?.AddIssueCountToName();
- AnalyzeSystem.SerializeData();
- }
- protected override void RowGUI(RowGUIArgs args)
- {
- var item = args.item as AnalyzeResultsTreeViewItem;
- if (item != null && item.severity != MessageType.None)
- {
- Texture2D icon = null;
- switch (item.severity)
- {
- case MessageType.Info:
- icon = GetInfoIcon();
- break;
- case MessageType.Warning:
- icon = GetWarningIcon();
- break;
- case MessageType.Error:
- icon = GetErrorIcon();
- break;
- }
- UnityEngine.GUI.Label(
- new Rect(args.rowRect.x + baseIndent, args.rowRect.y, args.rowRect.width - baseIndent,
- args.rowRect.height), new GUIContent(icon, string.Empty));
- }
- base.RowGUI(args);
- }
- Texture2D m_ErrorIcon;
- Texture2D m_WarningIcon;
- Texture2D m_InfoIcon;
- Texture2D GetErrorIcon()
- {
- if (m_ErrorIcon == null)
- FindMessageIcons();
- return m_ErrorIcon;
- }
- Texture2D GetWarningIcon()
- {
- if (m_WarningIcon == null)
- FindMessageIcons();
- return m_WarningIcon;
- }
- Texture2D GetInfoIcon()
- {
- if (m_InfoIcon == null)
- FindMessageIcons();
- return m_InfoIcon;
- }
- void FindMessageIcons()
- {
- m_ErrorIcon = EditorGUIUtility.FindTexture("console.errorIcon");
- m_WarningIcon = EditorGUIUtility.FindTexture("console.warnicon");
- m_InfoIcon = EditorGUIUtility.FindTexture("console.infoIcon");
- }
- }
- class AnalyzeTreeViewItemBase : TreeViewItem
- {
- private string baseDisplayName;
- private string currentDisplayName;
- public override string displayName
- {
- get { return currentDisplayName; }
- set { baseDisplayName = value; }
- }
- public AnalyzeTreeViewItemBase(int id, int depth, string displayName) : base(id, depth,
- displayName)
- {
- currentDisplayName = baseDisplayName = displayName;
- }
- public int AddIssueCountToName()
- {
- int issueCount = 0;
- if (children != null)
- {
- foreach (var child in children)
- {
- var analyzeNode = child as AnalyzeResultsTreeViewItem;
- if (analyzeNode != null)
- issueCount += analyzeNode.AddIssueCountToName();
- }
- }
- if (issueCount == 0)
- return 1;
- currentDisplayName = baseDisplayName + " (" + issueCount + ")";
- return issueCount;
- }
- }
- class AnalyzeResultsTreeViewItem : AnalyzeTreeViewItemBase
- {
- public MessageType severity { get; set; }
- public HashSet<AnalyzeRule.AnalyzeResult> results { get; }
- public bool IsError
- {
- get { return !displayName.Contains("No issues found"); }
- }
- public AnalyzeResultsTreeViewItem(int id, int depth, string displayName, MessageType type)
- : base(id, depth, displayName)
- {
- severity = type;
- results = new HashSet<AnalyzeRule.AnalyzeResult>();
- }
-
- public AnalyzeResultsTreeViewItem(int id, int depth, string displayName, MessageType type, AnalyzeRule.AnalyzeResult analyzeResult)
- : base(id, depth, displayName)
- {
- severity = type;
- results = new HashSet<AnalyzeRule.AnalyzeResult>() {analyzeResult};
- }
- internal static void ContextClicked(List<AnalyzeResultsTreeViewItem> items)
- {
- HashSet<UnityEngine.Object> objects = new HashSet<Object>();
-
- foreach (AnalyzeResultsTreeViewItem viewItem in items)
- {
- foreach (var itemResult in viewItem.results)
- {
- Object o = GetResultObject(itemResult.resultName);
- if (o != null)
- objects.Add(o);
- }
- }
- if (objects.Count > 0)
- {
- GenericMenu menu = new GenericMenu();
- menu.AddItem(new GUIContent(objects.Count > 0 ? "Select Assets" : "Select Asset"), false, () =>
- {
- Selection.objects = objects.ToArray();
- foreach (Object o in objects)
- EditorGUIUtility.PingObject(o);
- });
- menu.ShowAsContext();
- }
- }
- static UnityEngine.Object GetResultObject(string resultName)
- {
- int li = resultName.LastIndexOf(AnalyzeRule.kDelimiter);
- if (li >= 0)
- {
- string assetPath = resultName.Substring(li + 1);
- string guid = AssetDatabase.AssetPathToGUID(assetPath);
- if (!string.IsNullOrEmpty(guid))
- return AssetDatabase.LoadMainAssetAtPath(assetPath);
- }
- return null;
- }
- internal void DoubleClicked()
- {
- HashSet<UnityEngine.Object> objects = new HashSet<Object>();
- foreach (var itemResult in results)
- {
- Object o = GetResultObject(itemResult.resultName);
- if (o != null)
- objects.Add(o);
- }
- if (objects.Count > 0)
- {
- Selection.objects = objects.ToArray();
- foreach (Object o in objects)
- EditorGUIUtility.PingObject(o);
- }
- }
- }
- class AnalyzeRuleContainerTreeViewItem : AnalyzeTreeViewItemBase
- {
- internal AnalyzeRule analyzeRule;
- public AnalyzeRuleContainerTreeViewItem(int id, int depth, AnalyzeRule rule) : base(id, depth, rule.ruleName)
- {
- analyzeRule = rule;
- children = new List<TreeViewItem>();
- }
- public AnalyzeRuleContainerTreeViewItem(int id, int depth, string displayName) : base(id, depth, displayName)
- {
- analyzeRule = new AnalyzeRule();
- children = new List<TreeViewItem>();
- }
- }
- }
|