Пример #1
0
        HashSet <RunnableNode> FollowNode(Node currentNode, Node prevNode, RunnableNode lastRunnable, HashSet <Node> triedNodes, NodePath path)
        {
            // If this node has already been tried, it's path has already been followed - cancel this branch
            if (triedNodes.Contains(currentNode) && optimiseParallel)
            {
                if (recordNodePaths)
                {
                    checkinNodePaths.Add(path);
                }
                return(new HashSet <RunnableNode>());
            }

            /*if (triedNodes.Contains(currentNode) && optimiseParallel) {
             *  HashSet<RunnableNode> retNodes = new HashSet<RunnableNode>();
             *  retNodes.Add(lastRunnable);
             *  return retNodes;
             * }*/
            // Node has been encountered - trigger the event
            currentNode.OnEncountered(prevNode, _machine, this);
            // The current chain's HashSet of runnables to stop at
            HashSet <RunnableNode> runnables = new HashSet <RunnableNode>();

            runnables.Add(lastRunnable);
            // The HashSet of nodes to test next
            HashSet <Node> nextNodes = new HashSet <Node>();

            // Get nodes from the current node to test next
            // If not specified, default to link testing
            Node[] givenNextNodes = currentNode.NextNodes();
            if (givenNextNodes != null)
            {
                foreach (Node node in givenNextNodes)
                {
                    if (node == null)
                    {
                        Debug.LogError("Given null node to follow from " + currentNode + "!");
                    }
                    else
                    {
                        nextNodes.Add(node);
                    }
                }
            }
            else
            {
                // Get links from the current node to test next
                // Use node specified links if specified
                Link[] links = currentNode.NextLinks();
                if (links == null)
                {
                    links = _model.GetOutputLinks(currentNode).ToArray();
                }
                // Store the node in the loop checking HashSet if doing so
                if (optimiseParallel)
                {
                    triedNodes.Add(currentNode);
                }
                // If the current node is blocking, kill the chain
                if (currentNode.IsBlocking())
                {
                    if (recordNodePaths)
                    {
                        checkinNodePaths.Add(path);
                    }
                    return(runnables);
                }
                // Test connected links
                foreach (Link link in links)
                {
                    Node nextNode = _model.GetNodeFromID(link._to);
                    // Add the tested link to the current link chain for live preview
                    _currentLinks.Add(link);
                    nextNodes.Add(nextNode);
                }
            }
            currentNode.OnPassed(nextNodes, _machine, this);
            foreach (Node nextNode in nextNodes)
            {
                // Record next node as an entry in the path
                NodePath newPath = null;
                if (recordNodePaths)
                {
                    newPath             = new NodePath();
                    newPath.currentNode = nextNode;
                    newPath.fromPath    = path;
                    path.toPath         = newPath;
                }
                // If nextNode is an EndNode, kill the chain
                if (nextNode is EndNode)
                {
                    if (recordNodePaths)
                    {
                        checkinNodePaths.Add(newPath);
                    }
                    encounteredEnd = true;
                    return(new HashSet <RunnableNode>());
                }
                // If nextNode is a RunnableNode, store it as the next return point.
                // Otherwise continue with the last return point.
                RunnableNode makeLastRunnable = lastRunnable;
                if (nextNode is RunnableNode)
                {
                    makeLastRunnable = nextNode as RunnableNode;
                }
                // Set up new triedNodes listing
                HashSet <Node>         newTriedNodes = new HashSet <Node>(triedNodes);
                HashSet <RunnableNode> nextRunnables = FollowNode(nextNode, currentNode, makeLastRunnable, newTriedNodes, newPath);
                // If the model doesn't support parallel states, use first come first serve
                if (!_model.supportParallel)
                {
                    return(nextRunnables);
                }
                else
                {
                    runnables.Remove(lastRunnable);
                    foreach (RunnableNode runnable in nextRunnables)
                    {
                        runnables.Add(runnable);
                    }
                }
            }
            runnables.RemoveWhere(r => r == null);
            // Check if there are any runnables different from the last one given for this chain.
            bool runnableChange = false;

            foreach (RunnableNode runnable in runnables)
            {
                if (runnable != lastRunnable)
                {
                    runnableChange = true;
                    break;
                }
            }
            // If there is a change, remove the last runnable, otherwise maintain the chain.
            if (runnableChange)
            {
                runnables.Remove(lastRunnable);
            }
            if (recordNodePaths)
            {
                checkinNodePaths.Add(path);
            }
            return(runnables);
        }
Пример #2
0
        void OnGUI()
        {
            if (_model == null)
            {
                if (_selectedMachine == null)
                {
                    NodeMachineGUIUtils.DrawNothingOpenScreen(this);
                }
                else
                {
                    NodeMachineGUIUtils.DrawMachineNoModelScreen(this);
                }
                return;
            }

            Vector2 center = new Vector2(position.width / 2, position.height / 2) - (_nodeEditor.position / 2);

            _offset = _uncenteredOffset + center;

            titleContent = _changesMade ? NodeMachineEditor.titleUnsaved : NodeMachineEditor.titlePlain;

            bool livePreview = _selectedMachine != null && EditorApplication.isPlaying;

            bool modelNeedsSaving = false;

            _nodeEditor = new Rect(250, 30, position.width - 250, position.height - 30);
            _sideMenu   = new Rect(10, 20, 230, position.height - 20);
            _toolbar    = new Rect(260, 5, position.width - 260, 25);

            // ----- TOOLBAR --------

            GUILayout.BeginArea(_toolbar);
            GUILayout.BeginHorizontal();

            _drawTransparentLinks = GUILayout.Toggle(_drawTransparentLinks, " Link X-Ray", GUILayout.ExpandWidth(false));
            GUILayout.Label("  ", GUILayout.ExpandWidth(false));
            _showInivisibleNodes = GUILayout.Toggle(_showInivisibleNodes, " Reveal hidden nodes", GUILayout.ExpandWidth(false));
            GUILayout.Label("  ", GUILayout.ExpandWidth(false));

            GUILayout.EndHorizontal();
            GUILayout.EndArea();

            // ----- SIDE MENU ------

            GUILayout.BeginArea(_sideMenu);
            GUILayout.BeginVertical();

            EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);

            EditorGUILayout.LabelField(_model.name, EditorStyles.boldLabel);

            EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);

            EditorGUILayout.Space();

            float checkinTimeBeforeDraw     = _model.CheckinTime;
            bool  supportParallelBeforeDraw = _model.supportParallel;

            _model.CheckinTime     = EditorGUILayout.FloatField("Checkin time", _model.CheckinTime);
            _model.supportParallel = EditorGUILayout.Toggle("Parallel flow", _model.supportParallel);
            if (checkinTimeBeforeDraw != _model.CheckinTime || supportParallelBeforeDraw != _model.supportParallel)
            {
                modelNeedsSaving = true;
            }

            EditorGUILayout.Space();

            EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);

            EditorGUILayout.Space();

            _propertyMenu.DrawMenu(EditorApplication.isPlayingOrWillChangePlaymode, _selectedMachine);

            EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);

            // --------- ERRORS ---------

            EditorGUILayout.Space();

            _errorPanel.Draw();

            EditorGUILayout.Space();

            EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);

            GUILayout.EndVertical();
            GUILayout.EndArea();

            // ----- NODE EDITOR -----

            GUILayout.BeginArea(_nodeEditor, new GUIStyle("Box"));

            NodeMachineGUIUtils.DrawGrid(10, 0.2f, Color.gray, this); // * zoom
            NodeMachineGUIUtils.DrawGrid(50, 0.4f, Color.gray, this); // * zoom

            foreach (Link link in _model.GetLinks())
            {
                if (livePreview)
                {
                    NodeMachineGUIUtils.DrawLink(link, _selectedMachine.CurrentLinks.Contains(link), this);
                }
                else
                {
                    NodeMachineGUIUtils.DrawLink(link, false, this);
                }
            }

            if (_creatingLink)
            {
                Rect fromTransform = new Rect(_selectedNode.drawnTransform.position - _nodeEditor.position, _selectedNode.drawnTransform.size);
                NodeMachineGUIUtils.DrawArrow(fromTransform, Event.current.mousePosition, this);
            }

            foreach (Node node in _model.GetNodes())
            {
                if (livePreview && node is RunnableNode)
                {
                    RunnableNode runnable = node as RunnableNode;
                    if (_selectedMachine.CurrentRunnables.Contains(node))
                    {
                        if (NodeMachineGUIUtils.DrawNode(node, runnable.activeBackground, this, Event.current))
                        {
                            modelNeedsSaving = true;
                        }
                    }
                    else
                    {
                        if (NodeMachineGUIUtils.DrawNode(node, this, Event.current))
                        {
                            modelNeedsSaving = true;
                        }
                    }
                }
                else
                {
                    if (NodeMachineGUIUtils.DrawNode(node, this, Event.current))
                    {
                        modelNeedsSaving = true;
                    }
                }
            }

            // Draw transparent links over everything - looks like links are showing through from behind nodes
            if (_drawTransparentLinks)
            {
                foreach (Link link in _model.GetLinks())
                {
                    if (livePreview)
                    {
                        NodeMachineGUIUtils.DrawTransparentLink(link, _selectedMachine.CurrentLinks.Contains(link), this);
                    }
                    else
                    {
                        NodeMachineGUIUtils.DrawTransparentLink(link, false, this);
                    }
                }
            }

            GUILayout.EndArea();

            // --------------------- PROCESS EVENTS ----------------------------

            if (_nodeEditor.Contains(Event.current.mousePosition))
            {
                Vector2 totalOffset = _offset + _nodeEditor.position;
                foreach (Node node in _model.GetNodes().Reverse())
                {
                    if (node.visible || _showInivisibleNodes)
                    {
                        if (node.ProcessEvents(Event.current, _zoom, SelectNode, ProcessNodeContextMenu))
                        {
                            modelNeedsSaving = true;
                        }
                    }
                }
                foreach (Link link in _model.GetLinks())
                {
                    link.ProcessEvents(Event.current, totalOffset, ProcessLinkContextMenu, SelectLink);
                }
            }

            ProcessEvents(Event.current);

            if (modelNeedsSaving)
            {
                MarkUnsaved();
            }
            if (GUI.changed)
            {
                Repaint();
            }
        }