// ---------------------------------------------------------------------- public void SetSource(iCS_EditorObject inPort, iCS_EditorObject outPort, LibraryFunction convDesc) { if (convDesc == null) { SetSource(inPort, outPort); return; } var inPos = inPort.GlobalPosition; var outPos = outPort.GlobalPosition; Vector2 convPos = new Vector2(0.5f * (inPos.x + outPos.x), 0.5f * (inPos.y + outPos.y)); int grandParentId = inPort.ParentNode.ParentId; iCS_EditorObject conv = CreateNode(grandParentId, convDesc); conv.SetInitialPosition(convPos); ForEachChild(conv, (child) => { if (child.IsInputPort) { SetSource(child, outPort); } else if (child.IsOutputPort) { SetSource(inPort, child); } } ); }
// ---------------------------------------------------------------------- void CreateMuxPort(iCS_EditorObject fixPort, iCS_EditorObject parentMuxPort) { LibraryFunction conversion = null; if (!VerifyConnectionTypes(parentMuxPort, fixPort, out conversion)) { return; } var childPortType = parentMuxPort.IsInputPort ? VSObjectType.InChildMuxPort : VSObjectType.OutChildMuxPort; var source = parentMuxPort.ProducerPort; // Convert source port to child port. if (source != null) { var firstChildMux = IStorage.CreatePort(fixPort.DisplayName, parentMuxPort.InstanceId, parentMuxPort.RuntimeType, childPortType); IStorage.SetSource(firstChildMux, source); IStorage.SetSource(parentMuxPort, null); parentMuxPort.ObjectType = parentMuxPort.IsInputPort ? VSObjectType.InParentMuxPort : VSObjectType.OutParentMuxPort; parentMuxPort.PortIndex = (int)iCS_PortIndex.Return; } // Create new mux input port. var childMuxPort = IStorage.CreatePort(fixPort.DisplayName, parentMuxPort.InstanceId, parentMuxPort.RuntimeType, childPortType); IStorage.SetNewDataConnection(childMuxPort, fixPort, conversion); IStorage.CleanupMuxPort(parentMuxPort); }
// ---------------------------------------------------------------------- /// Extracts all functions of a given type. /// /// @param type The type from which to extract. /// static void ExtractFunctions(LibraryType parentType, Type type) { foreach (var method in type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static)) { ++myNbOfFunctions; var methodName = method.Name; var parameters = method.GetParameters(); LibraryObject libraryObject = null; if (methodName.StartsWith("get_") && parameters.Length == 0) { libraryObject = new LibraryPropertyGetter(method); } else if (methodName.StartsWith("set_") && parameters.Length == 1) { libraryObject = new LibraryPropertySetter(method); } else { libraryObject = new LibraryFunction(method); } parentType.AddChild(libraryObject); } }
// ---------------------------------------------------------------------- bool VerifyConnectionTypes(iCS_EditorObject inPort, iCS_EditorObject outPort, out LibraryFunction typeCast) { typeCast = null; Type inType = inPort.RuntimeType; Type outType = outPort.RuntimeType; if (iCS_Types.CanBeConnectedWithoutConversion(outType, inType)) // No conversion needed. { return(true); } // A conversion is required. if (iCS_Types.CanBeConnectedWithUpConversion(outType, inType)) { if (EditorUtility.DisplayDialog("Up Conversion Connection", "Are you sure you want to generate a conversion from <color=red>" + iCS_Types.TypeName(outType) + "</color> to " + iCS_Types.TypeName(inType) + "?", "Generate Conversion", "Abort")) { return(true); } return(false); } typeCast = FindTypeCast(outType, inType); if (typeCast == null) { ShowNotification(new GUIContent("No automatic type conversion exists from " + iCS_Types.TypeName(outType) + " to " + iCS_Types.TypeName(inType))); return(false); } return(true); }
// ---------------------------------------------------------------------- bool VerifyNewConnection(iCS_EditorObject fixPort, iCS_EditorObject overlappingPort) { // Only data ports can be connected together. if (!fixPort.IsDataOrControlPort || !overlappingPort.IsDataOrControlPort) { return(false); } // Verify for output Mux port creation iCS_EditorObject portParent = fixPort.Parent; iCS_EditorObject overlappingPortParent = overlappingPort.Parent; if (IsMuxPortKeyDown && overlappingPort.ProducerPort != null) { // Mux output port creation if (overlappingPort.IsOutputPort && overlappingPort.IsDynamicDataPort && !overlappingPortParent.IsInstanceNode) { var provideNode = overlappingPort.ProducerPort.ParentNode; if (overlappingPortParent.IsParentOf(provideNode) && overlappingPortParent.IsParentOf(portParent)) { CreateMuxPort(fixPort, overlappingPort); return(true); } } // Mux input port creation if (overlappingPort.IsInputPort && overlappingPort.IsDynamicDataPort) { if (!overlappingPortParent.IsParentOf(portParent)) { CreateMuxPort(fixPort, overlappingPort); return(true); } } } // Connect function & modules ports together. iCS_EditorObject inPort = null; iCS_EditorObject outPort = null; bool portIsChildOfOverlapping = IStorage.IsChildOf(portParent, overlappingPortParent); bool overlappingIsChildOfPort = IStorage.IsChildOf(overlappingPortParent, portParent); if (portIsChildOfOverlapping || overlappingIsChildOfPort) { if (fixPort.IsInputPort && overlappingPort.IsInputPort) { if (portIsChildOfOverlapping) { inPort = fixPort; outPort = overlappingPort; } else { inPort = overlappingPort; outPort = fixPort; } } else if (fixPort.IsOutputPort && overlappingPort.IsOutputPort) { if (portIsChildOfOverlapping) { inPort = overlappingPort; outPort = fixPort; } else { inPort = fixPort; outPort = overlappingPort; } } else { ShowNotification(new GUIContent("Cannot connect nested node ports from input to output !!!")); return(true); } } else { inPort = fixPort.IsInputPort ? fixPort : overlappingPort; outPort = overlappingPort.IsOutputPort ? overlappingPort : fixPort; } if (inPort != outPort) { LibraryFunction conversion = null; if (VerifyConnectionTypes(inPort, outPort, out conversion)) { IStorage.SetAndAutoLayoutNewDataConnection(inPort, outPort, conversion); } } else { string direction = inPort.IsInputPort ? "input" : "output"; ShowNotification(new GUIContent("Cannot connect an " + direction + " port to an " + direction + " port !!!")); } return(true); }
// ---------------------------------------------------------------------- public void SetNewDataConnection(iCS_EditorObject inPort, iCS_EditorObject outPort, LibraryFunction conversion = null) { iCS_EditorObject inParentNode = inPort.ParentNode; iCS_EditorObject outParentNode = outPort.ParentNode; iCS_EditorObject inGrandParent = inParentNode.ParentNode; iCS_EditorObject outGrandParent = outParentNode.ParentNode; // No need to create module ports if both connected nodes are under the same parent. if (inGrandParent == outGrandParent || inGrandParent == outParentNode || inParentNode == outGrandParent) { SetSource(inPort, outPort, conversion); OptimizeDataConnection(inPort, outPort); return; } // Create inPort if inParent is not part of the outParent hierarchy. bool inParentSeen = false; for (iCS_EditorObject op = outGrandParent.ParentNode; op != null; op = op.ParentNode) { if (inGrandParent == op) { inParentSeen = true; break; } } if (!inParentSeen && inGrandParent != null) { var sourcePort = inPort.ProducerPort; iCS_EditorObject newPort = null; // Attempt to reuse existing ports. if (sourcePort != null && sourcePort.ParentNode == inGrandParent && conversion == null) { newPort = sourcePort; } else { newPort = CreatePort(inPort.DisplayName, inGrandParent.InstanceId, outPort.RuntimeType, VSObjectType.InDynamicDataPort); SetSource(inPort, newPort, conversion); SetBestPositionForAutocreatedPort(newPort, inPort.GlobalPosition, outPort.GlobalPosition); } SetNewDataConnection(newPort, outPort); OptimizeDataConnection(inPort, outPort); return; } // Create outPort if outParent is not part of the inParent hierarchy. bool outParentSeen = false; for (iCS_EditorObject ip = inGrandParent.ParentNode; ip != null; ip = ip.ParentNode) { if (outGrandParent == ip) { outParentSeen = true; break; } } if (!outParentSeen && outGrandParent != null) { // Attempt to reuse existing port. iCS_EditorObject newPort = null; if (conversion == null && outGrandParent.UntilMatchingChild( p => { if (p.IsPort && p.ProducerPort == outPort) { newPort = p; return(true); } return(false); } ) ) { } else { newPort = CreatePort(outPort.DisplayName, outGrandParent.InstanceId, outPort.RuntimeType, VSObjectType.OutDynamicDataPort); SetSource(newPort, outPort, conversion); SetBestPositionForAutocreatedPort(newPort, inPort.GlobalPosition, outPort.GlobalPosition); } SetNewDataConnection(inPort, newPort); OptimizeDataConnection(inPort, outPort); return; } // Should never happen ... just connect the ports. SetSource(inPort, outPort, conversion); OptimizeDataConnection(inPort, outPort); }
// ---------------------------------------------------------------------- public void SetAndAutoLayoutNewDataConnection(iCS_EditorObject consumerPort, iCS_EditorObject providerPort, LibraryFunction conversion = null) { SetNewDataConnection(consumerPort, providerPort, conversion); AutoLayoutOfPointToPointBindingExclusive(providerPort, consumerPort); }