C#反射的实践纪录
問題來源:unity profiler?只能看,不能導出數據報表,想實現此功能,怎么辦?
由于它是用C#寫的,因此,反射大法。
一,使用什么工具,反編譯它的代碼到C#,經實踐,ILSPY即可。
二,想實現一個功能:在CPU usage分析模式下,當在搜索框中輸入搜索字符串時,有一個事件:searchChanged,如何將自己的函數注冊給這個事件,代碼如下:
?
其中,treeView是ProfilerFrameDataTreeView類型,類的反編譯代碼如下:
using System; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.CompilerServices; using UnityEditor; using UnityEditor.IMGUI.Controls; using UnityEditor.Profiling; using UnityEditorInternal.Profiling; using UnityEngine; using UnityEngine.Assertions;namespace UnityEditorInternal {internal class ProfilerFrameDataTreeView : TreeView{private class ExpandedMarkerIdHierarchy{public Dictionary<int, ProfilerFrameDataTreeView.ExpandedMarkerIdHierarchy> expandedMarkers;}public delegate void SelectionChangedCallback(int id);public delegate void SearchChangedCallback(string newSearch);private class FrameDataTreeViewItem : TreeViewItem{private HierarchyFrameDataView m_FrameDataView;private bool m_Initialized;private string[] m_StringProperties;private string m_ResolvedCallstack;public string[] columnStrings{get{return this.m_StringProperties;}}public string resolvedCallstack{get{bool flag = this.m_ResolvedCallstack == null;if (flag){this.m_ResolvedCallstack = this.m_FrameDataView.ResolveItemCallstack(this.id);}return this.m_ResolvedCallstack;}}public int samplesCount{get{return this.m_FrameDataView.GetItemMergedSamplesCount(this.id);}}public FrameDataTreeViewItem(HierarchyFrameDataView frameDataView, int id, int depth, TreeViewItem parent) : base(id, depth, parent, null){this.m_FrameDataView = frameDataView;this.m_Initialized = false;}internal void Init(HierarchyFrameDataView frameDataView, int id, int depth, TreeViewItem parent){this.id = id;this.depth = depth;this.parent = parent;this.displayName = null;this.m_FrameDataView = frameDataView;this.m_Initialized = false;}public void Init(ProfilerFrameDataMultiColumnHeader.Column[] columns, IProfilerSampleNameProvider profilerSampleNameProvider){bool initialized = this.m_Initialized;if (!initialized){this.m_StringProperties = new string[columns.Length];for (int i = 0; i < columns.Length; i++){int profilerColumn = columns[i].profilerColumn;bool flag = columns[i].profilerColumn == 0;string text;if (flag){text = profilerSampleNameProvider.GetItemName(this.m_FrameDataView, this.id);this.displayName = text;}else{text = this.m_FrameDataView.GetItemColumnData(this.id, columns[i].profilerColumn);}this.m_StringProperties[i] = text;}this.m_Initialized = true;}}}private struct TreeTraversalState{public ProfilerFrameDataTreeView.FrameDataTreeViewItem item;public ProfilerFrameDataTreeView.ExpandedMarkerIdHierarchy expandedHierarchy;}public static readonly GUIContent kFrameTooltip = EditorGUIUtility.TrTextContent("", "Press 'F' to frame selection", null);private const int kMaxPooledRowsCount = 1000000;private readonly List<TreeViewItem> m_Rows = new List<TreeViewItem>(1000);private ProfilerFrameDataMultiColumnHeader m_MultiColumnHeader;private HierarchyFrameDataView m_FrameDataView;private List<int> m_SelectedItemMarkerIdPath;private string m_LegacySelectedItemMarkerNamePath;[NonSerialized]protected IProfilerSampleNameProvider m_ProfilerSampleNameProvider;[NonSerialized]private ProfilerFrameDataTreeView.ExpandedMarkerIdHierarchy m_ExpandedMarkersHierarchy;[NonSerialized]private List<TreeViewItem> m_RowsPool = new List<TreeViewItem>();[NonSerialized]private Stack<List<TreeViewItem>> m_ChildrenPool = new Stack<List<TreeViewItem>>();[NonSerialized]private LinkedList<ProfilerFrameDataTreeView.TreeTraversalState> m_ReusableVisitList = new LinkedList<ProfilerFrameDataTreeView.TreeTraversalState>();[NonSerialized]private List<int> m_ReusableChildrenIds = new List<int>(1024);[NonSerialized]private Stack<LinkedListNode<ProfilerFrameDataTreeView.TreeTraversalState>> m_TreeTraversalStatePool = new Stack<LinkedListNode<ProfilerFrameDataTreeView.TreeTraversalState>>();[method: CompilerGenerated][DebuggerBrowsable(DebuggerBrowsableState.Never), CompilerGenerated]public event ProfilerFrameDataTreeView.SelectionChangedCallback selectionChanged;[method: CompilerGenerated][DebuggerBrowsable(DebuggerBrowsableState.Never), CompilerGenerated]public event ProfilerFrameDataTreeView.SearchChangedCallback searchChanged;public int sortedProfilerColumn{get{return this.m_MultiColumnHeader.sortedProfilerColumn;}}public bool sortedProfilerColumnAscending{get{return this.m_MultiColumnHeader.sortedProfilerColumnAscending;}}public ProfilerFrameDataTreeView(TreeViewState state, ProfilerFrameDataMultiColumnHeader multicolumnHeader, IProfilerSampleNameProvider profilerSampleNameProvider) : base(state, multicolumnHeader){Assert.IsNotNull<ProfilerFrameDataMultiColumnHeader>(multicolumnHeader);base.deselectOnUnhandledMouseDown = true;this.m_ProfilerSampleNameProvider = profilerSampleNameProvider;this.m_MultiColumnHeader = multicolumnHeader;this.m_MultiColumnHeader.sortingChanged += new MultiColumnHeader.HeaderCallback(this.OnSortingChanged);}public void SetFrameDataView(HierarchyFrameDataView frameDataView){bool flag = !object.Equals(this.m_FrameDataView, frameDataView);bool flag2 = frameDataView != null && frameDataView.valid && (frameDataView.sortColumn != this.m_MultiColumnHeader.sortedProfilerColumn || frameDataView.sortColumnAscending != this.m_MultiColumnHeader.sortedProfilerColumnAscending);bool flag3 = flag;if (flag3){this.StoreExpandedState();this.StoreSelectedState();}this.m_FrameDataView = frameDataView;bool flag4 = flag2;if (flag4){this.m_FrameDataView.Sort(this.m_MultiColumnHeader.sortedProfilerColumn, this.m_MultiColumnHeader.sortedProfilerColumnAscending);}bool flag5 = flag | flag2;if (flag5){base.Reload();}}private void AddExpandedChildrenRecursively(TreeViewItem item, ProfilerFrameDataTreeView.ExpandedMarkerIdHierarchy expandedHierarchy){bool flag = item.children == null;if (!flag){for (int i = 0; i < item.children.Count; i++){TreeViewItem treeViewItem = item.children[i];bool flag2 = treeViewItem.children != null && treeViewItem.children[0] != null;if (flag2){ProfilerFrameDataTreeView.ExpandedMarkerIdHierarchy expandedMarkerIdHierarchy = new ProfilerFrameDataTreeView.ExpandedMarkerIdHierarchy();bool flag3 = expandedHierarchy.expandedMarkers == null;if (flag3){expandedHierarchy.expandedMarkers = new Dictionary<int, ProfilerFrameDataTreeView.ExpandedMarkerIdHierarchy>();}try{expandedHierarchy.expandedMarkers.Add(this.m_FrameDataView.GetItemMarkerID(treeViewItem.id), expandedMarkerIdHierarchy);}catch (ArgumentException){}this.AddExpandedChildrenRecursively(treeViewItem, expandedMarkerIdHierarchy);}}}}private void StoreExpandedState(){bool flag = this.m_ExpandedMarkersHierarchy != null;if (!flag){bool flag2 = this.m_FrameDataView == null || !this.m_FrameDataView.valid;if (!flag2){this.m_ExpandedMarkersHierarchy = new ProfilerFrameDataTreeView.ExpandedMarkerIdHierarchy();this.AddExpandedChildrenRecursively(base.rootItem, this.m_ExpandedMarkersHierarchy);}}}public void SetSelectionFromLegacyPropertyPath(string selectedPropertyPath){bool flag = this.m_SelectedItemMarkerIdPath != null && this.PropertyPathMatchesSelectedIDs(selectedPropertyPath, base.state.selectedIDs);if (!flag){this.m_LegacySelectedItemMarkerNamePath = selectedPropertyPath;this.m_SelectedItemMarkerIdPath = null;}}private bool PropertyPathMatchesSelectedIDs(string legacyPropertyPath, List<int> selectedIDs){bool flag = this.m_FrameDataView == null || !this.m_FrameDataView.valid;bool result;if (flag){result = false;}else{bool flag2 = string.IsNullOrEmpty(legacyPropertyPath) || selectedIDs == null || selectedIDs.Count == 0;if (flag2){result = (string.IsNullOrEmpty(legacyPropertyPath) && (selectedIDs == null || selectedIDs.Count == 0));}else{result = (this.m_FrameDataView.GetItemPath(selectedIDs[0]) == legacyPropertyPath);}}return result;}private void StoreSelectedState(){bool flag = this.m_SelectedItemMarkerIdPath != null || this.m_LegacySelectedItemMarkerNamePath != null;if (!flag){bool flag2 = this.m_FrameDataView == null || !this.m_FrameDataView.valid;if (!flag2){IList<int> selection = base.GetSelection();bool flag3 = selection.Count == 0;if (!flag3){this.m_FrameDataView.GetItemMarkerIDPath(selection[0], this.m_SelectedItemMarkerIdPath);}}}}private void MigrateExpandedState(List<int> newExpandedIds){bool flag = newExpandedIds == null;if (!flag){base.state.expandedIDs = newExpandedIds;}}private void MigrateSelectedState(bool expandIfNecessary){bool flag = this.m_SelectedItemMarkerIdPath == null && this.m_LegacySelectedItemMarkerNamePath == null;if (!flag){int num = this.m_FrameDataView.GetRootItemID();bool flag2 = true;bool flag3 = this.m_SelectedItemMarkerIdPath != null;if (flag3){foreach (int current in this.m_SelectedItemMarkerIdPath){bool flag4 = this.m_FrameDataView.HasItemChildren(num);if (flag4){this.m_FrameDataView.GetItemChildren(num, this.m_ReusableChildrenIds);foreach (int current2 in this.m_ReusableChildrenIds){bool flag5 = current == this.m_FrameDataView.GetItemMarkerID(current2);if (flag5){bool flag6 = !base.IsExpanded(num);if (flag6){flag2 = false;}num = current2;break;}}}bool flag7 = num == 0;if (flag7){break;}}}else{bool flag8 = this.m_LegacySelectedItemMarkerNamePath != null;if (flag8){List<int> list = new List<int>();string[] array = this.m_LegacySelectedItemMarkerNamePath.Split(new char[]{'/'});string[] array2 = array;for (int i = 0; i < array2.Length; i++){string a = array2[i];bool flag9 = this.m_FrameDataView.HasItemChildren(num);if (flag9){this.m_FrameDataView.GetItemChildren(num, this.m_ReusableChildrenIds);foreach (int current3 in this.m_ReusableChildrenIds){bool flag10 = a == this.m_FrameDataView.GetItemName(current3);if (flag10){bool flag11 = !base.IsExpanded(num);if (flag11){flag2 = false;}num = current3;list.Add(this.m_FrameDataView.GetItemMarkerID(current3));break;}}}bool flag12 = num == 0;if (flag12){break;}}this.m_SelectedItemMarkerIdPath = list;this.m_LegacySelectedItemMarkerNamePath = null;}}List<int> arg_24B_0;if (num != 0){(arg_24B_0 = new List<int>()).Add(num);}else{arg_24B_0 = new List<int>();}List<int> selectedIDs = arg_24B_0;base.state.selectedIDs = selectedIDs;bool flag13 = ProfilerDriver.enabled && (ProfilerDriver.profileEditor || EditorApplication.isPlaying);bool flag14 = !flag13;bool flag15 = ((num != 0 && base.isInitialized) & flag14) && (flag2 | expandIfNecessary);if (flag15){base.FrameItem(num);}}}public IList<int> GetSelectedInstanceIds(){bool flag = this.m_FrameDataView == null || !this.m_FrameDataView.valid;IList<int> result;if (flag){result = null;}else{IList<int> selection = base.GetSelection();bool flag2 = selection == null || selection.Count == 0;if (flag2){result = null;}else{List<int> list = new List<int>();List<int> list2 = new List<int>();foreach (int current in selection){this.m_FrameDataView.GetItemMergedSamplesInstanceID(current, list2);list.AddRange(list2);}result = list;}}return result;}public void Clear(){bool flag = this.m_FrameDataView == null;if (!flag){this.m_FrameDataView.Dispose();this.m_FrameDataView = null;this.m_RowsPool.Clear();this.m_ChildrenPool.Clear();this.m_ReusableVisitList.Clear();this.m_ReusableChildrenIds.Clear();this.m_TreeTraversalStatePool.Clear();base.Reload();}}protected override TreeViewItem BuildRoot(){int id = (this.m_FrameDataView != null) ? this.m_FrameDataView.GetRootItemID() : 0;return new ProfilerFrameDataTreeView.FrameDataTreeViewItem(this.m_FrameDataView, id, -1, null);}protected override IList<TreeViewItem> BuildRows(TreeViewItem root){bool flag = this.m_RowsPool.Count < 1000000;if (flag){this.m_RowsPool.AddRange(this.m_Rows);}this.m_Rows.Clear();bool flag2 = this.m_FrameDataView == null || !this.m_FrameDataView.valid;IList<TreeViewItem> rows;if (flag2){rows = this.m_Rows;}else{List<int> newExpandedIds = (this.m_ExpandedMarkersHierarchy == null) ? null : new List<int>(base.state.expandedIDs.Count);bool flag3 = !string.IsNullOrEmpty(base.searchString);if (flag3){this.Search(root, base.searchString, this.m_Rows);}else{this.AddAllChildren((ProfilerFrameDataTreeView.FrameDataTreeViewItem)root, this.m_ExpandedMarkersHierarchy, this.m_Rows, newExpandedIds);}this.MigrateExpandedState(newExpandedIds);this.MigrateSelectedState(false);rows = this.m_Rows;}return rows;}private void Search(TreeViewItem searchFromThis, string search, List<TreeViewItem> result){bool flag = searchFromThis == null;if (flag){throw new ArgumentException("Invalid searchFromThis: cannot be null", "searchFromThis");}bool flag2 = string.IsNullOrEmpty(search);if (flag2){throw new ArgumentException("Invalid search: cannot be null or empty", "search");}Stack<int> stack = new Stack<int>();this.m_FrameDataView.GetItemChildren(searchFromThis.id, this.m_ReusableChildrenIds);foreach (int current in this.m_ReusableChildrenIds){stack.Push(current);}while (stack.Count > 0){int num = stack.Pop();string itemName = this.m_ProfilerSampleNameProvider.GetItemName(this.m_FrameDataView, num);bool flag3 = itemName.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0;if (flag3){ProfilerFrameDataTreeView.FrameDataTreeViewItem frameDataTreeViewItem = this.AcquireFrameDataTreeViewItem(this.m_FrameDataView, num, 0, searchFromThis);searchFromThis.AddChild(frameDataTreeViewItem);result.Add(frameDataTreeViewItem);}this.m_FrameDataView.GetItemChildren(num, this.m_ReusableChildrenIds);foreach (int current2 in this.m_ReusableChildrenIds){stack.Push(current2);}}}private LinkedListNode<ProfilerFrameDataTreeView.TreeTraversalState> AcquireTreeTraversalStateNode(ProfilerFrameDataTreeView.FrameDataTreeViewItem item, ProfilerFrameDataTreeView.ExpandedMarkerIdHierarchy expandedHierarchy){bool flag = this.m_TreeTraversalStatePool.Count == 0;LinkedListNode<ProfilerFrameDataTreeView.TreeTraversalState> result;if (flag){result = new LinkedListNode<ProfilerFrameDataTreeView.TreeTraversalState>(new ProfilerFrameDataTreeView.TreeTraversalState{item = item,expandedHierarchy = expandedHierarchy});}else{LinkedListNode<ProfilerFrameDataTreeView.TreeTraversalState> linkedListNode = this.m_TreeTraversalStatePool.Pop();linkedListNode.Value = new ProfilerFrameDataTreeView.TreeTraversalState{item = item,expandedHierarchy = expandedHierarchy};result = linkedListNode;}return result;}private ProfilerFrameDataTreeView.FrameDataTreeViewItem AcquireFrameDataTreeViewItem(HierarchyFrameDataView frameDataView, int id, int depth, TreeViewItem parent){bool flag = this.m_RowsPool.Count > 0;ProfilerFrameDataTreeView.FrameDataTreeViewItem result;if (flag){ProfilerFrameDataTreeView.FrameDataTreeViewItem frameDataTreeViewItem = (ProfilerFrameDataTreeView.FrameDataTreeViewItem)this.m_RowsPool[this.m_RowsPool.Count - 1];this.m_RowsPool.RemoveAt(this.m_RowsPool.Count - 1);frameDataTreeViewItem.Init(this.m_FrameDataView, id, depth, parent);bool flag2 = frameDataTreeViewItem.children != null;if (flag2){this.m_ChildrenPool.Push(frameDataTreeViewItem.children);frameDataTreeViewItem.children = null;}result = frameDataTreeViewItem;}else{result = new ProfilerFrameDataTreeView.FrameDataTreeViewItem(this.m_FrameDataView, id, depth, parent);}return result;}private void AddAllChildren(ProfilerFrameDataTreeView.FrameDataTreeViewItem parent, ProfilerFrameDataTreeView.ExpandedMarkerIdHierarchy parentExpandedHierararchy, IList<TreeViewItem> newRows, List<int> newExpandedIds){this.m_ReusableVisitList.AddFirst(this.AcquireTreeTraversalStateNode(parent, parentExpandedHierararchy));while (this.m_ReusableVisitList.First != null){ProfilerFrameDataTreeView.TreeTraversalState value = this.m_ReusableVisitList.First.Value;this.m_TreeTraversalStatePool.Push(this.m_ReusableVisitList.First);this.m_ReusableVisitList.RemoveFirst();bool flag = value.item.depth != -1;if (flag){newRows.Add(value.item);}this.m_FrameDataView.GetItemChildren(value.item.id, this.m_ReusableChildrenIds);int count = this.m_ReusableChildrenIds.Count;bool flag2 = count == 0;if (!flag2){bool flag3 = value.item.depth != -1;if (flag3){bool flag4 = this.m_ExpandedMarkersHierarchy == null;bool flag5;if (flag4){flag5 = base.IsExpanded(value.item.id);}else{flag5 = (value.expandedHierarchy != null);}bool flag6 = !flag5;if (flag6){bool flag7 = value.item.children == null;if (flag7){value.item.children = TreeView.CreateChildListForCollapsedParent();}continue;}bool flag8 = newExpandedIds != null;if (flag8){newExpandedIds.Add(value.item.id);}}bool flag9 = value.item.children == null;if (flag9){bool flag10 = this.m_ChildrenPool.Count > 0;if (flag10){value.item.children = this.m_ChildrenPool.Pop();}else{value.item.children = new List<TreeViewItem>();}}value.item.children.Clear();value.item.children.Capacity = count;for (int i = 0; i < count; i++){ProfilerFrameDataTreeView.FrameDataTreeViewItem item = this.AcquireFrameDataTreeViewItem(this.m_FrameDataView, this.m_ReusableChildrenIds[i], value.item.depth + 1, value.item);value.item.children.Add(item);}LinkedListNode<ProfilerFrameDataTreeView.TreeTraversalState> linkedListNode = null;foreach (TreeViewItem current in value.item.children){int itemMarkerID = this.m_FrameDataView.GetItemMarkerID(current.id);ProfilerFrameDataTreeView.ExpandedMarkerIdHierarchy expandedHierarchy = null;bool flag11 = value.expandedHierarchy != null && value.expandedHierarchy.expandedMarkers != null;if (flag11){value.expandedHierarchy.expandedMarkers.TryGetValue(itemMarkerID, out expandedHierarchy);}LinkedListNode<ProfilerFrameDataTreeView.TreeTraversalState> linkedListNode2 = this.AcquireTreeTraversalStateNode((ProfilerFrameDataTreeView.FrameDataTreeViewItem)current, expandedHierarchy);bool flag12 = linkedListNode == null;if (flag12){this.m_ReusableVisitList.AddFirst(linkedListNode2);}else{this.m_ReusableVisitList.AddAfter(linkedListNode, linkedListNode2);}linkedListNode = linkedListNode2;}}}bool flag13 = newExpandedIds != null;if (flag13){newExpandedIds.Sort();}}protected override bool CanMultiSelect(TreeViewItem item){return false;}protected override void SelectionChanged(IList<int> selectedIds){bool flag = selectedIds.Count > 0;if (flag){this.m_SelectedItemMarkerIdPath = null;this.m_LegacySelectedItemMarkerNamePath = null;}int id = (selectedIds.Count > 0) ? selectedIds[0] : -1;bool flag2 = this.selectionChanged != null;if (flag2){this.selectionChanged(id);}}protected override void ExpandedStateChanged(){this.m_ExpandedMarkersHierarchy = null;}protected override void DoubleClickedItem(int id){}protected override void ContextClickedItem(int id){}protected override void ContextClicked(){}protected override void SearchChanged(string newSearch){bool flag = this.searchChanged != null;if (flag){this.searchChanged(newSearch);}}protected override IList<int> GetAncestors(int id){bool flag = this.m_FrameDataView == null || !this.m_FrameDataView.valid;IList<int> result;if (flag){result = new List<int>();}else{List<int> list = new List<int>();this.m_FrameDataView.GetItemAncestors(id, list);result = list;}return result;}protected override IList<int> GetDescendantsThatHaveChildren(int id){bool flag = this.m_FrameDataView == null || !this.m_FrameDataView.valid;IList<int> result;if (flag){result = new List<int>();}else{List<int> list = new List<int>();this.m_FrameDataView.GetItemDescendantsThatHaveChildren(id, list);result = list;}return result;}private void OnSortingChanged(MultiColumnHeader header){bool flag = this.m_FrameDataView == null || base.multiColumnHeader.sortedColumnIndex == -1;if (!flag){this.m_FrameDataView.Sort(this.m_MultiColumnHeader.sortedProfilerColumn, this.m_MultiColumnHeader.sortedProfilerColumnAscending);base.Reload();}}public override void OnGUI(Rect rect){bool flag = this.m_LegacySelectedItemMarkerNamePath != null;if (flag){this.MigrateSelectedState(true);}base.OnGUI(rect);}protected override void RowGUI(TreeView.RowGUIArgs args){bool flag = Event.get_current().get_rawType() != 7;if (!flag){ProfilerFrameDataTreeView.FrameDataTreeViewItem frameDataTreeViewItem = (ProfilerFrameDataTreeView.FrameDataTreeViewItem)args.item;frameDataTreeViewItem.Init(this.m_MultiColumnHeader.columns, this.m_ProfilerSampleNameProvider);for (int i = 0; i < args.GetNumVisibleColumns(); i++){Rect cellRect = args.GetCellRect(i);this.CellGUI(cellRect, frameDataTreeViewItem, i == 0, args.GetColumn(i), ref args);}bool flag2 = !args.selected;if (!flag2){bool flag3 = args.rowRect.Contains(Event.get_current().get_mousePosition());bool flag4 = !flag3;if (!flag4){bool hasSearch = base.hasSearch;if (hasSearch){GUIStyle.SetMouseTooltip(ProfilerFrameDataTreeView.kFrameTooltip.get_tooltip(), args.rowRect);}}}}}private void CellGUI(Rect cellRect, ProfilerFrameDataTreeView.FrameDataTreeViewItem item, bool needsIndent, int column, ref TreeView.RowGUIArgs args){if (needsIndent){float num = base.GetContentIndent(item) + base.extraSpaceBeforeIconAndLabel;cellRect.set_xMin(cellRect.get_xMin() + num);}base.CenterRectUsingSingleLineHeight(ref cellRect);GUIContent gUIContent = GUIContent.Temp(item.columnStrings[column], string.Empty);TreeView.DefaultStyles.label.Draw(cellRect, gUIContent, false, false, args.selected, args.focused);}} } View Code?
總結
- 上一篇: 关于游戏开发中时间性能统计工具本身ove
- 下一篇: 反射调用private或internal