public void Main(MgaProject project, MgaFCO currentobj, MgaFCOs selectedobjs, ComponentStartMode startMode) { // This is the main ShowNet interpreter code Boolean ownLogger = false; if (Logger == null) { ownLogger = true; Logger = new CyPhyGUIs.GMELogger(project, "ShowNet"); } GMEConsole.Out.WriteLine("\n======================================================================================================================================\n"); Logger.WriteInfo("Starting ShowNet."); // Get RootFolder IMgaFolder rootFolder = project.RootFolder; //GMEConsole.Out.WriteLine(rootFolder.Name); // To use the domain-specific API: // Create another project with the same name as the paradigm name // Copy the paradigm .mga file to the directory containing the new project // In the new project, install the GME DSMLGenerator NuGet package (search for DSMLGenerator) // Add a Reference in this project to the other project // Add "using [ParadigmName] = ISIS.GME.Dsml.[ParadigmName].Classes.Interfaces;" to the top of this file bool done = false; if ((!done) && (null == currentobj)) { done = true; Logger.WriteError("The current object is null. Please select a ComponentAssembly or DesignContainer object."); } if ((!done) && (currentobj.Meta.Name != "ComponentAssembly" && currentobj.Meta.Name != "DesignContainer")) { done = true; Logger.WriteError("ShowNet only works on ComponentAssembly and DesignContainer objects."); Logger.WriteError("But, {1} is neither; it is a {0}.", currentobj.Meta.Name, currentobj.Name); } if (!done) { IEnumerable<CyPhy.PortComposition> portCompositionChildren = null; IEnumerable<CyPhy.ConnectorComposition> connectorCompositionChildren = null; if (currentobj.Meta.Name == "ComponentAssembly") { var componentAssembly = ISIS.GME.Dsml.CyPhyML.Classes.ComponentAssembly.Cast(currentobj); portCompositionChildren = componentAssembly.Children.PortCompositionCollection; connectorCompositionChildren = componentAssembly.Children.ConnectorCompositionCollection; } else if (currentobj.Meta.Name == "DesignContainer") { var designContainer = ISIS.GME.Dsml.CyPhyML.Classes.DesignContainer.Cast(currentobj); portCompositionChildren = designContainer.Children.PortCompositionCollection; connectorCompositionChildren = designContainer.Children.ConnectorCompositionCollection; } //================================================================= // Process the port connections //================================================================= NetworkManager portNetworkManager = new NetworkManager(); foreach (CyPhy.PortComposition port in portCompositionChildren) { Endpoint dstEndPoint = new Endpoint(port.DstEnd, port.GenericDstEndRef); Endpoint srcEndPoint = new Endpoint(port.SrcEnd, port.GenericSrcEndRef); //GMEConsole.Out.WriteLine("Found port: dst = '{0}' in the '{1}' {2}.", // dstEndPoint.Name, // dstEndPoint.ParentName, // dstEndPoint.ParentKind); //GMEConsole.Out.WriteLine(" src = '{0}' in the '{1}' {2}.", // srcEndPoint.Name, // srcEndPoint.ParentName, // srcEndPoint.ParentKind); // Create a network from the endpoints List<Endpoint> nodes = new List<Endpoint>() { srcEndPoint, dstEndPoint }; Network newNetwork = new Network(nodes); portNetworkManager.Add(newNetwork); } //================================================================= // Process the connector connections //================================================================= NetworkManager connectorNetworkManager = new NetworkManager(); foreach (CyPhy.ConnectorComposition connector in connectorCompositionChildren) { Endpoint dstEndPoint = new Endpoint(connector.DstEnd, connector.GenericDstEndRef); Endpoint srcEndPoint = new Endpoint(connector.SrcEnd, connector.GenericSrcEndRef); // Create a network from the endpoints List<Endpoint> nodes = new List<Endpoint>() { srcEndPoint, dstEndPoint }; Network newNetwork = new Network(nodes); connectorNetworkManager.Add(newNetwork); } // Make sure the network names are unique. NetworkNameChecker.Init(); NetworkNameChecker.Update(ref portNetworkManager.NetworkList); NetworkNameChecker.Update(ref connectorNetworkManager.NetworkList); // Display all the networks. Logger.WriteInfo(string.Format("===== Found {0} port networks on {1}: =====\n", portNetworkManager.NetworkList.Count, currentobj.Name)); foreach (Network mergedNet in portNetworkManager.NetworkList) { using (StringReader sr = new StringReader(mergedNet.ToString())) { string line; while ((line = sr.ReadLine()) != null) { GMEConsole.Out.WriteLine(line); } } } Logger.WriteInfo(string.Format("===== Found {0} connector networks on {1}: =====\n", connectorNetworkManager.NetworkList.Count, currentobj.Name)); foreach (Network mergedNet in connectorNetworkManager.NetworkList) { using (StringReader sr = new StringReader(mergedNet.ToString())) { string line; while ((line = sr.ReadLine()) != null) { GMEConsole.Out.WriteLine(line); } } } } Logger.WriteInfo("The ShowNet interpreter has finished."); if (ownLogger) { Logger.Dispose(); Logger = null; } }
/// <summary> /// Check if there is a connection between two networks. /// </summary> /// <param name="net1">The first network.</param> /// <param name="net2">The second network.</param> /// <exception> /// Throws an exception if the first network has internal duplicate endpoints. /// </exception> /// <returns>true if there is a connection, otherwise false.</returns> bool IsConnectionShared(Network net1, Network net2) { bool rVal = false; // We use the Endpoint ID as the key to determine endpoint uniqueness. Dictionary<string, Endpoint> epDictionary = new Dictionary<string, Endpoint>(); foreach (Endpoint ep in net1.Nodes) { if (!epDictionary.ContainsKey(ep.ID)) { epDictionary.Add(ep.ID, ep); } else { throw new Exception("Network contains duplicate endpoints."); } }; foreach (Endpoint ep in net2.Nodes) { if (!epDictionary.ContainsKey(ep.ID)) { epDictionary.Add(ep.ID, ep); } else { // Found a connection between the two networks. rVal = true; } }; return rVal; }
/// <summary> /// Merge the source netlist into the destination netlist. /// </summary> /// <param name="src">The source netlist.</param> /// <param name="dst">The destination netlist.</param> void MergeSrcIntoDst(Network src, ref Network dst) { // Build a dictionary with all the unique endpoints. // We use the Endpoint ID as the key to determine endpoint uniqueness. Dictionary<string, Endpoint> epDictionary = new Dictionary<string, Endpoint>(); foreach (Endpoint ep in src.Nodes) { if (!epDictionary.ContainsKey(ep.ID)) { epDictionary.Add(ep.ID, ep); } }; foreach (Endpoint ep in dst.Nodes) { if (!epDictionary.ContainsKey(ep.ID)) { epDictionary.Add(ep.ID, ep); } }; // Get the endpoint list from the dictionary. List<Endpoint> nodes = epDictionary.Values.ToList(); // Set the destination netlist to the merged network. dst = new Network(nodes); }
// Add a network to the list of networks, coalescing those with common connections. public void Add(Network newNetwork) { // Iterate list in reverse order, see http://stackoverflow.com/questions/1582285/how-to-remove-elements-from-a-generic-list-while-iterating-over-it for (int i = NetworkList.Count - 1; i >= 0; i--) { if (IsConnectionShared(NetworkList[i], newNetwork)) { MergeSrcIntoDst(NetworkList[i], ref newNetwork); NetworkList.RemoveAt(i); } } NetworkList.Add(newNetwork); }