Example #1
0
 void OnEnable()
 {
     windowIcon         = EditorGUIUtility.Load("Assets/NodeMachine/Editor/Editor Resources/State Machine Icon.png") as Texture2D;
     titlePlain.image   = windowIcon;
     titleUnsaved.image = windowIcon;
     titleContent       = titlePlain;
     NodeMachineGUIUtils.Init();
     _propertyMenu           = new PropertyMenu(this);
     _errorPanel             = new ErrorPanel(this);
     Undo.undoRedoPerformed += OnUndoRedo;
     if (_model == null)
     {
         _model = AssetDatabase.LoadAssetAtPath(AssetDatabase.GetAssetPath(_modelInstanceID), typeof(NodeMachineModel)) as NodeMachineModel;
     }
     if (_model != null)
     {
         LoadModel(_model);
         if (_selectedLink != null)
         {
             _selectedLink = _model.GetLinkFromID(_selectedLink.ID);
         }
         if (_selectedNode != null)
         {
             _selectedNode = _model.GetNodeFromID(_selectedNode.ID);
         }
     }
     else
     {
         _selectedLink = null;
         _selectedNode = null;
     }
     FindNodeMenuHandlers();
 }
Example #2
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);
        }