From a9f29f92ca9498665b5901dcf3cf1cc7bfb48f3e Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Fri, 18 Aug 2023 13:01:46 +0300 Subject: [PATCH] Add magix registry access service --- controls-core/README.md | 39 +++++++++++++++++++ controls-pi/README.md | 32 +++++++++++++++ .../kscience/magix/services/MagixRegistry.kt | 34 +++++++++++++++- 3 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 controls-core/README.md create mode 100644 controls-pi/README.md diff --git a/controls-core/README.md b/controls-core/README.md new file mode 100644 index 0000000..1a8fa70 --- /dev/null +++ b/controls-core/README.md @@ -0,0 +1,39 @@ +# Module controls-core + + + +## Features + + - [device](src/commonMain/kotlin/space/kscience/controls/api/Device.kt) : Device API with subscription (asynchronous and pseudo-synchronous properties) + - [deviceMessage](src/commonMain/kotlin/space/kscience/controls/api/DeviceMessage.kt) : Specification for messages used to communicate between Controls-kt devices. + - [deviceHub](src/commonMain/kotlin/space/kscience/controls/api/DeviceHub.kt) : Grouping of devices into local tree-like hubs. + + +## Usage + +## Artifact: + +The Maven coordinates of this project are `space.kscience:controls-core:0.2.0-dev-2`. + +**Gradle Groovy:** +```groovy +repositories { + maven { url 'https://repo.kotlin.link' } + mavenCentral() +} + +dependencies { + implementation 'space.kscience:controls-core:0.2.0-dev-2' +} +``` +**Gradle Kotlin DSL:** +```kotlin +repositories { + maven("https://repo.kotlin.link") + mavenCentral() +} + +dependencies { + implementation("space.kscience:controls-core:0.2.0-dev-2") +} +``` diff --git a/controls-pi/README.md b/controls-pi/README.md new file mode 100644 index 0000000..9d91bcf --- /dev/null +++ b/controls-pi/README.md @@ -0,0 +1,32 @@ +# Module controls-pi + + + +## Usage + +## Artifact: + +The Maven coordinates of this project are `space.kscience:controls-pi:0.2.0-dev-2`. + +**Gradle Groovy:** +```groovy +repositories { + maven { url 'https://repo.kotlin.link' } + mavenCentral() +} + +dependencies { + implementation 'space.kscience:controls-pi:0.2.0-dev-2' +} +``` +**Gradle Kotlin DSL:** +```kotlin +repositories { + maven("https://repo.kotlin.link") + mavenCentral() +} + +dependencies { + implementation("space.kscience:controls-pi:0.2.0-dev-2") +} +``` diff --git a/magix/magix-api/src/commonMain/kotlin/space/kscience/magix/services/MagixRegistry.kt b/magix/magix-api/src/commonMain/kotlin/space/kscience/magix/services/MagixRegistry.kt index e82dc24..f6af81c 100644 --- a/magix/magix-api/src/commonMain/kotlin/space/kscience/magix/services/MagixRegistry.kt +++ b/magix/magix-api/src/commonMain/kotlin/space/kscience/magix/services/MagixRegistry.kt @@ -2,7 +2,9 @@ package space.kscience.magix.services import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.flow.onEach import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -57,6 +59,9 @@ public class MagixRegistryErrorMessage( public val errorMessage: String? = null, ) : MagixRegistryMessage() +/** + * Launch a magix registry loop service based on local registry + */ public fun CoroutineScope.launchMagixRegistry( endpoint: MagixEndpoint, registry: MagixRegistry, @@ -71,11 +76,36 @@ public fun CoroutineScope.launchMagixRegistry( MagixRegistryMessage.format, MagixRegistryValueMessage(payload.propertyName, value ?: JsonNull) ) - } catch (ex: Exception){ + } catch (ex: Exception) { endpoint.send( MagixRegistryMessage.format, MagixRegistryErrorMessage(payload.propertyName, ex::class.simpleName, ex.message) ) } } - }.launchIn(this) \ No newline at end of file + }.launchIn(this) + +/** + * Request a property with given name and return a [Flow] of pairs (sourceEndpoint, value). + * + * Flow is ordered by response receive time. + * The subscriber can terminate the flow at any moment to stop subscription, or use it indefinitely to continue observing changes. + * To request a single value, use [Flow.first] function. + * + * If [targetEndpoint] field is provided, send request only to given endpoint. + */ +public suspend fun MagixEndpoint.getProperty( + propertyName: String, + user: JsonElement? = null, + targetEndpoint: String? = null, +): Flow> { + send(MagixRegistryMessage.format, MagixRegistryRequestMessage(propertyName), target = targetEndpoint, user = user) + return subscribe( + MagixRegistryMessage.format, + originFilter = targetEndpoint?.let { setOf(it) } + ).mapNotNull { (message, response) -> + if (response is MagixRegistryValueMessage && response.propertyName == propertyName) { + message.sourceEndpoint to response.value + } else null + } +} \ No newline at end of file