@@ -18,10 +18,12 @@ import space.kscience.controls.constructor.units.Numeric
1818import space.kscience.controls.constructor.values
1919import space.kscience.controls.spec.DevicePropertySpec
2020import space.kscience.controls.spec.name
21+ import space.kscience.controls.time.ClockManager
2122import space.kscience.controls.time.ValueWithTime
2223import space.kscience.controls.time.clock
2324import space.kscience.dataforge.context.Context
2425import space.kscience.dataforge.context.Global
26+ import space.kscience.dataforge.context.request
2527import space.kscience.dataforge.meta.Meta
2628import space.kscience.dataforge.meta.double
2729import kotlin.time.Clock
@@ -36,21 +38,34 @@ private val defaultMaxPoints get() = 800
3638private val defaultMinPoints get() = 400
3739private val defaultSampling get() = 1 .seconds
3840
39- private fun <T > Flow<T>.repeatOrSample (clock : Clock , interval : Duration ): Flow <ValueWithTime <T >> = flow {
41+ private fun <T > Flow<T>.repeatOrSample (clockManager : ClockManager , interval : Duration ): Flow <ValueWithTime <T >> = flow {
42+ val clock = clockManager.clock
43+
4044 coroutineScope {
45+
4146 var current: T ? = null
47+ var flag: Boolean = false
4248
4349 launch {
4450 collect {
4551 current = it
52+ flag = true
4653 }
4754 }
4855
4956 while (isActive) {
50- current?.let { emit(ValueWithTime (it, clock.now())) }
51- delay(interval)
57+ current?.let {
58+ if (! flag) {
59+ emit(ValueWithTime (it, clock.now()))
60+ }
61+ }
62+ flag = false
63+ withContext(clockManager.simulationDispatcher) {
64+ delay(interval)
65+ }
5266 }
5367 }
68+
5469}
5570
5671
@@ -121,11 +136,13 @@ public fun XYGraphScope<Instant, Double>.PlotDeviceProperty(
121136 lineStyle : LineStyle = defaultLineStyle,
122137) {
123138 var points by remember { mutableStateOf<List <ValueWithTime <Double >>>(emptyList()) }
139+ val clockManager =
140+ remember(device) { device.context.plugins.get<ClockManager >() ? : device.context.request(ClockManager ) }
124141
125142 LaunchedEffect (device, propertyName, maxAge, maxPoints, minPoints, sampling) {
126143 device.propertyMessageFlow(propertyName)
127144 .map { it.value.extractValue() }
128- .repeatOrSample(device.clock , sampling)
145+ .repeatOrSample(clockManager , sampling)
129146 .collectAndTrim(maxAge, maxPoints, minPoints, device.clock)
130147 .onEach { points = it }
131148 .launchIn(this )
@@ -166,14 +183,14 @@ public fun XYGraphScope<Instant, Double>.PlotNumberState(
166183 lineStyle : LineStyle = defaultLineStyle,
167184): Unit {
168185 var points by remember { mutableStateOf<List <ValueWithTime <Double >>>(emptyList()) }
169-
186+ val clockManager = remember(context) { context.plugins.get< ClockManager >() ? : context.request( ClockManager ) }
170187
171188 LaunchedEffect (context, state, maxAge, maxPoints, minPoints, sampling) {
172189 val clock = context.clock
173190
174191 state.subscribe()
175192 .map { it.toDouble() }
176- .repeatOrSample(clock , sampling)
193+ .repeatOrSample(clockManager , sampling)
177194 .collectAndTrim(maxAge, maxPoints, minPoints, clock)
178195 .onEach { points = it }
179196 .launchIn(this )
0 commit comments