public KnownUOM FindFromDimensions(Dimensions dimensions, bool bAllowCreate, out bool wasCreated, string name = null) { if (bAllowCreate && !IsConsistent()) { bAllowCreate = false; // Only makes sense to create base units in a consistent set } wasCreated = false; if (dimensions == null) { return(null); } foreach (var item in KnownUOMs) { if (item.Dimensions.Equals(dimensions)) { return(item); } } if (bAllowCreate && IsConsistent() && !Dimensions.IsDimenionless(dimensions)) { wasCreated = true; string sName = name; if (string.IsNullOrEmpty(sName)) { string sTop = ""; string sBottom = ""; AddUomStringPart(DimType.Mass, dimensions.Mass, ref sTop, ref sBottom); AddUomStringPart(DimType.Length, dimensions.Length, ref sTop, ref sBottom); AddUomStringPart(DimType.Time, dimensions.Time, ref sTop, ref sBottom); AddUomStringPart(DimType.ElectricCurrent, dimensions.ElectricCurrent, ref sTop, ref sBottom); AddUomStringPart(DimType.Temperature, dimensions.Temperature, ref sTop, ref sBottom); AddUomStringPart(DimType.QuantityOfSubstance, dimensions.QuantityOfSubstance, ref sTop, ref sBottom); AddUomStringPart(DimType.Luminosity, dimensions.Luminosity, ref sTop, ref sBottom); AddUomStringPart(DimType.PlaneAngle, dimensions.PlaneAngle, ref sTop, ref sBottom); AddUomStringPart(DimType.SolidAngle, dimensions.SolidAngle, ref sTop, ref sBottom); AddUomStringPart(DimType.Currency, dimensions.Currency, ref sTop, ref sBottom); sName = string.Format("{0}{1}{2}", (sTop.Length == 0 ? "1" : sTop), (sBottom.Length == 0 ? "" : "/"), (sBottom.Length == 0 ? "" : sBottom)); } KnownUOM uom = new KnownUOM("", dimensions, Name: sName, Description: sName, Symbol: sName, IsBase: true, BaseUOM: null, AFactor: 0, BFactor: 1, CFactor: 1, DFactor: 0); KnownUOMs.Add(uom); return(uom); } else { return(ParentUomSet?.FindFromDimensions(dimensions, bAllowCreate, out wasCreated)); } return(null); }
public ParamType(string packageName, string name, string description, string siBaseUom, Dimensions dimensions, int popularity) { Name = name; Description = description; Dimensions = dimensions; Popularity = popularity; PackageName = packageName; if (!Dimensions.IsDimenionless(dimensions)) { Result <KnownUOM> r_SIBaseUom = ContentManager.SiBaseUomFromDimensions(dimensions, siBaseUom); if (r_SIBaseUom.IsGood()) { SIBaseUom = r_SIBaseUom.Value; } else { throw new UnspecifiedException(r_SIBaseUom.Message); } } }
} // Safe symbol to use in pure text scenarios // --------------------------- /// <summary> /// Calculate the function as much as possible. /// For 'NormalFunction' objects we expect that the result is calculated from the args, and we do not change the args. /// However, this is not enforced at this time. /// Special sub-types, such as 'FnEquals', behave differently. /// /// Args will be converted to a consistent UOMSet, unless they are all UOMless, before calling the actual function calc. /// If the function requires any other specific UOM it must do the conversion itself. /// </summary> /// <param name="args"></param> /// <returns></returns> public CalcQuantity Calculate(IList <CalcQuantity> args) { CalcQuantity result = new CalcQuantity(); try { // ------------------- Loop through all the args, checking and converting UOMSet uomSet = null; IList <CalcQuantity> convertedArgs = new List <CalcQuantity>(); bool bStarted = false; for (int i = 0; i < args.Count; i++) { CalcQuantity arg = args[i]; // ------------------- Check for a Bad or missing value if (IsNormalFunction) // Otherwise more flexibility is allowed so we can't demand that all args are known before calculation { switch (arg.CalcStatus) { case CalcStatus.Uknown: case CalcStatus.Bad: result.CalcStatus = arg.CalcStatus; result.Message = "Missing or bad arguments"; return(result); default: break; } } // ------------------- Convert the arg to the same UOMSET CalcQuantity convertedArg = new CalcQuantity(arg); bool bDimLess = Dimensions.IsDimenionless(convertedArg?.AnonUOM?.Dimensions); if (!bDimLess) { if ((uomSet == null) & (!bStarted || !IsNormalFunction)) { bStarted = true; uomSet = convertedArg?.AnonUOM?.UOMSet; } else if (IsNormalFunction && (convertedArg?.AnonUOM?.UOMSet != uomSet)) { if ((uomSet == null) || (convertedArg?.AnonUOM?.UOMSet == null)) { result.CalcStatus = CalcStatus.Bad; result.Message = "Some arguments have units while others do not"; // They must all have a specified UOMSet, or none of them have return(result); } else { // Convert to the uomSet used by other args AnonUOM argUOM = convertedArg.AnonUOM; convertedArg.Value = argUOM.UOMSet.Convert(arg.Value, argUOM.Dimensions, uomSet); convertedArg.AnonUOM = new AnonUOM(argUOM.Dimensions, uomSet); } } } convertedArgs.Add(convertedArg); } // ------------------- Call the concrete implementations to actually do the calcualtion result = Calculate_Here(convertedArgs, uomSet); if (!IsNormalFunction) // Then some args might have been changed by the calculation (e.g. assignment in FnEquals) { for (int i = 0; i < convertedArgs.Count; i++) { convertedArgs[i].CopyMe(args[i]); } } } catch (Exception) { return(new CalcQuantity(0, CalcStatus.Bad, "Unexpected failure", null)); } return(result); }