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(); }
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); }