From c48e5aac25382c33061dc370292609898d532aff Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Mon, 29 May 2023 09:53:56 +0300 Subject: [PATCH] build update and minor API changes --- build.gradle.kts | 3 ++- demo/playground/build.gradle.kts | 2 +- gradle.properties | 3 ++- gradle/wrapper/gradle-wrapper.properties | 2 +- settings.gradle.kts | 2 +- .../kscience/visionforge/VisionChange.kt | 17 +++++++++++++- .../visionforge/meta/VisionPropertyTest.kt | 3 ++- .../kscience/visionforge/VisionClient.kt | 22 ++++++++++++++----- .../kscience/visionforge/html/htmlExport.kt | 2 +- visionforge-plotly/build.gradle.kts | 2 +- .../visionforge/solid/SolidPropertyTest.kt | 3 ++- 11 files changed, 45 insertions(+), 16 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 8cedd918..3ee913b2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,7 +13,7 @@ val fxVersion by extra("11") allprojects { group = "space.kscience" - version = "0.3.0-dev-7" + version = "0.3.0-dev-8" } subprojects { @@ -24,6 +24,7 @@ subprojects { maven("https://repo.kotlin.link") mavenCentral() maven("https://maven.jzy3d.org/releases") + maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") } tasks.withType { diff --git a/demo/playground/build.gradle.kts b/demo/playground/build.gradle.kts index fbc0b736..a2696fa6 100644 --- a/demo/playground/build.gradle.kts +++ b/demo/playground/build.gradle.kts @@ -65,7 +65,7 @@ kotlin { val jvmMain by getting { dependencies { implementation(projects.visionforgeServer) - implementation("ch.qos.logback:logback-classic:1.2.3") + implementation(spclibs.logback.classic) implementation("com.github.Ricky12Awesome:json-schema-serialization:0.6.6") } } diff --git a/gradle.properties b/gradle.properties index 11c3aafa..75046b66 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,4 +6,5 @@ kotlin.incremental.js.ir=true org.gradle.parallel=true org.gradle.jvmargs=-Xmx4G -toolsVersion=0.14.7-kotlin-1.8.20 \ No newline at end of file +toolsVersion=0.14.8-kotlin-1.8.20 +org.jetbrains.compose.experimental.jscanvas.enabled=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 070cb702..fae08049 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/settings.gradle.kts b/settings.gradle.kts index b9d8bf5b..e9e3deba 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,6 @@ rootProject.name = "visionforge" enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") -enableFeaturePreview("VERSION_CATALOGS") pluginManagement { @@ -46,6 +45,7 @@ include( ":ui:ring", // ":ui:material", ":ui:bootstrap", +// ":ui:compose", ":visionforge-core", ":visionforge-solid", // ":visionforge-fx", 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 15d59a0f..847368f3 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt @@ -41,7 +41,6 @@ public object NullVision : Vision { override val properties: MutableVisionProperties get() = error("Can't get properties of `NullVision`") override val descriptor: MetaDescriptor? = null - } @@ -89,6 +88,12 @@ public class VisionChangeBuilder : MutableVisionContainer { } } + private fun build(visionManager: VisionManager): VisionChange = VisionChange( + vision, + if (propertyChange.isEmpty()) null else propertyChange, + if (children.isEmpty()) null else children.mapValues { it.value.build(visionManager) } + ) + /** * Isolate collected changes by creating detached copies of given visions */ @@ -97,6 +102,13 @@ public class VisionChangeBuilder : MutableVisionContainer { if (propertyChange.isEmpty()) null else propertyChange.seal(), if (children.isEmpty()) null else children.mapValues { it.value.deepCopy(visionManager) } ) + + /** + * Transform current change directly to Json string without protective copy + */ + public fun toJsonString(visionManager: VisionManager): String = visionManager.encodeToString( + build(visionManager) + ) } /** @@ -115,6 +127,9 @@ public inline fun VisionManager.VisionChange(block: VisionChangeBuilder.() -> Un VisionChangeBuilder().apply(block).deepCopy(this) +/** + * Collect changes that are made to [source] to [collector] using [mutex] as a synchronization lock. + */ private fun CoroutineScope.collectChange( name: Name, source: Vision, diff --git a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt index 7b7cdd31..6e113f7f 100644 --- a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt +++ b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt @@ -15,6 +15,7 @@ import space.kscience.visionforge.* import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertNotEquals +import kotlin.time.Duration.Companion.milliseconds private class TestScheme : Scheme() { @@ -58,7 +59,7 @@ internal class VisionPropertyTest { } @Test - fun testChildrenPropertyPropagation() = runTest(dispatchTimeoutMs = 200) { + fun testChildrenPropertyPropagation() = runTest(timeout = 200.milliseconds) { val group = Global.request(VisionManager).group { properties { "test" put 11 diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt index e87f01fa..af3cd574 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt @@ -6,6 +6,8 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.isActive import kotlinx.coroutines.launch +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock import org.w3c.dom.* import org.w3c.dom.url.URL import space.kscience.dataforge.context.* @@ -30,8 +32,6 @@ public class VisionClient : AbstractPlugin() { override val tag: PluginTag get() = Companion.tag private val visionManager: VisionManager by require(VisionManager) - //private val visionMap = HashMap() - /** * Up-going tree traversal in search for endpoint attribute. If element is null, return window URL */ @@ -61,11 +61,19 @@ public class VisionClient : AbstractPlugin() { private fun Element.getFlag(attribute: String): Boolean = attributes[attribute]?.value != null + private val mutex = Mutex() private val changeCollector = VisionChangeBuilder() + /** + * Communicate vision property changed from rendering engine to model + */ public fun visionPropertyChanged(visionName: Name, propertyName: Name, item: Meta?) { - changeCollector.propertyChanged(visionName, propertyName, item) + context.launch { + mutex.withLock { + changeCollector.propertyChanged(visionName, propertyName, item) + } + } } // public fun visionChanged(name: Name?, child: Vision?) { @@ -131,8 +139,10 @@ public class VisionClient : AbstractPlugin() { delay(feedbackAggregationTime.milliseconds) val change = changeCollector[name] ?: continue if (!change.isEmpty()) { - send(visionManager.encodeToString(change.deepCopy(visionManager))) - change.reset() + mutex.withLock { + send(change.toJsonString(visionManager)) + change.reset() + } } } } @@ -232,7 +242,7 @@ public class VisionClient : AbstractPlugin() { public companion object : PluginFactory { override fun build(context: Context, meta: Meta): VisionClient = VisionClient() - override val tag: PluginTag = PluginTag(name = "vision.client", group = PluginTag.DATAFORGE_GROUP) + override val tag: PluginTag = PluginTag(name = "vision.client.js", group = PluginTag.DATAFORGE_GROUP) } } diff --git a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt index f1efe1b4..ec31b7b4 100644 --- a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt +++ b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt @@ -60,7 +60,7 @@ import java.nio.file.Path /** * Export a [VisionPage] to a file * - * @param fileHeaders additional file-system specific headers. + * @param fileHeaders additional file system specific headers. */ @DFExperimental public fun VisionPage.makeFile( diff --git a/visionforge-plotly/build.gradle.kts b/visionforge-plotly/build.gradle.kts index 56402f14..8b0a99d1 100644 --- a/visionforge-plotly/build.gradle.kts +++ b/visionforge-plotly/build.gradle.kts @@ -10,7 +10,7 @@ kscience { binaries.library() } dependencies { - api(project(":visionforge-core")) + api(projects.visionforgeCore) api("space.kscience:plotlykt-core:${plotlyVersion}") } useSerialization() diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt index 7589ee00..5fa22b86 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt @@ -10,6 +10,7 @@ import space.kscience.dataforge.names.asName import space.kscience.visionforge.* import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.time.Duration.Companion.milliseconds @OptIn(ExperimentalCoroutinesApi::class) @Suppress("UNUSED_VARIABLE") @@ -26,7 +27,7 @@ class SolidPropertyTest { } @Test - fun testColorUpdate() = runTest(dispatchTimeoutMs = 200) { + fun testColorUpdate() = runTest(timeout = 200.milliseconds) { val box = Box(10.0f, 10.0f, 10.0f) val c = CompletableDeferred()