Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System.Collections.Generic;
- using UnityEngine;
- using UnityEditor;
- using System.Reflection;
- using System.Text;
- namespace B83.UnityEditorTools.MDDebugger
- {
- public class AnalysedObject
- {
- public static HashSet<object> m_ObjectSet = new HashSet<object>();
- public AnalysedObject parent = null;
- public FieldInfo fieldInfo;
- public object obj;
- public System.Type type;
- public List<DelegateMember> members = new List<DelegateMember>();
- public List<AnalysedObject> children = new List<AnalysedObject>();
- public AnalysedObject(object aObj, AnalysedObject aParent = null, FieldInfo aFieldInfo = null)
- {
- obj = aObj;
- parent = aParent;
- fieldInfo = aFieldInfo;
- }
- public bool Analyse(BindingFlags aFlags)
- {
- type = obj.GetType();
- if (m_ObjectSet.Contains(obj))
- return false;
- else
- m_ObjectSet.Add(obj);
- var fields = type.GetFields(aFlags);
- bool hasContent = false;
- foreach (var field in fields)
- {
- if (typeof(System.Delegate).IsAssignableFrom(field.FieldType))
- {
- var dm = new DelegateMember(this, field);
- members.Add(dm);
- hasContent = true;
- }
- else if (field.FieldType.IsClass)
- {
- var val = field.GetValue(obj);
- if (val == null)
- continue;
- var tmp = new AnalysedObject(val, this, field);
- if (tmp.Analyse(aFlags))
- {
- hasContent = true;
- children.Add(tmp);
- }
- }
- }
- return hasContent;
- }
- public void Draw()
- {
- GUILayout.BeginHorizontal();
- GUILayout.Space(20);
- GUILayout.BeginVertical();
- GUILayout.BeginHorizontal();
- if (fieldInfo != null && fieldInfo.IsStatic)
- GUILayout.Label("static field: " + fieldInfo.Name);
- else if (fieldInfo != null)
- GUILayout.Label("field: " + fieldInfo.Name);
- GUILayout.Label(" type: " + TypeName.FixGenericTypeNames(type));
- if (typeof(MonoBehaviour).IsAssignableFrom(type))
- GUILayout.Label(" : MonoBehaviour");
- if (obj != null && obj is UnityEngine.Object uObj)
- EditorGUILayout.ObjectField(uObj, uObj.GetType(), true);
- GUILayout.FlexibleSpace();
- GUILayout.EndHorizontal();
- foreach (var d in members)
- {
- d.DrawReferences();
- }
- GUILayout.BeginVertical("box");
- foreach (var ch in children)
- {
- ch.Draw();
- }
- GUILayout.EndVertical();
- GUILayout.EndVertical();
- GUILayout.EndHorizontal();
- }
- }
- public class DelegateMember
- {
- public AnalysedObject parent;
- public FieldInfo fieldInfo;
- public List<MethodReference> references = new List<MethodReference>();
- public DelegateMember(AnalysedObject aParent, FieldInfo aFieldInfo)
- {
- parent = aParent;
- fieldInfo = aFieldInfo;
- if (parent.obj == null)
- return;
- var obj = (System.Delegate)fieldInfo.GetValue(parent.obj);
- if (obj == null)
- return;
- var list = obj.GetInvocationList();
- foreach(var d in list)
- {
- references.Add(new MethodReference {
- methodInfo = d.Method,
- obj = d.Target
- });
- }
- }
- public void DrawReferences()
- {
- GUILayout.BeginHorizontal();
- GUILayout.Space(20);
- GUILayout.BeginVertical();
- GUILayout.BeginHorizontal();
- if (fieldInfo.IsStatic)
- GUILayout.Label("static field: " + fieldInfo.Name);
- else
- GUILayout.Label("field: " + fieldInfo.Name);
- GUILayout.Label(" type: " + TypeName.FixGenericTypeNames(fieldInfo.FieldType));
- GUILayout.FlexibleSpace();
- GUILayout.EndHorizontal();
- foreach (var r in references)
- {
- GUILayout.BeginHorizontal();
- GUILayout.Space(20);
- GUILayout.Label("ref: " + r.methodInfo.Name+" @ " + TypeName.FixGenericTypeNames(r.methodInfo.ReflectedType));
- if (r.obj != null && r.obj is UnityEngine.Object target)
- EditorGUILayout.ObjectField(target, target.GetType(), true);
- GUILayout.FlexibleSpace();
- GUILayout.EndHorizontal();
- }
- GUILayout.EndVertical();
- GUILayout.EndHorizontal();
- }
- }
- public class MethodReference
- {
- public MemberInfo methodInfo;
- public object obj = null;
- }
- public class TypeName
- {
- public static void GenericTypeArguments(System.Type aType, StringBuilder aSB)
- {
- var name = aType.Name;
- if (!aType.IsGenericType)
- {
- aSB.Append(name);
- return;
- }
- name = name.Substring(0, aType.Name.IndexOf('`'));
- aSB.Append(name).Append("<");
- foreach (var p in aType.GenericTypeArguments)
- {
- GenericTypeArguments(p, aSB);
- }
- aSB.Append(">");
- }
- public static string FixGenericTypeNames(System.Type aType)
- {
- var sb = new StringBuilder();
- GenericTypeArguments(aType, sb);
- return sb.ToString();
- }
- }
- public class MulticastDelegateDebugger : EditorWindow
- {
- BindingFlags m_BindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
- List<AnalysedObject> m_Objs = new List<AnalysedObject>();
- Vector2 scrollPos;
- [MenuItem("Tools/B83/MulticastDelegateDebugger")]
- public static void Init()
- {
- GetWindow<MulticastDelegateDebugger>();
- }
- private void OnEnable()
- {
- titleContent = new GUIContent("MD Debugger");
- UpdateView();
- EditorApplication.playModeStateChanged += OnPlaymodeChanged;
- }
- private void OnDisable()
- {
- EditorApplication.playModeStateChanged -= OnPlaymodeChanged;
- }
- private void OnPlaymodeChanged(PlayModeStateChange aState)
- {
- UpdateView();
- }
- private void OnSelectionChange()
- {
- UpdateView();
- }
- private void UpdateView()
- {
- Analyse(Selection.gameObjects);
- Repaint();
- }
- void Analyse(GameObject[] aObjs)
- {
- m_Objs.Clear();
- AnalysedObject.m_ObjectSet.Clear();
- if (aObjs == null || aObjs.Length == 0)
- return;
- foreach (var go in aObjs)
- {
- foreach (var mb in go.GetComponents<MonoBehaviour>())
- {
- if (mb == null)
- continue;
- var analysedObject = new AnalysedObject(mb);
- if (analysedObject.Analyse(m_BindingFlags))
- m_Objs.Add(analysedObject);
- }
- }
- }
- void BindFlagsButton(string aName, BindingFlags aFlag)
- {
- bool active = (m_BindingFlags & aFlag) != 0;
- if (GUILayout.Toggle(active, aName, "Button"))
- m_BindingFlags |= aFlag;
- else
- m_BindingFlags &= ~aFlag;
- }
- void DrawBindingFlagSelection()
- {
- var oldFlags = m_BindingFlags;
- GUILayout.BeginHorizontal();
- BindFlagsButton("public", BindingFlags.Public);
- BindFlagsButton("private", BindingFlags.NonPublic);
- BindFlagsButton("instance", BindingFlags.Instance);
- BindFlagsButton("static", BindingFlags.Static);
- GUILayout.EndHorizontal();
- if (oldFlags != m_BindingFlags)
- UpdateView();
- }
- void OnGUI()
- {
- DrawBindingFlagSelection();
- scrollPos = GUILayout.BeginScrollView(scrollPos);
- foreach(var o in m_Objs)
- {
- GUILayout.BeginVertical("box");
- o.Draw();
- GUILayout.EndVertical();
- }
- GUILayout.EndScrollView();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement