diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionClient.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionClient.kt index 9d6a5561..20974f0c 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionClient.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionClient.kt @@ -2,8 +2,10 @@ package space.kscience.visionforge import kotlinx.coroutines.launch import space.kscience.dataforge.context.Plugin +import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.MetaRepr import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.parseAsName /** * A feedback client that communicates with a server and provides ability to propagate events and changes back to the model @@ -13,25 +15,24 @@ public interface VisionClient: Plugin { public suspend fun sendEvent(targetName: Name, event: VisionEvent) -// public fun notifyPropertyChanged(visionName: Name, propertyName: Name, item: Meta?) + public fun notifyPropertyChanged(visionName: Name, propertyName: Name, item: Meta?) } +public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Meta?) { + notifyPropertyChanged(visionName, propertyName.parseAsName(true), item) +} -//public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Meta?) { -// notifyPropertyChanged(visionName, propertyName.parseAsName(true), item) -//} -// -//public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Number) { -// notifyPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) -//} -// -//public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: String) { -// notifyPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) -//} -// -//public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Boolean) { -// notifyPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) -//} +public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Number) { + notifyPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) +} + +public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: String) { + notifyPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) +} + +public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Boolean) { + notifyPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) +} public fun VisionClient.sendEvent(targetName: Name, payload: MetaRepr): Unit { context.launch { diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt index 17958f97..c7ada5fe 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt @@ -65,20 +65,21 @@ public class JsVisionClient : AbstractPlugin(), VisionClient { private fun Element.getFlag(attribute: String): Boolean = attributes[attribute]?.value != null -// private val mutex = Mutex() + private val mutex = Mutex() + private val rootChangeCollector = VisionChangeBuilder() -// /** -// * Communicate vision property changed from rendering engine to model -// */ -// private fun notifyPropertyChanged(visionName: Name, propertyName: Name, item: Meta?) { -// context.launch { -// mutex.withLock { -// changeCollector.propertyChanged(visionName, propertyName, item) -// } -// } -// } + /** + * Communicate vision property changed from rendering engine to model + */ + override fun notifyPropertyChanged(visionName: Name, propertyName: Name, item: Meta?) { + context.launch { + mutex.withLock { + rootChangeCollector.propertyChanged(visionName, propertyName, item) + } + } + } private val eventCollector by lazy { MutableSharedFlow>(meta["feedback.eventCache"].int ?: 100) @@ -139,7 +140,6 @@ public class JsVisionClient : AbstractPlugin(), VisionClient { } } - //Backward change propagation var feedbackJob: Job? = null @@ -148,29 +148,20 @@ public class JsVisionClient : AbstractPlugin(), VisionClient { onopen = { - - val mutex = Mutex() - - val changeCollector = VisionChangeBuilder() - feedbackJob = visionManager.context.launch { //launch a separate coroutine to send events to the backend eventCollector.filter { it.first == visionName }.onEach { send(visionManager.jsonFormat.encodeToString(VisionEvent.serializer(), it.second)) }.launchIn(this) - //launch backward property propagation - vision.properties.changes.onEach { propertyName: Name -> - changeCollector.propertyChanged(visionName, propertyName, vision.properties[propertyName]) - }.launchIn(this) - //aggregate atomic changes while (isActive) { delay(feedbackAggregationTime.milliseconds) - if (!changeCollector.isEmpty()) { + val visionChangeCollector = rootChangeCollector[name] + if (visionChangeCollector?.isEmpty() == false) { mutex.withLock { - eventCollector.emit(visionName to changeCollector.deepCopy(visionManager)) - changeCollector.reset() + eventCollector.emit(visionName to visionChangeCollector.deepCopy(visionManager)) + rootChangeCollector.reset() } } }