From 926a52e34e39b73bc52018beaa456295326b02a7 Mon Sep 17 00:00:00 2001 From: Moritz Ruth Date: Fri, 26 May 2023 01:28:37 +0200 Subject: [PATCH] commit #21 --- .../kotlin/de/moritzruth/lampenfieber/Main.kt | 1 - .../kotlin/de/moritzruth/lampenfieber/Test.kt | 3 +- .../de/moritzruth/lampenfieber/act/Fourth.kt | 9 ++- .../theaterdsl/device/DynamicValue.kt | 79 ++++++++++--------- .../theaterdsl/dmx/DmxDataWriter.kt | 2 +- .../de/moritzruth/theaterdsl/dmx/DmxValue.kt | 4 +- .../de/moritzruth/theaterdsl/show/Dsl.kt | 12 ++- .../de/moritzruth/theaterdsl/value/Angle.kt | 14 ++-- .../de/moritzruth/theaterdsl/value/Color.kt | 18 ++--- .../moritzruth/theaterdsl/value/Frequency.kt | 8 +- .../de/moritzruth/theaterdsl/value/Math.kt | 6 +- .../moritzruth/theaterdsl/value/Percentage.kt | 14 ++-- .../theaterdsl/value/RangesAndValues.kt | 32 ++++---- .../theaterdsl/value/Temperature.kt | 2 +- 14 files changed, 105 insertions(+), 99 deletions(-) diff --git a/src/main/kotlin/de/moritzruth/lampenfieber/Main.kt b/src/main/kotlin/de/moritzruth/lampenfieber/Main.kt index 50bd495..288639b 100644 --- a/src/main/kotlin/de/moritzruth/lampenfieber/Main.kt +++ b/src/main/kotlin/de/moritzruth/lampenfieber/Main.kt @@ -9,7 +9,6 @@ import de.moritzruth.theaterdsl.dmx.EnttecOpenDmxUsb import de.moritzruth.theaterdsl.show.createShow import de.moritzruth.theaterdsl.show.runShow -@Suppress("DuplicatedCode") val show = createShow { firstAct() secondAct() diff --git a/src/main/kotlin/de/moritzruth/lampenfieber/Test.kt b/src/main/kotlin/de/moritzruth/lampenfieber/Test.kt index b504a4d..d5505e8 100644 --- a/src/main/kotlin/de/moritzruth/lampenfieber/Test.kt +++ b/src/main/kotlin/de/moritzruth/lampenfieber/Test.kt @@ -4,6 +4,7 @@ import de.moritzruth.lampenfieber.device.devices import de.moritzruth.theaterdsl.dmx.EnttecOpenDmxUsb import de.moritzruth.theaterdsl.dmx.PerDeviceDmxDataWriter import kotlinx.coroutines.awaitCancellation +import kotlinx.coroutines.coroutineScope suspend fun main() { EnttecOpenDmxUsb.start() @@ -23,6 +24,6 @@ suspend fun main() { awaitCancellation() } -fun test() { +suspend fun test() = coroutineScope { } \ No newline at end of file diff --git a/src/main/kotlin/de/moritzruth/lampenfieber/act/Fourth.kt b/src/main/kotlin/de/moritzruth/lampenfieber/act/Fourth.kt index dd04c33..1aa77ed 100644 --- a/src/main/kotlin/de/moritzruth/lampenfieber/act/Fourth.kt +++ b/src/main/kotlin/de/moritzruth/lampenfieber/act/Fourth.kt @@ -353,6 +353,7 @@ fun ShowBuilderContext.fourthAct() = act("Vierter Akt") { step(StepCue.MusicEnd) { actors { -"Paula" + -"David" -"Theaterlehrer" -"Sven" -"Heike" @@ -403,10 +404,6 @@ fun ShowBuilderContext.fourthAct() = act("Vierter Akt") { scene("10") { step(StepCue.Text("Kai", "Hilfe, los, runter!")) { - actors { - +"Paula / steht bei Markierung" - } - curtainState = CurtainState.OPEN onRun { @@ -415,6 +412,10 @@ fun ShowBuilderContext.fourthAct() = act("Vierter Akt") { } step(StepCue.Curtain(CurtainState.OPEN, false)) { + actors { + +"Paula / steht bei Markierung" + } + onRun { Tops.both.forEach { it.brightness.fade(50.percent, 1.5.seconds) } bar.color.static(Color.WHITE) diff --git a/src/main/kotlin/de/moritzruth/theaterdsl/device/DynamicValue.kt b/src/main/kotlin/de/moritzruth/theaterdsl/device/DynamicValue.kt index 754fa38..d1f0462 100644 --- a/src/main/kotlin/de/moritzruth/theaterdsl/device/DynamicValue.kt +++ b/src/main/kotlin/de/moritzruth/theaterdsl/device/DynamicValue.kt @@ -19,33 +19,32 @@ interface DynamicValue { } @OptIn(ExperimentalTime::class) -abstract class FloatDV(private val initialStaticValue: Float) : DynamicValue { +abstract class DoubleDV(private val initialStaticValue: Double) : DynamicValue { private sealed interface State { - data class Static(val value: Float) : State + data class Static(val value: Double) : State - data class Fade(val start: Float, val end: Float, val duration: Duration) : State { + data class Fade(val start: Double, val end: Double, val duration: Duration) : State { val delta = end - start } data class Sine( - val offset: Double, - val minimum: Float, - val maximum: Float, - val period: Duration + val minimum: Double, + val maximum: Double, + val b: Double, + val c: Double ) : State { companion object { - fun calculateA(minimum: Float, maximum: Float) = (maximum - minimum) * 0.5 - fun calculateX(progress: Double, offset: Double) = 2 * PI * progress - offset - fun calculateD(minimum: Float) = 0.5 + minimum + fun calculateB(period: Duration) = period.inWholeMilliseconds / (2 * PI) + fun calculateX(elapsedTime: Duration, b: Double, c: Double) = b * elapsedTime.inWholeMilliseconds + c } } - data class Step(val steps: ImmutableList, val interval: Duration, val startIndex: Int) : State - data class PulseOnce(val rampUpDuration: Duration, val rampDownDuration: Duration, val peakValue: Float, val start: Float, val end: Float) : State + data class Step(val steps: ImmutableList, val interval: Duration, val startIndex: Int) : State + data class PulseOnce(val rampUpDuration: Duration, val rampDownDuration: Duration, val peakValue: Double, val start: Double, val end: Double) : State } - protected abstract fun toDomain(value: Float): T - protected abstract fun fromDomain(value: T): Float + protected abstract fun toDomain(value: Double): T + protected abstract fun fromDomain(value: T): Double protected abstract val minimumValue: T protected abstract val maximumValue: T @@ -63,15 +62,12 @@ abstract class FloatDV(private val initialStaticValue: Float) : DynamicValue< override fun getCurrentValue(): T { val elapsedTime = stateChangeMark.elapsedNow() - val float = when (val s = state) { + val double = when (val s = state) { is State.Static -> s.value - is State.Fade -> (min(elapsedTime / s.duration, 1.0) * s.delta + s.start).toFloat() + is State.Fade -> (min(elapsedTime / s.duration, 1.0) * s.delta + s.start) is State.Sine -> { - val a = State.Sine.calculateA(s.minimum, s.maximum) - val x = State.Sine.calculateX(elapsedTime / s.period, s.offset) - val d = State.Sine.calculateD(s.minimum) - - (a * sin(x) + d).toFloat() + val fromZeroToOne = (sin(State.Sine.calculateX(elapsedTime, s.b, s.c)) + 1) / 2 + (fromZeroToOne * (s.maximum - s.minimum) + s.minimum) } is State.Step -> { @@ -83,16 +79,16 @@ abstract class FloatDV(private val initialStaticValue: Float) : DynamicValue< if (elapsedTime <= s.rampUpDuration) { val progress = elapsedTime / s.rampUpDuration val delta = s.peakValue - s.start - (progress * delta + s.start).toFloat() + (progress * delta + s.start) } else { val progress = min(elapsedTime / s.rampDownDuration, 1.0) val delta = s.peakValue - s.end - (s.peakValue - progress * delta).toFloat() + (s.peakValue - progress * delta) } } } - return toDomain(float) + return toDomain(double) } fun static(value: T) { @@ -108,9 +104,14 @@ abstract class FloatDV(private val initialStaticValue: Float) : DynamicValue< } fun sine(period: Duration, minimum: T = minimumValue, maximum: T = maximumValue, start: T = getCurrentValue()) { - val coercedStart = fromDomain(start).coerceIn(fromDomain(minimum), fromDomain(maximum)) - val offset = asin((coercedStart - State.Sine.calculateD(fromDomain(minimum))) / State.Sine.calculateA(fromDomain(minimum), fromDomain(maximum))) - state = State.Sine(offset, fromDomain(minimum), fromDomain(maximum), period) + val b = State.Sine.calculateB(period) + val doubleMinimum = fromDomain(minimum) + val doubleMaximum = fromDomain(maximum) + val delta = doubleMaximum - doubleMinimum + + val coercedStart = fromDomain(start).coerceIn(doubleMinimum, fromDomain(maximum)) + val c = asin(2 * ((coercedStart - doubleMinimum) / delta) - 1) + state = State.Sine(fromDomain(minimum), fromDomain(maximum), b, c) } fun steps(steps: List, interval: Duration, startIndex: Int = 0) { @@ -132,16 +133,16 @@ abstract class FloatDV(private val initialStaticValue: Float) : DynamicValue< } } -class PercentageDV(initialStaticValue: Percentage = 0.percent) : FloatDV(initialStaticValue.value) { - override fun fromDomain(value: Percentage): Float = value.value - override fun toDomain(value: Float): Percentage = Percentage(value) +class PercentageDV(initialStaticValue: Percentage = 0.percent) : DoubleDV(initialStaticValue.value) { + override fun fromDomain(value: Percentage): Double = value.value + override fun toDomain(value: Double): Percentage = Percentage(value) override val minimumValue: Percentage = 0.percent override val maximumValue: Percentage = 100.percent } -class AngleDV(initialStaticValue: Angle = 0.degrees) : FloatDV(initialStaticValue.degrees) { - override fun fromDomain(value: Angle): Float = value.degrees - override fun toDomain(value: Float): Angle = Angle(value) +class AngleDV(initialStaticValue: Angle = 0.degrees) : DoubleDV(initialStaticValue.degrees) { + override fun fromDomain(value: Angle): Double = value.degrees + override fun toDomain(value: Double): Angle = Angle(value) override val minimumValue: Angle = 0.degrees override val maximumValue: Angle = 360.degrees } @@ -199,9 +200,9 @@ class ColorDV(private val initialStaticValue: Color = Color.WHITE) : DynamicValu val progress = min(elapsedTime / s.duration, 1.0) Color( - hue = Angle((s.start.hue.degrees + s.deltaHue * progress).toFloat()), - saturation = Percentage((s.start.saturation.value + s.deltaSaturation * progress).toFloat()), - brightness = Percentage((s.start.brightness.value + s.deltaBrightness * progress).toFloat()) + hue = Angle((s.start.hue.degrees + s.deltaHue * progress)), + saturation = Percentage((s.start.saturation.value + s.deltaSaturation * progress)), + brightness = Percentage((s.start.brightness.value + s.deltaBrightness * progress)) ) } @@ -209,11 +210,11 @@ class ColorDV(private val initialStaticValue: Color = Color.WHITE) : DynamicValu val startRandom = Random((elapsedTime / s.interval).toInt() - 1) val endRandom = Random((elapsedTime / s.interval).toInt()) val progress = (elapsedTime / s.interval).mod(1.0) - val startHue = s.hue.degrees - s.deviation.degrees + startRandom.nextFloat() * s.deviation.degrees * 2 - val endHue = s.hue.degrees - s.deviation.degrees + endRandom.nextFloat() * s.deviation.degrees * 2 + val startHue = s.hue.degrees - s.deviation.degrees + startRandom.nextDouble() * s.deviation.degrees * 2 + val endHue = s.hue.degrees - s.deviation.degrees + endRandom.nextDouble() * s.deviation.degrees * 2 val delta = endHue - startHue - Color(hue = Angle((progress * delta).toFloat())) + Color(hue = Angle((progress * delta))) } } } diff --git a/src/main/kotlin/de/moritzruth/theaterdsl/dmx/DmxDataWriter.kt b/src/main/kotlin/de/moritzruth/theaterdsl/dmx/DmxDataWriter.kt index 80767c4..67ef96d 100644 --- a/src/main/kotlin/de/moritzruth/theaterdsl/dmx/DmxDataWriter.kt +++ b/src/main/kotlin/de/moritzruth/theaterdsl/dmx/DmxDataWriter.kt @@ -10,7 +10,7 @@ interface DmxDataWriter { /** * @param startAtOne Whether the written value is in `1..255` or in `0..255`. */ - fun writeInRange(range: ClosedFloatingPointRange, value: Float, startAtOne: Boolean = false) = + fun writeInRange(range: ClosedFloatingPointRange, value: Double, startAtOne: Boolean = false) = writeRaw(Percentage((value - range.start) / (range.endInclusive - range.start)).roundToDmxValue(startAtOne)) fun writeHighByte(value: UShort) = writeRaw(DmxValue(value.toUInt().shr(8).toUByte())) diff --git a/src/main/kotlin/de/moritzruth/theaterdsl/dmx/DmxValue.kt b/src/main/kotlin/de/moritzruth/theaterdsl/dmx/DmxValue.kt index b46a121..22cce9a 100644 --- a/src/main/kotlin/de/moritzruth/theaterdsl/dmx/DmxValue.kt +++ b/src/main/kotlin/de/moritzruth/theaterdsl/dmx/DmxValue.kt @@ -16,5 +16,5 @@ value class DmxValue(val value: UByte) : Comparable { * @param startAtOne Whether the output range is `1..255` or `0..255`. */ fun Percentage.roundToDmxValue(startAtOne: Boolean = false): DmxValue = - if (startAtOne) DmxValue(((value * (DmxValue.VALUE_RANGE.last.toFloat() - 1f)).roundToInt() + 1).toUByte()) - else DmxValue((value * DmxValue.VALUE_RANGE.last.toFloat()).roundToInt().toUByte()) \ No newline at end of file + if (startAtOne) DmxValue(((value * (DmxValue.VALUE_RANGE.last.toDouble() - 1f)).roundToInt() + 1).toUByte()) + else DmxValue((value * DmxValue.VALUE_RANGE.last.toDouble()).roundToInt().toUByte()) \ No newline at end of file diff --git a/src/main/kotlin/de/moritzruth/theaterdsl/show/Dsl.kt b/src/main/kotlin/de/moritzruth/theaterdsl/show/Dsl.kt index ac0a624..2d81c1f 100644 --- a/src/main/kotlin/de/moritzruth/theaterdsl/show/Dsl.kt +++ b/src/main/kotlin/de/moritzruth/theaterdsl/show/Dsl.kt @@ -88,7 +88,7 @@ private fun buildAct(actIndex: Int, actName: String, build: ActBuilderContext.() var leftSpotTarget: String? var rightSpotTarget: String? - var curtainState = CurtainState.CLOSED + var curtainState_ = CurtainState.CLOSED object : ActBuilderContext { override fun scene(@Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE") sceneName: String, build: SceneBuilderContext.() -> Unit) { @@ -111,7 +111,11 @@ private fun buildAct(actIndex: Int, actName: String, build: ActBuilderContext.() override val props = PropsBuilderMap(changedProps) override var rightSpotTarget: String? = null override var leftSpotTarget: String? = null - override var curtainState: CurtainState by ::curtainState + override var curtainState: CurtainState + get() = curtainState_ + set(value) { + curtainState_ = value + } override fun actors(build: ActorsBuildContext.() -> Unit) { ActorsBuildContext(actorEntrances, actorExits).build() @@ -155,7 +159,7 @@ private fun buildAct(actIndex: Int, actName: String, build: ActBuilderContext.() logger.warn("These actors cannot enter because they are already on the stage: ${addedActorsAlreadyOnStage.joinToString()}") } - actorsOnStage.removeAll(actorExitsNames) + actorsOnStage.removeAll(actorExitsNames.toSet()) actorsOnStage.addAll(actorEntrancesNames) changedProps.forEach { (k, v) -> props[k] = v } @@ -171,7 +175,7 @@ private fun buildAct(actIndex: Int, actName: String, build: ActBuilderContext.() changedProps.isNotEmpty(), leftSpotTarget, rightSpotTarget, - curtainState, + curtainState_, runner ) ) diff --git a/src/main/kotlin/de/moritzruth/theaterdsl/value/Angle.kt b/src/main/kotlin/de/moritzruth/theaterdsl/value/Angle.kt index ad2f71c..ba98d15 100644 --- a/src/main/kotlin/de/moritzruth/theaterdsl/value/Angle.kt +++ b/src/main/kotlin/de/moritzruth/theaterdsl/value/Angle.kt @@ -1,13 +1,13 @@ package de.moritzruth.theaterdsl.value @JvmInline -value class Angle(val degrees: Float) : Comparable { +value class Angle(val degrees: Double) : Comparable { override fun toString(): String = "${degrees}°" override fun compareTo(other: Angle): Int = degrees.compareTo(other.degrees) fun inSingleRotation(): Angle = Angle( - if (degrees == 360f || degrees == -360f) degrees + if (degrees == 360.0 || degrees == -360.0) degrees else degrees.mod(360f) ) @@ -17,18 +17,18 @@ value class Angle(val degrees: Float) : Comparable { ): ClosedFloatingPointRange { override fun lessThanOrEquals(a: Angle, b: Angle): Boolean = a.degrees <= b.degrees - fun asFloatRange(): ClosedFloatingPointRange = start.degrees..endInclusive.degrees + fun asDoubleRange(): ClosedFloatingPointRange = start.degrees..endInclusive.degrees companion object { - val FULL_ROTATION: Range = Range(Angle(0f), Angle(360f)) + val FULL_ROTATION: Range = Range(Angle(0.0), Angle(360.0)) } } } inline val Int.degrees: Angle - get() = Angle(this.toFloat()) + get() = Angle(this.toDouble()) inline val Double.degrees: Angle - get() = Angle(this.toFloat()) + get() = Angle(this) -fun Float.asAngle(): Angle = Angle(this) +fun Double.asAngle(): Angle = Angle(this) diff --git a/src/main/kotlin/de/moritzruth/theaterdsl/value/Color.kt b/src/main/kotlin/de/moritzruth/theaterdsl/value/Color.kt index e4091fc..03c7ea8 100644 --- a/src/main/kotlin/de/moritzruth/theaterdsl/value/Color.kt +++ b/src/main/kotlin/de/moritzruth/theaterdsl/value/Color.kt @@ -13,44 +13,44 @@ data class Color( val x = c * (1 - abs(h.mod(2f) - 1)) val m = brightness.value - c - val r: Float - val g: Float - val b: Float + val r: Double + val g: Double + val b: Double when { h < 1 -> { r = c g = x - b = 0f + b = 0.0 } h < 2 -> { r = x g = c - b = 0f + b = 0.0 } h < 3 -> { - r = 0f + r = 0.0 g = c b = x } h < 4 -> { - r = 0f + r = 0.0 g = x b = c } h < 5 -> { r = x - g = 0f + g = 0.0 b = c } else /* h < 6 */ -> { r = c - g = 0f + g = 0.0 b = x } } diff --git a/src/main/kotlin/de/moritzruth/theaterdsl/value/Frequency.kt b/src/main/kotlin/de/moritzruth/theaterdsl/value/Frequency.kt index 9f5d681..dfec174 100644 --- a/src/main/kotlin/de/moritzruth/theaterdsl/value/Frequency.kt +++ b/src/main/kotlin/de/moritzruth/theaterdsl/value/Frequency.kt @@ -1,10 +1,10 @@ package de.moritzruth.theaterdsl.value @JvmInline -value class Frequency(val hertz: Float) : Comparable { +value class Frequency(val hertz: Double) : Comparable { companion object { - val ZERO: Frequency = Frequency(0f) - val INFINITY: Frequency = Frequency(Float.POSITIVE_INFINITY) + val ZERO: Frequency = Frequency(0.0) + val INFINITY: Frequency = Frequency(Double.POSITIVE_INFINITY) } init { @@ -21,7 +21,7 @@ value class Frequency(val hertz: Float) : Comparable { ) : ClosedFloatingPointRange { override fun lessThanOrEquals(a: Frequency, b: Frequency): Boolean = a.hertz <= b.hertz - fun asFloatRange(): ClosedFloatingPointRange = start.hertz..endInclusive.hertz + fun asDoubleRange(): ClosedFloatingPointRange = start.hertz..endInclusive.hertz override fun toString(): String = "$start..$endInclusive" } diff --git a/src/main/kotlin/de/moritzruth/theaterdsl/value/Math.kt b/src/main/kotlin/de/moritzruth/theaterdsl/value/Math.kt index 4932965..2444d95 100644 --- a/src/main/kotlin/de/moritzruth/theaterdsl/value/Math.kt +++ b/src/main/kotlin/de/moritzruth/theaterdsl/value/Math.kt @@ -4,15 +4,15 @@ import kotlin.math.pow import kotlin.math.roundToInt val IntProgression.delta: Int get() = last - first -val ClosedFloatingPointRange.delta: Float get() = endInclusive - start +val ClosedFloatingPointRange.delta: Double get() = endInclusive - start fun Int.transfer(from: IntRange, to: IntRange): Int = ((this - from.first) / from.delta) * to.delta + to.first -fun Float.transfer(from: ClosedFloatingPointRange, to: ClosedFloatingPointRange): Float = +fun Double.transfer(from: ClosedFloatingPointRange, to: ClosedFloatingPointRange): Double = ((this - from.start) / from.delta) * to.delta + to.start -fun Float.toString(decimalPlaces: Int): String { +fun Double.toString(decimalPlaces: Int): String { val s = (this * (10f.pow(decimalPlaces))).roundToInt().toString().padStart(decimalPlaces + 1, '0') return s.dropLast(decimalPlaces) + "." + s.takeLast(decimalPlaces) } diff --git a/src/main/kotlin/de/moritzruth/theaterdsl/value/Percentage.kt b/src/main/kotlin/de/moritzruth/theaterdsl/value/Percentage.kt index 314cc56..bfcc841 100644 --- a/src/main/kotlin/de/moritzruth/theaterdsl/value/Percentage.kt +++ b/src/main/kotlin/de/moritzruth/theaterdsl/value/Percentage.kt @@ -1,16 +1,16 @@ package de.moritzruth.theaterdsl.value @JvmInline -value class Percentage(val value: Float) : Comparable { +value class Percentage(val value: Double) : Comparable { companion object { - val VALUE_RANGE: ClosedFloatingPointRange = 0f..1f + val VALUE_RANGE: ClosedFloatingPointRange = 0.0..1.0 } init { require(value in VALUE_RANGE) { "value ($value) must be in 0..1" } } - fun ofRange(range: ClosedFloatingPointRange): Float = value.transfer(VALUE_RANGE, range) + fun ofRange(range: ClosedFloatingPointRange): Double = value.transfer(VALUE_RANGE, range) override fun compareTo(other: Percentage): Int = value.compareTo(other.value) @@ -22,7 +22,7 @@ value class Percentage(val value: Float) : Comparable { ) : ClosedFloatingPointRange { override fun lessThanOrEquals(a: Percentage, b: Percentage): Boolean = a.value <= b.value - fun asFloatRange(): ClosedFloatingPointRange = start.value..endInclusive.value + fun asDoubleRange(): ClosedFloatingPointRange = start.value..endInclusive.value companion object { val FULL: Range = Range(VALUE_RANGE.start.asPercentage(), VALUE_RANGE.endInclusive.asPercentage()) @@ -32,16 +32,16 @@ value class Percentage(val value: Float) : Comparable { inline val Int.percent: Percentage get() = try { - Percentage(this / 100f) + Percentage(this / 100.0) } catch (e: IllegalArgumentException) { throw IllegalArgumentException("must be in 0..100") } inline val Double.percent: Percentage get() = try { - Percentage(this.toFloat() / 100f) + Percentage(this / 100f) } catch (e: IllegalArgumentException) { throw IllegalArgumentException("must be in 0..100") } -fun Float.asPercentage(): Percentage = Percentage(this) +fun Double.asPercentage(): Percentage = Percentage(this) diff --git a/src/main/kotlin/de/moritzruth/theaterdsl/value/RangesAndValues.kt b/src/main/kotlin/de/moritzruth/theaterdsl/value/RangesAndValues.kt index eaae50d..b0a6185 100644 --- a/src/main/kotlin/de/moritzruth/theaterdsl/value/RangesAndValues.kt +++ b/src/main/kotlin/de/moritzruth/theaterdsl/value/RangesAndValues.kt @@ -3,31 +3,31 @@ package de.moritzruth.theaterdsl.value import kotlinx.collections.immutable.ImmutableSet import kotlin.math.abs -data class FloatRangesAndValues(val ranges: ImmutableSet>, val values: ImmutableSet) { +data class DoubleRangesAndValues(val ranges: ImmutableSet>, val values: ImmutableSet) { init { require(ranges.isNotEmpty() || values.isNotEmpty()) { "at least one range or value is required" } } - val highest: Float - val highestBeforeInfinity: Float - val lowest: Float - val lowestAfterInfinity: Float + val highest: Double + val highestBeforeInfinity: Double + val lowest: Double + val lowestAfterInfinity: Double init { - var l = Float.POSITIVE_INFINITY - var lai = Float.POSITIVE_INFINITY - var h = Float.NEGATIVE_INFINITY - var hbi = Float.NEGATIVE_INFINITY + var l = Double.POSITIVE_INFINITY + var lai = Double.POSITIVE_INFINITY + var h = Double.NEGATIVE_INFINITY + var hbi = Double.NEGATIVE_INFINITY for (v in values + ranges.flatMap { listOf(it.start, it.endInclusive) }) { if (v < lai) { l = v - if (v != Float.NEGATIVE_INFINITY) lai = v + if (v != Double.NEGATIVE_INFINITY) lai = v } if (v > hbi) { h = v - if (v != Float.POSITIVE_INFINITY) hbi = v + if (v != Double.POSITIVE_INFINITY) hbi = v } } @@ -37,12 +37,12 @@ data class FloatRangesAndValues(val ranges: ImmutableSet { +value class Temperature(val kelvin: Double) : Comparable { override fun toString(): String = "${kelvin}K" override fun compareTo(other: Temperature): Int = kelvin.compareTo(other.kelvin)