Completely rewrite Units.csproj

This commit is contained in:
ig 2023-02-26 15:39:55 +01:00
parent fd1b479783
commit 53737a8e1c
17 changed files with 199 additions and 334 deletions

View File

@ -1,20 +1,17 @@
using DecimalMath; using DecimalMath;
using InnovEnergy.Lib.Units.Generator;
using InnovEnergy.Lib.Utils; using InnovEnergy.Lib.Utils;
namespace InnovEnergy.Lib.Units; namespace InnovEnergy.Lib.Units;
using T = Angle; [Generate]
public readonly partial struct Angle
public readonly struct Angle
{ {
public static String Unit => "rad"; public static String Unit => "rad";
public static String Symbol => "∠"; public static String Symbol => "∠";
public static readonly Angle Pi = new Angle(DecimalEx.Pi); public static readonly Angle Pi = new Angle(DecimalEx.Pi);
public Decimal Value { get; }
public Angle(Decimal value) public Angle(Decimal value)
{ {
@ -25,49 +22,4 @@ public readonly struct Angle
: modulo; : modulo;
} }
public override String ToString() => Value + Unit;
#region scalar multiplication
public static Angle operator *(Decimal scalar, Angle angle ) => new Angle(scalar * angle.Value);
public static Angle operator *(Angle angle , Decimal scalar) => new Angle(scalar * angle.Value);
public static Angle operator /(Angle angle , Decimal scalar) => new Angle(angle.Value / scalar);
#endregion
#region addition
public static T operator +(T left, T right) => new T(left.Value + right.Value);
public static T operator -(T left, T right) => new T(left.Value - right.Value);
public static T operator -(T t) => new T(-t.Value);
#endregion
#region compare
public static Boolean operator ==(T left, T right) => left.Value == right.Value;
public static Boolean operator !=(T left, T right) => left.Value != right.Value;
public static Boolean operator > (T left, T right) => left.Value > right.Value;
public static Boolean operator < (T left, T right) => left.Value < right.Value;
public static Boolean operator >=(T left, T right) => left.Value >= right.Value;
public static Boolean operator <=(T left, T right) => left.Value <= right.Value;
#endregion
#region conversion
public static implicit operator T(Decimal d) => new T(d);
public static implicit operator T(Double d) => new T((Decimal)d);
public static implicit operator T(Int32 i) => new T(i);
public static implicit operator Decimal(T t) => t.Value;
#endregion
#region equality
public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
public override Int32 GetHashCode() => Value.GetHashCode();
#endregion
} }

View File

@ -0,0 +1,16 @@
using InnovEnergy.Lib.Units.Generator;
namespace InnovEnergy.Lib.Units;
[Generate]
public readonly partial struct ApparentPower
{
public static String Unit => "VA";
public static String Symbol => "S";
public ApparentPower(Decimal value)
{
if (value < 0) throw new ArgumentException("Apparent power cannot be negative", nameof(value));
Value = value;
}
}

View File

@ -1,10 +1,10 @@
namespace InnovEnergy.Lib.Units.Composite; namespace InnovEnergy.Lib.Units.Composite;
public record Ac1Phase public record Ac1Phase
( (
Voltage Voltage, Voltage Voltage,
Current Current, Current Current,
Angle Phi, Angle Phi,
Frequency Frequency Frequency Frequency
) : ) :
AcPhase(Voltage, Current, Phi); AcPhase(Voltage, Current, Phi);

View File

@ -1,8 +1,12 @@
using static DecimalMath.DecimalEx;
namespace InnovEnergy.Lib.Units.Composite; namespace InnovEnergy.Lib.Units.Composite;
public record Ac3Phase(AcPhase L1, AcPhase L2, AcPhase L3, Decimal Frequency) public record Ac3Phase(AcPhase L1, AcPhase L2, AcPhase L3, Decimal Frequency)
{ {
public Power ApparentPower => L1.ApparentPower + L2.ApparentPower + L3.ApparentPower; public ApparentPower ApparentPower => L1.ApparentPower + L2.ApparentPower + L3.ApparentPower;
public Power ReactivePower => L1.ReactivePower + L2.ReactivePower + L3.ReactivePower; public ReactivePower ReactivePower => L1.ReactivePower + L2.ReactivePower + L3.ReactivePower;
public Power ActivePower => L1.ActivePower + L2.ActivePower + L3.ActivePower; public Power ActivePower => L1.ActivePower + L2.ActivePower + L3.ActivePower;
public Angle Phi => ATan2(ReactivePower, ActivePower);
} }

View File

@ -5,7 +5,7 @@ namespace InnovEnergy.Lib.Units.Composite;
public record AcPhase : Phase public record AcPhase : Phase
{ {
protected AcPhase(Voltage voltage, Current current, Angle phi) : base(voltage, current) public AcPhase(Voltage voltage, Current current, Angle phi) : base(voltage, current)
{ {
if (voltage < 0) throw new ArgumentException("RMS value cannot be negative", nameof(voltage)); if (voltage < 0) throw new ArgumentException("RMS value cannot be negative", nameof(voltage));
if (current < 0) throw new ArgumentException("RMS value cannot be negative", nameof(current)); if (current < 0) throw new ArgumentException("RMS value cannot be negative", nameof(current));
@ -15,8 +15,8 @@ public record AcPhase : Phase
public Angle Phi { get; } public Angle Phi { get; }
public Power ApparentPower => Voltage * Current; public ApparentPower ApparentPower => Math.Abs(Voltage.Value * Current.Value) ;
public Power ActivePower => ApparentPower * PowerFactor; public Power ActivePower => ApparentPower.Value * PowerFactor;
public Power ReactivePower => ApparentPower * Sin(Phi); public ReactivePower ReactivePower => ApparentPower.Value * Sin(Phi);
public Decimal PowerFactor => Cos(Phi); public Decimal PowerFactor => Cos(Phi);
} }

View File

@ -1,59 +1,13 @@
using InnovEnergy.Lib.Units.Generator;
namespace InnovEnergy.Lib.Units; namespace InnovEnergy.Lib.Units;
using T = Frequency;
public readonly struct Frequency [Generate]
public readonly partial struct Frequency
{ {
public static String Unit => "Hz"; public static String Unit => "Hz";
public static String Symbol => "f"; public static String Symbol => "f";
public Decimal Value { get; }
public Frequency(Decimal value) => Value = value; public Frequency(Decimal value) => Value = value;
public override String ToString() => Value + Unit;
#region scalar multiplication
public static T operator *(Decimal scalar, T t) => new T(scalar * t.Value);
public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value);
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
#endregion
#region addition
public static T operator +(T left, T right) => new T(left.Value + right.Value);
public static T operator -(T left, T right) => new T(left.Value - right.Value);
public static T operator -(T t) => new T(-t.Value);
#endregion
#region compare
public static Boolean operator ==(T left, T right) => left.Value == right.Value;
public static Boolean operator !=(T left, T right) => left.Value != right.Value;
public static Boolean operator > (T left, T right) => left.Value > right.Value;
public static Boolean operator < (T left, T right) => left.Value < right.Value;
public static Boolean operator >=(T left, T right) => left.Value >= right.Value;
public static Boolean operator <=(T left, T right) => left.Value <= right.Value;
#endregion
#region conversion
public static implicit operator T(Decimal d) => new T(d);
public static implicit operator T(Double d) => new T((Decimal)d);
public static implicit operator T(Int32 i) => new T(i);
public static implicit operator Decimal(T t) => t.Value;
#endregion
#region equality
public Boolean Equals(T other) => Value == other.Value;
public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
public override Int32 GetHashCode() => Value.GetHashCode();
#endregion
} }

View File

@ -0,0 +1,5 @@
namespace InnovEnergy.Lib.Units.Generator;
[AttributeUsage(AttributeTargets.Struct)]
internal class GenerateAttribute: Attribute
{}

View File

@ -0,0 +1,46 @@
#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
namespace InnovEnergy.Lib.Units;
using T = Template;
public readonly partial struct Template
{
public Decimal Value { get; }
public override String ToString() => Value + Unit;
// scalar multiplication
public static T operator *(Decimal scalar, T t) => new T(scalar * t.Value);
public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value);
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
// addition
public static T operator +(T left, T right) => new T(left.Value + right.Value);
public static T operator -(T left, T right) => new T(left.Value - right.Value);
public static T operator -(T t) => new T(-t.Value);
// compare
public static Boolean operator ==(T left, T right) => left.Value == right.Value;
public static Boolean operator !=(T left, T right) => left.Value != right.Value;
public static Boolean operator > (T left, T right) => left.Value > right.Value;
public static Boolean operator < (T left, T right) => left.Value < right.Value;
public static Boolean operator >=(T left, T right) => left.Value >= right.Value;
public static Boolean operator <=(T left, T right) => left.Value <= right.Value;
// conversion
public static implicit operator T(Decimal d) => new T(d);
public static implicit operator T(Double d) => new T((Decimal)d);
public static implicit operator T(Int32 i) => new T(i);
public static implicit operator Decimal(T t) => t.Value;
// equality
public Boolean Equals(T other) => Value == other.Value;
public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
public override Int32 GetHashCode() => Value.GetHashCode();
}

View File

@ -0,0 +1,13 @@
#!/usr/bin/env bash
scriptDir=$( dirname -- "$0"; )
cd "$scriptDir/.." || exit
for file in $(grep -l '\[Generate\]' *.cs)
do
filename=$(basename -- "$file")
class="${filename%.*}"
echo "generating $filename"
sed "s/Template/$class/g" "./Generator/Template.txt" > "./$class.generated.cs"
done

View File

@ -1,66 +1,19 @@
using InnovEnergy.Lib.Units.Generator;
namespace InnovEnergy.Lib.Units; namespace InnovEnergy.Lib.Units;
using T = Power; [Generate]
public readonly partial struct Power
public readonly struct Power
{ {
public static String Unit => "W"; public static String Unit => "W";
public static String Symbol => "P"; public static String Symbol => "P";
public Decimal Value { get; }
public Power(Decimal value) => Value = value; public Power(Decimal value) => Value = value;
public override String ToString() => Value + Unit;
// P=UI // P=UI
public static Voltage operator /(Power power, Current current) => new Voltage(power.Value / current.Value); public static Voltage operator /(Power power, Current current) => new Voltage(power.Value / current.Value);
public static Current operator /(Power power, Voltage voltage) => new Current(power.Value / voltage.Value); public static Current operator /(Power power, Voltage voltage) => new Current(power.Value / voltage.Value);
#region scalar multiplication
public static T operator *(Decimal scalar, T t) => new T(scalar * t.Value);
public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value);
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
#endregion
#region addition
public static T operator +(T left, T right) => new T(left.Value + right.Value);
public static T operator -(T left, T right) => new T(left.Value - right.Value);
public static T operator -(T t) => new T(-t.Value);
#endregion
#region compare
public static Boolean operator ==(T left, T right) => left.Value == right.Value;
public static Boolean operator !=(T left, T right) => left.Value != right.Value;
public static Boolean operator > (T left, T right) => left.Value > right.Value;
public static Boolean operator < (T left, T right) => left.Value < right.Value;
public static Boolean operator >=(T left, T right) => left.Value >= right.Value;
public static Boolean operator <=(T left, T right) => left.Value <= right.Value;
#endregion
#region conversion
public static implicit operator T(Decimal d) => new T(d);
public static implicit operator T(Double d) => new T((Decimal)d);
public static implicit operator T(Int32 i) => new T(i);
public static implicit operator Decimal(T t) => t.Value;
#endregion
#region equality
public Boolean Equals(T other) => Value == other.Value;
public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
public override Int32 GetHashCode() => Value.GetHashCode();
#endregion
} }

View File

@ -0,0 +1,46 @@
#nullable enable // Auto-generated code requires an explicit '#nullable' directive in source.
namespace InnovEnergy.Lib.Units;
using T = ReactivePower;
public readonly partial struct ReactivePower
{
public Decimal Value { get; }
public override String ToString() => Value + Unit;
// scalar multiplication
public static T operator *(Decimal scalar, T t) => new T(scalar * t.Value);
public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value);
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
// addition
public static T operator +(T left, T right) => new T(left.Value + right.Value);
public static T operator -(T left, T right) => new T(left.Value - right.Value);
public static T operator -(T t) => new T(-t.Value);
// compare
public static Boolean operator ==(T left, T right) => left.Value == right.Value;
public static Boolean operator !=(T left, T right) => left.Value != right.Value;
public static Boolean operator > (T left, T right) => left.Value > right.Value;
public static Boolean operator < (T left, T right) => left.Value < right.Value;
public static Boolean operator >=(T left, T right) => left.Value >= right.Value;
public static Boolean operator <=(T left, T right) => left.Value <= right.Value;
// conversion
public static implicit operator T(Decimal d) => new T(d);
public static implicit operator T(Double d) => new T((Decimal)d);
public static implicit operator T(Int32 i) => new T(i);
public static implicit operator Decimal(T t) => t.Value;
// equality
public Boolean Equals(T other) => Value == other.Value;
public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
public override Int32 GetHashCode() => Value.GetHashCode();
}

View File

@ -0,0 +1,13 @@
using InnovEnergy.Lib.Units.Generator;
namespace InnovEnergy.Lib.Units;
[Generate]
public readonly partial struct ReactivePower
{
public static String Unit => "var";
public static String Symbol => "Q";
public ReactivePower(Decimal value) => Value = value;
}

View File

@ -1,63 +1,19 @@
using InnovEnergy.Lib.Units.Generator;
namespace InnovEnergy.Lib.Units; namespace InnovEnergy.Lib.Units;
using T = Resistance; [Generate]
public readonly partial struct Resistance
public readonly struct Resistance
{ {
public static String Unit => "Ω"; public static String Unit => "Ω";
public static String Symbol => "R"; public static String Symbol => "R";
public Decimal Value { get; }
public Resistance(Decimal value) => Value = value; public Resistance(Decimal value) => Value = value;
public override String ToString() => Value + Unit;
// U=RI // U=RI
public static Voltage operator *(Resistance resistance, Current current) => new Voltage(resistance.Value * current.Value); public static Voltage operator *(Resistance resistance, Current current) => new Voltage(resistance.Value * current.Value);
#region scalar multiplication
public static T operator *(Decimal scalar, T t) => new T(scalar * t.Value);
public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value);
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
#endregion
#region addition
public static T operator +(T left, T right) => new T(left.Value + right.Value);
public static T operator -(T left, T right) => new T(left.Value - right.Value);
public static T operator -(T t) => new T(-t.Value);
#endregion
#region compare
public static Boolean operator ==(T left, T right) => left.Value == right.Value;
public static Boolean operator !=(T left, T right) => left.Value != right.Value;
public static Boolean operator > (T left, T right) => left.Value > right.Value;
public static Boolean operator < (T left, T right) => left.Value < right.Value;
public static Boolean operator >=(T left, T right) => left.Value >= right.Value;
public static Boolean operator <=(T left, T right) => left.Value <= right.Value;
#endregion
#region conversion
public static implicit operator T(Decimal d) => new T(d);
public static implicit operator T(Double d) => new T((Decimal)d);
public static implicit operator T(Int32 i) => new T(i);
public static implicit operator Decimal(T t) => t.Value;
#endregion
#region equality
public Boolean Equals(T other) => Value == other.Value;
public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
public override Int32 GetHashCode() => Value.GetHashCode();
#endregion
} }

View File

@ -1,61 +1,12 @@
using InnovEnergy.Lib.Units.Generator;
namespace InnovEnergy.Lib.Units; namespace InnovEnergy.Lib.Units;
using T = Temperature; [Generate]
public readonly partial struct Temperature
public readonly struct Temperature
{ {
public static String Unit => "°C"; public static String Unit => "°C";
public static String Symbol => "T"; public static String Symbol => "T";
public Decimal Value { get; }
public Temperature(Decimal value) => Value = value; public Temperature(Decimal value) => Value = value;
public override String ToString() => Value + Unit;
#region scalar multiplication
public static T operator *(Decimal scalar, T t) => new T(scalar * t.Value);
public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value);
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
#endregion
#region addition
public static T operator +(T left, T right) => new T(left.Value + right.Value);
public static T operator -(T left, T right) => new T(left.Value - right.Value);
public static T operator -(T t) => new T(-t.Value);
#endregion
#region compare
public static Boolean operator ==(T left, T right) => left.Value == right.Value;
public static Boolean operator !=(T left, T right) => left.Value != right.Value;
public static Boolean operator > (T left, T right) => left.Value > right.Value;
public static Boolean operator < (T left, T right) => left.Value < right.Value;
public static Boolean operator >=(T left, T right) => left.Value >= right.Value;
public static Boolean operator <=(T left, T right) => left.Value <= right.Value;
#endregion
#region conversion
public static implicit operator T(Decimal d) => new T(d);
public static implicit operator T(Double d) => new T((Decimal)d);
public static implicit operator T(Int32 i) => new T(i);
public static implicit operator Decimal(T t) => t.Value;
#endregion
#region equality
public Boolean Equals(T other) => Value == other.Value;
public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
public override Int32 GetHashCode() => Value.GetHashCode();
#endregion
} }

View File

@ -5,16 +5,23 @@ namespace InnovEnergy.Lib.Units;
public static class Units public static class Units
{ {
public static Current A (this Decimal value) => new Current(value); public static Current A (this Decimal value) => new Current(value);
public static Voltage V (this Decimal value) => new Voltage(value); public static Voltage V (this Decimal value) => new Voltage(value);
public static Power W (this Decimal value) => new Power(value); public static Power W (this Decimal value) => new Power(value);
public static Resistance Ohm(this Decimal value) => new Resistance(value); public static ReactivePower Var (this Decimal value) => new ReactivePower(value);
public static ApparentPower Va (this Decimal value) => new ApparentPower(value);
public static Resistance Ohm (this Decimal value) => new Resistance(value);
public static Frequency Hz (this Decimal value) => new Frequency(value);
public static Angle Rad (this Decimal value) => new Angle(value);
public static Temperature Celsius(this Decimal value) => new Temperature(value);
public static readonly IReadOnlyList<JsonConverter> JsonConverters = new JsonConverter[] public static readonly IReadOnlyList<JsonConverter> JsonConverters = new JsonConverter[]
{ {
new CurrentConverter(), new CurrentConverter(),
new VoltageConverter(), new VoltageConverter(),
new PowerConverter(), new PowerConverter(),
new ResistanceConverter() new ResistanceConverter(),
// TODO
}; };
} }

View File

@ -1,11 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<Import Project="../InnovEnergy.Lib.props" /> <Import Project="../InnovEnergy.Lib.props" />
<PropertyGroup>
<OutputType>Library</OutputType>
<LangVersion>preview</LangVersion>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="DecimalMath.DecimalEx" Version="1.0.2" /> <PackageReference Include="DecimalMath.DecimalEx" Version="1.0.2" />
</ItemGroup> </ItemGroup>
@ -14,4 +9,8 @@
<ProjectReference Include="..\Utils\Utils.csproj" /> <ProjectReference Include="..\Utils\Utils.csproj" />
</ItemGroup> </ItemGroup>
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
<Exec Command="./Generator/generate.sh" />
</Target>
</Project> </Project>

View File

@ -1,69 +1,19 @@
using InnovEnergy.Lib.Units.Generator;
namespace InnovEnergy.Lib.Units; namespace InnovEnergy.Lib.Units;
using T = Voltage; [Generate]
public readonly partial struct Voltage
public readonly struct Voltage
{ {
public static String Unit => "V"; public static String Unit => "V";
public static String Symbol => "U"; public static String Symbol => "U";
public Decimal Value { get; }
public Voltage(Decimal value) => Value = value; public Voltage(Decimal value) => Value = value;
public override String ToString() => Value + Unit;
// U=RI // U=RI
public static Current operator /(Voltage voltage, Resistance resistance) => new Current(voltage.Value / resistance.Value); public static Current operator /(Voltage voltage, Resistance resistance) => new Current(voltage.Value / resistance.Value);
// P=UI // P=UI
public static Power operator *(Voltage voltage, Current current) => new Power(current.Value * voltage.Value); public static Power operator *(Voltage voltage, Current current) => new Power(current.Value * voltage.Value);
#region scalar multiplication
public static T operator *(Decimal scalar, T t) => new T(scalar * t.Value);
public static T operator *(T t, Decimal scalar) => new T(scalar * t.Value);
public static T operator /(T t, Decimal scalar) => new T(t.Value / scalar);
#endregion
#region addition
public static T operator +(T left, T right) => new T(left.Value + right.Value);
public static T operator -(T left, T right) => new T(left.Value - right.Value);
public static T operator -(T t) => new T(-t.Value);
#endregion
#region compare
public static Boolean operator ==(T left, T right) => left.Value == right.Value;
public static Boolean operator !=(T left, T right) => left.Value != right.Value;
public static Boolean operator > (T left, T right) => left.Value > right.Value;
public static Boolean operator < (T left, T right) => left.Value < right.Value;
public static Boolean operator >=(T left, T right) => left.Value >= right.Value;
public static Boolean operator <=(T left, T right) => left.Value <= right.Value;
#endregion
#region conversion
public static implicit operator T(Decimal d) => new T(d);
public static implicit operator T(Double d) => new T((Decimal)d);
public static implicit operator T(Int32 i) => new T(i);
public static implicit operator Decimal(T t) => t.Value;
#endregion
#region equality
public Boolean Equals(T other) => Value == other.Value;
public override Boolean Equals(Object? obj) => obj is T other && Equals(other);
public override Int32 GetHashCode() => Value.GetHashCode();
#endregion
} }