protected virtual void OnBuildTree(TreeViewItem root) { // int=typeIndex var groupLookup = new Dictionary <int, GroupItem>(); for (int n = 0, nend = m_Snapshot.managedObjects.Length; n < nend; ++n) { if (window.isClosing) // the window is closing { break; } var mo = m_Snapshot.managedObjects[n]; if (!OnCanAddObject(mo)) { continue; } GroupItem group; if (!groupLookup.TryGetValue(mo.managedTypesArrayIndex, out group)) { group = new GroupItem { id = m_UniqueId++, depth = 0, displayName = "" }; group.Initialize(m_Snapshot, m_Snapshot.managedTypes[mo.managedTypesArrayIndex]); groupLookup[mo.managedTypesArrayIndex] = group; root.AddChild(group); } var item = new ManagedObjectItem { id = m_UniqueId++, depth = group.depth + 1, displayName = "" }; item.Initialize(this, m_Snapshot, mo); group.AddChild(item); m_ManagedObjectCount++; m_ManagedObjectSize += item.size; } }
public TreeViewItem BuildTree(PackedMemorySnapshot snapshot) { m_Snapshot = snapshot; m_UniqueId = 1; var root = new TreeViewItem { id = 0, depth = -1, displayName = "Root" }; if (m_Snapshot == null) { root.AddChild(new TreeViewItem { id = 1, depth = -1, displayName = "" }); return(root); } // int=typeIndex var groupLookup = new Dictionary <int, GroupItem>(); for (int n = 0, nend = m_Snapshot.gcHandles.Length; n < nend; ++n) { var gcHandle = m_Snapshot.gcHandles[n]; var managedTypeIndex = -1; if (gcHandle.managedObjectsArrayIndex >= 0) { managedTypeIndex = m_Snapshot.managedObjects[gcHandle.managedObjectsArrayIndex].managedTypesArrayIndex; } var targetItem = root; if (managedTypeIndex >= 0) { GroupItem group; if (!groupLookup.TryGetValue(managedTypeIndex, out group)) { group = new GroupItem { id = m_UniqueId++, depth = 0, displayName = "" }; group.Initialize(m_Snapshot, managedTypeIndex); groupLookup[managedTypeIndex] = group; root.AddChild(group); } targetItem = group; } var item = new GCHandleItem { id = m_UniqueId++, depth = targetItem.depth + 1, displayName = "" }; item.Initialize(this, m_Snapshot, gcHandle.gcHandlesArrayIndex); targetItem.AddChild(item); } // remove groups if it contains one item only for (int n = root.children.Count - 1; n >= 0; --n) { var group = root.children[n]; if (group.hasChildren && group.children.Count == 1) { group.children[0].depth -= 1; root.AddChild(group.children[0]); root.children.RemoveAt(n); } } return(root); }
protected override void OnBuildTree(TreeViewItem root) { progress.value = 0; var lookup = new Dictionary <Hash128, AbstractItem>(); var memoryReader = new MemoryReader(m_Snapshot); for (int n = 0, nend = m_Snapshot.managedObjects.Length; n < nend; ++n) { if (window.isClosing) // the window is closing { break; } progress.value = (n + 1.0f) / nend; var obj = m_Snapshot.managedObjects[n]; if (obj.address == 0) { continue; } var type = m_Snapshot.managedTypes[obj.managedTypesArrayIndex]; if (type.isPrimitive && !type.isPointer) { continue; } if (type.isValueType) { continue; } var hash = memoryReader.ComputeObjectHash(obj.address, type); AbstractItem parent; if (!lookup.TryGetValue(hash, out parent)) { var group = new GroupItem() { id = m_UniqueId++, depth = root.depth + 1, displayName = "" }; group.Initialize(m_Snapshot, type); lookup[hash] = parent = group; root.AddChild(group); } var item = new ManagedObjectItem { id = m_UniqueId++, depth = parent.depth + 1, displayName = "" }; item.Initialize(this, m_Snapshot, obj); parent.AddChild(item); } if (root.hasChildren) { for (var n = root.children.Count - 1; n >= 0; --n) { if (!root.children[n].hasChildren) { root.children.RemoveAt(n); continue; } if (root.children[n].children.Count < 2) { root.children.RemoveAt(n); continue; } var item = root.children[n] as AbstractItem; m_ManagedObjectCount += item.count; m_ManagedObjectSize += item.size; } } progress.value = 1; }
protected override void OnBuildTree(TreeViewItem root) { progress.value = 0; var lookup = new Dictionary <string, AbstractItem>(); var memoryReader = new MemoryReader(m_Snapshot); for (int n = 0, nend = m_Snapshot.managedObjects.Length; n < nend; ++n) { progress.value = (n + 1.0f) / nend; var obj = m_Snapshot.managedObjects[n]; if (obj.address == 0) { continue; // points to null } if (obj.nativeObjectsArrayIndex != -1) { continue; // has a native object, thus can't be an empty shell object } var type = m_Snapshot.managedTypes[obj.managedTypesArrayIndex]; // Only UnityEngine.Object objects can have a m_CachedPtr connection to a native object. if (!type.isUnityEngineObject) { continue; } // Could be an array of an UnityEngine.Object, such as Texture[] if (type.isArray) { continue; } // Get type as a "higher level" representation that is easier to work with var richType = new RichManagedType(m_Snapshot, obj.managedTypesArrayIndex); // Try to get the m_InstanceID field (only exists in editor, not in built players) PackedManagedField packedField; if (richType.FindField("m_InstanceID", out packedField)) { // The editor contains various empty shell objects whose instanceID all contain 0. // I guess it's some kind of special object? In this case we just ignore them. var instanceID = memoryReader.ReadInt32(obj.address + (ulong)packedField.offset); if (instanceID == 0) { continue; } } // Check if we already have a grouping node for that type. // Create a new node if we don't have it. AbstractItem parent; if (!lookup.TryGetValue(type.name, out parent)) { var group = new GroupItem() { id = m_UniqueId++, depth = root.depth + 1, displayName = "" }; group.Initialize(m_Snapshot, type); lookup[type.name] = parent = group; root.AddChild(group); } // Create and add the managed object item var item = new ManagedObjectItem { id = m_UniqueId++, depth = parent.depth + 1, displayName = "" }; item.Initialize(this, m_Snapshot, obj); parent.AddChild(item); m_ManagedObjectCount++; m_ManagedObjectSize += item.size; } progress.value = 1; }
public TreeViewItem BuildDuplicatesTree(PackedMemorySnapshot snapshot, BuildArgs buildArgs) { m_Snapshot = snapshot; m_UniqueId = 1; m_NativeObjectsCount = 0; m_NativeObjectsSize = 0; var root = new TreeViewItem { id = 0, depth = -1, displayName = "Root" }; if (m_Snapshot == null) { root.AddChild(new TreeViewItem { id = 1, depth = -1, displayName = "" }); return(root); } var dupesLookup = new Dictionary <Hash128, List <int> >(); for (int n = 0, nend = m_Snapshot.nativeObjects.Length; n < nend; ++n) { var no = m_Snapshot.nativeObjects[n]; if (!no.isPersistent) { continue; } if (!buildArgs.CanAdd(no)) { continue; } if (no.nativeTypesArrayIndex == -1) { continue; } var nativeType = m_Snapshot.nativeTypes[no.nativeTypesArrayIndex]; if (nativeType.managedTypeArrayIndex == -1) { continue; } if (m_Snapshot.IsSubclassOf(m_Snapshot.managedTypes[nativeType.managedTypeArrayIndex], m_Snapshot.coreTypes.unityEngineComponent)) { continue; } if (m_Snapshot.IsSubclassOf(m_Snapshot.managedTypes[nativeType.managedTypeArrayIndex], m_Snapshot.coreTypes.unityEngineGameObject)) { continue; } var hash = new Hash128((uint)no.nativeTypesArrayIndex, (uint)no.size, (uint)no.name.GetHashCode(), 0); List <int> list; if (!dupesLookup.TryGetValue(hash, out list)) { dupesLookup[hash] = list = new List <int>(); } list.Add(n); } // int=typeIndex var groupLookup = new Dictionary <Hash128, GroupItem>(); foreach (var dupePair in dupesLookup) { for (int n = 0, nend = dupePair.Value.Count; n < nend; ++n) { var list = dupePair.Value; if (list.Count <= 1) { continue; } var no = m_Snapshot.nativeObjects[list[n]]; GroupItem group; if (!groupLookup.TryGetValue(dupePair.Key, out group)) { group = new GroupItem { id = m_UniqueId++, depth = root.depth + 1, displayName = no.name }; group.Initialize(m_Snapshot, no.nativeTypesArrayIndex); groupLookup[dupePair.Key] = group; root.AddChild(group); } var item = new NativeObjectItem { id = m_UniqueId++, depth = group.depth + 1, displayName = "" }; item.Initialize(this, no); m_NativeObjectsCount++; m_NativeObjectsSize += item.size; group.AddChild(item); } } SortItemsRecursive(root, OnSortItem); if (!root.hasChildren) { root.AddChild(new TreeViewItem { id = 1, depth = -1, displayName = "" }); } return(root); }
public TreeViewItem BuildTree(PackedMemorySnapshot snapshot, BuildArgs buildArgs) { m_Snapshot = snapshot; m_UniqueId = 1; m_NativeObjectsCount = 0; m_NativeObjectsSize = 0; var root = new TreeViewItem { id = 0, depth = -1, displayName = "Root" }; if (m_Snapshot == null) { root.AddChild(new TreeViewItem { id = 1, depth = -1, displayName = "" }); return(root); } // int=typeIndex var groupLookup = new Dictionary <long, GroupItem>(); for (int n = 0, nend = m_Snapshot.nativeObjects.Length; n < nend; ++n) { var no = m_Snapshot.nativeObjects[n]; if (!buildArgs.CanAdd(no)) { continue; } GroupItem group; if (!groupLookup.TryGetValue(no.nativeTypesArrayIndex, out group)) { group = new GroupItem { id = m_UniqueId++, depth = root.depth + 1, displayName = "" }; group.Initialize(m_Snapshot, no.nativeTypesArrayIndex); groupLookup[no.nativeTypesArrayIndex] = group; root.AddChild(group); } var typeNameOverride = ""; // Derived MonoBehaviour types appear just as MonoBehaviour on the native side. // This is not very informative. However, the actual name can be derived from the MonoScript of such MonoBehaviour instead. // The following tries to find the corresponding MonoScript and uses the MonoScript name instead. #region Add MonoBehaviour using name of MonoScript if (no.nativeTypesArrayIndex == m_Snapshot.coreTypes.nativeMonoBehaviour || no.nativeTypesArrayIndex == m_Snapshot.coreTypes.nativeScriptableObject) { string monoScriptName; var monoScriptIndex = m_Snapshot.FindNativeMonoScriptType(no.nativeObjectsArrayIndex, out monoScriptName); if (monoScriptIndex != -1 && monoScriptIndex < m_Snapshot.nativeTypes.Length) { typeNameOverride = monoScriptName; long key = (monoScriptName.GetHashCode() << 32) | monoScriptIndex; GroupItem group2; if (!groupLookup.TryGetValue(key, out group2)) { group2 = new GroupItem { id = m_UniqueId++, depth = group.depth + 1, //displayName = monoScriptName, typeNameOverride = monoScriptName, }; group2.Initialize(m_Snapshot, no.nativeTypesArrayIndex); groupLookup[key] = group2; group.AddChild(group2); } group = group2; } } #endregion var item = new NativeObjectItem { id = m_UniqueId++, depth = group.depth + 1, displayName = "", typeNameOverride = typeNameOverride }; item.Initialize(this, no); m_NativeObjectsCount++; m_NativeObjectsSize += item.size; group.AddChild(item); } // remove groups if it contains one item only if (root.hasChildren) { for (int n = root.children.Count - 1; n >= 0; --n) { var group = root.children[n]; if (group.children.Count == 1) { group.children[0].depth -= 1; root.AddChild(group.children[0]); root.children.RemoveAt(n); } } } SortItemsRecursive(root, OnSortItem); if (!root.hasChildren) { root.AddChild(new TreeViewItem { id = 1, depth = -1, displayName = "" }); } return(root); }