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 {
} }
} }
public fun <D : Device> DeviceManager.install(name: String, device: D): D {
/**
* 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)
registerDevice(NameToken(name), device) registerDevice(NameToken(name), device)
device.launch { device.launch {
device.open() device.open()
@ -50,6 +45,13 @@ public fun <D : Device> DeviceManager.install(name: String, factory: Factory<D>,
return device 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 * 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.CoroutineScope
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.*
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import space.kscience.controls.api.ActionDescriptor import space.kscience.controls.api.ActionDescriptor
import space.kscience.controls.api.Device import space.kscience.controls.api.Device
@ -105,19 +102,31 @@ public operator fun <T, D : Device> D.set(propertySpec: WritableDevicePropertySp
write(propertySpec, value) 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]. * 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>, spec: DevicePropertySpec<D, T>,
callback: suspend PropertyChangedMessage.(T?) -> Unit, callback: suspend PropertyChangedMessage.(T) -> Unit,
): Job = messageFlow ): Job = messageFlow
.filterIsInstance<PropertyChangedMessage>() .filterIsInstance<PropertyChangedMessage>()
.filter { it.property == spec.name } .filter { it.property == spec.name }
.onEach { change -> .onEach { change ->
change.callback(spec.converter.metaToObject(change.value)) val newValue = spec.converter.metaToObject(change.value)
if (newValue != null) {
change.callback(newValue)
}
}.launchIn(this) }.launchIn(this)
/** /**
* Reset the logical state of a property * Reset the logical state of a property
*/ */

View File

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

View File

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