static void Parse(SystemHandle systemHandle, PlayerLoopSystemGraph graph, IPlayerLoopNode parent = null)
        {
            IPlayerLoopNode node;

            graph.AllSystems.Add(systemHandle);

            if (systemHandle.Managed != null && systemHandle.Managed is ComponentSystemGroup group)
            {
                var groupNode = Pool <ComponentGroupNode> .GetPooled();

                groupNode.Value = group;
                node            = groupNode;

                ref var updateSystemList = ref group.m_MasterUpdateList;
                for (int i = 0, count = updateSystemList.length; i < count; ++i)
                {
                    var updateIndex = updateSystemList[i];
                    if (updateIndex.IsManaged)
                    {
                        var child = group.Systems[updateIndex.Index];
                        Parse(child, graph, node);
                    }
                    else
                    {
                        var child = group.UnmanagedSystems[updateIndex.Index];
                        Parse(new SystemHandle(child, group.World), graph, node);
                    }
                }
            }
        static bool DidChange(IPlayerLoopNode lhs, IPlayerLoopNode rhs)
        {
            if (lhs.Parent?.Hash != rhs.Parent?.Hash)
            {
                return(true);
            }

            if (lhs.Children.Count != rhs.Children.Count)
            {
                return(true);
            }

            if (lhs.Hash != rhs.Hash)
            {
                return(true);
            }

            for (var i = 0; i < lhs.Children.Count; ++i)
            {
                if (DidChange(lhs.Children[i], rhs.Children[i]))
                {
                    return(true);
                }
            }

            return(false);
        }
        public static SystemTreeViewItem Acquire(PlayerLoopSystemGraph graph, IPlayerLoopNode node, SystemTreeViewItem parent, World world)
        {
            var item = Pool.Acquire();

            item.World  = world;
            item.Graph  = graph;
            item.Node   = node;
            item.parent = parent;

            return(item);
        }
 static void AddToGraph(PlayerLoopSystemGraph graph, IPlayerLoopNode node, IPlayerLoopNode parent = null)
 {
     if (null == parent)
     {
         graph.Roots.Add(node);
     }
     else
     {
         node.Parent = parent;
         parent.Children.Add(node);
     }
 }
        static void Parse(ComponentSystemBase system, PlayerLoopSystemGraph graph, IPlayerLoopNode parent = null)
        {
            IPlayerLoopNode node;

            graph.AllSystems.Add(system);

            switch (system)
            {
            case ComponentSystemGroup group:
                var groupNode = Pool <ComponentGroupNode> .GetPooled();

                groupNode.Value = group;
                node            = groupNode;
                foreach (var s in group.Systems)
                {
                    Parse(s, graph, node);
                }
                break;

            default:
                var systemNode = Pool <ComponentSystemBaseNode> .GetPooled();

                systemNode.Value = system;
                node             = systemNode;

                var recorder    = Recorder.Get($"{system.World?.Name ?? "none"} {system.GetType().FullName}");
                var recorderKey = new RecorderKey
                {
                    World  = system.World,
                    Group  = (ComponentSystemGroup)((ComponentGroupNode)parent).System,
                    System = system
                };

                if (!graph.RecordersBySystem.ContainsKey(recorderKey))
                {
                    graph.RecordersBySystem.Add(recorderKey, new AverageRecorder(recorder));
                }
                else
                {
                    UnityEngine.Debug.LogError("System added twice: " + system);
                }

                recorder.enabled = true;
                break;
            }

            AddToGraph(graph, node, parent);
        }
        static void Parse(PlayerLoopSystem playerLoopSystem, PlayerLoopSystemGraph graph, IPlayerLoopNode parent = null)
        {
            // The integration of `ComponentSystemBase` into the player loop is done through a wrapper type.
            // If the target of the player loop system is the wrapper type, we will parse this as a `ComponentSystemBase`.
            if (null != playerLoopSystem.updateDelegate && playerLoopSystem.updateDelegate.Target is SystemWrapper wrapper)
            {
                Parse(wrapper.System, graph, parent);
                return;
            }

            // Add the player loop system to the graph if it is not the root one.
            if (null != playerLoopSystem.type)
            {
                var playerLoopSystemNode = Pool <PlayerLoopSystemNode> .GetPooled();

                playerLoopSystemNode.Value = playerLoopSystem;
                var node = playerLoopSystemNode;
                AddToGraph(graph, node, parent);
                parent = node;
            }

            if (null == playerLoopSystem.subSystemList)
            {
                return;
            }

            foreach (var subSystem in playerLoopSystem.subSystemList)
            {
                Parse(subSystem, graph, parent);
            }
        }
        public static SystemTreeViewItem GetSystemTreeViewItem(PlayerLoopSystemGraph graph, IPlayerLoopNode node, SystemTreeViewItem parent, World world)
        {
            var item = Pool <SystemTreeViewItem> .GetPooled(LifetimePolicy.Permanent);

            item.World  = world;
            item.Graph  = graph;
            item.Node   = node;
            item.parent = parent;
            return(item);
        }