示例#1
0
 /// <summary>
 /// Connect an edge to this port
 /// </summary>
 /// <param name="edge"></param>
 public void Add(SerializableEdge edge)
 {
     if (!edges.Contains(edge))
     {
         edges.Add(edge);
     }
 }
示例#2
0
        PushDataDelegate CreatePushDataDelegateForEdge(SerializableEdge edge)
        {
            try
            {
                //Creation of the delegate to move the data from the input node to the output node:
                FieldInfo inputField  = edge.inputNode.GetType().GetField(edge.trueInputFieldName, BindingFlags.Public | BindingFlags.Instance);
                FieldInfo outputField = edge.outputNode.GetType().GetField(edge.trueOutputFieldName, BindingFlags.Public | BindingFlags.Instance);

// We keep slow checks inside the editor
#if UNITY_EDITOR
                if (!inputField.FieldType.IsReallyAssignableFrom(outputField.FieldType))
                {
                    Debug.LogError("Can't convert from " + inputField.FieldType + " to " + outputField.FieldType + ", you must specify a custom port function (i.e CustomPortInput or CustomPortOutput) for non-implicit convertions");
                }
#endif

                MemberExpression inputParamField  = Expression.Field(Expression.Constant(edge.inputNode), inputField);
                MemberExpression outputParamField = Expression.Field(Expression.Constant(edge.outputNode), outputField);

                BinaryExpression assign = Expression.Assign(inputParamField, Expression.Convert(outputParamField, inputField.FieldType));
                return(Expression.Lambda <PushDataDelegate>(assign).Compile());
            } catch (Exception e) {
                Debug.LogError(e);
                return(null);
            }
        }
示例#3
0
        public void Add(SerializableEdge edge)
        {
            string portFieldName = (edge.inputNode == node) ? edge.inputFieldName : edge.outputFieldName;
            var    port          = this.FirstOrDefault(p => p.fieldName == portFieldName);

            port.Add(edge);
        }
示例#4
0
        /// <summary>
        /// Connect an edge to this port
        /// </summary>
        /// <param name="edge"></param>
        public void Add(SerializableEdge edge)
        {
            if (!edges.Contains(edge))
            {
                edges.Add(edge);
            }

            if (edge.inputNode == owner)
            {
                if (edge.outputPort.customPortIOMethod != null)
                {
                    edgeWithRemoteCustomIO.Add(edge);
                }
            }
            else
            {
                if (edge.inputPort.customPortIOMethod != null)
                {
                    edgeWithRemoteCustomIO.Add(edge);
                }
            }

            //if we have a custom io implementation, we don't need to genereate the defaut one
            if (edge.inputPort.customPortIOMethod != null || edge.outputPort.customPortIOMethod != null)
            {
                return;
            }

            PushDataDelegate edgeDelegate = CreatePushDataDelegateForEdge(edge);

            if (edgeDelegate != null)
            {
                pushDataDelegates[edge] = edgeDelegate;
            }
        }
示例#5
0
        public void OnEdgeConnected(SerializableEdge edge)
        {
            bool input = edge.inputNode == this;
            NodePortContainer portCollection = (input) ? (NodePortContainer)inputPorts : outputPorts;

            portCollection.Add(edge);
        }
示例#6
0
        public SerializableEdge Connect(BaseNode inputNode, string inputFieldName, BaseNode outputNode, string outputFieldName)
        {
            var edge = SerializableEdge.CreateNewEdge(this, inputNode, inputFieldName, outputNode, outputFieldName);

            edges.Add(edge);

            return(edge);
        }
示例#7
0
        /// <summary>
        /// Disconnect an Edge from this port
        /// </summary>
        /// <param name="edge"></param>
        public void Remove(SerializableEdge edge)
        {
            if (!edges.Contains(edge))
            {
                return;
            }

            edges.Remove(edge);
        }
示例#8
0
        public void OnEdgeConnected(SerializableEdge edge)
        {
            bool input = edge.inputNode == this;
            NodePortContainer portCollection = (input) ? (NodePortContainer)inputPorts : outputPorts;

            portCollection.Add(edge);

            UpdatePortsForField((input) ? edge.inputFieldName : edge.outputFieldName);
        }
示例#9
0
        /// <summary>
        /// Disconnect an Edge from this port
        /// </summary>
        /// <param name="edge"></param>
        public void Remove(SerializableEdge edge)
        {
            if (!edges.Contains(edge))
            {
                return;
            }

            pushDataDelegates.Remove(edge);
            edges.Remove(edge);
        }
示例#10
0
        public void OnEdgeConnected(SerializableEdge edge)
        {
            bool input = edge.inputNode == this;
            NodePortContainer portCollection = (input) ? (NodePortContainer)inputPorts : outputPorts;

            portCollection.Add(edge);

            UpdateAllPorts();

            onAfterEdgeConnected?.Invoke(edge);
        }
示例#11
0
        public void OnEdgeDisonnected(SerializableEdge edge)
        {
            if (edge == null)
            {
                return;
            }

            bool input = edge.inputNode == this;
            NodePortContainer portCollection = (input) ? (NodePortContainer)inputPorts : outputPorts;

            portCollection.Remove(edge);
        }
示例#12
0
        public static SerializableEdge CreateNewEdge(BaseGraph graph, BaseNode inputNode, string inputFieldName, BaseNode outputNode, string outputFieldName)
        {
            SerializableEdge edge = new SerializableEdge();

            edge.owner           = graph;
            edge.GUID            = System.Guid.NewGuid().ToString();
            edge.inputNode       = inputNode;
            edge.inputFieldName  = inputFieldName;
            edge.outputNode      = outputNode;
            edge.outputFieldName = outputFieldName;
            edge.inputPort       = inputNode.GetPort(inputFieldName);
            edge.outputPort      = outputNode.GetPort(outputFieldName);

            return(edge);
        }
示例#13
0
        public void OnEdgeDisconnected(SerializableEdge edge)
        {
            if (edge == null)
            {
                return;
            }

            bool input = edge.inputNode == this;
            NodePortContainer portCollection = (input) ? (NodePortContainer)inputPorts : outputPorts;

            portCollection.Remove(edge);

            UpdatePortsForField((input) ? edge.inputFieldName : edge.outputFieldName);

            onAfterEdgeDisconnected?.Invoke(edge);
        }
        public static SerializableEdge CreateNewEdge(BaseGraph graph, NodePort inputPort, NodePort outputPort)
        {
            SerializableEdge edge = new SerializableEdge();

            edge.owner                = graph;
            edge.GUID                 = System.Guid.NewGuid().ToString();
            edge.inputNode            = inputPort.owner;
            edge.inputFieldName       = inputPort.fieldName;
            edge.outputNode           = outputPort.owner;
            edge.outputFieldName      = outputPort.fieldName;
            edge.inputPort            = inputPort;
            edge.outputPort           = outputPort;
            edge.inputPortIdentifier  = inputPort.portData.identifier;
            edge.outputPortIdentifier = outputPort.portData.identifier;

            return(edge);
        }
示例#15
0
        PushDataDelegate CreatePushDataDelegateForEdge(SerializableEdge edge)
        {
            try
            {
                //Creation of the delegate to move the data from the input node to the output node:
                FieldInfo inputField  = edge.inputNode.GetType().GetField(edge.trueInputFieldName, BindingFlags.Public | BindingFlags.Instance);
                FieldInfo outputField = edge.outputNode.GetType().GetField(edge.trueOutputFieldName, BindingFlags.Public | BindingFlags.Instance);

                MemberExpression inputParamField  = Expression.Field(Expression.Constant(edge.inputNode), inputField);
                MemberExpression outputParamField = Expression.Field(Expression.Constant(edge.outputNode), outputField);

                BinaryExpression assign = Expression.Assign(inputParamField, Expression.Convert(outputParamField, inputField.FieldType));
                return(Expression.Lambda <PushDataDelegate>(assign).Compile());
            } catch (Exception e) {
                Debug.LogError(e);
                return(null);
            }
        }
示例#16
0
        PushDataDelegate CreatePushDataDelegateForEdge(SerializableEdge edge)
        {
            try
            {
                //Creation of the delegate to move the data from the input node to the output node:
                FieldInfo inputField  = edge.inputNode.GetType().GetField(edge.inputFieldName, BindingFlags.Public | BindingFlags.Instance);
                FieldInfo outputField = edge.outputNode.GetType().GetField(edge.outputFieldName, BindingFlags.Public | BindingFlags.Instance);

// We keep slow checks inside the editor
#if UNITY_EDITOR
                if (!BaseGraph.TypesAreConnectable(inputField.FieldType, outputField.FieldType))
                {
                    Debug.LogError("Can't convert from " + inputField.FieldType + " to " + outputField.FieldType + ", you must specify a custom port function (i.e CustomPortInput or CustomPortOutput) for non-implicit convertions");
                }
#endif

                Expression inputParamField  = Expression.Field(Expression.Constant(edge.inputNode), inputField);
                Expression outputParamField = Expression.Field(Expression.Constant(edge.outputNode), outputField);

                var inType  = edge.inputPort.portData.displayType ?? inputField.FieldType;
                var outType = edge.outputPort.portData.displayType ?? outputField.FieldType;

                // If there is a user defined convertion function, then we call it
                if (TypeAdapter.AreAssignable(outType, inType))
                {
                    // We add a cast in case there we're calling the conversion method with a base class parameter (like object)
                    var convertedParam = Expression.Convert(outputParamField, outType);
                    outputParamField = Expression.Call(TypeAdapter.GetConvertionMethod(outType, inType), convertedParam);
                    // In case there is a custom port behavior in the output, then we need to re-cast to the base type because
                    // the convertion method return type is not always assignable directly:
                    outputParamField = Expression.Convert(outputParamField, inputField.FieldType);
                }
                else                 // otherwise we cast
                {
                    outputParamField = Expression.Convert(outputParamField, inputField.FieldType);
                }

                BinaryExpression assign = Expression.Assign(inputParamField, outputParamField);
                return(Expression.Lambda <PushDataDelegate>(assign).Compile());
            } catch (Exception e) {
                Debug.LogError(e);
                return(null);
            }
        }
示例#17
0
        public void OnEdgeConnected(SerializableEdge edge)
        {
            bool input = edge.inputNode == this;
            NodePortContainer portCollection = (input) ? (NodePortContainer)inputPorts : outputPorts;

            portCollection.Add(edge);

            // Reset default values of input port:
            bool haveConnectedEdges = edge.inputNode.inputPorts.Where(p => p.fieldName == edge.inputFieldName).Any(p => p.GetEdges().Count != 0);

            if (edge.inputNode == this && !haveConnectedEdges)
            {
                edge.inputPort?.ResetToDefault();
            }

            UpdateAllPorts();

            onAfterEdgeConnected?.Invoke(edge);
        }
示例#18
0
        public void Add(SerializableEdge edge)
        {
            string portFieldName  = (edge.inputNode == node) ? edge.inputFieldName : edge.outputFieldName;
            string portIdentifier = (edge.inputNode == node) ? edge.inputPortIdentifier : edge.outputPortIdentifier;

            // Force empty string to null since portIdentifier is a serialized value
            if (String.IsNullOrEmpty(portIdentifier))
            {
                portIdentifier = null;
            }

            var port = this.FirstOrDefault(p => { return(p.fieldName == portFieldName && p.portData.identifier == portIdentifier); });

            if (port == null)
            {
                Debug.LogError("The edge can't be properly connected because it's ports can't be found");
                return;
            }

            port.Add(edge);
        }
示例#19
0
        public bool Connect(PortView inputPortView, PortView outputPortView, bool autoDisconnectInputs = true)
        {
            var inputPort  = inputPortView.owner.nodeTarget.GetPort(inputPortView.fieldName, inputPortView.portData.identifier);
            var outputPort = outputPortView.owner.nodeTarget.GetPort(outputPortView.fieldName, outputPortView.portData.identifier);

            // Checks that the node we are connecting still exists
            if (inputPortView.owner.parent == null || outputPortView.owner.parent == null)
            {
                return(false);
            }

            var newEdge = SerializableEdge.CreateNewEdge(graph, inputPort, outputPort);

            var edgeView = new EdgeView()
            {
                userData = newEdge,
                input    = inputPortView,
                output   = outputPortView,
            };

            return(Connect(edgeView));
        }
示例#20
0
        PushDataDelegate CreatePushDataDelegateForEdge(SerializableEdge edge)
        {
            try
            {
                //Creation of the delegate to move the data from the input node to the output node:
                FieldInfo inputField  = edge.inputNode.GetType().GetField(edge.inputFieldName, BindingFlags.Public | BindingFlags.Instance);
                FieldInfo outputField = edge.outputNode.GetType().GetField(edge.outputFieldName, BindingFlags.Public | BindingFlags.Instance);

// We keep slow checks inside the editor
#if UNITY_EDITOR
                if (!BaseGraph.TypesAreConnectable(inputField.FieldType, outputField.FieldType))
                {
                    Debug.LogError("Can't convert from " + inputField.FieldType + " to " + outputField.FieldType + ", you must specify a custom port function (i.e CustomPortInput or CustomPortOutput) for non-implicit convertions");
                }
#endif

                // TODO: TypeAdapter convertion method here

                Expression inputParamField  = Expression.Field(Expression.Constant(edge.inputNode), inputField);
                Expression outputParamField = Expression.Field(Expression.Constant(edge.outputNode), outputField);

                // If there is a user defined convertion function, then we call it
                if (TypeAdapter.AreAssignable(outputField.FieldType, inputField.FieldType))
                {
                    outputParamField = Expression.Call(TypeAdapter.GetConvertionMethod(outputField.FieldType, inputField.FieldType), outputParamField);
                }
                else                 // otherwise we cast
                {
                    outputParamField = Expression.Convert(outputParamField, inputField.FieldType);
                }

                BinaryExpression assign = Expression.Assign(inputParamField, outputParamField);
                return(Expression.Lambda <PushDataDelegate>(assign).Compile());
            } catch (Exception e) {
                Debug.LogError(e);
                return(null);
            }
        }
示例#21
0
        void UnserializeAndPasteCallback(string operationName, string serializedData)
        {
            var data = JsonUtility.FromJson <CopyPasteHelper>(serializedData);

            RegisterCompleteObjectUndo(operationName);

            Dictionary <string, BaseNode> copiedNodesMap = new Dictionary <string, BaseNode>();

            foreach (var serializedNode in data.copiedNodes)
            {
                var node = JsonSerializer.DeserializeNode(serializedNode);

                if (node == null)
                {
                    continue;
                }

                string sourceGUID = node.GUID;
                graph.nodesPerGUID.TryGetValue(sourceGUID, out var sourceNode);
                //Call OnNodeCreated on the new fresh copied node
                node.OnNodeCreated();
                //And move a bit the new node
                node.position.position += new Vector2(20, 20);

                var newNodeView = AddNode(node);

                // If the nodes were copied from another graph, then the source is null
                if (sourceNode != null)
                {
                    nodeDuplicated?.Invoke(sourceNode, node);
                }
                copiedNodesMap[sourceGUID] = node;

                //Select the new node
                AddToSelection(nodeViewsPerNode[node]);
            }

            foreach (var serializedGroup in data.copiedGroups)
            {
                var group = JsonSerializer.Deserialize <Group>(serializedGroup);

                //Same than for node
                group.OnCreated();

                // try to centre the created node in the screen
                group.position.position += new Vector2(20, 20);

                var oldGUIDList = group.innerNodeGUIDs.ToList();
                group.innerNodeGUIDs.Clear();
                foreach (var guid in oldGUIDList)
                {
                    graph.nodesPerGUID.TryGetValue(guid, out var node);

                    // In case group was copied from another graph
                    if (node == null)
                    {
                        copiedNodesMap.TryGetValue(guid, out node);
                        group.innerNodeGUIDs.Add(node.GUID);
                    }
                    else
                    {
                        group.innerNodeGUIDs.Add(copiedNodesMap[guid].GUID);
                    }
                }

                AddGroup(group);
            }

            foreach (var serializedEdge in data.copiedEdges)
            {
                var edge = JsonSerializer.Deserialize <SerializableEdge>(serializedEdge);

                edge.Deserialize();

                // Find port of new nodes:
                copiedNodesMap.TryGetValue(edge.inputNode.GUID, out var oldInputNode);
                copiedNodesMap.TryGetValue(edge.outputNode.GUID, out var oldOutputNode);

                // We avoid to break the graph by replacing unique connections:
                if (oldInputNode == null && !edge.inputPort.portData.acceptMultipleEdges || !edge.outputPort.portData.acceptMultipleEdges)
                {
                    continue;
                }

                oldInputNode  = oldInputNode ?? edge.inputNode;
                oldOutputNode = oldOutputNode ?? edge.outputNode;

                var inputPort  = oldInputNode.GetPort(edge.inputPort.fieldName, edge.inputPortIdentifier);
                var outputPort = oldOutputNode.GetPort(edge.outputPort.fieldName, edge.outputPortIdentifier);

                var newEdge = SerializableEdge.CreateNewEdge(graph, inputPort, outputPort);

                if (nodeViewsPerNode.ContainsKey(oldInputNode) && nodeViewsPerNode.ContainsKey(oldOutputNode))
                {
                    var edgeView = new EdgeView()
                    {
                        userData = newEdge,
                        input    = nodeViewsPerNode[oldInputNode].GetPortViewFromFieldName(newEdge.inputFieldName, newEdge.inputPortIdentifier),
                        output   = nodeViewsPerNode[oldOutputNode].GetPortViewFromFieldName(newEdge.outputFieldName, newEdge.outputPortIdentifier)
                    };

                    Connect(edgeView);
                }
            }
        }
示例#22
0
 /// <summary>
 /// Remove an edge that is connected to one of the node in the container
 /// </summary>
 /// <param name="edge"></param>
 public void Remove(SerializableEdge edge)
 {
     ForEach(p => p.Remove(edge));
 }
示例#23
0
 /// <summary>
 /// Disconnect an Edge from this port
 /// </summary>
 /// <param name="edge"></param>
 public void Remove(SerializableEdge edge)
 {
     pushDataDelegates.Remove(edge);
     edges.Remove(edge);
 }
示例#24
0
        PushDataDelegate CreatePushDataDelegateForEdge(SerializableEdge edge)
        {
            try
            {
                //Creation of the delegate to move the data from the input node to the output node:
                FieldInfo inputField = edge.inputNode.GetType().GetField(edge.inputFieldName, BindingFlags.Public | BindingFlags.Instance);
                FieldInfo outputField = edge.outputNode.GetType().GetField(edge.outputFieldName, BindingFlags.Public | BindingFlags.Instance);
                Type      inType, outType;

#if DEBUG_LAMBDA
                return(new PushDataDelegate(() => {
                    var outValue = outputField.GetValue(edge.outputNode);
                    inType = edge.inputPort.portData.displayType ?? inputField.FieldType;
                    outType = edge.outputPort.portData.displayType ?? outputField.FieldType;
                    Debug.Log($"Push: {inType}({outValue}) -> {outType} | {owner.name}");

                    object convertedValue = outValue;
                    if (TypeAdapter.AreAssignable(outType, inType))
                    {
                        var convertionMethod = TypeAdapter.GetConvertionMethod(outType, inType);
                        Debug.Log("Convertion method: " + convertionMethod.Name);
                        convertedValue = convertionMethod.Invoke(null, new object[] { outValue });
                    }

                    inputField.SetValue(edge.inputNode, convertedValue);
                }));
#endif

// We keep slow checks inside the editor
#if UNITY_EDITOR
                if (!BaseGraph.TypesAreConnectable(inputField.FieldType, outputField.FieldType))
                {
                    return(null);
                }
#endif

                Expression inputParamField  = Expression.Field(Expression.Constant(edge.inputNode), inputField);
                Expression outputParamField = Expression.Field(Expression.Constant(edge.outputNode), outputField);

                inType  = edge.inputPort.portData.displayType ?? inputField.FieldType;
                outType = edge.outputPort.portData.displayType ?? outputField.FieldType;

                // If there is a user defined convertion function, then we call it
                if (TypeAdapter.AreAssignable(outType, inType))
                {
                    // We add a cast in case there we're calling the conversion method with a base class parameter (like object)
                    var convertedParam = Expression.Convert(outputParamField, outType);
                    outputParamField = Expression.Call(TypeAdapter.GetConvertionMethod(outType, inType), convertedParam);
                    // In case there is a custom port behavior in the output, then we need to re-cast to the base type because
                    // the convertion method return type is not always assignable directly:
                    outputParamField = Expression.Convert(outputParamField, inputField.FieldType);
                }
                else                 // otherwise we cast
                {
                    outputParamField = Expression.Convert(outputParamField, inputField.FieldType);
                }

                BinaryExpression assign = Expression.Assign(inputParamField, outputParamField);
                return(Expression.Lambda <PushDataDelegate>(assign).Compile());
            }
            catch (Exception e)
            {
                Debug.LogError(e);
                return(null);
            }
        }