/// <summary> /// Connect an edge to this port /// </summary> /// <param name="edge"></param> public void Add(SerializableEdge edge) { if (!edges.Contains(edge)) { edges.Add(edge); } }
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); } }
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); }
/// <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; } }
public void OnEdgeConnected(SerializableEdge edge) { bool input = edge.inputNode == this; NodePortContainer portCollection = (input) ? (NodePortContainer)inputPorts : outputPorts; portCollection.Add(edge); }
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); }
/// <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); }
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); }
/// <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); }
public void OnEdgeConnected(SerializableEdge edge) { bool input = edge.inputNode == this; NodePortContainer portCollection = (input) ? (NodePortContainer)inputPorts : outputPorts; portCollection.Add(edge); UpdateAllPorts(); onAfterEdgeConnected?.Invoke(edge); }
public void OnEdgeDisonnected(SerializableEdge edge) { if (edge == null) { return; } bool input = edge.inputNode == this; NodePortContainer portCollection = (input) ? (NodePortContainer)inputPorts : outputPorts; portCollection.Remove(edge); }
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); }
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); }
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); } }
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); } }
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); }
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); }
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)); }
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); } }
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); } } }
/// <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)); }
/// <summary> /// Disconnect an Edge from this port /// </summary> /// <param name="edge"></param> public void Remove(SerializableEdge edge) { pushDataDelegates.Remove(edge); edges.Remove(edge); }
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); } }