private MgaFCO GetRefportOrParent(MgaConnection conn, string role = "src") { MgaConnPoint connPoint = conn.ConnPoints.Cast<MgaConnPoint>().Where(cp => cp.ConnRole == role).First(); if (connPoint.References != null && connPoint.References.Count > 0) { return connPoint.References[1]; } return connPoint.Target; }
private MgaFCO GetRefportOrParent(MgaConnection conn, string role = "src") { MgaConnPoint connPoint = conn.ConnPoints.Cast <MgaConnPoint>().Where(cp => cp.ConnRole == role).First(); if (connPoint.References != null && connPoint.References.Count > 0) { return(connPoint.References[1]); } return(connPoint.Target); }
/** * First we disconnect all connections to refports, then move the reference, then reconnect */ public static void MoveReferenceWithRefportConnections(IMgaFCO fco2, IMgaReference origref, WriteLineF WriteLine) { Queue <IMgaReference> references = new Queue <IMgaReference>(); references.Enqueue(origref); IMgaFCO targetModel = fco2; while (targetModel is IMgaReference) { targetModel = ((IMgaReference)targetModel).Referred; } MgaFCOs fco2ChildFCOs = ((IMgaModel)targetModel).ChildFCOs; Dictionary <string, IMgaFCO> newRefeChildren = GetNameMap(fco2ChildFCOs, x => { }); // TODO: warn, but only for refport-connected children //GMEConsole.Warning.WriteLine("Warning: " + fco2.Name + " has multiple children named " + x)); int origPrefs = fco2.Project.Preferences; // Magic word allows us to remove ConnPoints fco2.Project.Preferences = origPrefs | (int)GME.MGA.preference_flags.MGAPREF_IGNORECONNCHECKS | (int)GME.MGA.preference_flags.MGAPREF_FREEINSTANCEREFS; try { MgaConnection conn = null; var ReconnectList = MakeList(new { ConnRole = "src", Ref = origref, Port = fco2, Conn = conn }); while (references.Count != 0) { IMgaReference refe = references.Dequeue(); foreach (IMgaConnPoint connPoint in refe.UsedByConns) { if (connPoint.References[1] != refe) { continue; } IMgaFCO fco2Port; if (newRefeChildren.TryGetValue(connPoint.Target.Name, out fco2Port)) { if (fco2Port == null) { // fco2Port == null => multiple children with the same name // Try matching based on Kind too fco2Port = fco2ChildFCOs.Cast <IMgaFCO>().Where(x => x.Name == connPoint.Target.Name && x.Meta.MetaRef == connPoint.Target.Meta.MetaRef).FirstOrDefault(); } if (fco2Port != null) { ReconnectList.Add(new { ConnRole = connPoint.ConnRole, Ref = refe, Port = fco2Port, Conn = connPoint.Owner }); connPoint.Remove(); } } else { WriteLine((x, y) => "Can't find corresponding port for " + x + " in " + y, connPoint.Target, fco2); connPoint.Owner.DestroyObject(); } } foreach (IMgaReference x in refe.ReferencedBy.Cast <IMgaReference>()) { if (x.ID == origref.ID) { throw new Exception("Circular reference chain starting with " + origref.AbsPath); } references.Enqueue(x); } } origref.Referred = (MgaFCO)fco2; foreach (var reconnect in ReconnectList) { if (reconnect.ConnRole == "src") { (reconnect.Conn as IMgaSimpleConnection).SetSrc((MgaFCOs)GetRefChain(reconnect.Ref), (MgaFCO)reconnect.Port); } else { (reconnect.Conn as IMgaSimpleConnection).SetDst((MgaFCOs)GetRefChain(reconnect.Ref), (MgaFCO)reconnect.Port); } } } finally { fco2.Project.Preferences = origPrefs; } }
public Dictionary <string, ComponentLibraryFilterParameter> GenerateFilter( IMgaModel alternativeDesignContainer, System.IO.TextWriter errorWriter = null, System.IO.TextWriter infoWriter = null) { var consoleErrorLogger = (errorWriter == null) ? Console.Error : errorWriter; var consoleInfoLogger = (infoWriter == null) ? Console.Out : infoWriter; Dictionary <string, ComponentLibraryFilterParameter> filterParams = new Dictionary <string, ComponentLibraryFilterParameter>(); List <string> filtersWithConflictingMaxMin = new List <string>(); // Get all the PropertyConstraint objects in the DesignContainer var propertyConstraints = alternativeDesignContainer.ChildFCOs.OfType <MgaAtom>().Where(x => x.Meta.Name == "PropertyConstraint"); // Iterate over the PropertyConstraint collection and create/modify filters: foreach (MgaFCO propConstraint in propertyConstraints) { string filterName = null; string filterUnit = null; string targetType = propConstraint.StrAttrByName["TargetType"]; double targetValue = propConstraint.FloatAttrByName["TargetValue"]; // Check if they are connected to a Property var propertyConstraintConnectionPoints = propConstraint.PartOfConns; // One PropertyConstraint might be connected to multiple Properties (valid in GME); might need to create multiple filters per foreach (MgaConnPoint cp in propertyConstraintConnectionPoints) { MgaConnection conn = (cp as MgaConnPoint).Owner; if (conn.Meta.Name != "PropertyConstraintBinding") { continue; } else { // get the Property MgaFCO property = (conn as IMgaSimpleConnection).Dst; // We want to skip PropertyConstraints connected directly to the selected Component (they don't agree with Desert...) if (property.ParentModel.ID == this.CyPhyComponent.ID) { errorWriter.WriteLine( "PropertyConstraint '{0}' should not be connected directly to the ComponentRef Property. Constraint on Property '{1}' will be ignored.", propConstraint.Name, property.Name); infoWriter.WriteLine( "Please create a Property within this DesignContainer, name it 'ComponentProperty.Name', and connect the PropertyConstraint."); continue; } // Check if the 'floating' Property has a matching property (by name) in the selected component bool componentHasMatchingProperty = false; foreach (MgaConnPoint connPoint in property.PartOfConns) { MgaConnection valueFlow = connPoint.Owner; if (valueFlow.Meta.Name != "ValueFlow") { continue; } // check if the ValueFlow is FROM the component TO the 'floating' property MgaFCO dst = (valueFlow as IMgaSimpleConnection).Dst; MgaFCO src = (valueFlow as IMgaSimpleConnection).Src; if (property != dst) { errorWriter.WriteLine( "DesignContainer Property '{0}' is the Source of a ValueFlow into '{1}'; Constraint '{2}' will be ignored.", property.Name, dst.Name, propConstraint.Name); infoWriter.WriteLine( "To correctly filter your search results, DesignContainer Properties must get their values from Component Properties."); continue; } bool srcIsWithinComponent = src.ParentModel.ID == this.CyPhyComponent.ID; bool namesMatch = property.Name == src.Name; if (srcIsWithinComponent && namesMatch) { componentHasMatchingProperty = true; break; } } if (!componentHasMatchingProperty) { errorWriter.WriteLine( "Property '{0}' is not connected to a Property with a matching name. Constraint '{1}' will be ignored.", property.Name, propConstraint.Name); infoWriter.WriteLine( "To correctly filter your search results, the names of DesignContainer Properties must match the Properties within Components."); continue; } filterName = property.Name; if ((property as MgaReference).Referred != null) { // TODO: Might need to use Adam's QUDT stuff to get the correct unit; for now, just get the referred unit's name. filterUnit = (property as MgaReference).Referred.Name; } } // if that property already has a filter, modify it (add max, add min) // else create a new filter for this property //bool discreteFilter = false; double newMaximum = double.NaN; double newMinimum = double.NaN; //double myEpsilon = targetValue * 1E-12; double scaledEpsilon = targetValue == 0 ? double.Epsilon : Math.Pow(10, Math.Floor(Math.Log10(targetValue)) - 15); switch (targetType) { case "Must Be Less Than": newMaximum = targetValue; break; case "Must Not Exceed": newMaximum = targetValue + scaledEpsilon; break; case "Must Equal": newMaximum = targetValue + scaledEpsilon; newMinimum = targetValue - scaledEpsilon; //discreteFilter = true; break; case "Must Equal or Exceed": newMinimum = targetValue - scaledEpsilon; break; default: // "Must Exceed" newMinimum = targetValue; break; } // Create a new filter object ContinuousFilterParameter newParam = new ContinuousFilterParameter(filterName); // Check if there is an existing filter with this name if (filterParams.ContainsKey(filterName)) { // Get the existing filter ComponentLibraryFilterParameter filterParameter = filterParams[filterName]; // Type check it if (filterParameter is ContinuousFilterParameter) { // Assign it to this local var to modify it newParam = filterParameter as ContinuousFilterParameter; } } // Overwrite filter attributes with new info, or leave them as before double currentMinimum = double.MinValue; double currentMaximum = double.MaxValue; // check if the PropertyConstraint could affect the filter's minimum value if (!double.IsNaN(newMinimum)) { // if the current MinValue is of type 'double', compare with newMinimum, possibly overwrite if (double.TryParse(newParam.MinValue, out currentMinimum)) { if (newMinimum > currentMinimum) { // the 'new' PropertyConstraint minimum is higher (more strict) than the existing one; overwrite it newParam.MinValue = newMinimum.ToString("G17"); } } } // check if the PropertyConstraint could affect the filter's maximum value if (!double.IsNaN(newMaximum)) { // if the current MaxValue is of type 'double', compare with newMaximum, possibly overwrite if (double.TryParse(newParam.MaxValue, out currentMaximum)) { if (newMaximum < currentMaximum) { // the 'new' PropertyConstraint maximum is lower (more strict) than the existing one; overwrite it newParam.MaxValue = newMaximum.ToString("G17"); } } } newParam.Unit = filterUnit != null ? filterUnit : null; filterParams[filterName] = newParam; // check if a filter's minimum is greater than its maximum, log the conflict if (double.TryParse(newParam.MaxValue, out currentMaximum) && double.TryParse(newParam.MinValue, out currentMinimum)) { if (currentMaximum < currentMinimum) { filtersWithConflictingMaxMin.Add(filterName); } } //if (discreteFilter) //{ // continue; // //DiscreteFilterParameter newParam = new DiscreteFilterParameter(filterName); // //List<string> filterParameterValues = new List<string>(); // //filterParameterValues.Add(targetValue.ToString()); // //newParam.Values = filterParameterValues; // //filterParams[filterName] = newParam; //} //else //{ // Make a ContinuousFilter (this is done in all cases) //} } } foreach (string name in filtersWithConflictingMaxMin) { if (filterParams.ContainsKey(name)) { string min = (filterParams[name] as ContinuousFilterParameter).MinValue; string max = (filterParams[name] as ContinuousFilterParameter).MaxValue; consoleErrorLogger.WriteLine( "Property '{0}' has conflicting PropertyConstraints (Min {1} > Max {2}); no filter will be generated.", name, min, max); filterParams.Remove(name); } } return(filterParams); }
//assume root model (located directly in folder) will not need replacing //creates all model, atoms, and reference replacements (not connections) //Parents of new/old objects is set to the new object if model is being replaced //properties are copied over private void createNewFCOs(MgaModel model) { bool newParent = model.ParentFolder == null && oldToNewFCO.ContainsKey(model as MgaFCO); if (model == null || migratedModels.Contains(model) || (model.IsInstance && !newParent)) //if model already migrated, stop //INSTANCE BUG SOLUTION { return; } //INSTANCE BUG SOLUTION if (model.IsInstance) //newParent = true { foreach (var childObject in model.ChildObjects.OfType <MgaFCO>()) { oldToNewFCO.Add(childObject, null); if (childObject is MgaModel) { createNewFCOs(childObject as MgaModel); } } migratedModels.Add(model); return; } //END SOLUTION foreach (var childObject in model.ChildObjects.OfType <MgaFCO>()) { string role = (childObject as MgaFCO).MetaRole.Name; //special case (cadmodel): assumes cadmodel is not replaced if (role == "CADModel") { string cadFileType = childObject.get_StrAttrByName("FileType"); string cadFileExtension = (cadFileType == "Part") ? ".prt" : ".asm"; //check already has resource? bool makeFCOs = true; foreach (MgaConnPoint point in childObject.PartOfConns) { if (point.Owner.MetaRole.Name == "UsesResource") { makeFCOs = false; MgaConnection conn = point.Owner; MgaFCO resourceObj = null; if ((conn as IMgaSimpleConnection).Dst.Meta.Name == "Resource") { resourceObj = (conn as IMgaSimpleConnection).Dst; } else if ((conn as IMgaSimpleConnection).Src.Meta.Name == "Resource") { resourceObj = (conn as IMgaSimpleConnection).Src; } if (resourceObj != null) { UpdateResourcePath(resourceObj, cadFileExtension); } } } if (makeFCOs) { MgaFCO resource; MgaFCO conn; if (newParent) { MgaFCO newCAD = makeFCO(oldToNewFCO[model as MgaFCO] as MgaModel, childObject.MetaRole.Name); oldToNewFCO.Add(childObject, newCAD); copyFCO(childObject, newCAD); resource = makeFCO(oldToNewFCO[model as MgaFCO] as MgaModel, "Resource"); conn = makeConn(oldToNewFCO[model as MgaFCO] as MgaModel, newCAD, resource, "UsesResource"); } else { resource = makeFCO(model, "Resource"); conn = makeConn(model, childObject, resource, "UsesResource"); } resource.set_StrAttrByName("Path", childObject.get_StrAttrByName("FilePathWithinResource")); childObject.set_StrAttrByName("FilePathWithinResource", ""); UpdateResourcePath(resource, cadFileExtension); } } if (childObject.ArcheType != null && RootFolder != project.RootFolder && !oldToNewFCO.ContainsKey(childObject.ArcheType) && !willBeMigrated(childObject.ArcheType)) //migrate archetype if not going to be/hasn't been migrated { createNewFCOs(childObject.ArcheType.ParentModel); } if (oldToNewRole.ContainsKey(role) && !oldToNewFCO.ContainsKey(childObject) && !(childObject is MgaConnection)) //if child type is obselete, not yet migrated, and not a connection { //general case for models/atoms/references if (newParent) { oldToNewFCO.Add(childObject, makeFCO(oldToNewFCO[model as MgaFCO] as MgaModel, oldToNewRole[role])); } else { oldToNewFCO.Add(childObject, makeFCO(model, oldToNewRole[role])); } if (childObject.Name != childObject.MetaRole.Name && childObject.Name != childObject.Meta.Name && childObject.Name != childObject.Meta.DisplayedName) //name default? { oldToNewFCO[childObject].Name = childObject.Name; } //copy over specified properties to new FCO if (role == "StructuralInterface") { oldToNewFCO[childObject].set_StrAttrByName("Definition", childObject.get_StrAttrByName("Type")); oldToNewFCO[childObject].Name = childObject.Name; } else if (role == "SurfaceGeometry" || role == "AxisGeometry" || role == "PointGeometry" || role == "CoordinateSystemGeometry") { oldToNewFCO[childObject].set_StrAttrByName("DatumName", childObject.get_StrAttrByName("Datum")); } } else if (newParent && !oldToNewFCO.ContainsKey(childObject) && !(childObject is MgaConnection)) //if child type not obselete, not yet migrated, needs a new parent (and not a connection) { MgaFCO copy = makeFCO(oldToNewFCO[model as MgaFCO] as MgaModel, childObject.MetaRole.Name); copyFCO(childObject, copy); oldToNewFCO.Add(childObject, copy); } //for directFCOs if (childObject is MgaConnection || childObject is MgaReference) { oldConnsAndRefs.Add(childObject); } if (childObject.ArcheType != null) { oldSubsAndInstances.Add(childObject); } //recursion if (childObject is MgaModel) { createNewFCOs(childObject as MgaModel); } } migratedModels.Add(model); }