private void QueueHierarchy(
            [NotNull] CrawlItem parent,
            [NotNull] Queue <CrawlItem> queue,
            [CanBeNull] object v,
            [NotNull] CrawlSettings crawlSettings)
        {
            var go = v as GameObject;

            if (go == null)
            {
                return;
            }

            var components = go.GetComponents <Component>();

            foreach (var c in components)
            {
                if (ReferenceEquals(c, null))
                {
                    continue;
                }

                QueueValue(parent, queue, c, c.GetType().GetDisplayName(), crawlSettings);
            }

            var t = go.transform;

            for (int i = 0; i < t.childCount; ++i)
            {
                var childGo = t.GetChild(i).gameObject;
                QueueValue(parent, queue, childGo, childGo.name, crawlSettings);
            }
        }
        private static void DisplayCollectProgressBar([NotNull] CrawlSettings crawlSettings)
        {
#if UNITY_EDITOR
            EditorUtility.DisplayProgressBar("Heap Snapshot", "Collecting: " + crawlSettings.Caption + "...",
                                             crawlSettings.StartProgress);
#endif
        }
        private void QueueArrayElements(
            [NotNull] CrawlItem parent,
            [NotNull] Queue <CrawlItem> queue,
            [CanBeNull] object array,
            [NotNull] CrawlSettings crawlSettings)
        {
            if (array == null)
            {
                return;
            }

            if (!array.GetType().IsArray)
            {
                return;
            }

            var elementType = array.GetType().GetElementType();

            if (elementType == null)
            {
                return;
            }

            int index = 0;

            foreach (var arrayItem in (Array)array)
            {
                QueueValue(parent, queue, arrayItem, $"[{index}]", crawlSettings);
                index++;
            }
        }
        private void CrawlRoot([NotNull] CrawlItem root, [NotNull] CrawlSettings crawlSettings)
        {
            var queue = new Queue <CrawlItem>();

            queue.Enqueue(root);

            while (queue.Count > 0)
            {
                var next     = queue.Dequeue();
                var type     = next.Object.GetType();
                var typeData = TypeData.Get(type);

                if (type.IsArray)
                {
                    QueueArrayElements(next, queue, next.Object, crawlSettings);
                }
                if (type == typeof(GameObject))
                {
                    QueueHierarchy(next, queue, next.Object, crawlSettings);
                }
                if (typeData.DynamicSizedFields != null)
                {
                    foreach (var field in typeData.DynamicSizedFields)
                    {
                        var v = field.GetValue(next.Object);
                        QueueValue(next, queue, v, field.Name, crawlSettings);
                    }
                }
            }

            root.UpdateSize(SizeMode);
        }
        private int CrawlRoots([NotNull] CrawlSettings crawlSettings)
        {
            if (rootsQueue.Count <= 0)
            {
                return(0);
            }

            int processedRoots = 0;
            int totalSize      = 0;
            var roots          = new List <CrawlItem>();

            while (rootsQueue.Count > 0)
            {
                var r = rootsQueue.Dequeue();
                localRootsQueue.Enqueue(r);

                while (localRootsQueue.Count > 0)
                {
#if UNITY_EDITOR
                    if (processedRoots % 10 == 0)
                    {
                        int   remainingRoots = rootsQueue.Count + localRootsQueue.Count;
                        int   totalRoots     = remainingRoots + processedRoots;
                        float progress       = Mathf.Lerp(
                            crawlSettings.StartProgress,
                            crawlSettings.EndProgress,
                            1f * processedRoots / totalRoots
                            );
                        EditorUtility.DisplayProgressBar("Heap Snapshot", "Crawling: " + crawlSettings.Caption + "...", progress);
                    }
#endif
                    var root = localRootsQueue.Dequeue();
                    CrawlRoot(root);
                    totalSize += root.TotalSize;
                    root.Cleanup(crawlSettings);
                    processedRoots++;

                    if (root.TotalSize >= crawlSettings.MinItemSize)
                    {
                        roots.Add(root);
                    }
                }
            }

            roots.Sort();
            using (var output = new StreamWriter(outputDir + crawlSettings.Filename))
            {
                foreach (var root in roots)
                {
                    root.Print(output, sizeFormat);
                }
            }

            return(totalSize);
        }
        public CrawlSettings AddRootsGroup(
            [NotNull] string filename,
            [NotNull] string caption,
            CrawlOrder order,
            params object[] roots)
        {
            var crawlSettings = new CrawlSettings(filename, caption, () => CollectRoots(roots), order);

            crawlOrder.Add(crawlSettings);
            return(crawlSettings);
        }
        public CrawlSettings AddUnityRootsGroup <T>(
            [NotNull] string filename,
            [NotNull] string caption,
            CrawlOrder order)
        {
            var crawlSettings = new CrawlSettings(filename, caption, () => CollectUnityObjects(typeof(T)), order)
            {
                IncludeAllUnityTypes = true
            };

            crawlOrder.Add(crawlSettings);
            return(crawlSettings);
        }
        public HeapSnapshotCollector()
        {
            UserRootsSettings         = CrawlSettings.CreateUserRoots(CollectUserRoots);
            StaticFieldsSettings      = CrawlSettings.CreateStaticFields(CollectStaticFields);
            HierarchySettings         = CrawlSettings.CreateHierarchy(CollectRootHierarchyGameObjects);
            ScriptableObjectsSettings = CrawlSettings.CreateScriptableObjects(() => CollectUnityObjects(typeof(ScriptableObject)));
            PrefabsSettings           = CrawlSettings.CreatePrefabs(CollectPrefabs);
            UnityObjectsSettings      = CrawlSettings.CreateUnityObjects(() => CollectUnityObjects(typeof(Object)));

            forbiddenTypes.Add(typeof(TypeData));
            forbiddenTypes.Add(typeof(TypeStats));
            forbiddenTypes.Add(typeof(SnapshotHistory));
        }
        private void QueueValue(
            [NotNull] CrawlItem parent,
            [NotNull] Queue <CrawlItem> queue,
            [CanBeNull] object v,
            [NotNull] string name,
            [NotNull] CrawlSettings crawlSettings)
        {
            if (v == null)
            {
                return;
            }

            if (IsForbidden(v))
            {
                return;
            }

            TypeStats.RegisterInstance(parent, name, v);
            if (visitedObjects.Contains(v))
            {
                return;
            }

            if (unityObjects.Contains(v) && !crawlSettings.IsUnityTypeAllowed(v.GetType()))
            {
                return;
            }

            if (IsRoot(v))
            {
                var rootName = parent.Object.GetType().GetDisplayName() + '.' + name;
                EnqueueRoot(v, rootName, true);
                return;
            }

            visitedObjects.Add(v);
            var item = new CrawlItem(parent, v, name);

            queue.Enqueue(item);
            parent.AddChild(item);
        }
Esempio n. 10
0
        public void Cleanup(CrawlSettings crawlSettings)
        {
            if (!crawlSettings.PrintChildren)
            {
                Children = null;
            }

            if (crawlSettings.MaxDepth > 0 && depth >= crawlSettings.MaxDepth)
            {
                Children = null;
            }

            // check for destroyed objects
            var unityObject = Object as UnityEngine.Object;

            if (!ReferenceEquals(unityObject, null) && !unityObject)
            {
                const string destroyedObjectString = "(destroyed Unity Object)";
                if (string.IsNullOrWhiteSpace(Name))
                {
                    Name = destroyedObjectString;
                }
                else
                {
                    Name = Name + " " + destroyedObjectString;
                }

                Children = null;
            }

            if (Children == null)
            {
                return;
            }

            if (crawlSettings.PrintOnlyGameObjects)
            {
                Children.RemoveAll(c => !(c.Object is GameObject));
            }

            int fullChildrenCount = Children.Count;

            if (crawlSettings.MinItemSize > 0)
            {
                Children.RemoveAll(c => c.TotalSize < crawlSettings.MinItemSize);
            }
            if (crawlSettings.MaxChildren > 0 && Children.Count > crawlSettings.MaxChildren)
            {
                Children.RemoveRange(crawlSettings.MaxChildren, Children.Count - crawlSettings.MaxChildren);
            }

            if (Children.Count < fullChildrenCount)
            {
                childrenFiltered = true;
            }

            depth++;
            foreach (var child in Children)
            {
                child.Cleanup(crawlSettings);
            }
            depth--;
        }
Esempio n. 11
0
 public void Cleanup(CrawlSettings crawlSettings)
 {
     CleanupUnchanged();
     CleanupInternal(crawlSettings);
 }