Beispiel #1
0
        /// <summary>
        /// Creates a new NodeOutput in NodeBody of specified type
        /// </summary>
        public static NodeOutput Create(Node NodeBody, string OutputName, string OutputType)
        {
            NodeOutput output = CreateInstance <NodeOutput> ();

            output.body = NodeBody;
            output.name = OutputName;
            output.SetType(OutputType);
            NodeBody.Outputs.Add(output);
            return(output);
        }
Beispiel #2
0
        /// <summary>
        /// Creates a new NodeOutput in NodeBody of specified type
        /// </summary>
        public static NodeOutput Create(Node NodeBody, string OutputName, string OutputType)
        {
            NodeOutput output = CreateInstance <NodeOutput> ();

            output.body        = NodeBody;
            output.type        = OutputType;
            output.knobTexture = ConnectionTypes.GetTypeData(OutputType).OutputKnob;
            output.name        = OutputName;
            NodeBody.Outputs.Add(output);
            return(output);
        }
Beispiel #3
0
 /// <summary>
 /// A recursive function to clear all calculations depending on this node.
 /// Usually does not need to be called manually
 /// </summary>
 public static void ClearCalculation(Node node)
 {
     node.calculated = false;
     for (int outCnt = 0; outCnt < node.Outputs.Count; outCnt++)
     {
         NodeOutput output = node.Outputs [outCnt];
         for (int conCnt = 0; conCnt < output.connections.Count; conCnt++)
         {
             ClearCalculation(output.connections [conCnt].body);
         }
     }
 }
Beispiel #4
0
        /// <summary>
        /// Creates a new NodeOutput in NodeBody of specified type at the specified Node Side
        /// </summary>
        public static NodeOutput Create(Node nodeBody, string outputName, string outputType, NodeSide nodeSide, float sidePosition)
        {
            NodeOutput output = CreateInstance <NodeOutput> ();

            output.body         = nodeBody;
            output.name         = outputName;
            output.type         = outputType;
            output.side         = nodeSide;
            output.sidePosition = sidePosition;
            output.ReloadKnobTexture();
            nodeBody.Outputs.Add(output);
            return(output);
        }
Beispiel #5
0
        /// <summary>
        /// Removes the connection from this NodeInput
        /// </summary>
        public void RemoveConnection()
        {
            if (connection == null)
            {
                return;
            }

            NodeEditorCallbacks.IssueOnRemoveConnection(this);
            connection.connections.Remove(this);
            connection = null;

            NodeEditor.RecalculateFrom(body);
        }
Beispiel #6
0
        /// <summary>
        /// Removes the connection from this NodeInput
        /// </summary>
        public void RemoveConnection()
        {
            if (connection == null)
            {
                return;
            }

            NodeEditorCallbacks.IssueOnRemoveConnection(this);
            connection.connections.Remove(this);
            connection = null;

            NodeEditor.curNodeCanvas.OnNodeChange(body);
        }
Beispiel #7
0
 /// <summary>
 /// Draws the node curves; splitted from knobs because of the render order
 /// </summary>
 public void DrawConnections()
 {
     for (int outCnt = 0; outCnt < Outputs.Count; outCnt++)
     {
         NodeOutput output = Outputs [outCnt];
         for (int conCnt = 0; conCnt < output.connections.Count; conCnt++)
         {
             NodeEditor.DrawConnection(output.GetGUIKnob().center,
                                       output.connections [conCnt].GetGUIKnob().center,
                                       ConnectionTypes.GetTypeData(output.type).col);
         }
     }
 }
 public bool CanApplyConnection(NodeOutput output)
 {
     if ((UnityEngine.Object)output == (UnityEngine.Object)null || (UnityEngine.Object)body == (UnityEngine.Object)output.body || (UnityEngine.Object)connection == (UnityEngine.Object)output || !typeData.Type.IsAssignableFrom(output.typeData.Type))
     {
         return(false);
     }
     if (output.body.isChildOf(body) && !output.body.allowsLoopRecursion(body))
     {
         Debug.LogWarning("Cannot apply connection: Recursion detected!");
         return(false);
     }
     return(true);
 }
Beispiel #9
0
 /// <summary>
 /// Draws the node knobs; splitted from curves because of the render order
 /// </summary>
 protected internal virtual void DrawKnobs()
 {
     for (int outCnt = 0; outCnt < Outputs.Count; outCnt++)
     {
         NodeOutput output   = Outputs[outCnt];
         Rect       knobRect = output.GetGUIKnob();
         GUI.DrawTexture(knobRect, output.knobTexture);
     }
     for (int inCnt = 0; inCnt < Inputs.Count; inCnt++)
     {
         NodeInput input    = Inputs[inCnt];
         Rect      knobRect = input.GetGUIKnob();
         GUI.DrawTexture(knobRect, input.knobTexture);
     }
 }
Beispiel #10
0
 public void ClearCalculation()
 {
     if (!BeginRecursiveSearchLoop())
     {
         calculated = false;
         for (int i = 0; i < Outputs.Count; i++)
         {
             NodeOutput nodeOutput = Outputs[i];
             for (int j = 0; j < nodeOutput.connections.Count; j++)
             {
                 nodeOutput.connections[j].body.ClearCalculation();
             }
         }
         EndRecursiveSearchLoop();
     }
 }
Beispiel #11
0
        /// <summary>
        /// Applies a connection between output and input. 'CanApplyConnection' has to be checked before
        /// </summary>
        public static void ApplyConnection(NodeOutput output, NodeInput input)
        {
            if (input != null && output != null)
            {
                if (input.connection != null)
                {
                    input.connection.connections.Remove(input);
                }
                input.connection = output;
                output.connections.Add(input);

                NodeEditor.RecalculateFrom(input.body);

                NodeEditorCallbacks.IssueOnAddConnection(input);
            }
        }
Beispiel #12
0
        protected static void ReassignOutputType(ref NodeOutput output, Type newOutputType)
        {
            Node   body = output.body;
            string name = output.name;
            IEnumerable <NodeInput> enumerable = from connection in output.connections
                                                 where connection.typeData.Type.IsAssignableFrom(newOutputType)
                                                 select connection;

            output.Delete();
            NodeEditorCallbacks.IssueOnAddNodeKnob(NodeOutput.Create(body, name, newOutputType.AssemblyQualifiedName));
            output = body.Outputs[body.Outputs.Count - 1];
            foreach (NodeInput item in enumerable)
            {
                item.ApplyConnection(output);
            }
        }
Beispiel #13
0
 /// <summary>
 /// A recursive function to clear all calculations depending on this node.
 /// Usually does not need to be called manually
 /// </summary>
 public void ClearCalculation()
 {
     if (BeginRecursiveSearchLoop())
     {
         return;
     }
     calculated = false;
     for (int outCnt = 0; outCnt < Outputs.Count; outCnt++)
     {
         NodeOutput output = Outputs [outCnt];
         for (int conCnt = 0; conCnt < output.connections.Count; conCnt++)
         {
             output.connections [conCnt].body.ClearCalculation();
         }
     }
     EndRecursiveSearchLoop();
 }
Beispiel #14
0
        /// <summary>
        /// Reassigns the type of the given output. This actually recreates it
        /// </summary>
        protected static void ReassignOutputType(ref NodeOutput output, Type newOutputType)
        {
            Node   body       = output.body;
            string outputName = output.name;
            // Store all valid connections that are not affected by the type change
            IEnumerable <NodeInput> validConnections = output.connections.Where((NodeInput connection) => connection.typeData.Type.IsAssignableFrom(newOutputType));

            // Delete the output of the old type
            output.Delete();
            // Create Output with new type
            NodeEditorCallbacks.IssueOnAddNodeKnob(NodeOutput.Create(body, outputName, newOutputType.AssemblyQualifiedName));
            output = body.Outputs[body.Outputs.Count - 1];
            // Restore the valid connections
            foreach (NodeInput input in validConnections)
            {
                input.ApplyConnection(output);
            }
        }
Beispiel #15
0
 internal bool isInLoop()
 {
     if (BeginRecursiveSearchLoop())
     {
         return((UnityEngine.Object) this == (UnityEngine.Object)startRecursiveSearchNode);
     }
     for (int i = 0; i < Inputs.Count; i++)
     {
         NodeOutput connection = Inputs[i].connection;
         if ((UnityEngine.Object)connection != (UnityEngine.Object)null && connection.body.isInLoop())
         {
             StopRecursiveSearchLoop();
             return(true);
         }
     }
     EndRecursiveSearchLoop();
     return(false);
 }
Beispiel #16
0
 protected internal virtual void DrawConnections()
 {
     CheckNodeKnobMigration();
     if (Event.current.type == EventType.Repaint)
     {
         for (int i = 0; i < Outputs.Count; i++)
         {
             NodeOutput nodeOutput = Outputs[i];
             Vector2    center     = nodeOutput.GetGUIKnob().center;
             Vector2    direction  = nodeOutput.GetDirection();
             for (int j = 0; j < nodeOutput.connections.Count; j++)
             {
                 NodeInput nodeInput = nodeOutput.connections[j];
                 NodeEditorGUI.DrawConnection(center, direction, nodeInput.GetGUIKnob().center, nodeInput.GetDirection(), nodeOutput.typeData.Color);
             }
         }
     }
 }
Beispiel #17
0
 /// <summary>
 /// Recursively checks whether this node is in a loop
 /// </summary>
 internal bool isInLoop()
 {
     if (BeginRecursiveSearchLoop())
     {
         return(this == startRecursiveSearchNode);
     }
     foreach (NodeInput input in Inputs)
     {
         NodeOutput connection = input.connection;
         if (connection != null && connection.body.isInLoop())
         {
             StopRecursiveSearchLoop();
             return(true);
         }
     }
     EndRecursiveSearchLoop();
     return(false);
 }
Beispiel #18
0
 /// <summary>
 /// Recursively checks whether this node is in a loop
 /// </summary>
 internal bool isInLoop()
 {
     if (BeginRecursiveSearchLoop())
     {
         return(this == startRecursiveSearchNode);
     }
     for (int cnt = 0; cnt < Inputs.Count; cnt++)
     {
         NodeOutput connection = Inputs [cnt].connection;
         if (connection != null && connection.body.isInLoop())
         {
             StopRecursiveSearchLoop();
             return(true);
         }
     }
     EndRecursiveSearchLoop();
     return(false);
 }
Beispiel #19
0
        /// <summary>
        /// Check if the passed NodeOutput can be connected to this NodeInput
        /// </summary>
        public bool CanApplyConnection(NodeOutput output)
        {
            if (output == null || body == output.body || connection == output || typeData.Type != output.typeData.Type)
            {
                return(false);
            }

            if (output.body.isChildOf(body))
            {             // Recursive
                if (!output.body.allowsLoopRecursion(body))
                {
                    // TODO: Generic Notification
                    Debug.LogWarning("Cannot apply connection: Recursion detected!");
                    return(false);
                }
            }
            return(true);
        }
Beispiel #20
0
        protected static void ReassignInputType(ref NodeInput input, Type newInputType)
        {
            Node       body       = input.body;
            string     name       = input.name;
            NodeOutput nodeOutput = null;

            if ((UnityEngine.Object)input.connection != (UnityEngine.Object)null && newInputType.IsAssignableFrom(input.connection.typeData.Type))
            {
                nodeOutput = input.connection;
            }
            input.Delete();
            NodeEditorCallbacks.IssueOnAddNodeKnob(NodeInput.Create(body, name, newInputType.AssemblyQualifiedName));
            input = body.Inputs[body.Inputs.Count - 1];
            if ((UnityEngine.Object)nodeOutput != (UnityEngine.Object)null)
            {
                input.ApplyConnection(nodeOutput);
            }
        }
Beispiel #21
0
        /// <summary>
        /// Draws the node curves; splitted from knobs because of the render order
        /// </summary>
        protected internal virtual void DrawConnections()
        {
            for (int outCnt = 0; outCnt < Outputs.Count; outCnt++)
            {
                NodeOutput output   = Outputs [outCnt];
                Vector2    startPos = output.GetGUIKnob().center;
                Vector2    startDir = output.GetDirection();

                for (int conCnt = 0; conCnt < output.connections.Count; conCnt++)
                {
                    NodeInput input = output.connections [conCnt];
                    NodeEditorGUI.DrawConnection(startPos,
                                                 startDir,
                                                 input.GetGUIKnob().center,
                                                 input.GetDirection(),
                                                 ConnectionTypes.GetTypeData(output.type).col);
                }
            }
        }
Beispiel #22
0
        /// <summary>
        /// Check if the passed NodeOutput can be connected to this NodeInput
        /// </summary>
        public bool CanApplyConnection(NodeOutput output)
        {
            if (output == null || body == output.body || connection == output || !typeData.Type.IsAssignableFrom(output.typeData.Type))
            {
//				Debug.LogError ("Cannot assign " + typeData.Type.ToString () + " to " + output.typeData.Type.ToString ());
                return(false);
            }

            if (output.body.isChildOf(body))
            {             // Recursive
                if (!output.body.allowsLoopRecursion(body))
                {
                    // TODO: Generic Notification
                    Debug.LogWarning("Cannot apply connection: Recursion detected!");
                    return(false);
                }
            }
            return(true);
        }
Beispiel #23
0
        /// <summary>
        /// Create the a Node of the type specified by the nodeID at position
        /// Auto-connects the passed connectingOutput if not null to the first compatible input
        /// </summary>
        public static Node Create(string nodeID, Vector2 position, NodeOutput connectingOutput)
        {
            if (!NodeCanvasManager.CheckCanvasCompability(nodeID, NodeEditor.curNodeCanvas))
            {
                throw new UnityException("Cannot create Node with ID '" + nodeID + "' as it is not compatible with the current canavs type (" + NodeEditor.curNodeCanvas.GetType().ToString() + ")!");
            }
            if (!NodeEditor.curNodeCanvas.CanAddNode(nodeID))
            {
                throw new UnityException("Cannot create another Node with ID '" + nodeID + "' on the current canvas of type (" + NodeEditor.curNodeCanvas.GetType().ToString() + ")!");
            }
            Node node = NodeTypes.getDefaultNode(nodeID);

            if (node == null)
            {
                throw new UnityException("Cannot create Node as ID '" + nodeID + "' is not registered!");
            }

            node = node.Create(position);

            if (node == null)
            {
                return(null);
            }

            node.InitBase();

            if (connectingOutput != null)
            {             // Handle auto-connection and link the output to the first compatible input
                foreach (NodeInput input in node.Inputs)
                {
                    if (input.TryApplyConnection(connectingOutput))
                    {
                        break;
                    }
                }
            }

            NodeEditorCallbacks.IssueOnAddNode(node);
            NodeEditor.curNodeCanvas.Validate();

            return(node);
        }
Beispiel #24
0
        /// <summary>
        /// Applies a connection between the passed NodeOutput and this NodeInput. 'CanApplyConnection' has to be checked before to avoid interferences!
        /// </summary>
        public void ApplyConnection(NodeOutput output)
        {
            if (output == null)
            {
                return;
            }

            if (connection != null)
            {
                NodeEditorCallbacks.IssueOnRemoveConnection(this);
                connection.connections.Remove(this);
            }
            connection = output;
            output.connections.Add(this);

            NodeEditor.RecalculateFrom(body);
            output.body.OnAddOutputConnection(output);
            body.OnAddInputConnection(this);
            NodeEditorCallbacks.IssueOnAddConnection(this);
        }
Beispiel #25
0
 /// <summary>
 /// Gets the compatible nodes that have atleast one NodeInput that can connect to the given nodeOutput
 /// </summary>
 public static List<Node> getCompatibleNodes(NodeOutput nodeOutput)
 {
     if (nodeOutput == null)
         throw new ArgumentNullException ("nodeOutput");
     List<Node> compatibleNodes = new List<Node> ();
     foreach (Node node in NodeTypes.nodes.Keys)
     { // Check if any of the NodeInputs is able to connect to the given NodeOutput
         for (int inputCnt = 0; inputCnt < node.Inputs.Count; inputCnt++)
         { // Checking for compability, not using CanApplyConnection to leave out unnessecary dependancy checks
             NodeInput input = node.Inputs[inputCnt];
             if (input == null)
                 throw new UnityException ("Input " + inputCnt + " is null!");
             if (input.typeData.Type.IsAssignableFrom (nodeOutput.typeData.Type))
             {
                 compatibleNodes.Add (node);
                 break;
             }
         }
     }
     return compatibleNodes;
 }
Beispiel #26
0
 /// <summary>
 /// Recursive function which continues calculation on this node and all the child nodes
 /// Usually does not need to be called manually
 /// Returns success/failure of this node only
 /// </summary>
 public static bool ContinueCalculation(Node node)
 {
     if (node.descendantsCalculated() && node.Calculate())
     {             // finished Calculating, continue with the children
         for (int outCnt = 0; outCnt < node.Outputs.Count; outCnt++)
         {
             NodeOutput output = node.Outputs [outCnt];
             for (int conCnt = 0; conCnt < output.connections.Count; conCnt++)
             {
                 ContinueCalculation(output.connections [conCnt].body);
             }
         }
         workList.Remove(node);
         node.calculated = true;
         return(true);
     }
     else if (!workList.Contains(node))
     {             // failed to calculate, add it to check later
         workList.Add(node);
     }
     return(false);
 }
Beispiel #27
0
        /// <summary>
        /// Applies a connection between the passed NodeOutput and this NodeInput. 'CanApplyConnection' has to be checked before to avoid interferences!
        /// </summary>
        public void ApplyConnection(NodeOutput output)
        {
            Debug.Log("ApplyConnection");
            if (output == null)
            {
                return;
            }

            if (connection != null)
            {
                NodeEditorCallbacks.IssueOnRemoveConnection(this);
                connection.connections.Remove(this);
            }

            connection = output;
            output.connections.Add(this);
            output.body.OnAddOutputConnection(output);
            body.OnAddInputConnection(this);
            NodeEditorCallbacks.IssueOnAddConnection(this);

            NodeEditor.curNodeCanvas.OnNodeChange(body);
        }
Beispiel #28
0
        /// <summary>
        /// Reassigns the type of the given output. This actually recreates it
        /// </summary>
        protected static void ReassignInputType(ref NodeInput input, Type newInputType)
        {
            Node   body      = input.body;
            string inputName = input.name;
            // Store the valid connection if it's not affected by the type change
            NodeOutput validConnection = null;

            if (input.connection != null && newInputType.IsAssignableFrom(input.connection.typeData.Type))
            {
                validConnection = input.connection;
            }
            // Delete the input of the old type
            input.Delete();
            // Create Output with new type
            NodeEditorCallbacks.IssueOnAddNodeKnob(NodeInput.Create(body, inputName, newInputType.AssemblyQualifiedName));
            input = body.Inputs[body.Inputs.Count - 1];
            // Restore the valid connections
            if (validConnection != null)
            {
                input.ApplyConnection(validConnection);
            }
        }
Beispiel #29
0
 public bool isChildOf(Node otherNode)
 {
     if ((UnityEngine.Object)otherNode == (UnityEngine.Object)null || (UnityEngine.Object)otherNode == (UnityEngine.Object) this)
     {
         return(false);
     }
     if (BeginRecursiveSearchLoop())
     {
         return(false);
     }
     for (int i = 0; i < Inputs.Count; i++)
     {
         NodeOutput connection = Inputs[i].connection;
         if ((UnityEngine.Object)connection != (UnityEngine.Object)null && (UnityEngine.Object)connection.body != (UnityEngine.Object)startRecursiveSearchNode && ((UnityEngine.Object)connection.body == (UnityEngine.Object)otherNode || connection.body.isChildOf(otherNode)))
         {
             StopRecursiveSearchLoop();
             return(true);
         }
     }
     EndRecursiveSearchLoop();
     return(false);
 }
Beispiel #30
0
 /// <summary>
 /// Deletes this Node from curNodeCanvas and the save file
 /// </summary>
 public void Delete()
 {
     if (!NodeEditor.curNodeCanvas.nodes.Contains(this))
     {
         throw new UnityException("The Node " + name + " does not exist on the Canvas " + NodeEditor.curNodeCanvas.name + "!");
     }
     NodeEditorCallbacks.IssueOnDeleteNode(this);
     NodeEditor.curNodeCanvas.nodes.Remove(this);
     for (int outCnt = 0; outCnt < Outputs.Count; outCnt++)
     {
         NodeOutput output = Outputs [outCnt];
         while (output.connections.Count != 0)
         {
             output.connections[0].RemoveConnection();
         }
         DestroyImmediate(output, true);
     }
     for (int inCnt = 0; inCnt < Inputs.Count; inCnt++)
     {
         NodeInput input = Inputs [inCnt];
         if (input.connection != null)
         {
             input.connection.connections.Remove(input);
         }
         DestroyImmediate(input, true);
     }
     for (int knobCnt = 0; knobCnt < nodeKnobs.Count; knobCnt++)
     {             // Inputs/Outputs need specific treatment, unfortunately
         if (nodeKnobs[knobCnt] != null)
         {
             DestroyImmediate(nodeKnobs[knobCnt], true);
         }
     }
     for (int transCnt = 0; transCnt < transitions.Count; transCnt++)
     {
         transitions [transCnt].Delete();
     }
     DestroyImmediate(this, true);
 }