Exemplo n.º 1
0
        public override void OnProcess(Event e)
        {
            if (m_menu != null)
            {
                m_menu.ShowAsContext();
                m_menu = null;
            }

            if (e.IsMouseDown(MouseButton.Right) && e.IsMouseInsideRect(canvas.unscaledRect))
            {
                for (int i = 0; i < canvas.nodes.Length; i++)
                {
                    Node currentNode = canvas.nodes[i];

                    if (currentNode.isHidden)
                    {
                        continue;
                    }

                    if (currentNode.rect.Contains(canvas.mousePosition))
                    {
                        for (int j = 0; j < currentNode.ports.Length; j++)
                        {
                            if (currentNode.ports[j].rect.Contains(canvas.mousePosition))
                            {
                                return;
                            }
                        }

                        m_menu = new GenericMenu();

                        // save variables
                        Node            node        = currentNode;
                        AIController    controller  = graph.controller;
                        NodeRestoreData restoreData = Serializer.CreateNodeRestoreData(node);


                        // Add remove item if its not entry or any state.
                        // Else add disabled remove item.
                        if (node.IsEntryState() || node.IsAnyState())
                        {
                            m_menu.AddDisabledItem(new GUIContent("Delete"), false);
                        }
                        else
                        {
                            m_menu.AddItem(new GUIContent("Delete"), false, () => {
                                GraphUndo.RecordAndPerform("Delete node [" + node.name + "]",
                                                           () => { Serializer.RemoveNodeFromController(controller, node, false); },
                                                           () => { Serializer.RestoreNodeToController(controller, node, restoreData); });
                            });
                        }

                        // Add remove all connections item if the node has connections.
                        // Else add disabled remove all connections item.

                        // calculate connection count and save old connections.
                        int connectionsCount = 0;
                        Dictionary <ConnectionPort, ConnectionPort[]> oldConnections = new Dictionary <ConnectionPort, ConnectionPort[]> ();
                        foreach (ConnectionPort port in node.ports)
                        {
                            connectionsCount += port.connectionCount;
                            oldConnections.Add(port, port.connectedPorts);
                        }

                        string itemName = connectionsCount > 1 ? "Remove all connections" : "Remove connection";

                        if (connectionsCount == 0)
                        {
                            m_menu.AddDisabledItem(new GUIContent(itemName), false);
                        }
                        else
                        {
                            m_menu.AddItem(new GUIContent(itemName), false, () => {
                                GraphUndo.RecordAndPerform(itemName + " from node [" + node.name + "]",
                                                           () => { Serializer.DisconnectAllPorts(node); },
                                                           () => {
                                    foreach (ConnectionPort fromPort in oldConnections.Keys)
                                    {
                                        foreach (ConnectionPort toPort in oldConnections[fromPort])
                                        {
                                            Serializer.ConnectPorts(fromPort, toPort);
                                        }
                                    }
                                });
                            });
                        }

                        e.Use();
                    }
                }
            }
        }
        /// <summary>
        /// Remove the given node from the given controller.
        /// </summary>
        /// <param name="destroyImmediate">If it's set to true, the node and all of its scriptableObject-Assets will be removed immediate. A re-add </param>
        public static NodeRestoreData RemoveNodeFromController(AIController controller, Node node, bool destroyImmediate = false, bool autoSave = true)
        {
            NodeRestoreData nodeRestoreData = null;

            if (!destroyImmediate)
            {
                nodeRestoreData = CreateNodeRestoreData(node);
            }

            // unbind exposed parameters.
            foreach (ExposedParameter exposedParameter in controller.exposedParameters)
            {
                if (exposedParameter.ContainsBoundedNode(node))
                {
                    exposedParameter.Unbind(node);

                    #if SERIALIZER_DEBUG
                    Debug.Log("Unbind [" + node.name + " from the exposed parameter [" + exposedParameter.name + "]");
                    #endif
                }
            }

            // unbind node parameters.
            foreach (NodeParameter nodeParameter in controller.nodeParameters)
            {
                if (nodeParameter.ContainsBoundedNode(node))
                {
                    nodeParameter.Unbind(node);

                    #if SERIALIZER_DEBUG
                    Debug.Log("Unbind [" + node.name + " from the node parameter [" + nodeParameter.name + "]");
                    #endif
                }
            }

            // disconnect all ports
            Serializer.DisconnectAllPorts(node, false);

            // remove from controller.
            controller.RemoveNode(node);
            node.controller = null;

            #if SERIALIZER_DEBUG
            Debug.Log("Node [" + node.name + "] removed from the controller [" + controller.name + "]");
            #endif


            if (destroyImmediate)
            {
                foreach (ScriptableObject scriptableObject in node.GetScriptableObjects())
                {
                    if (scriptableObject != null)
                    {
                        #if SERIALIZER_DEBUG
                        Debug.Log(scriptableObject.GetType().Name + " [" + scriptableObject.name + "] destroyed");
                        #endif

                        Object.DestroyImmediate(scriptableObject, true);
                    }
                    else
                    {
                        #if SERIALIZER_DEBUG
                        Debug.Log(scriptableObject + " is null");
                        #endif

                        Object.DestroyImmediate(scriptableObject, true);
                    }
                }

                #if SERIALIZER_DEBUG
                Debug.Log("Node [" + node.name + "] destroyed");
                #endif

                Object.DestroyImmediate(node, true);

                Save();

                return(null);
            }

            if (autoSave)
            {
                Save();
            }

            controller.isDirty = true;

            return(nodeRestoreData);
        }
 /// <summary>
 /// Creates a restore data object of the given node.
 /// </summary>
 public static NodeRestoreData CreateNodeRestoreData(Node node)
 {
     return(NodeRestoreData.Create(node));
 }
        /// <summary>
        /// Add the given node to the given controller.
        /// Can only be used, if the node was already in the given controller.
        /// </summary>
        public static void RestoreNodeToController(AIController controller, Node node, NodeRestoreData nodeRestoreData, bool autoSave = true)
        {
            if (!node.IsSubAssetOf(controller))
            {
                Debug.LogError("The node [" + node.name + "] was never in the given controller [" + controller.name + "]");
                return;
            }

            foreach (ScriptableObject scriptableObject in node.GetScriptableObjects())
            {
                if (!scriptableObject.IsSubAssetOf(controller))
                {
                    Debug.LogError("The node [" + node.name + "] that should re-add has ScriptableObjects that are no sub assets of the given controller [" + controller.name + "]");
                    return;
                }
            }

            controller.AddNode(node);
            node.controller = controller;


            if (nodeRestoreData != null)
            {
                if (nodeRestoreData.restoredNode == node)
                {
                    #if SERIALIZER_DEBUG
                    Debug.Log("Restore exposed parameter");
                    #endif

                    foreach (NodeRestoreData.ExposedParameterRestoreData restoreData in nodeRestoreData.exposedParameters)
                    {
                        if (restoreData.parameterReference.type == restoreData.type)
                        {
                            restoreData.parameterReference.Bind(node, restoreData.parameterReference.type);
                        }
                        else
                        {
                            #if SERIALIZER_DEBUG
                            Debug.Log("The Exposed Parameter [" + restoreData.parameterReference.name + "] has now a different bound type now: [" + restoreData.parameterReference.type + "] before: [" + restoreData.type + "]");
                            #endif
                        }
                    }

                    #if SERIALIZER_DEBUG
                    Debug.Log("Restore node parameter");
                    #endif

                    foreach (NodeRestoreData.NodeParameterRestoreData restoreData in nodeRestoreData.nodeParameters)
                    {
                        if (restoreData.parameterReference.type == restoreData.type)
                        {
                            restoreData.parameterReference.Bind(node, restoreData.parameterReference.type);
                        }
                        else
                        {
                            #if SERIALIZER_DEBUG
                            Debug.Log("The Node Parameter [" + restoreData.parameterReference.name + "] has now a different bound type now: [" + restoreData.parameterReference.type + "] before: [" + restoreData.type + "]");
                            #endif
                        }
                    }

                    #if SERIALIZER_DEBUG
                    Debug.Log("Restore connections");
                    #endif

                    foreach (ConnectionPort fromPort in nodeRestoreData.ports)
                    {
                        ConnectionPort[] lastConnectedPorts = nodeRestoreData.GetConnectedPorts(fromPort);

                        foreach (ConnectionPort toPort in lastConnectedPorts)
                        {
                            ConnectPorts(fromPort, toPort, false);
                        }
                    }
                }
                else
                {
                    Debug.LogWarning("The given NodeRestoreData is not compatible with the given node [" + node.name + "]");
                }
            }

            #if SERIALIZER_DEBUG
            Debug.Log("Node [" + node.name + " added again to the given controller [" + controller.name + "]");
            #endif

            if (autoSave)
            {
                Save();
            }

            controller.isDirty = true;
        }