diff --git a/gradle.properties b/gradle.properties index 23061828..c89e530c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,6 @@ kotlin.code.style=official kotlin.mpp.stability.nowarn=true kotlin.js.compiler=ir -#kotlin.incremental.js.ir=true org.gradle.parallel=true org.gradle.jvmargs=-Xmx4G diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt index 00386948..eb800111 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt @@ -147,7 +147,7 @@ private fun CoroutineScope.collectChange( ) { //Collect properties change - source.properties.flowChanges().onEach { propertyName -> + source.properties.changes.onEach { propertyName -> val newItem = source.properties.own[propertyName] collector.propertyChanged(name, propertyName, newItem) }.launchIn(this) diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt index 752b7bd3..9201d0bf 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt @@ -40,7 +40,11 @@ public interface VisionProperties : MetaProvider { override fun get(name: Name): Meta? = get(name, null, null) - public fun flowChanges(): Flow + public val changes: Flow + + @Deprecated("Replace with property", ReplaceWith("changes")) + public fun flowChanges(): Flow = changes + /** * Notify all listeners that a property has been changed and should be invalidated. @@ -64,7 +68,7 @@ public interface MutableVisionProperties : VisionProperties, MutableMetaProvider public fun set( name: Name, - node: Meta?, + item: Meta?, notify: Boolean, ) @@ -186,28 +190,28 @@ public open class AbstractVisionProperties( return descriptor?.defaultValue } - override fun set(name: Name, node: Meta?, notify: Boolean) { + override fun set(name: Name, item: Meta?, notify: Boolean) { //ignore if the value is the same as existing - if (own[name] == node) return + if (own[name] == item) return if (name.isEmpty()) { - if (node == null) { + if (item == null) { own.items.keys.forEach { remove(it.asName()) } } else { - (own.items.keys - node.items.keys).forEach { + (own.items.keys - item.items.keys).forEach { remove(it.asName()) } - node.items.forEach { (token, item) -> + item.items.forEach { (token, item) -> set(token, item) } } - } else if (node == null) { - own[name] = node + } else if (item == null) { + own[name] = item } else { - own[name] = node + own[name] = item } if (notify) { invalidate(name) @@ -231,7 +235,8 @@ public open class AbstractVisionProperties( @Transient protected val changesInternal: MutableSharedFlow = MutableSharedFlow() - override fun flowChanges(): Flow = changesInternal + override val changes: Flow + get() = changesInternal override fun invalidate(propertyName: Name) { //send update signal diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/flowProperty.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/flowProperty.kt index 8d1bbb72..60c39c20 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/flowProperty.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/flowProperty.kt @@ -18,7 +18,7 @@ public fun Vision.flowProperty( ): Flow = flow { //Pass initial value. emit(properties.get(propertyName, inherit, includeStyles)) - properties.flowChanges().collect { name -> + properties.changes.collect { name -> if (name.startsWith(propertyName)) { emit(properties.get(propertyName, inherit, includeStyles)) } @@ -41,7 +41,7 @@ public fun Vision.flowPropertyValue( ): Flow = flow { //Pass initial value. emit(properties.getValue(propertyName, inherit, includeStyles)) - properties.flowChanges().collect { name -> + properties.changes.collect { name -> if (name.startsWith(propertyName)) { emit(properties.getValue(propertyName, inherit, includeStyles)) } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt index 07ed4bd9..fcdea6d3 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt @@ -25,7 +25,7 @@ public fun Vision.useProperty( ): Job { //Pass initial value. callback(properties.get(propertyName, inherit, includeStyles)) - return properties.flowChanges().onEach { name -> + return properties.changes.onEach { name -> if (name.startsWith(propertyName)) { callback(properties.get(propertyName, inherit, includeStyles)) } @@ -47,7 +47,7 @@ public fun V.useProperty( ): Job { //Pass initial value. callback(property.get(this)) - return properties.flowChanges().onEach { name -> + return properties.changes.onEach { name -> if (name.startsWith(property.name.asName())) { callback(property.get(this@useProperty)) } @@ -60,7 +60,7 @@ public fun V.useProperty( public fun Vision.onPropertyChange( scope: CoroutineScope = manager?.context ?: error("Orphan Vision can't observe properties. Use explicit scope."), callback: suspend (Name) -> Unit, -): Job = properties.flowChanges().onEach { +): Job = properties.changes.onEach { callback(it) }.launchIn(scope) @@ -71,6 +71,6 @@ public fun V.onPropertyChange( property: KProperty1, scope: CoroutineScope = manager?.context ?: error("Orphan Vision can't observe properties. Use explicit scope."), callback: suspend V.(T) -> Unit, -): Job = properties.flowChanges().filter { it.startsWith(property.name.asName()) }.onEach { +): Job = properties.changes.filter { it.startsWith(property.name.asName()) }.onEach { callback(property.get(this)) }.launchIn(scope) \ No newline at end of file diff --git a/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt b/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt index 0e2a3206..3490fdd7 100644 --- a/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt +++ b/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt @@ -1,23 +1,17 @@ package space.kscience.visionforge.plotly import kotlinx.coroutines.channels.awaitClose -import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.callbackFlow -import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.launch import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.Transient -import space.kscience.dataforge.meta.MutableMeta -import space.kscience.dataforge.meta.MutableMetaSerializer -import space.kscience.dataforge.meta.ObservableMeta -import space.kscience.dataforge.meta.asObservable +import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.names.Name import space.kscience.plotly.Plot import space.kscience.plotly.Plotly import space.kscience.plotly.PlotlyConfig -import space.kscience.visionforge.AbstractVisionProperties import space.kscience.visionforge.MutableVisionProperties import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionBuilder @@ -26,36 +20,52 @@ import space.kscience.visionforge.html.VisionOutput @Serializable @SerialName("vision.plotly") public class VisionOfPlotly private constructor( - @Serializable(MutableMetaSerializer::class) public val meta: MutableMeta, + @Serializable(MutableMetaSerializer::class) private val meta: MutableMeta, ) : Vision { public constructor(plot: Plot) : this(plot.meta) - public val plot: Plot get() = Plot(meta.asObservable()) + @Transient + public val plot: Plot = Plot(meta.asObservable()) @Transient override var parent: Vision? = null @Transient - override val properties: MutableVisionProperties = object : AbstractVisionProperties(this, meta) { + override val properties: MutableVisionProperties = object : MutableVisionProperties { + override val own: Meta get() = plot.meta - override fun flowChanges(): Flow = if (meta is ObservableMeta) { - callbackFlow { - meta.onChange(this) { - launch { - send(it) - } - } - awaitClose { - meta.removeListener(this) + override val changes = callbackFlow { + plot.meta.onChange(this) { + println(it) + launch { + send(it) } } - } else emptyFlow() - - - override fun invalidate(propertyName: Name) { - // Do nothing + awaitClose { + plot.meta.removeListener(this) + } } + override fun invalidate(propertyName: Name) { + //do nothing, updates to source already counted +// manager?.context?.launch { +// changes.emit(propertyName) +// } + } + + override fun getValue(name: Name, inherit: Boolean?, includeStyles: Boolean?): Value? = plot.meta[name]?.value + + override fun set(name: Name, item: Meta?, notify: Boolean) { + plot.meta[name] = item + if (notify) invalidate(name) + } + + override fun setValue(name: Name, value: Value?, notify: Boolean) { + plot.meta[name] = value + if (notify) invalidate(name) + } + + override val descriptor: MetaDescriptor get() = plot.descriptor } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt index ec13823e..b98bd4cb 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt @@ -166,16 +166,16 @@ internal class SolidReferenceChild( includeStyles: Boolean?, ): Value? = own.getValue(name) ?: prototype.properties.getValue(name, inherit, includeStyles) - override fun set(name: Name, node: Meta?, notify: Boolean) { - own[name] = node + override fun set(name: Name, item: Meta?, notify: Boolean) { + own[name] = item } override fun setValue(name: Name, value: Value?, notify: Boolean) { own.setValue(name, value) } - override fun flowChanges(): Flow = - owner.properties.flowChanges().filter { it.startsWith(childToken(childName)) } + override val changes: Flow + get() = owner.properties.changes.filter { it.startsWith(childToken(childName)) } override fun invalidate(propertyName: Name) { owner.properties.invalidate(childPropertyName(childName, propertyName)) diff --git a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt index a4e13533..c943668a 100644 --- a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt @@ -89,7 +89,7 @@ public class ThreePlugin : AbstractPlugin(), ComposeHtmlVisionRenderer { updatePosition(vision) //obj.onChildrenChange() if (observe) { - vision.properties.flowChanges().onEach { name -> + vision.properties.changes.onEach { name -> if ( name.startsWith(Solid.POSITION_KEY) || name.startsWith(Solid.ROTATION_KEY) || diff --git a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/compose/ThreeView.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/compose/ThreeView.kt index 1f496b05..2dbd1f48 100644 --- a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/compose/ThreeView.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/compose/ThreeView.kt @@ -147,7 +147,7 @@ public fun ThreeView( } }, name = Name.EMPTY, - updates = vision.properties.flowChanges(), + updates = vision.properties.changes, rootDescriptor = vision.descriptor ) vision.styles.takeIf { it.isNotEmpty() }?.let { styles ->