From 2a966d8cb309b158f6202f1b3ac0f8dbd82d4687 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 24 May 2023 09:37:56 +0300 Subject: [PATCH] Minor refactor of property listeners --- .../controls/manager/DeviceManager.kt | 14 ++++++----- .../controls/spec/DevicePropertySpec.kt | 23 +++++++++++++------ controls-pi/build.gradle.kts | 8 +++---- .../space/kscience/controls/pi/PiPlugin.kt | 3 +++ 4 files changed, 31 insertions(+), 17 deletions(-) diff --git a/controls-core/src/commonMain/kotlin/space/kscience/controls/manager/DeviceManager.kt b/controls-core/src/commonMain/kotlin/space/kscience/controls/manager/DeviceManager.kt index 871f236..cc043c7 100644 --- a/controls-core/src/commonMain/kotlin/space/kscience/controls/manager/DeviceManager.kt +++ b/controls-core/src/commonMain/kotlin/space/kscience/controls/manager/DeviceManager.kt @@ -37,12 +37,7 @@ public class DeviceManager : AbstractPlugin(), DeviceHub { } } - -/** - * Register and start a device built by [factory] with current [Context] and [meta]. - */ -public fun DeviceManager.install(name: String, factory: Factory, meta: Meta = Meta.EMPTY): D { - val device = factory(meta, context) +public fun DeviceManager.install(name: String, device: D): D { registerDevice(NameToken(name), device) device.launch { device.open() @@ -50,6 +45,13 @@ public fun DeviceManager.install(name: String, factory: Factory, return device } + +/** + * Register and start a device built by [factory] with current [Context] and [meta]. + */ +public fun DeviceManager.install(name: String, factory: Factory, meta: Meta = Meta.EMPTY): D = + install(name, factory(meta, context)) + /** * A delegate that initializes device on the first use */ diff --git a/controls-core/src/commonMain/kotlin/space/kscience/controls/spec/DevicePropertySpec.kt b/controls-core/src/commonMain/kotlin/space/kscience/controls/spec/DevicePropertySpec.kt index 078a43d..0e72fca 100644 --- a/controls-core/src/commonMain/kotlin/space/kscience/controls/spec/DevicePropertySpec.kt +++ b/controls-core/src/commonMain/kotlin/space/kscience/controls/spec/DevicePropertySpec.kt @@ -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 D.set(propertySpec: WritableDevicePropertySp write(propertySpec, value) } +/** + * A type safe flow of property changes for given property + */ +public fun D.propertyFlow(spec: DevicePropertySpec): Flow = messageFlow + .filterIsInstance() + .filter { it.property == spec.name } + .mapNotNull { spec.converter.metaToObject(it.value) } + /** * A type safe property change listener. Uses the device [CoroutineScope]. */ -public fun Device.onPropertyChange( +public fun D.onPropertyChange( spec: DevicePropertySpec, - callback: suspend PropertyChangedMessage.(T?) -> Unit, + callback: suspend PropertyChangedMessage.(T) -> Unit, ): Job = messageFlow .filterIsInstance() .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 */ diff --git a/controls-pi/build.gradle.kts b/controls-pi/build.gradle.kts index 3fa0dbc..b269c85 100644 --- a/controls-pi/build.gradle.kts +++ b/controls-pi/build.gradle.kts @@ -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") } \ No newline at end of file diff --git a/controls-pi/src/main/kotlin/space/kscience/controls/pi/PiPlugin.kt b/controls-pi/src/main/kotlin/space/kscience/controls/pi/PiPlugin.kt index e3d6a0a..547a142 100644 --- a/controls-pi/src/main/kotlin/space/kscience/controls/pi/PiPlugin.kt +++ b/controls-pi/src/main/kotlin/space/kscience/controls/pi/PiPlugin.kt @@ -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 {