Minor refactor of property listeners

This commit is contained in:
Alexander Nozik 2023-05-24 09:37:56 +03:00
parent 0612c6e3a2
commit 2a966d8cb3
4 changed files with 31 additions and 17 deletions

View File

@ -37,12 +37,7 @@ public class DeviceManager : AbstractPlugin(), DeviceHub {
}
}
/**
* Register and start a device built by [factory] with current [Context] and [meta].
*/
public fun <D : Device> DeviceManager.install(name: String, factory: Factory<D>, meta: Meta = Meta.EMPTY): D {
val device = factory(meta, context)
public fun <D : Device> DeviceManager.install(name: String, device: D): D {
registerDevice(NameToken(name), device)
device.launch {
device.open()
@ -50,6 +45,13 @@ public fun <D : Device> DeviceManager.install(name: String, factory: Factory<D>,
return device
}
/**
* Register and start a device built by [factory] with current [Context] and [meta].
*/
public fun <D : Device> DeviceManager.install(name: String, factory: Factory<D>, meta: Meta = Meta.EMPTY): D =
install(name, factory(meta, context))
/**
* A delegate that initializes device on the first use
*/

View File

@ -2,10 +2,7 @@ package space.kscience.controls.spec
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import space.kscience.controls.api.ActionDescriptor
import space.kscience.controls.api.Device
@ -105,19 +102,31 @@ public operator fun <T, D : Device> D.set(propertySpec: WritableDevicePropertySp
write(propertySpec, value)
}
/**
* A type safe flow of property changes for given property
*/
public fun <D : Device, T> D.propertyFlow(spec: DevicePropertySpec<D, T>): Flow<T> = messageFlow
.filterIsInstance<PropertyChangedMessage>()
.filter { it.property == spec.name }
.mapNotNull { spec.converter.metaToObject(it.value) }
/**
* A type safe property change listener. Uses the device [CoroutineScope].
*/
public fun <D : Device, T> Device.onPropertyChange(
public fun <D : Device, T> D.onPropertyChange(
spec: DevicePropertySpec<D, T>,
callback: suspend PropertyChangedMessage.(T?) -> Unit,
callback: suspend PropertyChangedMessage.(T) -> Unit,
): Job = messageFlow
.filterIsInstance<PropertyChangedMessage>()
.filter { it.property == spec.name }
.onEach { change ->
change.callback(spec.converter.metaToObject(change.value))
val newValue = spec.converter.metaToObject(change.value)
if (newValue != null) {
change.callback(newValue)
}
}.launchIn(this)
/**
* Reset the logical state of a property
*/

View File

@ -5,8 +5,8 @@ plugins {
dependencies{
api(project(":controls-core"))
implementation("com.pi4j:pi4j-ktx:2.4.0") // Kotlin DSL
implementation("com.pi4j:pi4j-core:2.3.0")
implementation("com.pi4j:pi4j-plugin-raspberrypi:2.3.0")
implementation("com.pi4j:pi4j-plugin-pigpio:2.3.0")
api("com.pi4j:pi4j-ktx:2.4.0") // Kotlin DSL
api("com.pi4j:pi4j-core:2.3.0")
api("com.pi4j:pi4j-plugin-raspberrypi:2.3.0")
api("com.pi4j:pi4j-plugin-pigpio:2.3.0")
}

View File

@ -1,5 +1,6 @@
package space.kscience.controls.pi
import space.kscience.controls.ports.Ports
import space.kscience.dataforge.context.AbstractPlugin
import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.PluginFactory
@ -7,6 +8,8 @@ import space.kscience.dataforge.context.PluginTag
import space.kscience.dataforge.meta.Meta
public class PiPlugin : AbstractPlugin() {
public val ports: Ports by require(Ports)
override val tag: PluginTag get() = Companion.tag
public companion object : PluginFactory<PiPlugin> {