Make constructor device use context instead of device manager
This commit is contained in:
parent
701ea8cf57
commit
bec075328b
@ -13,7 +13,7 @@ val xodusVersion by extra("2.0.1")
|
||||
|
||||
allprojects {
|
||||
group = "space.kscience"
|
||||
version = "0.3.0-dev-4"
|
||||
version = "0.3.0-dev-5"
|
||||
repositories{
|
||||
maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev")
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package space.kscience.controls.constructor
|
||||
|
||||
import space.kscience.controls.api.Device
|
||||
import space.kscience.controls.api.PropertyDescriptor
|
||||
import space.kscience.controls.manager.DeviceManager
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.context.Factory
|
||||
import space.kscience.dataforge.meta.Meta
|
||||
import space.kscience.dataforge.meta.transformations.MetaConverter
|
||||
@ -18,9 +18,9 @@ import kotlin.time.Duration
|
||||
* A base for strongly typed device constructor blocks. Has additional delegates for type-safe devices
|
||||
*/
|
||||
public abstract class DeviceConstructor(
|
||||
deviceManager: DeviceManager,
|
||||
context: Context,
|
||||
meta: Meta,
|
||||
) : DeviceGroup(deviceManager, meta) {
|
||||
) : DeviceGroup(context, meta) {
|
||||
|
||||
/**
|
||||
* Register a device, provided by a given [factory] and
|
||||
|
@ -27,7 +27,7 @@ import kotlin.coroutines.CoroutineContext
|
||||
* A mutable group of devices and properties to be used for lightweight design and simulations.
|
||||
*/
|
||||
public open class DeviceGroup(
|
||||
public val deviceManager: DeviceManager,
|
||||
final override val context: Context,
|
||||
override val meta: Meta,
|
||||
) : DeviceHub, CachingDevice {
|
||||
|
||||
@ -42,9 +42,6 @@ public open class DeviceGroup(
|
||||
)
|
||||
|
||||
|
||||
override final val context: Context get() = deviceManager.context
|
||||
|
||||
|
||||
private val sharedMessageFlow = MutableSharedFlow<DeviceMessage>()
|
||||
|
||||
override val messageFlow: Flow<DeviceMessage>
|
||||
@ -175,7 +172,7 @@ public fun DeviceManager.registerDeviceGroup(
|
||||
meta: Meta = Meta.EMPTY,
|
||||
block: DeviceGroup.() -> Unit,
|
||||
): DeviceGroup {
|
||||
val group = DeviceGroup(this, meta).apply(block)
|
||||
val group = DeviceGroup(context, meta).apply(block)
|
||||
install(name, group)
|
||||
return group
|
||||
}
|
||||
@ -194,7 +191,7 @@ private fun DeviceGroup.getOrCreateGroup(name: Name): DeviceGroup {
|
||||
when (val d = devices[token]) {
|
||||
null -> install(
|
||||
token,
|
||||
DeviceGroup(deviceManager, meta[token] ?: Meta.EMPTY)
|
||||
DeviceGroup(context, meta[token] ?: Meta.EMPTY)
|
||||
)
|
||||
|
||||
else -> (d as? DeviceGroup) ?: error("Device $name is not a DeviceGroup")
|
||||
@ -234,7 +231,7 @@ public fun <D : Device> DeviceGroup.install(
|
||||
deviceMeta: Meta? = null,
|
||||
metaLocation: Name = name,
|
||||
): D {
|
||||
val newDevice = factory.build(deviceManager.context, Laminate(deviceMeta, meta[metaLocation]))
|
||||
val newDevice = factory.build(context, Laminate(deviceMeta, meta[metaLocation]))
|
||||
install(name, newDevice)
|
||||
return newDevice
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ import kotlinx.io.readByteArray
|
||||
|
||||
/**
|
||||
* Transform byte fragments into complete phrases using given delimiter. Not thread safe.
|
||||
*
|
||||
* TODO add type wrapper for phrases
|
||||
*/
|
||||
public fun Flow<ByteArray>.withDelimiter(delimiter: ByteArray): Flow<ByteArray> {
|
||||
require(delimiter.isNotEmpty()) { "Delimiter must not be empty" }
|
||||
|
@ -81,7 +81,7 @@ public suspend fun <T, D : Device> D.read(propertySpec: DevicePropertySpec<D, T>
|
||||
public suspend fun <T, D : DeviceBase<D>> D.readOrNull(propertySpec: DevicePropertySpec<D, T>): T? =
|
||||
readPropertyOrNull(propertySpec.name)?.let(propertySpec.converter::metaToObject)
|
||||
|
||||
public suspend fun <T, D : Device> D.request(propertySpec: DevicePropertySpec<D, T>): T? =
|
||||
public suspend fun <T, D : Device> D.request(propertySpec: DevicePropertySpec<D, T>): T =
|
||||
propertySpec.converter.metaToObject(requestProperty(propertySpec.name))
|
||||
|
||||
/**
|
||||
|
@ -18,6 +18,8 @@ import space.kscience.controls.api.propertyMessageFlow
|
||||
import space.kscience.controls.constructor.DeviceState
|
||||
import space.kscience.controls.manager.clock
|
||||
import space.kscience.controls.misc.ValueWithTime
|
||||
import space.kscience.controls.spec.DevicePropertySpec
|
||||
import space.kscience.controls.spec.name
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.meta.*
|
||||
import space.kscience.plotly.Plot
|
||||
@ -28,8 +30,8 @@ import space.kscience.plotly.models.Trace
|
||||
import space.kscience.plotly.models.TraceValues
|
||||
import space.kscience.plotly.scatter
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.hours
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
import kotlin.time.Duration.Companion.minutes
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
private var TraceValues.values: List<Value>
|
||||
get() = value?.list ?: emptyList()
|
||||
@ -82,6 +84,11 @@ private class TimeData(private var points: MutableList<ValueWithTime<Value>> = m
|
||||
}
|
||||
}
|
||||
|
||||
private val defaultMaxAge get() = 10.minutes
|
||||
private val defaultMaxPoints get() = 800
|
||||
private val defaultMinPoints get() = 400
|
||||
private val defaultSampling get() = 1.seconds
|
||||
|
||||
/**
|
||||
* Add a trace that shows a [Device] property change over time. Show only latest [maxPoints] .
|
||||
* @return a [Job] that handles the listener
|
||||
@ -90,10 +97,10 @@ public fun Plot.plotDeviceProperty(
|
||||
device: Device,
|
||||
propertyName: String,
|
||||
extractValue: Meta.() -> Value = { value ?: Null },
|
||||
maxAge: Duration = 1.hours,
|
||||
maxPoints: Int = 800,
|
||||
minPoints: Int = 400,
|
||||
sampling: Duration = 10.milliseconds,
|
||||
maxAge: Duration = defaultMaxAge,
|
||||
maxPoints: Int = defaultMaxPoints,
|
||||
minPoints: Int = defaultMinPoints,
|
||||
sampling: Duration = defaultSampling,
|
||||
coroutineScope: CoroutineScope = device.context,
|
||||
configuration: Scatter.() -> Unit = {},
|
||||
): Job = scatter(configuration).run {
|
||||
@ -108,14 +115,27 @@ public fun Plot.plotDeviceProperty(
|
||||
}.launchIn(coroutineScope)
|
||||
}
|
||||
|
||||
public fun Plot.plotDeviceProperty(
|
||||
device: Device,
|
||||
property: DevicePropertySpec<*, Number>,
|
||||
maxAge: Duration = defaultMaxAge,
|
||||
maxPoints: Int = defaultMaxPoints,
|
||||
minPoints: Int = defaultMinPoints,
|
||||
sampling: Duration = defaultSampling,
|
||||
coroutineScope: CoroutineScope = device.context,
|
||||
configuration: Scatter.() -> Unit = {},
|
||||
): Job = plotDeviceProperty(
|
||||
device, property.name, { value ?: Null }, maxAge, maxPoints, minPoints, sampling, coroutineScope, configuration
|
||||
)
|
||||
|
||||
private fun <T> Trace.updateFromState(
|
||||
context: Context,
|
||||
state: DeviceState<T>,
|
||||
extractValue: T.() -> Value = { state.converter.objectToMeta(this).value ?: space.kscience.dataforge.meta.Null },
|
||||
maxAge: Duration = 1.hours,
|
||||
maxPoints: Int = 800,
|
||||
minPoints: Int = 400,
|
||||
sampling: Duration = 10.milliseconds,
|
||||
extractValue: T.() -> Value,
|
||||
maxAge: Duration,
|
||||
maxPoints: Int,
|
||||
minPoints: Int,
|
||||
sampling: Duration,
|
||||
): Job {
|
||||
val clock = context.clock
|
||||
val data = TimeData()
|
||||
@ -131,10 +151,10 @@ public fun <T> Plot.plotDeviceState(
|
||||
context: Context,
|
||||
state: DeviceState<T>,
|
||||
extractValue: T.() -> Value = { state.converter.objectToMeta(this).value ?: Null },
|
||||
maxAge: Duration = 1.hours,
|
||||
maxPoints: Int = 800,
|
||||
minPoints: Int = 400,
|
||||
sampling: Duration = 10.milliseconds,
|
||||
maxAge: Duration = defaultMaxAge,
|
||||
maxPoints: Int = defaultMaxPoints,
|
||||
minPoints: Int = defaultMinPoints,
|
||||
sampling: Duration = defaultSampling,
|
||||
configuration: Scatter.() -> Unit = {},
|
||||
): Job = scatter(configuration).run {
|
||||
updateFromState(context, state, extractValue, maxAge, maxPoints, minPoints, sampling)
|
||||
@ -144,10 +164,10 @@ public fun <T> Plot.plotDeviceState(
|
||||
public fun Plot.plotNumberState(
|
||||
context: Context,
|
||||
state: DeviceState<out Number>,
|
||||
maxAge: Duration = 1.hours,
|
||||
maxPoints: Int = 800,
|
||||
minPoints: Int = 400,
|
||||
sampling: Duration = 10.milliseconds,
|
||||
maxAge: Duration = defaultMaxAge,
|
||||
maxPoints: Int = defaultMaxPoints,
|
||||
minPoints: Int = defaultMinPoints,
|
||||
sampling: Duration = defaultSampling,
|
||||
configuration: Scatter.() -> Unit = {},
|
||||
): Job = scatter(configuration).run {
|
||||
updateFromState(context, state, { asValue() }, maxAge, maxPoints, minPoints, sampling)
|
||||
@ -157,10 +177,10 @@ public fun Plot.plotNumberState(
|
||||
public fun Plot.plotBooleanState(
|
||||
context: Context,
|
||||
state: DeviceState<Boolean>,
|
||||
maxAge: Duration = 1.hours,
|
||||
maxPoints: Int = 800,
|
||||
minPoints: Int = 400,
|
||||
sampling: Duration = 10.milliseconds,
|
||||
maxAge: Duration = defaultMaxAge,
|
||||
maxPoints: Int = defaultMaxPoints,
|
||||
minPoints: Int = defaultMinPoints,
|
||||
sampling: Duration = defaultSampling,
|
||||
configuration: Bar.() -> Unit = {},
|
||||
): Job = bar(configuration).run {
|
||||
updateFromState(context, state, { asValue() }, maxAge, maxPoints, minPoints, sampling)
|
||||
|
@ -26,7 +26,6 @@ import space.kscience.controls.vision.plotDeviceProperty
|
||||
import space.kscience.controls.vision.plotNumberState
|
||||
import space.kscience.controls.vision.showDashboard
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.context.request
|
||||
import space.kscience.dataforge.meta.Meta
|
||||
import space.kscience.plotly.models.ScatterMode
|
||||
import space.kscience.visionforge.plotly.PlotlyPlugin
|
||||
@ -44,7 +43,7 @@ class LinearDrive(
|
||||
mass: Double,
|
||||
pidParameters: PidParameters,
|
||||
meta: Meta = Meta.EMPTY,
|
||||
) : DeviceConstructor(context.request(DeviceManager), meta) {
|
||||
) : DeviceConstructor(context, meta) {
|
||||
|
||||
val drive by device(VirtualDrive.factory(mass, state))
|
||||
val pid by device(PidRegulator(drive, pidParameters))
|
||||
|
Loading…
Reference in New Issue
Block a user