Skip to content

Commit 7234a77

Browse files
committed
More informative toString in model states
1 parent 1136922 commit 7234a77

File tree

7 files changed

+89
-27
lines changed

7 files changed

+89
-27
lines changed

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,17 +126,16 @@ public fun <T : Any> DeviceConstructor.mutableProperty(
126126
)
127127

128128
/**
129-
* Create and register a virtual mutable property with optional [callback]
129+
* Create and register a virtual mutable property
130130
*/
131131
public fun <T> DeviceConstructor.virtualProperty(
132132
metaConverter: MetaConverter<T>,
133133
initialState: T,
134134
descriptorBuilder: PropertyDescriptor.() -> Unit = {},
135135
nameOverride: String? = null,
136-
callback: (T) -> Unit = {},
137136
): PropertyDelegateProvider<DeviceConstructor, ReadOnlyProperty<DeviceConstructor, MutableDeviceState<T>>> = property(
138137
metaConverter,
139-
MutableDeviceState(initialState, callback),
138+
MutableDeviceState(initialState),
140139
descriptorBuilder,
141140
nameOverride,
142141
)

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,9 +315,8 @@ public fun <T : Any> DeviceGroup.registerVirtualProperty(
315315
initialValue: T,
316316
converter: MetaConverter<T>,
317317
descriptorBuilder: PropertyDescriptor.() -> Unit = {},
318-
callback: (T) -> Unit = {},
319318
): MutableDeviceState<T> {
320-
val state = MutableDeviceState<T>(initialValue, callback)
319+
val state = MutableDeviceState<T>(initialValue)
321320
registerMutableProperty(name, converter, state, descriptorBuilder)
322321
return state
323322
}

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

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public fun <T, R> DeviceState.Companion.map(
8080

8181
override fun subscribe(): Flow<R> = state.subscribe().map(mapper)
8282

83-
override fun toString(): String = "DeviceState.map(state=${state}, mapper=$mapper)"
83+
override fun toString(): String = "DeviceState.map(state=${state.value}, value=$value)"
8484
}
8585

8686
public fun <T, R> DeviceState<T>.map(mapper: (T) -> R): DeviceStateWithDependencies<R> =
@@ -105,7 +105,7 @@ public fun <T, R> DeviceState.Companion.map(
105105

106106
override fun subscribe(): StateFlow<R> = valueFlow
107107

108-
override fun toString(): String = "DeviceState.map(state=${state}, mapper=$mapper)"
108+
override fun toString(): String = "DeviceState.map(state=${state.value}, value=$value)"
109109
}
110110

111111
public fun <T, R> DeviceState<T>.map(scope: CoroutineScope, mapper: (T) -> R): DeviceStateWithDependencies<R> =
@@ -136,7 +136,7 @@ public fun <T, R> DeviceState.Companion.transform(
136136

137137
override fun subscribe(): StateFlow<R> = valueFlow
138138

139-
override fun toString(): String = "DeviceState.transform(state=${state}, transform=$transform)"
139+
override fun toString(): String = "DeviceState.transform(state=${state.value}, value=$value)"
140140
}
141141

142142
public suspend fun <T, R> DeviceState<T>.transform(
@@ -167,7 +167,8 @@ public fun <T1, T2, R> DeviceState.Companion.combine(
167167

168168
override fun subscribe(): StateFlow<R> = valueFlow
169169

170-
override fun toString(): String = "DeviceState.combine(state1=$state1, state2=$state2)"
170+
override fun toString(): String =
171+
"DeviceState.combine(state1=${state1.value}, state2=${state2.value}, value=$value)"
171172
}
172173

173174
/**
@@ -195,7 +196,8 @@ public fun <T1, T2, T3, R> DeviceState.Companion.combine(
195196

196197
override fun subscribe(): SharedFlow<R> = valueFlow
197198

198-
override fun toString(): String = "DeviceState.combine(state1=$state1, state2=$state2, state3=$state3)"
199+
override fun toString(): String =
200+
"DeviceState.combine(state1=${state1.value}, state2=${state2.value}, state3=${state3.value}, value=$value)"
199201
}
200202

201203
public fun <T1, T2, T3, T4, R> DeviceState.Companion.combine(
@@ -221,7 +223,7 @@ public fun <T1, T2, T3, T4, R> DeviceState.Companion.combine(
221223
override fun subscribe(): StateFlow<R> = valueFlow
222224

223225
override fun toString(): String =
224-
"DeviceState.combine(state1=$state1, state2=$state2, state3=$state3, state4=$state4)"
226+
"DeviceState.combine(state1=${state1.value}, state2=${state2.value}, state3=${state3.value}, state4=${state4.value}, value=$value)"
225227
}
226228

227229
/**
@@ -250,7 +252,14 @@ public fun <T, R> DeviceState.Companion.combine(
250252

251253
override fun subscribe(): StateFlow<R> = valueFlow
252254

253-
override fun toString(): String = "DeviceState.combine(states=${states.joinToString()})"
255+
override fun toString(): String =
256+
"DeviceState.combine(states=${
257+
states.joinToString(
258+
prefix = "[",
259+
separator = ", ",
260+
postfix = "]"
261+
) { "${it.value}" }
262+
}, value=$value)"
254263
}
255264

256265
/**
@@ -285,7 +294,14 @@ public fun <T, K, R> DeviceState.Companion.combine(
285294

286295
override fun subscribe(): StateFlow<R> = valueFlow
287296

288-
override fun toString(): String = "DeviceState.associate(states=${states})"
297+
override fun toString(): String =
298+
"DeviceState.associate(states=${
299+
states.entries.joinToString(
300+
prefix = "[",
301+
separator = ", ",
302+
postfix = "]"
303+
) { "${it.key}=${it.value.value}" }
304+
}, value=$value)"
289305
}
290306

291307
/**

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ private open class ExternalDeviceState<T>(
2929

3030
override fun subscribe(): StateFlow<T> = flow
3131

32-
override fun toString(): String = "ExternalState()"
32+
override fun toString(): String = "ExternalState(value=$value)"
3333
}
3434

3535
/**

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ public class LateBindDeviceState<T>(
4747
}
4848

4949

50-
override fun toString(): String =
51-
"LateBindDeviceState(initialValue=$initialValue, binding=${binding.takeIf { it.isCompleted }?.getCompleted()})"
50+
override fun toString(): String = if (isBound) {
51+
"LateBindDeviceState(binding=${binding.getCompleted()})"
52+
} else {
53+
"LateBindDeviceState(initialValue=$initialValue)"
54+
}
5255
}

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

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,8 @@ import kotlinx.coroutines.flow.flowOf
1212
*/
1313
private class VirtualDeviceState<T>(
1414
initialValue: T,
15-
private val callback: (T) -> Unit = {}
1615
) : MutableDeviceState<T> {
1716

18-
init {
19-
callback(initialValue)
20-
}
21-
2217
private val flow = MutableStateFlow(initialValue)
2318

2419
override fun subscribe(): StateFlow<T> = flow
@@ -27,12 +22,10 @@ private class VirtualDeviceState<T>(
2722
get() = flow.value
2823
set(value) {
2924
flow.value = value
30-
callback(value)
3125
}
3226

3327
override suspend fun emit(value: T) {
3428
flow.emit(value)
35-
callback(value)
3629
}
3730

3831
override fun toString(): String = "VirtualDeviceState($value)"
@@ -46,8 +39,7 @@ private class VirtualDeviceState<T>(
4639
*/
4740
public fun <T> MutableDeviceState(
4841
initialValue: T,
49-
callback: (T) -> Unit = {}
50-
): MutableDeviceState<T> = VirtualDeviceState(initialValue, callback)
42+
): MutableDeviceState<T> = VirtualDeviceState(initialValue)
5143

5244

5345
/**

controls-constructor/src/commonTest/kotlin/space/kscience/controls/constructor/ContinuousFlowTest.kt

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ class ContinuousFlowTest {
2222

2323
val epoch = Instant.fromEpochMilliseconds(0L)
2424

25+
val kilograms = NumericAmountAlgebra<Kilograms>()
26+
2527
val context = Context("test") {
2628
withVirtualTime(epoch)
2729
}
@@ -108,13 +110,13 @@ class ContinuousFlowTest {
108110
joinABC.consumation.printEach(this@runTest, "joinABC.consumation")
109111

110112
assertEquals(Numeric(6.0), joinABC.production.value)
111-
assertEquals(2.0,bProducer.production.value.value)
113+
assertEquals(2.0, bProducer.production.value.value)
112114
assertEquals(1.0, joinAB.individualConsumation["a"]?.value?.value)
113115

114116
abcConsumation.value = Numeric(3.0)
115117

116118
assertEquals(Numeric(1.5), joinAB.production.value)
117-
assertEquals(1.0,bProducer.production.value.value)
119+
assertEquals(1.0, bProducer.production.value.value)
118120
assertEquals(0.5, joinAB.individualConsumation["a"]?.value?.value)
119121

120122
abcConsumation.value = Numeric(4.0)
@@ -242,6 +244,57 @@ class ContinuousFlowTest {
242244
assertEquals(2.0, transformer.production.value.value)
243245
assertEquals(2.0, consumer.consumation.value.value)
244246
assertEquals(20.0, producer.production.value.value)
247+
}
248+
}
249+
250+
@Test
251+
fun separation() = runTest {
252+
val model = object : ContinuousFlowModel(context) {
253+
val production = MutableDeviceState(Numeric<Kilograms>(4.0))
254+
val aConsumation = MutableDeviceState(Numeric<Kilograms>(2.0))
255+
val bConsumation = MutableDeviceState(Numeric<Kilograms>(2.0))
256+
val cConsumation = MutableDeviceState(Numeric<Kilograms>(1.0))
257+
258+
val producer = producer(production)
259+
260+
val splitter1 = separator(
261+
algebra = kilograms,
262+
separationRule = SeparationRule.proportional(kilograms, mapOf("a" to 1.0, "bc" to 1.0))
263+
).apply {
264+
connectProducer(producer)
265+
}
266+
267+
val aConsumer = consumer(aConsumation).apply {
268+
connectProducer(splitter1.asProducer("a"))
269+
}
270+
271+
val splitter2 = separator(
272+
algebra = kilograms,
273+
separationRule = SeparationRule.proportional(kilograms, mapOf("b" to 1.0, "c" to 1.0))
274+
).apply {
275+
connectProducer(splitter1.asProducer("bc"))
276+
}
277+
278+
val bConsumer = consumer(bConsumation).apply {
279+
connectProducer(splitter2.asProducer("b"))
280+
}
281+
282+
val cConsumer = consumer(cConsumation).apply {
283+
connectProducer(splitter2.asProducer("c"))
284+
}
285+
}.runSimulation {
286+
287+
assertEquals(4.0, producer.production.value.value)
288+
assertEquals(2.0, aConsumer.consumation.value.value)
289+
assertEquals(1.0, bConsumer.consumation.value.value)
290+
assertEquals(1.0, cConsumer.consumation.value.value)
291+
292+
aConsumation.value = Numeric(1.0)
293+
294+
assertEquals(2.0, producer.production.value.value)
295+
assertEquals(1.0, aConsumer.consumation.value.value)
296+
assertEquals(0.5, bConsumer.consumation.value.value)
297+
assertEquals(0.5, cConsumer.consumation.value.value)
245298

246299
}
247300
}

0 commit comments

Comments
 (0)