Skip to content

Commit 4f52e0b

Browse files
committed
First separator version
1 parent 5b27c97 commit 4f52e0b

File tree

19 files changed

+485
-107
lines changed

19 files changed

+485
-107
lines changed

controls-constructor/src/commonMain/kotlin/space/kscience/controls/constructor/LateBindDeviceState.kt

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package space.kscience.controls.constructor
22

33
import kotlinx.coroutines.CompletableDeferred
4-
import kotlinx.coroutines.CoroutineScope
54
import kotlinx.coroutines.ExperimentalCoroutinesApi
65
import kotlinx.coroutines.flow.Flow
76
import kotlinx.coroutines.flow.flow
@@ -15,7 +14,6 @@ import kotlinx.coroutines.flow.flow
1514
*/
1615
@OptIn(ExperimentalCoroutinesApi::class)
1716
public class LateBindDeviceState<T>(
18-
scope: CoroutineScope,
1917
private val initialValue: T
2018
) : DeviceState<T> {
2119

controls-constructor/src/commonMain/kotlin/space/kscience/controls/constructor/models/continuous/ContinuousBuffer.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ public class ContinuousBuffer<U : UnitsOfMeasurement, T : Amount<U>>(
2828
context: Context,
2929
public val algebra: AmountAlgebra<U, T>,
3030
public val bufferCapacity: DeviceState<Numeric<U>>,
31-
override val supplyRequest: LateBindDeviceState<T> = LateBindDeviceState(context, algebra.zero),
32-
override val consumerRequest: LateBindDeviceState<Numeric<U>> = LateBindDeviceState(context, Numeric.zero()),
31+
override val supplyRequest: LateBindDeviceState<T> = LateBindDeviceState( algebra.zero),
32+
override val consumerRequest: LateBindDeviceState<Numeric<U>> = LateBindDeviceState( Numeric.zero()),
3333
initialLevel: T = algebra.zero,
3434
timeStep: Duration = 1.seconds
3535
) : ModelConstructor(context), ContinuousProducerInterface<U, T>, ContinuousConsumerInterface<U, T> {

controls-constructor/src/commonMain/kotlin/space/kscience/controls/constructor/models/continuous/ContinuousConsumer.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public class ContinuousConsumer<U : UnitsOfMeasurement, T : Amount<U>>(
4343
override val consumationCapacity: DeviceState<Numeric<U>>,
4444
) : ModelConstructor(context), ContinuousConsumerInterface<U, T> {
4545

46-
override val supplyRequest: LateBindDeviceState<T> = LateBindDeviceState(this, algebra.zero)
46+
override val supplyRequest: LateBindDeviceState<T> = LateBindDeviceState(algebra.zero)
4747

4848
init {
4949
registerState(consumationCapacity)

controls-constructor/src/commonMain/kotlin/space/kscience/controls/constructor/models/continuous/ContinuousMix.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ public class ContinuousMix<U : UnitsOfMeasurement, T : Amount<U>>(
3232
private val joinManagementStrategy: JoinManagementStrategy = JoinManagementStrategy.PROPORTIONAL,
3333
) : ModelConstructor(context), ContinuousProducerInterface<U, T> {
3434

35-
override val consumerRequest: LateBindDeviceState<Numeric<U>> = LateBindDeviceState(this, Numeric.zero())
35+
override val consumerRequest: LateBindDeviceState<Numeric<U>> = LateBindDeviceState( Numeric.zero())
3636

3737

3838
public val supplyRequest: Map<String, LateBindDeviceState<T>> = supplyKeys.associateWith {
39-
LateBindDeviceState(this, algebra.zero)
39+
LateBindDeviceState( algebra.zero)
4040
}
4141

4242

@@ -125,7 +125,7 @@ public fun <U : UnitsOfMeasurement> ContinuousMix(
125125
outputNames: Collection<String>,
126126
joinManagementStrategy: JoinManagementStrategy = JoinManagementStrategy.PROPORTIONAL
127127
): ContinuousMix<U, Numeric<U>> =
128-
ContinuousMix(context, NumericAmountAlgebra<U>(), outputNames, joinManagementStrategy)
128+
ContinuousMix(context, NumericAmountAlgebra(), outputNames, joinManagementStrategy)
129129

130130
/**
131131
* Creates a consumer instance for a specific supply key from a continuous mix instance.

controls-constructor/src/commonMain/kotlin/space/kscience/controls/constructor/models/continuous/ContinuousProducer.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public class ContinuousProducer<U : UnitsOfMeasurement, T : Amount<U>>(
4242
context: Context,
4343
public val algebra: AmountAlgebra<U, T>,
4444
override val productionCapacity: DeviceState<T>,
45-
override val consumerRequest: LateBindDeviceState<Numeric<U>> = LateBindDeviceState(context,Numeric.zero()),
45+
override val consumerRequest: LateBindDeviceState<Numeric<U>> = LateBindDeviceState(Numeric.zero()),
4646
) : ModelConstructor(context), ContinuousProducerInterface<U, T> {
4747

4848
init {

controls-constructor/src/commonMain/kotlin/space/kscience/controls/constructor/models/continuous/ContinuousReaction.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,9 @@ public class ContinuousReaction<U : UnitsOfMeasurement, T : Amount<U>>(
7979
public val reaction: ReactionRule<U, T>,
8080
) : ModelConstructor(context), ContinuousProducerInterface<U, T> {
8181

82-
override val consumerRequest: LateBindDeviceState<Numeric<U>> = LateBindDeviceState(this, Numeric.zero())
82+
override val consumerRequest: LateBindDeviceState<Numeric<U>> = LateBindDeviceState( Numeric.zero())
8383
public val supplyRequest: Map<String, LateBindDeviceState<T>> = reaction.supplyKeys.associateWith {
84-
LateBindDeviceState(this, algebra.zero)
84+
LateBindDeviceState( algebra.zero)
8585
}
8686

8787

controls-constructor/src/commonMain/kotlin/space/kscience/controls/constructor/models/continuous/ContinuousSeparate.kt

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public interface SeparationRule<U : UnitsOfMeasurement, T : Amount<U>> {
3434
}
3535

3636
}
37+
3738
}
3839
}
3940

@@ -43,10 +44,10 @@ public class ContinuousSeparate<U : UnitsOfMeasurement, T : Amount<U>>(
4344
public val rule: SeparationRule<U, T>,
4445
) : ModelConstructor(context), ContinuousConsumerInterface<U, T> {
4546

46-
override val supplyRequest: LateBindDeviceState<T> = LateBindDeviceState(this, algebra.zero)
47+
override val supplyRequest: LateBindDeviceState<T> = LateBindDeviceState( algebra.zero)
4748

4849
public val consumationRequest: Map<String, LateBindDeviceState<Numeric<U>>> = rule.productionKeys.associateWith {
49-
LateBindDeviceState(this, Numeric.zero())
50+
LateBindDeviceState( Numeric.zero())
5051
}
5152

5253
private val jointConsumationRequest: DeviceState<Map<String, Numeric<U>>> = combineState(consumationRequest) {
@@ -58,9 +59,9 @@ public class ContinuousSeparate<U : UnitsOfMeasurement, T : Amount<U>>(
5859
second = jointConsumationRequest
5960
) { supply: T, consumation: Map<String, Numeric<U>> ->
6061
val expectation = rule.forward(supply)
61-
val limitingFactor = expectation.minOf { (key, value) ->
62+
val limitingFactor = expectation.minOfOrNull { (key, value) ->
6263
(consumation[key] ?: Numeric.zero()).value / value.value
63-
}
64+
} ?: 0.0
6465
with(algebra) {
6566
supply * limitingFactor to expectation.mapValues { (key, value) -> supply * limitingFactor }
6667
}
@@ -69,7 +70,7 @@ public class ContinuousSeparate<U : UnitsOfMeasurement, T : Amount<U>>(
6970
public val production: DeviceState<Map<String, T>> = mapState(balance) { it.second }
7071

7172
public val individualProduction: Map<String, DeviceState<T>> = rule.productionKeys.associateWith { key ->
72-
mapState(production) { it[key]!! }
73+
mapState(production) { it[key] ?: algebra.zero }
7374
}
7475

7576
public val productionCapacity: DeviceState<Map<String, T>> = combineState(
@@ -84,7 +85,7 @@ public class ContinuousSeparate<U : UnitsOfMeasurement, T : Amount<U>>(
8485
}
8586

8687
public val individualProductionCapacity: Map<String, DeviceState<T>> = rule.productionKeys.associateWith { key ->
87-
mapState(productionCapacity) { it[key]!! }
88+
mapState(productionCapacity) { it[key] ?: algebra.zero }
8889
}
8990

9091
override val consumation: DeviceState<T> = mapState(balance) { it.first }

controls-constructor/src/commonMain/kotlin/space/kscience/controls/constructor/models/continuous/ContinuousTransformer.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ public class ContinuousTransformer<U1 : UnitsOfMeasurement, T : Amount<U1>, U2 :
4545
public val rule: ContinuousTransformationRule<U1, T, U2, R>,
4646
) : ModelConstructor(context), ContinuousProducerInterface<U2, R>, ContinuousConsumerInterface<U1, T> {
4747

48-
override val supplyRequest: LateBindDeviceState<T> = LateBindDeviceState(this, supplyAlgebra.zero)
49-
override val consumerRequest: LateBindDeviceState<Numeric<U2>> = LateBindDeviceState(this, Numeric.zero())
48+
override val supplyRequest: LateBindDeviceState<T> = LateBindDeviceState(supplyAlgebra.zero)
49+
override val consumerRequest: LateBindDeviceState<Numeric<U2>> = LateBindDeviceState(Numeric.zero())
5050

5151
override val consumation: DeviceState<T> = combineState(supplyRequest, consumerRequest) { supply, consume ->
5252
with(supplyAlgebra) {

controls-constructor/src/commonMain/kotlin/space/kscience/controls/constructor/models/continuous/modifications.kt

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,38 +11,52 @@ import space.kscience.controls.constructor.units.Numeric
1111
import space.kscience.controls.constructor.units.UnitsOfMeasurement
1212
import kotlin.time.Duration
1313

14+
/**
15+
* Delays the emission of the values from the current [DeviceState] by a specified [delay] duration.
16+
*
17+
* @param scope The [CoroutineScope] used to manage the asynchronous operation of delaying the values.
18+
* @param delay The delay duration to apply to each value emitted by the [DeviceState].
19+
* @return A new [DeviceState] that emits delayed values from the current state by the specified [delay].
20+
*/
21+
public fun <T> DeviceState<T>.delayedBy(scope: CoroutineScope, delay: Duration): DeviceState<T> =
22+
DeviceState.transform(scope, this, value) {
23+
delay(delay)
24+
it
25+
}
1426

27+
/**
28+
* Delays the emission of values from the production and productionCapacity properties of a
29+
* [ContinuousProducerInterface] by a specified duration.
30+
*
31+
* @param scope The [CoroutineScope] used to manage the asynchronous operation of delaying values.
32+
* @param delay The duration by which the values are delayed.
33+
* @return A new [ContinuousProducerInterface] with production and productionCapacity values delayed by the specified duration.
34+
*/
1535
public fun <U : UnitsOfMeasurement, T : Amount<U>> ContinuousProducerInterface<U, T>.delayed(
1636
scope: CoroutineScope,
17-
delay: Duration
37+
delay: Duration,
1838
): ContinuousProducerInterface<U, T> = object : ContinuousProducerInterface<U, T> {
1939

20-
override val production: DeviceState<T> = DeviceState.transform(
21-
scope = scope,
22-
state = this@delayed.production,
23-
initialValue = this@delayed.production.value
24-
) {
25-
delay(delay)
26-
it
27-
}
40+
override val production: DeviceState<T> = this@delayed.production
2841

42+
override val productionCapacity: DeviceState<T> get() = this@delayed.productionCapacity.delayedBy(scope, delay)
2943

30-
override val productionCapacity: DeviceState<T> get() = this@delayed.productionCapacity
44+
override val consumerRequest: LateBindDeviceState<Numeric<U>> = LateBindDeviceState(Numeric.zero())
3145

32-
override val consumerRequest: LateBindDeviceState<Numeric<U>> get() = this@delayed.consumerRequest
46+
init {
47+
this@delayed.consumerRequest.bind(consumerRequest.delayedBy(scope, delay))
48+
}
3349
}
3450

3551
public fun <U : UnitsOfMeasurement, T : Amount<U>> ContinuousProducerInterface<U, T>.limited(
3652
scope: CoroutineScope,
3753
productionLimit: DeviceState<Numeric<U>>
3854
): ContinuousProducerInterface<U, T> = object : ContinuousProducerInterface<U, T> {
39-
override val production: DeviceState<T>
40-
get() = this@limited.production
55+
override val production: DeviceState<T> get() = this@limited.production
4156

42-
override val productionCapacity: DeviceState<T>
43-
get() = this@limited.productionCapacity
57+
override val productionCapacity: DeviceState<T> get() = this@limited.productionCapacity
4458

45-
override val consumerRequest: LateBindDeviceState<Numeric<U>> = LateBindDeviceState(scope,productionLimit.value)
59+
override val consumerRequest: LateBindDeviceState<Numeric<U>> = LateBindDeviceState(productionLimit.value)
4660

4761
private val limitedValue: DeviceState<Numeric<U>> = DeviceState.combine(
4862
scope,

controls-constructor/src/commonMain/kotlin/space/kscience/controls/constructor/units/AmountAlgebra.kt

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,22 +35,18 @@ public fun <U : UnitsOfMeasurement, T : Amount<U>> AmountAlgebra<U, T>.maxOf(fir
3535
public fun <U : UnitsOfMeasurement, T : Amount<U>> AmountAlgebra<U, T>.sum(args: Iterable<T>): T =
3636
args.fold(zero) { acc, t -> acc + t }
3737

38-
private object NumericAmountAlgebra : AmountAlgebra<Nothing, Numeric<Nothing>> {
39-
override fun Numeric<Nothing>.plus(other: Numeric<Nothing>): Numeric<Nothing> = Numeric(value + other.value)
38+
public open class NumericAmountAlgebra<U: UnitsOfMeasurement> : AmountAlgebra<U, Numeric<U>> {
39+
override fun Numeric<U>.plus(other: Numeric<U>): Numeric<U> = Numeric(value + other.value)
4040

41-
override fun Numeric<Nothing>.minus(other: Numeric<Nothing>): Numeric<Nothing> = Numeric(value - other.value)
41+
override fun Numeric<U>.minus(other: Numeric<U>): Numeric<U> = Numeric(value - other.value)
4242

43-
override fun Numeric<Nothing>.unaryMinus(): Numeric<Nothing> = Numeric(-value)
43+
override fun Numeric<U>.unaryMinus(): Numeric<U> = Numeric(-value)
4444

45-
override fun Numeric<Nothing>.times(scale: Number): Numeric<Nothing> = Numeric(value * scale.toDouble())
45+
override fun Numeric<U>.times(scale: Number): Numeric<U> = Numeric(value * scale.toDouble())
4646

47-
override fun Numeric<Nothing>.div(scale: Number): Numeric<Nothing> = Numeric(value / scale.toDouble())
47+
override fun Numeric<U>.div(scale: Number): Numeric<U> = Numeric(value / scale.toDouble())
4848

49-
override val zero: Numeric<Nothing> = Numeric(0.0)
49+
override val zero: Numeric<U> = Numeric(0.0)
5050

51-
override val one: Numeric<Nothing> = Numeric(1.0)
52-
}
53-
54-
@Suppress("UNCHECKED_CAST", "FunctionName")
55-
public fun <U : UnitsOfMeasurement> NumericAmountAlgebra(): AmountAlgebra<U, Numeric<U>> =
56-
NumericAmountAlgebra as AmountAlgebra<U, Numeric<U>>
51+
override val one: Numeric<U> = Numeric(1.0)
52+
}

0 commit comments

Comments
 (0)