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;
            }
        }
Beispiel #2
0
        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;
        }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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);
        }