From 0ea1ee056a48c32538da677f57abbb56a59ea9b3 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Fri, 12 Aug 2022 22:16:06 +0300 Subject: [PATCH] All tests pass --- build.gradle.kts | 2 +- cern-root-loader/build.gradle.kts | 2 +- .../kotlin/ru/mipt/npm/root/dRootToSolid.kt | 2 +- demo/gdml/build.gradle.kts | 8 +- .../visionforge/gdml/GDMLVisionTest.kt | 7 +- .../visionforge/gdml/demo/GDMLAppComponent.kt | 3 +- .../visionforge/gdml/demo/GdmlJsDemoApp.kt | 3 +- demo/js-playground/build.gradle.kts | 2 +- demo/muon-monitor/build.gradle.kts | 2 +- .../kotlin/ru/mipt/npm/muon/monitor/Model.kt | 2 +- .../mipt/npm/muon/monitor/MMAppComponent.kt | 3 +- .../ru/mipt/npm/muon/monitor/MMDemoApp.kt | 1 + .../src/jsMain/resources/index.html | 1 - demo/sat-demo/build.gradle.kts | 2 +- demo/solid-showcase/build.gradle.kts | 6 +- .../visionforge/solid/demo/VariableBox.kt | 9 +- gradle.properties | 2 +- jupyter/build.gradle.kts | 4 +- .../visionforge-jupyter-gdml/build.gradle.kts | 4 +- settings.gradle.kts | 10 +- ui/bootstrap/build.gradle.kts | 2 +- .../visionforge/bootstrap/outputConfig.kt | 6 +- .../bootstrap/visionPropertyEditor.kt | 32 ++++-- ui/react/build.gradle.kts | 2 +- .../visionforge/react/MultiSelectChooser.kt | 2 +- .../visionforge/react/PropertyEditor.kt | 104 +++++++++++------- .../visionforge/react/RangeValueChooser.kt | 2 +- .../kscience/visionforge/react/VisionTree.kt | 13 ++- .../visionforge/react/valueChooser.kt | 16 +-- ui/ring/build.gradle.kts | 2 +- .../ThreeViewWithControls.kt | 42 ++++--- .../ringPropertyEditor.kt | 34 ++++-- .../ringThreeControls.kt | 6 +- visionforge-core/build.gradle.kts | 4 +- .../space/kscience/visionforge/StyleSheet.kt | 8 +- .../space/kscience/visionforge/Vision.kt | 14 ++- .../kscience/visionforge/VisionChange.kt | 6 +- .../kscience/visionforge/VisionContainer.kt | 6 +- .../kscience/visionforge/VisionManager.kt | 3 +- .../kscience/visionforge/VisionProperties.kt | 103 ++++++----------- .../visionforge/html/VisionOfHtmlInput.kt | 2 +- .../kscience/visionforge/html/HtmlTagTest.kt | 2 +- .../visionforge/meta/VisionPropertyTest.kt | 6 +- .../kscience/visionforge/VisionClient.kt | 2 +- visionforge-fx/build.gradle.kts | 8 +- .../kscience/visionforge/solid/FX3DPlugin.kt | 3 +- .../solid/VisualObjectFXBinding.kt | 3 +- visionforge-gdml/build.gradle.kts | 7 +- .../kscience/visionforge/gdml/markLayers.kt | 3 +- .../src/commonTest/kotlin/TestCubes.kt | 2 +- visionforge-markdown/build.gradle.kts | 2 +- visionforge-plotly/build.gradle.kts | 2 +- .../visionforge/plotly/VisionOfPlotly.kt | 2 +- visionforge-server/build.gradle.kts | 2 +- .../visionforge/server/VisionServer.kt | 1 + visionforge-solid/build.gradle.kts | 9 +- .../visionforge/solid/ColorAccessor.kt | 2 +- .../kscience/visionforge/solid/Composite.kt | 4 +- .../kscience/visionforge/solid/Extruded.kt | 2 +- .../kscience/visionforge/solid/PolyLine.kt | 2 +- .../space/kscience/visionforge/solid/Solid.kt | 4 +- .../kscience/visionforge/solid/SolidGroup.kt | 2 +- .../visionforge/solid/SolidMaterial.kt | 8 +- .../visionforge/solid/SolidReference.kt | 31 +++--- .../solid/transform/RemoveSingleChild.kt | 2 +- .../visionforge/solid/PropertyTest.kt | 9 +- .../visionforge/solid/SerializationTest.kt | 4 +- visionforge-tables/build.gradle.kts | 4 +- .../visionforge/tables/VisionOfTableTest.kt | 2 +- visionforge-threejs/build.gradle.kts | 2 +- .../solid/three/MeshThreeFactory.kt | 7 +- .../solid/three/ThreeCanvasLabelFactory.kt | 3 +- .../solid/three/ThreeLineFactory.kt | 3 +- .../visionforge/solid/three/ThreeMaterials.kt | 17 +-- .../visionforge/solid/three/ThreePlugin.kt | 17 +-- .../solid/three/ThreeReferenceFactory.kt | 21 ++-- .../build.gradle.kts | 2 +- 77 files changed, 372 insertions(+), 314 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index d02cd7c5..f2c4e6d5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.project") + id("space.kscience.gradle.project") // id("org.jetbrains.kotlinx.kover") version "0.5.0" } diff --git a/cern-root-loader/build.gradle.kts b/cern-root-loader/build.gradle.kts index fa26fab5..0ea3de8f 100644 --- a/cern-root-loader/build.gradle.kts +++ b/cern-root-loader/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") } kscience{ diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt index 48a21ff1..a867f054 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt @@ -321,7 +321,7 @@ private fun buildVolume(volume: DGeoVolume, context: RootToSolidContext): Solid? } return if (group.children.isEmpty()) { null - } else if (group.items.size == 1 && group.properties.raw == null) { + } else if (group.items.size == 1 && group.properties.own == null) { group.items.values.first().apply { parent = null } } else { group diff --git a/demo/gdml/build.gradle.kts b/demo/gdml/build.gradle.kts index a6c3fb0a..39c82290 100644 --- a/demo/gdml/build.gradle.kts +++ b/demo/gdml/build.gradle.kts @@ -1,8 +1,8 @@ -import ru.mipt.npm.gradle.DependencyConfiguration -import ru.mipt.npm.gradle.FXModule +import space.kscience.gradle.DependencyConfiguration +import space.kscience.gradle.FXModule plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") application } @@ -36,7 +36,7 @@ kotlin { jvmMain { dependencies { implementation(project(":visionforge-fx")) - implementation("ch.qos.logback:logback-classic:1.2.5") + implementation("ch.qos.logback:logback-classic:1.2.11") } } jsMain { diff --git a/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt b/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt index 0f74e9a8..723edb3b 100644 --- a/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt +++ b/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt @@ -6,7 +6,6 @@ import space.kscience.dataforge.names.Name import space.kscience.gdml.GdmlShowCase import space.kscience.visionforge.Vision import space.kscience.visionforge.get -import space.kscience.visionforge.getPropertyValue import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.material @@ -20,7 +19,7 @@ class GDMLVisionTest { @Test fun testCubesStyles(){ val segment = cubes.children["composite-000.segment-0"] as Solid - println(segment.getPropertyValue(Vision.STYLE_KEY)) + println(segment.properties.getValue(Vision.STYLE_KEY)) // println(segment.computePropertyNode(SolidMaterial.MATERIAL_KEY)) // println(segment.computeProperty(SolidMaterial.MATERIAL_COLOR_KEY)) @@ -34,7 +33,7 @@ class GDMLVisionTest { fun testPrototypeProperty() { val child = cubes[Name.of("composite-000","segment-0")] assertNotNull(child) - child.setPropertyValue(SolidMaterial.MATERIAL_COLOR_KEY, "red".asValue()) - assertEquals("red", child.getProperty(SolidMaterial.MATERIAL_COLOR_KEY).string) + child.properties.setValue(SolidMaterial.MATERIAL_COLOR_KEY, "red".asValue()) + assertEquals("red", child.properties.getProperty(SolidMaterial.MATERIAL_COLOR_KEY).string) } } \ No newline at end of file diff --git a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt index b28dec12..8f605ccd 100644 --- a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt +++ b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt @@ -26,6 +26,7 @@ import space.kscience.visionforge.setAsRoot import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.Solids import space.kscience.visionforge.solid.ambientLight +import space.kscience.visionforge.solid.set import styled.css import styled.styledDiv @@ -56,7 +57,7 @@ val GDMLApp = fc("GDMLApp") { props -> console.info("Marking layers for file $name") markLayers() ambientLight { - color(Colors.white) + color.set(Colors.white) } } } diff --git a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt index 1cd1b0ff..d4a80876 100644 --- a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt +++ b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt @@ -10,6 +10,7 @@ import space.kscience.visionforge.Colors import space.kscience.visionforge.gdml.toVision import space.kscience.visionforge.react.render import space.kscience.visionforge.solid.ambientLight +import space.kscience.visionforge.solid.set import space.kscience.visionforge.solid.three.ThreePlugin import space.kscience.visionforge.startApplication import styled.injectGlobal @@ -46,7 +47,7 @@ private class GDMLDemoApp : Application { child(GDMLApp) { val vision = GdmlShowCase.cubes().toVision().apply { ambientLight { - color(Colors.white) + color.set(Colors.white) } } //println(context.plugins.fetch(VisionManager).encodeToString(vision)) diff --git a/demo/js-playground/build.gradle.kts b/demo/js-playground/build.gradle.kts index ccec7015..ada5841a 100644 --- a/demo/js-playground/build.gradle.kts +++ b/demo/js-playground/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.js") + id("space.kscience.gradle.js") } kscience{ diff --git a/demo/muon-monitor/build.gradle.kts b/demo/muon-monitor/build.gradle.kts index f3b1710c..ad37a7c2 100644 --- a/demo/muon-monitor/build.gradle.kts +++ b/demo/muon-monitor/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") application } diff --git a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt index 4bf18124..aeb0abd3 100644 --- a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt +++ b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt @@ -69,7 +69,7 @@ class Model(val manager: VisionManager) { fun reset() { map.values.forEach { - it.properties[SolidMaterial.MATERIAL_COLOR_KEY] = null + it.properties.setProperty(SolidMaterial.MATERIAL_COLOR_KEY, null) } tracks.children.clear() } diff --git a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt index 77ad5845..20a33fe2 100644 --- a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt +++ b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt @@ -25,6 +25,7 @@ import space.kscience.visionforge.react.flexRow import space.kscience.visionforge.ring.ThreeCanvasWithControls import space.kscience.visionforge.ring.tab import space.kscience.visionforge.solid.ambientLight +import space.kscience.visionforge.solid.set import space.kscience.visionforge.solid.specifications.Canvas3DOptions import space.kscience.visionforge.solid.three.edges import styled.css @@ -57,7 +58,7 @@ val MMApp = fc("Muon monitor") { props -> props.model.root.apply { edges() ambientLight{ - color(Colors.white) + color.set(Colors.white) } } } diff --git a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt index 17c3f149..9c96ad07 100644 --- a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt +++ b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt @@ -17,6 +17,7 @@ private class MMDemoApp : Application { val context = Context("MM-demo") { plugin(ThreePlugin) } + val visionManager = context.fetch(VisionManager) val model = Model(visionManager) diff --git a/demo/muon-monitor/src/jsMain/resources/index.html b/demo/muon-monitor/src/jsMain/resources/index.html index dbca2406..f9dee8bd 100644 --- a/demo/muon-monitor/src/jsMain/resources/index.html +++ b/demo/muon-monitor/src/jsMain/resources/index.html @@ -5,7 +5,6 @@ Three js demo for particle physics -
diff --git a/demo/sat-demo/build.gradle.kts b/demo/sat-demo/build.gradle.kts index 267e4a82..e12b730f 100644 --- a/demo/sat-demo/build.gradle.kts +++ b/demo/sat-demo/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.jvm") + id("space.kscience.gradle.jvm") application } diff --git a/demo/solid-showcase/build.gradle.kts b/demo/solid-showcase/build.gradle.kts index bc391b9d..d3e03135 100644 --- a/demo/solid-showcase/build.gradle.kts +++ b/demo/solid-showcase/build.gradle.kts @@ -1,8 +1,8 @@ -import ru.mipt.npm.gradle.DependencyConfiguration -import ru.mipt.npm.gradle.FXModule +import space.kscience.gradle.DependencyConfiguration +import space.kscience.gradle.FXModule plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") application } diff --git a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt index 4ddc185a..56221efb 100644 --- a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt +++ b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt @@ -4,7 +4,6 @@ import info.laht.threekt.core.Object3D import info.laht.threekt.geometries.BoxGeometry import info.laht.threekt.objects.Mesh import space.kscience.dataforge.meta.asValue -import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.int import space.kscience.dataforge.meta.number import space.kscience.dataforge.names.asName @@ -43,13 +42,13 @@ internal class VariableBox(val xSize: Number, val ySize: Number) : ThreeJsVision it.layers.enable(this@VariableBox.layer) } } - mesh.scale.z = meta[VALUE].number?.toDouble() ?: 1.0 + mesh.scale.z = properties.getValue(VALUE)?.number?.toDouble() ?: 1.0 //add listener to object properties onPropertyChange { name -> when { name == VALUE -> { - val value = meta[VALUE].int ?: 0 + val value = properties.getValue(VALUE)?.int ?: 0 val size = value.toFloat() / 255f * 20f mesh.scale.z = size.toDouble() mesh.position.z = size.toDouble() / 2 @@ -69,9 +68,9 @@ internal class VariableBox(val xSize: Number, val ySize: Number) : ThreeJsVision } var value: Int - get() = meta[VALUE].int ?: 0 + get() = properties.getValue(VALUE)?.int ?: 0 set(value) { - setPropertyValue(VALUE, value.asValue()) + properties.setValue(VALUE, value.asValue()) } companion object { diff --git a/gradle.properties b/gradle.properties index 92f33679..aeb2ca21 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,4 +6,4 @@ kotlin.jupyter.add.scanner=false org.gradle.parallel=true org.gradle.jvmargs=-Xmx4G -toolsVersion=0.11.8-kotlin-1.7.10 \ No newline at end of file +toolsVersion=0.12.0-kotlin-1.7.20-Beta \ No newline at end of file diff --git a/jupyter/build.gradle.kts b/jupyter/build.gradle.kts index 0b406250..45aaeaa3 100644 --- a/jupyter/build.gradle.kts +++ b/jupyter/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") id("org.jetbrains.kotlin.jupyter.api") } @@ -21,5 +21,5 @@ kotlin { } readme { - maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL + maturity = space.kscience.gradle.Maturity.EXPERIMENTAL } \ No newline at end of file diff --git a/jupyter/visionforge-jupyter-gdml/build.gradle.kts b/jupyter/visionforge-jupyter-gdml/build.gradle.kts index 4a575602..3129de1e 100644 --- a/jupyter/visionforge-jupyter-gdml/build.gradle.kts +++ b/jupyter/visionforge-jupyter-gdml/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") } description = "Jupyter api artifact for GDML rendering" @@ -56,5 +56,5 @@ kscience { } readme { - maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL + maturity = space.kscience.gradle.Maturity.EXPERIMENTAL } \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 3ae9f6f9..4215d150 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -15,10 +15,10 @@ pluginManagement { } plugins { - id("ru.mipt.npm.gradle.project") version toolsVersion - id("ru.mipt.npm.gradle.mpp") version toolsVersion - id("ru.mipt.npm.gradle.jvm") version toolsVersion - id("ru.mipt.npm.gradle.js") version toolsVersion + id("space.kscience.gradle.project") version toolsVersion + id("space.kscience.gradle.mpp") version toolsVersion + id("space.kscience.gradle.jvm") version toolsVersion + id("space.kscience.gradle.js") version toolsVersion } } @@ -34,7 +34,7 @@ dependencyResolutionManagement { versionCatalogs { create("npmlibs") { - from("ru.mipt.npm:version-catalog:$toolsVersion") + from("space.kscience:version-catalog:$toolsVersion") } } } diff --git a/ui/bootstrap/build.gradle.kts b/ui/bootstrap/build.gradle.kts index b1b0588e..c0b980d9 100644 --- a/ui/bootstrap/build.gradle.kts +++ b/ui/bootstrap/build.gradle.kts @@ -1,6 +1,6 @@ plugins { kotlin("js") - id("ru.mipt.npm.gradle.js") + id("space.kscience.gradle.js") } val dataforgeVersion: String by rootProject.extra diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt index 0d4e2dc7..deb63381 100644 --- a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt +++ b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt @@ -1,5 +1,6 @@ package space.kscience.visionforge.bootstrap +import kotlinx.coroutines.GlobalScope import kotlinx.css.BorderStyle import kotlinx.css.Color import kotlinx.css.padding @@ -15,7 +16,6 @@ import react.RBuilder import react.dom.attrs import react.dom.button import react.fc -import space.kscience.dataforge.meta.withDefault import space.kscience.visionforge.Vision import space.kscience.visionforge.encodeToString import space.kscience.visionforge.react.flexColumn @@ -69,8 +69,8 @@ public val CanvasControls: FC = fc("CanvasControls") { prop } } propertyEditor( - ownProperties = props.canvasOptions.meta, - allProperties = props.canvasOptions.meta.withDefault(Canvas3DOptions.descriptor.defaultNode), + scope = props.vision?.manager?.context ?: GlobalScope, + properties = props.canvasOptions.meta, descriptor = Canvas3DOptions.descriptor, expanded = false ) diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt index 4393565a..b82d48fe 100644 --- a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt +++ b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt @@ -3,13 +3,16 @@ package space.kscience.visionforge.bootstrap import org.w3c.dom.Element import react.RBuilder import react.dom.client.createRoot +import react.key import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.meta.get import space.kscience.visionforge.Vision -import space.kscience.visionforge.computeProperties import space.kscience.visionforge.getStyle +import space.kscience.visionforge.react.EditorPropertyState +import space.kscience.visionforge.react.PropertyEditor import space.kscience.visionforge.react.metaViewer -import space.kscience.visionforge.react.propertyEditor import space.kscience.visionforge.react.render +import space.kscience.visionforge.root import space.kscience.visionforge.solid.SolidReference import space.kscience.visionforge.styles @@ -20,12 +23,25 @@ public fun RBuilder.visionPropertyEditor( ) { card("Properties") { - propertyEditor( - ownProperties = vision.meta, - allProperties = vision.computeProperties(), - descriptor = descriptor, - key = key - ) + child(PropertyEditor){ + attrs{ + this.key = key?.toString() + this.meta = vision.properties.root() + this.updates = vision.properties.changes + this.descriptor = descriptor + this.scope = vision.manager?.context ?: error("Orphan vision could not be observed") + this.getPropertyState = {name-> + if(vision.properties.own?.get(name)!= null){ + EditorPropertyState.Defined + } else if(vision.properties.root()[name] != null){ + // TODO differentiate + EditorPropertyState.Default() + } else { + EditorPropertyState.Undefined + } + } + } + } } val styles = if (vision is SolidReference) { (vision.styles + vision.prototype.styles).distinct() diff --git a/ui/react/build.gradle.kts b/ui/react/build.gradle.kts index d71dc6ac..1a58d333 100644 --- a/ui/react/build.gradle.kts +++ b/ui/react/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.js") + id("space.kscience.gradle.js") } dependencies{ diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt index 612fdfe6..fb339429 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt @@ -25,7 +25,7 @@ public val MultiSelectChooser: FC = fc("MultiSelectChooser") select { attrs { multiple = true - values = (props.actual.value?.list ?: emptyList()).mapTo(HashSet()) { it.string } + values = (props.meta.value?.list ?: emptyList()).mapTo(HashSet()) { it.string } onChangeFunction = onChange } props.descriptor?.allowedValues?.forEach { optionValue -> diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt index 29c9b49e..4e94ef06 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt @@ -1,13 +1,18 @@ package space.kscience.visionforge.react +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch import kotlinx.css.* import kotlinx.css.properties.TextDecoration import kotlinx.html.js.onClickFunction -import org.w3c.dom.Element import org.w3c.dom.events.Event import react.* import react.dom.attrs -import react.dom.client.createRoot import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.ValueRequirement @@ -19,17 +24,30 @@ import styled.styledButton import styled.styledDiv import styled.styledSpan +/** + * The display state of a property + */ +public sealed class EditorPropertyState { + public object Defined : EditorPropertyState() + public class Default(public val source: String = "unknown") : EditorPropertyState() + + public object Undefined : EditorPropertyState() + +} + + public external interface PropertyEditorProps : Props { /** * Root config object - always non-null */ - public var meta: ObservableMutableMeta + public var meta: MutableMeta - /** - * Provide default item (greyed out if used) - */ - public var withDefault: MetaProvider + public var getPropertyState: (Name) -> EditorPropertyState + + public var scope: CoroutineScope + + public var updates: Flow /** * Full path to the displayed node in [meta]. Could be empty @@ -54,7 +72,7 @@ private val PropertyEditorItem: FC = fc("PropertyEditorItem private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { var expanded: Boolean by useState { props.expanded ?: true } val descriptor: MetaDescriptor? = useMemo(props.descriptor, props.name) { props.descriptor?.get(props.name) } - var ownProperty: ObservableMutableMeta by useState { props.meta.getOrCreate(props.name) } + var property: MutableMeta by useState { props.meta.getOrCreate(props.name) } val keys = useMemo(descriptor) { buildSet { @@ -70,17 +88,18 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { val token = props.name.lastOrNull()?.toString() ?: "Properties" fun update() { - ownProperty = props.meta.getOrCreate(props.name) + property = props.meta.getOrCreate(props.name) } useEffect(props.meta) { - props.meta.onChange(props) { updatedName -> + val job = props.updates.onEach { updatedName -> if (updatedName == props.name) { update() } - } + }.launchIn(props.scope) + cleanup { - props.meta.removeListener(props) + job.cancel() } } @@ -115,7 +134,7 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { styledSpan { css { +TreeStyles.treeLabel - if (ownProperty.isEmpty()) { + if (property.isEmpty()) { +TreeStyles.treeLabelInactive } } @@ -131,8 +150,8 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { ValueChooser { attrs { this.descriptor = descriptor - this.meta = ownProperty - this.actual = props.withDefault.getMeta(props.name) ?: ownProperty + this.meta = property + this.state = props.getPropertyState(props.name) } } } @@ -156,7 +175,7 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { } +"\u00D7" attrs { - if (ownProperty.isEmpty()) { + if (property.isEmpty()) { disabled = true } else { onClickFunction = removeClick @@ -179,9 +198,11 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { attrs { this.key = props.name.toString() this.meta = props.meta - this.withDefault = props.withDefault this.name = props.name + token this.descriptor = props.descriptor + this.scope = props.scope + this.getPropertyState = { props.getPropertyState(props.name + token) } + this.updates = props.updates } } //configEditor(props.root, props.name + token, props.descriptor, props.default) @@ -197,44 +218,51 @@ public val PropertyEditor: FC = fc("PropertyEditor") { prop attrs { this.key = "" this.meta = props.meta - this.withDefault = props.withDefault this.name = Name.EMPTY this.descriptor = props.descriptor this.expanded = props.expanded + this.scope = props.scope + this.getPropertyState = props.getPropertyState + this.updates = props.updates } } } +@OptIn(ExperimentalCoroutinesApi::class) public fun RBuilder.propertyEditor( - ownProperties: ObservableMutableMeta, - allProperties: MetaProvider = ownProperties, + scope: CoroutineScope, + properties: ObservableMutableMeta, descriptor: MetaDescriptor? = null, key: Any? = null, expanded: Boolean? = null, ) { child(PropertyEditor) { attrs { - this.meta = ownProperties - this.withDefault = allProperties + this.meta = properties this.descriptor = descriptor this.key = key?.toString() ?: "" this.expanded = expanded + this.scope = scope + this.getPropertyState = { name -> + if (properties[name] != null) { + EditorPropertyState.Defined + } else if (descriptor?.get(name)?.defaultValue != null) { + EditorPropertyState.Default("descriptor") + } else { + EditorPropertyState.Undefined + } + } + this.updates = callbackFlow { + properties.onChange(scope) { name -> + scope.launch { + send(name) + } + } + + invokeOnClose { + properties.removeListener(scope) + } + } } } -} - -public fun RBuilder.configEditor( - config: ObservableMutableMeta, - default: MetaProvider = config, - descriptor: MetaDescriptor? = null, - key: Any? = null, -): Unit = propertyEditor(config, default, descriptor, key = key) - -public fun Element.configEditor( - config: ObservableMutableMeta, - default: Meta = config, - descriptor: MetaDescriptor? = null, - key: Any? = null, -): Unit = createRoot(this).render { - configEditor(config, default, descriptor, key = key) } \ No newline at end of file diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt index 382209c2..ae6386d9 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt @@ -20,7 +20,7 @@ import styled.styledInput @JsExport public val RangeValueChooser: FC = fc("RangeValueChooser") { props -> - var innerValue by useState(props.actual.double) + var innerValue by useState(props.meta.double) var rangeDisabled: Boolean by useState(props.meta.value == null) val handleDisable: (Event) -> Unit = { diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/VisionTree.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/VisionTree.kt index 84f9347f..9866c30e 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/VisionTree.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/VisionTree.kt @@ -16,6 +16,7 @@ import space.kscience.dataforge.names.plus import space.kscience.dataforge.names.startsWith import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionGroup +import space.kscience.visionforge.asSequence import space.kscience.visionforge.isEmpty import styled.css import styled.styledDiv @@ -59,9 +60,9 @@ private fun RBuilder.visionTree(props: ObjectTreeProps): Unit { val obj = props.obj //display as node if any child is visible - if (obj is VisionGroup<*>) { + if (obj is VisionGroup) { flexRow { - if (obj.items.any { !it.key.body.startsWith("@") }) { + if (obj.children.keys.any { !it.body.startsWith("@") }) { styledSpan { css { +TreeStyles.treeCaret @@ -81,9 +82,9 @@ private fun RBuilder.visionTree(props: ObjectTreeProps): Unit { css { +TreeStyles.tree } - obj.items.entries - .filter { !it.key.toString().startsWith("@") } // ignore statics and other hidden children - .sortedBy { (it.value as? VisionGroup<*>)?.isEmpty() ?: true } // ignore empty groups + obj.children.asSequence() + .filter { !it.first.toString().startsWith("@") } // ignore statics and other hidden children + .sortedBy { (it.second as? VisionGroup)?.children?.isEmpty() ?: true } // ignore empty groups .forEach { (childToken, child) -> styledDiv { css { @@ -92,7 +93,7 @@ private fun RBuilder.visionTree(props: ObjectTreeProps): Unit { child(ObjectTree) { attrs { this.name = props.name + childToken - this.obj = child.vision + this.obj = child this.selected = props.selected this.clickCallback = props.clickCallback } diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt index cd769414..75cd3a0c 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt @@ -27,13 +27,13 @@ import styled.styledSelect public external interface ValueChooserProps : Props { public var descriptor: MetaDescriptor? - public var meta: ObservableMutableMeta - public var actual: Meta + public var meta: MutableMeta + public var state: EditorPropertyState } @JsExport public val StringValueChooser: FC = fc("StringValueChooser") { props -> - var value by useState(props.actual.string ?: "") + var value by useState(props.meta.string ?: "") val keyDown: (Event) -> Unit = { event -> if (event.type == "keydown" && event.asDynamic().key == "Enter") { value = (event.target as HTMLInputElement).value @@ -67,7 +67,7 @@ public val BooleanValueChooser: FC = fc("BooleanValueChooser" } attrs { //this.attributes["indeterminate"] = (props.item == null).toString() - checked = props.actual.boolean ?: false + checked = props.meta.boolean ?: false onChangeFunction = handleChange } } @@ -75,7 +75,7 @@ public val BooleanValueChooser: FC = fc("BooleanValueChooser" @JsExport public val NumberValueChooser: FC = fc("NumberValueChooser") { props -> - var innerValue by useState(props.actual.string ?: "") + var innerValue by useState(props.meta.string ?: "") val keyDown: (Event) -> Unit = { event -> if (event.type == "keydown" && event.asDynamic().key == "Enter") { innerValue = (event.target as HTMLInputElement).value @@ -113,7 +113,7 @@ public val NumberValueChooser: FC = fc("NumberValueChooser") @JsExport public val ComboValueChooser: FC = fc("ComboValueChooser") { props -> - var selected by useState(props.actual.string ?: "") + var selected by useState(props.meta.string ?: "") val handleChange: (Event) -> Unit = { selected = (it.target as HTMLSelectElement).value props.meta.value = selected.asValue() @@ -128,7 +128,7 @@ public val ComboValueChooser: FC = fc("ComboValueChooser") { } } attrs { - this.value = props.actual.string ?: "" + this.value = props.meta.string ?: "" multiple = false onChangeFunction = handleChange } @@ -146,7 +146,7 @@ public val ColorValueChooser: FC = fc("ColorValueChooser") { margin(0.px) } attrs { - this.value = props.actual.value?.let { value -> + this.value = props.meta.value?.let { value -> if (value.type == ValueType.NUMBER) Colors.rgbToString(value.int) else value.string } ?: "#000000" diff --git a/ui/ring/build.gradle.kts b/ui/ring/build.gradle.kts index 7d7564b5..aa168c11 100644 --- a/ui/ring/build.gradle.kts +++ b/ui/ring/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.js") + id("space.kscience.gradle.js") } val dataforgeVersion: String by rootProject.extra diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt index 085ff608..babafb2e 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt @@ -9,18 +9,19 @@ import react.dom.div import react.dom.span import ringui.* import space.kscience.dataforge.context.Context +import space.kscience.dataforge.meta.get import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken import space.kscience.dataforge.names.isEmpty import space.kscience.dataforge.names.length -import space.kscience.visionforge.* -import space.kscience.visionforge.react.ThreeCanvasComponent -import space.kscience.visionforge.react.flexColumn -import space.kscience.visionforge.react.flexRow -import space.kscience.visionforge.react.propertyEditor +import space.kscience.visionforge.Vision +import space.kscience.visionforge.react.* +import space.kscience.visionforge.root +import space.kscience.visionforge.setAsRoot import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.SolidGroup import space.kscience.visionforge.solid.specifications.Canvas3DOptions +import space.kscience.visionforge.visionManager import styled.css import styled.styledDiv @@ -38,7 +39,7 @@ public fun ThreeCanvasWithControlsProps.solid(block: SolidGroup.() -> Unit) { } } -public fun ThreeCanvasWithControlsProps.options(block: Canvas3DOptions.() -> Unit){ +public fun ThreeCanvasWithControlsProps.options(block: Canvas3DOptions.() -> Unit) { options = Canvas3DOptions(block) } @@ -81,14 +82,14 @@ public fun RBuilder.nameCrumbs(name: Name?, link: (Name) -> Unit): Unit = styled @JsExport public val ThreeCanvasWithControls: FC = fc("ThreeViewWithControls") { props -> - var selected by useState { props.selected } + var selected: Name? by useState { props.selected } var solid: Solid? by useState(null) useEffect { props.context.launch { solid = props.builderOfSolid.await() //ensure that the solid is properly rooted - if(solid?.parent == null){ + if (solid?.parent == null) { solid?.setAsRoot(props.context.visionManager) } } @@ -164,12 +165,25 @@ public val ThreeCanvasWithControls: FC = fc("Three nameCrumbs(selected) { selected = it } } IslandContent { - propertyEditor( - ownProperties = vision.properties(), - allProperties = vision.computeProperties(), - descriptor = vision.descriptor, - key = selected - ) + child(PropertyEditor) { + attrs { + this.key = selected.toString() + this.meta = vision.properties.root() + this.updates = vision.properties.changes + this.descriptor = vision.descriptor + this.scope = props.context + this.getPropertyState = { name -> + if (vision.properties.own?.get(name) != null) { + EditorPropertyState.Defined + } else if (vision.properties.root()[name] != null) { + // TODO differentiate + EditorPropertyState.Default() + } else { + EditorPropertyState.Undefined + } + } + } + } } } } diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt index 5c959184..b4ce3284 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt @@ -4,17 +4,16 @@ import org.w3c.dom.Element import react.RBuilder import react.dom.client.createRoot import react.dom.p +import react.key import ringui.Island import ringui.SmartTabs import ringui.Tab import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.meta.get import space.kscience.visionforge.Vision -import space.kscience.visionforge.computeProperties import space.kscience.visionforge.getStyle -import space.kscience.visionforge.react.flexColumn -import space.kscience.visionforge.react.metaViewer -import space.kscience.visionforge.react.propertyEditor -import space.kscience.visionforge.react.render +import space.kscience.visionforge.react.* +import space.kscience.visionforge.root import space.kscience.visionforge.solid.SolidReference import space.kscience.visionforge.styles @@ -31,12 +30,25 @@ public fun RBuilder.ringPropertyEditor( flexColumn { Island("Properties") { - propertyEditor( - ownProperties = vision.meta, - allProperties = vision.computeProperties(), - descriptor = descriptor, - key = key - ) + child(PropertyEditor) { + attrs { + this.key = key?.toString() + this.meta = vision.properties.root() + this.updates = vision.properties.changes + this.descriptor = descriptor + this.scope = vision.manager?.context ?: error("Orphan vision could not be observed") + this.getPropertyState = {name-> + if(vision.properties.own?.get(name)!= null){ + EditorPropertyState.Defined + } else if(vision.properties.root()[name] != null){ + // TODO differentiate + EditorPropertyState.Default() + } else { + EditorPropertyState.Undefined + } + } + } + } } if (styles.isNotEmpty()) { diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt index 68cc13b2..1b62bd1f 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt @@ -1,5 +1,6 @@ package space.kscience.visionforge.ring +import kotlinx.coroutines.GlobalScope import kotlinx.css.BorderStyle import kotlinx.css.Color import kotlinx.css.padding @@ -18,7 +19,6 @@ import react.fc import ringui.Island import ringui.SmartTabs import ringui.Tab -import space.kscience.dataforge.meta.withDefault import space.kscience.dataforge.names.Name import space.kscience.visionforge.Vision import space.kscience.visionforge.encodeToString @@ -75,8 +75,8 @@ internal val CanvasControls: FC = fc("CanvasControls") { pr } } propertyEditor( - ownProperties = props.options.meta, - allProperties = props.options.meta.withDefault(Canvas3DOptions.descriptor.defaultNode), + scope = props.vision?.manager?.context ?: GlobalScope, + properties = props.options.meta, descriptor = Canvas3DOptions.descriptor, expanded = false ) diff --git a/visionforge-core/build.gradle.kts b/visionforge-core/build.gradle.kts index 227c80dc..d9bf251c 100644 --- a/visionforge-core/build.gradle.kts +++ b/visionforge-core/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") } val dataforgeVersion: String by rootProject.extra @@ -28,5 +28,5 @@ kscience{ } readme{ - maturity = ru.mipt.npm.gradle.Maturity.DEVELOPMENT + maturity = space.kscience.gradle.Maturity.DEVELOPMENT } \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt index 9fc148b3..1c05d6d6 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt @@ -13,7 +13,7 @@ import kotlin.jvm.JvmInline @JvmInline public value class StyleSheet(private val owner: Vision) { - private val styleNode: Meta get() = owner.properties[STYLESHEET_KEY] + private val styleNode: Meta get() = owner.properties.getProperty(STYLESHEET_KEY) public val items: Map get() = styleNode.items @@ -23,7 +23,7 @@ public value class StyleSheet(private val owner: Vision) { * Define a style without notifying owner */ public fun define(key: String, style: Meta?) { - owner.properties[STYLESHEET_KEY + key] = style + owner.properties.setProperty(STYLESHEET_KEY + key, style) } /** @@ -86,7 +86,7 @@ public val Vision.styleSheet: StyleSheet get() = StyleSheet(this) * Add style name to the list of styles to be resolved later. The style with given name does not necessary exist at the moment. */ public fun Vision.useStyle(name: String) { - styles = (properties.getValue(Vision.STYLE_KEY)?.stringList ?: emptyList()) + name + styles = (properties.own?.get(Vision.STYLE_KEY)?.stringList ?: emptyList()) + name } @@ -94,7 +94,7 @@ public fun Vision.useStyle(name: String) { * Resolve a style with given name for given [Vision]. The style is not necessarily applied to this [Vision]. */ public fun Vision.getStyle(name: String): Meta? = - properties.raw?.getMeta(StyleSheet.STYLESHEET_KEY + name) ?: parent?.getStyle(name) + properties.own?.getMeta(StyleSheet.STYLESHEET_KEY + name) ?: parent?.getStyle(name) /** * Resolve a property from all styles diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt index 9b8304de..a8b590e7 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt @@ -1,9 +1,9 @@ package space.kscience.visionforge +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach -import space.kscience.dataforge.context.Global import space.kscience.dataforge.meta.asValue import space.kscience.dataforge.meta.boolean import space.kscience.dataforge.meta.descriptors.Described @@ -30,7 +30,7 @@ public interface Vision : Described { /** * Owner [VisionManager]. Used to define coroutine scope a serialization */ - public val manager: VisionManager get() = parent?.manager ?: Global.visionManager + public val manager: VisionManager? get() = parent?.manager public val properties: MutableVisionProperties @@ -67,13 +67,17 @@ public var Vision.visible: Boolean? /** * Subscribe on property updates. The subscription is bound to the given scope and canceled when the scope is canceled */ -public fun Vision.onPropertyChange(callback: (Name) -> Unit): Job = properties.changes.onEach { +public fun Vision.onPropertyChange( + scope: CoroutineScope? = manager?.context, + callback: (Name) -> Unit +): Job = properties.changes.onEach { callback(it) -}.launchIn(manager.context) +}.launchIn(scope ?: error("Orphan Vision can't observe properties")) public fun V.useProperty( property: KProperty1, + scope: CoroutineScope? = manager?.context, callBack: V.(T) -> Unit, ): Job { //Pass initial value. @@ -82,5 +86,5 @@ public fun V.useProperty( if (name.startsWith(property.name.asName())) { callBack(property.get(this@useProperty)) } - }.launchIn(manager.context) + }.launchIn(scope ?: error("Orphan Vision can't observe properties")) } \ No newline at end of file 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 d0a7ec70..0e3a8dc1 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt @@ -91,8 +91,8 @@ private fun CoroutineScope.collectChange( ) { //Collect properties change - source.onPropertyChange { propertyName -> - val newItem = source.properties.raw?.get(propertyName) + source.onPropertyChange(this) { propertyName -> + val newItem = source.properties.own?.get(propertyName) collector().propertyChanged(name, propertyName, newItem) } @@ -118,8 +118,8 @@ private fun CoroutineScope.collectChange( */ public fun Vision.flowChanges( collectionDuration: Duration, - manager: VisionManager = this.manager, ): Flow = flow { + val manager = manager?: error("Orphan vision could not collect changes") var collector = VisionChangeBuilder(manager) coroutineScope { diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt index 529c01a1..481a53ce 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt @@ -124,7 +124,7 @@ internal abstract class VisionChildrenImpl( return items!! } - private val scope: CoroutineScope get() = group.manager.context + private val scope: CoroutineScope? get() = group.manager?.context override val keys: Set get() = items?.keys ?: emptySet() @@ -134,7 +134,7 @@ internal abstract class VisionChildrenImpl( override val changes: SharedFlow get() = _changes private fun onChange(name: Name) { - scope.launch { + scope?.launch { _changes.emit(name) } } @@ -158,7 +158,7 @@ internal abstract class VisionChildrenImpl( //set parent value.parent = group //start update jobs (only if the vision is rooted) - scope.let { scope -> + scope?.let { scope -> val job = value.children?.changes?.onEach { onChange(token + it) }?.launchIn(scope) diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt index 3428dd33..a6f1a7c6 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt @@ -107,7 +107,8 @@ public abstract class VisionPlugin(meta: Meta = Meta.EMPTY) : AbstractPlugin(met */ public val Context.visionManager: VisionManager get() = fetch(VisionManager) -public fun Vision.encodeToString(): String = manager.encodeToString(this) +public fun Vision.encodeToString(): String = + manager?.encodeToString(this) ?: error("Orphan vision could not be encoded") /** * A root vision attached to [VisionManager] 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 7b6c6e7b..693e85bf 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt @@ -1,5 +1,7 @@ package space.kscience.visionforge +import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.SharedFlow @@ -16,14 +18,14 @@ public interface VisionProperties { /** * Raw Visions own properties without styles, defaults, etc. */ - public val raw: Meta? + public val own: Meta? public val descriptor: MetaDescriptor? public fun getValue( name: Name, - inherit: Boolean, - includeStyles: Boolean, + inherit: Boolean? = null, + includeStyles: Boolean? = null, ): Value? /** @@ -31,10 +33,10 @@ public interface VisionProperties { * @param inherit toggles parent node property lookup. Null means inference from descriptor. * @param includeStyles toggles inclusion of properties from styles. */ - public operator fun get( + public fun getProperty( name: Name, - inherit: Boolean, - includeStyles: Boolean, + inherit: Boolean? = null, + includeStyles: Boolean? = null, ): Meta public val changes: Flow @@ -48,10 +50,10 @@ public interface VisionProperties { public interface MutableVisionProperties : VisionProperties { - override operator fun get( + override fun getProperty( name: Name, - inherit: Boolean, - includeStyles: Boolean, + inherit: Boolean?, + includeStyles: Boolean?, ): MutableMeta = VisionPropertiesItem( this, name, @@ -60,7 +62,7 @@ public interface MutableVisionProperties : VisionProperties { ) - public operator fun set( + public fun setProperty( name: Name, node: Meta?, ) @@ -84,7 +86,7 @@ private class VisionPropertiesItem( override val items: Map get() { - val metaKeys = properties.raw?.getMeta(nodeName)?.items?.keys ?: emptySet() + val metaKeys = properties.own?.getMeta(nodeName)?.items?.keys ?: emptySet() val descriptorKeys = descriptor?.children?.map { NameToken(it.key) } ?: emptySet() val defaultKeys = default?.get(nodeName)?.items?.keys ?: emptySet() val inheritFlag = descriptor?.inherited ?: inherit @@ -119,7 +121,7 @@ private class VisionPropertiesItem( ) override fun setMeta(name: Name, node: Meta?) { - properties[nodeName + name] = node + properties.setProperty(nodeName + name, node) } override fun toString(): String = Meta.toString(this) @@ -131,11 +133,10 @@ public abstract class AbstractVisionProperties( private val vision: Vision, ) : MutableVisionProperties { override val descriptor: MetaDescriptor? get() = vision.descriptor - protected val default: Meta? get() = descriptor?.defaultNode protected abstract var properties: MutableMeta? - override val raw: Meta? get() = properties + override val own: Meta? get() = properties @Synchronized protected fun getOrCreateProperties(): MutableMeta { @@ -149,20 +150,24 @@ public abstract class AbstractVisionProperties( override fun getValue( name: Name, - inherit: Boolean, - includeStyles: Boolean, + inherit: Boolean?, + includeStyles: Boolean?, ): Value? { - raw?.get(name)?.value?.let { return it } - if (includeStyles) { + val descriptor = descriptor?.get(name) + val inheritFlag = inherit ?: descriptor?.inherited ?: false + val stylesFlag = includeStyles ?: descriptor?.usesStyles ?: true + + own?.get(name)?.value?.let { return it } + if (stylesFlag) { vision.getStyleProperty(name)?.value?.let { return it } } - if (inherit) { + if (inheritFlag) { vision.parent?.properties?.getValue(name, inherit, includeStyles)?.let { return it } } - return default?.get(name)?.value + return descriptor?.defaultValue } - override fun set(name: Name, node: Meta?) { + override fun setProperty(name: Name, node: Meta?) { //TODO check old value? if (name.isEmpty()) { properties = node?.asMutableMeta() @@ -188,6 +193,7 @@ public abstract class AbstractVisionProperties( private val _changes = MutableSharedFlow(10) override val changes: SharedFlow get() = _changes + @OptIn(DelicateCoroutinesApi::class) override fun invalidate(propertyName: Name) { if (propertyName == Vision.STYLE_KEY) { vision.styles.asSequence() @@ -198,85 +204,46 @@ public abstract class AbstractVisionProperties( invalidate(it.key.asName()) } } - vision.manager.context.launch { + (vision.manager?.context ?: GlobalScope).launch { _changes.emit(propertyName) } } } -public fun VisionProperties.getValue( - name: Name, - inherit: Boolean? = null, - includeStyles: Boolean? = null, -): Value? { - val descriptor = descriptor?.get(name) - val inheritFlag = inherit ?: descriptor?.inherited ?: false - val stylesFlag = includeStyles ?: descriptor?.usesStyles ?: true - return getValue(name, inheritFlag, stylesFlag) -} - public fun VisionProperties.getValue( name: String, inherit: Boolean? = null, includeStyles: Boolean? = null, ): Value? = getValue(name.parseAsName(), inherit, includeStyles) -/** - * Compute the property based on the provided value descriptor. By default, use Vision own descriptor - */ -public operator fun VisionProperties.get( - name: Name, - inherit: Boolean? = null, - includeStyles: Boolean? = null, -): Meta { - val descriptor: MetaDescriptor? = descriptor?.get(name) - val inheritFlag = inherit ?: descriptor?.inherited ?: false - val stylesFlag = includeStyles ?: descriptor?.usesStyles ?: true - return get(name, inheritFlag, stylesFlag) -} - - /** * Get [Vision] property using key as a String */ -public operator fun VisionProperties.get( +public fun VisionProperties.getProperty( name: String, inherit: Boolean? = null, includeStyles: Boolean? = null, -): Meta = get(name.parseAsName(), inherit, includeStyles) - - -/** - * Compute the property based on the provided value descriptor. By default, use Vision own descriptor - */ -public operator fun MutableVisionProperties.get( - name: Name, - inherit: Boolean? = null, - includeStyles: Boolean? = null, -): MutableMeta { - val descriptor: MetaDescriptor? = descriptor?.get(name) - val inheritFlag = inherit ?: descriptor?.inherited ?: false - val stylesFlag = includeStyles ?: descriptor?.usesStyles ?: true - return get(name, inheritFlag, stylesFlag) -} +): Meta = getProperty(name.parseAsName(), inherit, includeStyles) /** * The root property node with given inheritance and style flags + * @param inherit - inherit properties from the [Vision] parent. If null, infer from descriptor + * @param includeStyles - include style information. If null, infer from descriptor */ public fun MutableVisionProperties.root( inherit: Boolean? = null, includeStyles: Boolean? = null, -): MutableMeta = get(Name.EMPTY, inherit, includeStyles) +): MutableMeta = getProperty(Name.EMPTY, inherit, includeStyles) /** * Get [Vision] property using key as a String */ -public operator fun MutableVisionProperties.get( +public fun MutableVisionProperties.getProperty( name: String, inherit: Boolean? = null, includeStyles: Boolean? = null, -): MutableMeta = get(name.parseAsName(), inherit, includeStyles) +): MutableMeta = getProperty(name.parseAsName(), inherit, includeStyles) public operator fun MutableVisionProperties.set(name: Name, value: Number): Unit = diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt index 19106240..3a818b08 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt @@ -9,7 +9,7 @@ import space.kscience.dataforge.names.Name import space.kscience.visionforge.* //TODO replace by something -internal val Vision.mutableProperties get() = properties[Name.EMPTY, false, false] +internal val Vision.mutableProperties get() = properties.getProperty(Name.EMPTY, false, false) @Serializable public abstract class VisionOfHtmlInput : AbstractVision() { diff --git a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt index d6128963..f72fe2bf 100644 --- a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt +++ b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt @@ -54,7 +54,7 @@ class HtmlTagTest { div { h2 { +"Properties" } ul { - vision.properties.raw?.items?.forEach { + vision.properties.own?.items?.forEach { li { a { +it.key.toString() } p { +it.value.toString() } 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 23517112..e7a35faa 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 @@ -2,7 +2,7 @@ package space.kscience.visionforge.meta import space.kscience.dataforge.meta.* import space.kscience.visionforge.VisionGroup -import space.kscience.visionforge.get +import space.kscience.visionforge.getProperty import space.kscience.visionforge.getValue import space.kscience.visionforge.set import kotlin.test.Test @@ -30,7 +30,7 @@ internal class VisionPropertyTest { @Test fun testPropertyEdit() { val vision = VisionGroup() - vision.properties["fff.ddd"].apply { + vision.properties.getProperty("fff.ddd").apply { value = 2.asValue() } assertEquals(2, vision.properties.getValue("fff.ddd")?.int) @@ -40,7 +40,7 @@ internal class VisionPropertyTest { @Test fun testPropertyUpdate() { val vision = VisionGroup() - vision.properties["fff"].updateWith(TestScheme) { + vision.properties.getProperty("fff").updateWith(TestScheme) { ddd = 2 } assertEquals(2, vision.properties.getValue("fff.ddd")?.int) 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 e9425afb..41018759 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt @@ -115,7 +115,7 @@ public class VisionClient : AbstractPlugin() { onopen = { feedbackJob = vision.flowChanges( - feedbackAggregationTime.milliseconds + feedbackAggregationTime.milliseconds, ).onEach { change -> send(visionManager.encodeToString(change)) }.launchIn(visionManager.context) diff --git a/visionforge-fx/build.gradle.kts b/visionforge-fx/build.gradle.kts index 26fa13c8..464c7af3 100644 --- a/visionforge-fx/build.gradle.kts +++ b/visionforge-fx/build.gradle.kts @@ -1,12 +1,12 @@ plugins { - id("ru.mipt.npm.gradle.jvm") + id("space.kscience.gradle.jvm") } val dataforgeVersion: String by rootProject.extra val fxVersion: String by rootProject.extra kscience{ - useFx(ru.mipt.npm.gradle.FXModule.CONTROLS, version = fxVersion) + useFx(space.kscience.gradle.FXModule.CONTROLS, version = fxVersion) } dependencies { @@ -15,12 +15,12 @@ dependencies { api("org.fxyz3d:fxyz3d:0.5.4") { exclude(module = "slf4j-simple") } - api("org.jetbrains.kotlinx:kotlinx-coroutines-javafx:${ru.mipt.npm.gradle.KScienceVersions.coroutinesVersion}") + api("org.jetbrains.kotlinx:kotlinx-coroutines-javafx:${space.kscience.gradle.KScienceVersions.coroutinesVersion}") implementation("eu.mihosoft.vrl.jcsg:jcsg:0.5.7") { exclude(module = "slf4j-simple") } } readme{ - maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE + maturity = space.kscience.gradle.Maturity.PROTOTYPE } \ No newline at end of file diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt index bac388ee..d39f284c 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FX3DPlugin.kt @@ -16,7 +16,6 @@ import space.kscience.dataforge.context.* import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.boolean import space.kscience.dataforge.misc.Type -import space.kscience.visionforge.get import space.kscience.visionforge.solid.FX3DFactory.Companion.TYPE import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_KEY import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_WIREFRAME_KEY @@ -77,7 +76,7 @@ public class FX3DPlugin : AbstractPlugin() { is PolyLine -> PolyLine3D( obj.points.map { Point3D(it.x, it.y, it.z) }, obj.thickness.toFloat(), - obj.properties.get(SolidMaterial.MATERIAL_COLOR_KEY).color() + obj.properties.getProperty(SolidMaterial.MATERIAL_COLOR_KEY).color() ).apply { this.meshView.cullFace = CullFace.FRONT } diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisualObjectFXBinding.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisualObjectFXBinding.kt index 8d3e2836..2eb2255c 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisualObjectFXBinding.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisualObjectFXBinding.kt @@ -6,7 +6,6 @@ import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.startsWith import space.kscience.visionforge.Vision -import space.kscience.visionforge.get import space.kscience.visionforge.onPropertyChange import tornadofx.* @@ -35,7 +34,7 @@ public class VisualObjectFXBinding(public val fx: FX3DPlugin, public val obj: Vi public operator fun get(key: Name): ObjectBinding { return bindings.getOrPut(key) { object : ObjectBinding() { - override fun computeValue(): Meta = obj.properties[key] + override fun computeValue(): Meta = obj.properties.getProperty(key) } } } diff --git a/visionforge-gdml/build.gradle.kts b/visionforge-gdml/build.gradle.kts index 1e9b59b9..345445da 100644 --- a/visionforge-gdml/build.gradle.kts +++ b/visionforge-gdml/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") } kotlin { @@ -13,5 +13,10 @@ kotlin { api("space.kscience:gdml:0.4.0") } } + jvmTest{ + dependencies{ + implementation("ch.qos.logback:logback-classic:1.2.11") + } + } } } \ No newline at end of file diff --git a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/markLayers.kt b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/markLayers.kt index b2dbce57..7af53964 100644 --- a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/markLayers.kt +++ b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/markLayers.kt @@ -1,5 +1,6 @@ package space.kscience.visionforge.gdml +import space.kscience.dataforge.context.Global import space.kscience.dataforge.context.info import space.kscience.dataforge.context.logger import space.kscience.dataforge.names.Name @@ -50,7 +51,7 @@ private fun VisionCounterTree.topToBottom(): Sequence = seque } public fun SolidGroup.markLayers(thresholds: List = listOf(500, 1000, 20000, 50000)) { - val logger = manager.context.logger + val logger = manager?.context?.logger ?: Global.logger val counterTree = VisionCounterTree(Name.EMPTY, this, hashMapOf()) val totalCount = counterTree.childrenCount if (totalCount > (thresholds.firstOrNull() ?: 0)) { diff --git a/visionforge-gdml/src/commonTest/kotlin/TestCubes.kt b/visionforge-gdml/src/commonTest/kotlin/TestCubes.kt index 948ad214..a30cf863 100644 --- a/visionforge-gdml/src/commonTest/kotlin/TestCubes.kt +++ b/visionforge-gdml/src/commonTest/kotlin/TestCubes.kt @@ -26,7 +26,7 @@ class TestCubes { val smallBoxPrototype = vision.getPrototype(Name.parse("solids.smallBox")) as? Box assertNotNull(smallBoxPrototype) assertEquals(30.0, smallBoxPrototype.xSize.toDouble()) - val smallBoxVision = vision.children["composite-111.smallBox"]?.unref as? Box + val smallBoxVision = vision.children["composite-111.smallBox"]?.prototype as? Box assertNotNull(smallBoxVision) assertEquals(30.0, smallBoxVision.xSize.toDouble()) } diff --git a/visionforge-markdown/build.gradle.kts b/visionforge-markdown/build.gradle.kts index 1a8e4efd..2909ab6d 100644 --- a/visionforge-markdown/build.gradle.kts +++ b/visionforge-markdown/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") } val markdownVersion = "0.2.4" diff --git a/visionforge-plotly/build.gradle.kts b/visionforge-plotly/build.gradle.kts index 1c1ed308..919dde07 100644 --- a/visionforge-plotly/build.gradle.kts +++ b/visionforge-plotly/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") } val plotlyVersion = "0.5.3-dev-1" 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 c23de631..2e89dbf5 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 @@ -16,7 +16,7 @@ import space.kscience.visionforge.root public class VisionOfPlotly private constructor() : AbstractVision() { public constructor(plot: Plot) : this() { - properties[Name.EMPTY] = plot.meta + properties.setProperty(Name.EMPTY, plot.meta) } public val plot: Plot get() = Plot(properties.root().asObservable()) diff --git a/visionforge-server/build.gradle.kts b/visionforge-server/build.gradle.kts index a89f2d07..236dda78 100644 --- a/visionforge-server/build.gradle.kts +++ b/visionforge-server/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.jvm") + id("space.kscience.gradle.jvm") } val ktorVersion = npmlibs.versions.ktor.get() diff --git a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt index bb88fa22..d4bf939f 100644 --- a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt +++ b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt @@ -92,6 +92,7 @@ public class VisionServer internal constructor( header() } title(title) + consumer.header() } body { //Load the fragment and remember all loaded visions diff --git a/visionforge-solid/build.gradle.kts b/visionforge-solid/build.gradle.kts index ce669659..f794afe4 100644 --- a/visionforge-solid/build.gradle.kts +++ b/visionforge-solid/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") } kscience{ @@ -20,9 +20,14 @@ kotlin { implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4") } } + jvmTest{ + dependencies{ + implementation("ch.qos.logback:logback-classic:1.2.11") + } + } } } readme{ - maturity = ru.mipt.npm.gradle.Maturity.DEVELOPMENT + maturity = space.kscience.gradle.Maturity.DEVELOPMENT } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt index dde24ef0..29de1575 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt @@ -29,7 +29,7 @@ public class ColorAccessor( } public fun Vision.color(): ReadOnlyProperty = ReadOnlyProperty { _, property -> - ColorAccessor(properties.root(), property.name.asName()) + ColorAccessor(properties.root(true), property.name.asName()) } public var ColorAccessor?.string: String? diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt index f30c641b..fb1b4774 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt @@ -33,7 +33,7 @@ public inline fun MutableVisionContainer.composite( } val res = Composite(type, children[0], children[1]) - res.properties[Name.EMPTY] = group.properties.raw + res.properties.setProperty(Name.EMPTY, group.properties.own) set(name, res) return res @@ -49,7 +49,7 @@ public fun SolidGroup.smartComposite( @VisionBuilder builder: SolidGroup.() -> Unit, ): Solid = if (type == CompositeType.GROUP) { val group = SolidGroup(builder) - if (name == null && group.properties.raw == null) { + if (name == null && group.properties.own == null) { //append directly to group if no properties are defined group.items.forEach { (_, value) -> value.parent = null diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt index 0b1c2e20..68eded95 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt @@ -107,7 +107,7 @@ public class ExtrudeBuilder( } internal fun build(): Extruded = Extruded(shape, layers).apply { - this.properties[Name.EMPTY] = this@ExtrudeBuilder.properties + this.properties.setProperty(Name.EMPTY, this@ExtrudeBuilder.properties) } } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt index df28b344..587e803c 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt @@ -10,7 +10,7 @@ import space.kscience.visionforge.* public class PolyLine(public val points: List) : SolidBase() { //var lineType by string() - public var thickness: Number by properties[SolidMaterial.MATERIAL_KEY].number { 1.0 } + public var thickness: Number by properties.getProperty(SolidMaterial.MATERIAL_KEY).number { 1.0 } } @VisionBuilder diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt index d932a4b3..2283f187 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt @@ -170,7 +170,7 @@ internal fun float(name: Name, default: Number): ReadWriteProperty = object : ReadWriteProperty { override fun getValue(thisRef: Solid, property: KProperty<*>): Point3D? { - val item = thisRef.properties.raw?.get(name) ?: return null + val item = thisRef.properties.own?.get(name) ?: return null return object : Point3D { override val x: Float get() = item[X_KEY]?.float ?: default override val y: Float get() = item[Y_KEY]?.float ?: default @@ -180,7 +180,7 @@ internal fun point(name: Name, default: Float): ReadWriteProperty, value: Point3D?) { if (value == null) { - thisRef.properties[name] = null + thisRef.properties.setProperty(name, null) } else { thisRef.properties[name + X_KEY] = value.x thisRef.properties[name + Y_KEY] = value.y diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt index e514dee4..80a1129d 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt @@ -54,7 +54,7 @@ public class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder, Mutable * If prototype is a ref, then it is unfolded automatically. */ override fun getPrototype(name: Name): Solid? = - prototypes?.get(name)?.unref ?: (parent as? PrototypeHolder)?.getPrototype(name) + prototypes?.get(name)?.prototype ?: (parent as? PrototypeHolder)?.getPrototype(name) /** * Create or edit prototype node as a group diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt index e8da3499..7d5c4d00 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt @@ -99,15 +99,15 @@ public class SolidMaterial : Scheme() { } public val Solid.color: ColorAccessor - get() = ColorAccessor(properties.root(), MATERIAL_COLOR_KEY) + get() = ColorAccessor(properties.root(true), MATERIAL_COLOR_KEY) public var Solid.material: SolidMaterial? - get() = SolidMaterial.read(properties[MATERIAL_KEY]) - set(value) = properties.set(MATERIAL_KEY, value?.meta) + get() = SolidMaterial.read(properties.getProperty(MATERIAL_KEY)) + set(value) = properties.setProperty(MATERIAL_KEY, value?.meta) @VisionBuilder public fun Solid.material(builder: SolidMaterial.() -> Unit) { - properties[MATERIAL_KEY].updateWith(SolidMaterial, builder) + properties.getProperty(MATERIAL_KEY).updateWith(SolidMaterial, builder) } public var Solid.opacity: Number? 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 e071d07b..51e0bc6b 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 @@ -16,9 +16,10 @@ import space.kscience.visionforge.solid.SolidReference.Companion.REFERENCE_CHILD * Get a vision prototype if it is a [SolidReference] or vision itself if it is not. * Unref is recursive, so it always returns a non-reference. */ -public val Vision.unref: Solid +public val Vision.prototype: Solid get() = when (this) { - is SolidReference -> prototype.unref + is SolidReference -> prototype.prototype + is SolidReferenceChild -> prototype.prototype is Solid -> this else -> error("This Vision is neither Solid nor SolidReference") } @@ -55,13 +56,13 @@ public class SolidReference( propertiesInternal = value } - override val raw: Meta? get() = properties + override val own: Meta? get() = properties - override fun get(name: Name, inherit: Boolean, includeStyles: Boolean): MutableMeta { - return properties?.getMeta(name) ?: prototype.properties.get(name, inherit, includeStyles) + override fun getProperty(name: Name, inherit: Boolean?, includeStyles: Boolean?): MutableMeta { + return properties?.getMeta(name) ?: prototype.properties.getProperty(name, inherit, includeStyles) } - override fun getValue(name: Name, inherit: Boolean, includeStyles: Boolean): Value? { + override fun getValue(name: Name, inherit: Boolean?, includeStyles: Boolean?): Value? { return properties?.getValue(name) ?: prototype.properties.getValue(name, inherit, includeStyles) } } @@ -105,23 +106,23 @@ internal class SolidReferenceChild( override val properties: MutableVisionProperties = object : MutableVisionProperties { override val descriptor: MetaDescriptor get() = this@SolidReferenceChild.descriptor - override val raw: MutableMeta by lazy { owner.properties[childToken(childName).asName()] } + override val own: MutableMeta by lazy { owner.properties.getProperty(childToken(childName).asName()) } - override fun get(name: Name, inherit: Boolean, includeStyles: Boolean): MutableMeta = - raw.getMeta(name) ?: prototype.properties.get(name, inherit, includeStyles) + override fun getProperty(name: Name, inherit: Boolean?, includeStyles: Boolean?): MutableMeta = + own.getMeta(name) ?: prototype.properties.getProperty(name, inherit, includeStyles) override fun getValue( name: Name, - inherit: Boolean, - includeStyles: Boolean, - ): Value? = raw.getValue(name) ?: prototype.properties.getValue(name, inherit, includeStyles) + inherit: Boolean?, + includeStyles: Boolean?, + ): Value? = own.getValue(name) ?: prototype.properties.getValue(name, inherit, includeStyles) - override fun set(name: Name, node: Meta?) { - raw.setMeta(name, node) + override fun setProperty(name: Name, node: Meta?) { + own.setMeta(name, node) } override fun setValue(name: Name, value: Value?) { - raw.setValue(name, value) + own.setValue(name, value) } override val changes: Flow get() = owner.properties.changes.filter { it.startsWith(childToken(childName)) } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt index dbdc58ec..dc01e749 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt @@ -20,7 +20,7 @@ internal fun Solid.updateFrom(other: Solid): Solid { scaleX *= other.scaleX scaleY *= other.scaleY scaleZ *= other.scaleZ - properties[Name.EMPTY] = other.properties.root() + properties.setProperty(Name.EMPTY, other.properties.root()) return this } diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt index 2eb4c65d..5e26284e 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt @@ -3,7 +3,6 @@ package space.kscience.visionforge.solid import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest -import kotlinx.coroutines.withTimeout import space.kscience.dataforge.meta.int import space.kscience.dataforge.meta.string import space.kscience.dataforge.names.asName @@ -26,13 +25,13 @@ class PropertyTest { @OptIn(ExperimentalCoroutinesApi::class) @Test - fun testColorUpdate() = runTest { + fun testColorUpdate() = runTest(dispatchTimeoutMs = 200) { val box = Box(10.0f, 10.0f, 10.0f) val c = CompletableDeferred() - box.onPropertyChange { + val subscription = box.onPropertyChange(this) { if (it == SolidMaterial.MATERIAL_COLOR_KEY) { c.complete(box.color.string) } @@ -42,8 +41,8 @@ class PropertyTest { color.set("pink") } - assertEquals("pink", withTimeout(50) { c.await() }) - + assertEquals("pink", c.await()) + subscription.cancel() } @Test diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt index baad6110..c2dee067 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt @@ -31,7 +31,7 @@ class SerializationTest { val string = Solids.encodeToString(cube) println(string) val newCube = Solids.decodeFromString(string) - assertEquals(cube.properties.raw, newCube.properties.raw) + assertEquals(cube.properties.own, newCube.properties.own) } @Test @@ -52,7 +52,7 @@ class SerializationTest { val string = Solids.encodeToString(group) println(string) val reconstructed = Solids.decodeFromString(string) as SolidGroup - assertEquals(group.children["cube"]?.properties?.raw, reconstructed.children["cube"]?.properties?.raw) + assertEquals(group.children["cube"]?.properties?.own, reconstructed.children["cube"]?.properties?.own) } @Test diff --git a/visionforge-tables/build.gradle.kts b/visionforge-tables/build.gradle.kts index d4e86bf1..55cc27e5 100644 --- a/visionforge-tables/build.gradle.kts +++ b/visionforge-tables/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") } val tablesVersion = "0.2.0-dev-3" @@ -36,5 +36,5 @@ kotlin { } readme{ - maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE + maturity = space.kscience.gradle.Maturity.PROTOTYPE } \ No newline at end of file diff --git a/visionforge-tables/src/commonTest/kotlin/space/kscience/visionforge/tables/VisionOfTableTest.kt b/visionforge-tables/src/commonTest/kotlin/space/kscience/visionforge/tables/VisionOfTableTest.kt index e3b199d1..e1210ffa 100644 --- a/visionforge-tables/src/commonTest/kotlin/space/kscience/visionforge/tables/VisionOfTableTest.kt +++ b/visionforge-tables/src/commonTest/kotlin/space/kscience/visionforge/tables/VisionOfTableTest.kt @@ -17,7 +17,7 @@ internal class VisionOfTableTest { val x by ColumnHeader.typed() val y by ColumnHeader.typed() - val table = ColumnTable(100) { + val table = ColumnTable(100) { x.fill { it.asValue() } y.values = x.values.map { it?.double?.pow(2)?.asValue() } } diff --git a/visionforge-threejs/build.gradle.kts b/visionforge-threejs/build.gradle.kts index f0462837..d9d0f96d 100644 --- a/visionforge-threejs/build.gradle.kts +++ b/visionforge-threejs/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.js") + id("space.kscience.gradle.js") } kotlin{ diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt index 04f192fd..9309848f 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt @@ -10,7 +10,6 @@ import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus import space.kscience.dataforge.names.startsWith import space.kscience.visionforge.VisionBuilder -import space.kscience.visionforge.get import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.set import space.kscience.visionforge.solid.Solid @@ -78,7 +77,7 @@ public abstract class MeshThreeFactory( @VisionBuilder public fun Solid.edges(enabled: Boolean = true, block: SolidMaterial.() -> Unit = {}) { properties.set(EDGES_ENABLED_KEY, enabled) - SolidMaterial.write(properties[EDGES_MATERIAL_KEY]).apply(block) + SolidMaterial.write(properties.getProperty(EDGES_MATERIAL_KEY)).apply(block) } internal fun Mesh.applyProperties(obj: Solid): Mesh = apply { @@ -94,9 +93,9 @@ internal fun Mesh.applyProperties(obj: Solid): Mesh = apply { public fun Mesh.applyEdges(obj: Solid) { val edges = children.find { it.name == "@edges" } as? LineSegments //inherited edges definition, enabled by default - if (obj.properties.get(EDGES_ENABLED_KEY, inherit = true).boolean != false) { + if (obj.properties.getProperty(EDGES_ENABLED_KEY, inherit = true).boolean != false) { val bufferGeometry = geometry as? BufferGeometry ?: return - val material = ThreeMaterials.getLineMaterial(obj.properties[EDGES_MATERIAL_KEY], true) + val material = ThreeMaterials.getLineMaterial(obj.properties.getProperty(EDGES_MATERIAL_KEY), true) if (edges == null) { add( LineSegments( diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt index 8108389e..d33c7e79 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt @@ -11,7 +11,6 @@ import org.w3c.dom.CanvasRenderingContext2D import org.w3c.dom.CanvasTextBaseline import org.w3c.dom.HTMLCanvasElement import org.w3c.dom.MIDDLE -import space.kscience.visionforge.get import space.kscience.visionforge.solid.SolidLabel import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.three.ThreeCanvas.Companion.DO_NOT_HIGHLIGHT_TAG @@ -27,7 +26,7 @@ public object ThreeCanvasLabelFactory : ThreeFactory { val canvas = document.createElement("canvas") as HTMLCanvasElement val context = canvas.getContext("2d") as CanvasRenderingContext2D context.font = "Bold ${obj.fontSize}pt ${obj.fontFamily}" - context.fillStyle = obj.properties[SolidMaterial.MATERIAL_COLOR_KEY].value ?: "black" + context.fillStyle = obj.properties.getProperty(SolidMaterial.MATERIAL_COLOR_KEY).value ?: "black" context.textBaseline = CanvasTextBaseline.MIDDLE val metrics = context.measureText(obj.text) //canvas.width = metrics.width.toInt() diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt index 70938e99..fcd92b7c 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt @@ -4,7 +4,6 @@ import info.laht.threekt.core.BufferGeometry import info.laht.threekt.core.Object3D import info.laht.threekt.math.Color import info.laht.threekt.objects.LineSegments -import space.kscience.visionforge.get import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.solid.PolyLine import space.kscience.visionforge.solid.SolidMaterial @@ -25,7 +24,7 @@ public object ThreeLineFactory : ThreeFactory { } val material = ThreeMaterials.getLineMaterial( - obj.properties[SolidMaterial.MATERIAL_KEY], + obj.properties.getProperty(SolidMaterial.MATERIAL_KEY), false ) diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt index a9f68f69..20bd7f3a 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt @@ -10,7 +10,9 @@ import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus -import space.kscience.visionforge.* +import space.kscience.visionforge.Colors +import space.kscience.visionforge.Vision +import space.kscience.visionforge.getStyleNodes import space.kscience.visionforge.solid.ColorAccessor import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.SolidReference @@ -129,15 +131,15 @@ private var Material.cached: Boolean } public fun Mesh.updateMaterial(vision: Vision) { - val ownMaterialMeta = vision.properties.raw?.get(SolidMaterial.MATERIAL_KEY) + val ownMaterialMeta = vision.properties.own?.get(SolidMaterial.MATERIAL_KEY) if (ownMaterialMeta == null) { if (vision is SolidReference && vision.getStyleNodes(SolidMaterial.MATERIAL_KEY).isEmpty()) { updateMaterial(vision.prototype) } else { - material = ThreeMaterials.cacheMaterial(vision.properties[SolidMaterial.MATERIAL_KEY]) + material = ThreeMaterials.cacheMaterial(vision.properties.getProperty(SolidMaterial.MATERIAL_KEY)) } } else { - material = ThreeMaterials.buildMaterial(vision.properties[SolidMaterial.MATERIAL_KEY]) + material = ThreeMaterials.buildMaterial(vision.properties.getProperty(SolidMaterial.MATERIAL_KEY)) } } @@ -152,15 +154,16 @@ public fun Mesh.updateMaterialProperty(vision: Vision, propertyName: Name) { } else { when (propertyName) { SolidMaterial.MATERIAL_COLOR_KEY -> { - material.asDynamic().color = vision.properties[SolidMaterial.MATERIAL_COLOR_KEY].threeColor() + material.asDynamic().color = vision.properties.getProperty(SolidMaterial.MATERIAL_COLOR_KEY).threeColor() ?: ThreeMaterials.DEFAULT_COLOR } SolidMaterial.SPECULAR_COLOR_KEY -> { - material.asDynamic().specular = vision.properties[SolidMaterial.SPECULAR_COLOR_KEY].threeColor() + material.asDynamic().specular = vision.properties.getProperty(SolidMaterial.SPECULAR_COLOR_KEY).threeColor() ?: ThreeMaterials.DEFAULT_COLOR } SolidMaterial.MATERIAL_EMISSIVE_COLOR_KEY -> { - material.asDynamic().emissive = vision.properties[SolidMaterial.MATERIAL_EMISSIVE_COLOR_KEY].threeColor() + material.asDynamic().emissive = vision.properties.getProperty(SolidMaterial.MATERIAL_EMISSIVE_COLOR_KEY) + .threeColor() ?: ThreeMaterials.BLACK_COLOR } SolidMaterial.MATERIAL_OPACITY_KEY -> { diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt index 03ed5ee4..2fe9585c 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt @@ -1,6 +1,8 @@ package space.kscience.visionforge.solid.three import info.laht.threekt.core.Object3D +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import org.w3c.dom.Element import org.w3c.dom.HTMLElement import space.kscience.dataforge.context.* @@ -9,7 +11,6 @@ import space.kscience.dataforge.meta.update import space.kscience.dataforge.names.* import space.kscience.visionforge.ElementVisionRenderer import space.kscience.visionforge.Vision -import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.solid.* import space.kscience.visionforge.solid.specifications.Canvas3DOptions import space.kscience.visionforge.visible @@ -48,11 +49,11 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { public fun buildObject3D(obj: Solid): Object3D = when (obj) { is ThreeJsVision -> obj.render(this) - is SolidReferenceGroup -> ThreeReferenceFactory.build(this, obj) + is SolidReference -> ThreeReferenceFactory.build(this, obj) is SolidGroup -> { val group = ThreeGroup() obj.items.forEach { (token, child) -> - if (child is Solid && token != SolidGroup.PROTOTYPES_TOKEN && child.ignore != true) { + if (token != SolidGroup.PROTOTYPES_TOKEN && child.ignore != true) { try { val object3D = buildObject3D(child) group[token] = object3D @@ -67,7 +68,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { updatePosition(obj) //obj.onChildrenChange() - obj.onPropertyChange { name -> + obj.properties.changes.onEach { name -> if ( name.startsWith(Solid.POSITION_KEY) || name.startsWith(Solid.ROTATION_KEY) || @@ -78,10 +79,10 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { } else if (name == Vision.VISIBLE_KEY) { visible = obj.visible ?: true } - } + }.launchIn(context) - obj.onStructureChanged(this){ childName -> - val child = get(childName) + obj.children.changes.onEach { childName -> + val child = obj.children[childName] //removing old object findChild(childName)?.let { oldChild -> @@ -97,7 +98,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { logger.error(ex) { "Failed to render $child" } } } - } + }.launchIn(context) } } is Composite -> compositeFactory.build(this, obj) diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt index 8e667dcb..27657931 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt @@ -7,20 +7,21 @@ import space.kscience.dataforge.names.cutFirst import space.kscience.dataforge.names.firstOrNull import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.solid.Solid -import space.kscience.visionforge.solid.SolidReferenceGroup -import space.kscience.visionforge.solid.SolidReferenceGroup.Companion.REFERENCE_CHILD_PROPERTY_PREFIX +import space.kscience.visionforge.solid.SolidReference +import space.kscience.visionforge.solid.SolidReference.Companion.REFERENCE_CHILD_PROPERTY_PREFIX import kotlin.reflect.KClass -public object ThreeReferenceFactory : ThreeFactory { +public object ThreeReferenceFactory : ThreeFactory { private val cache = HashMap() - override val type: KClass = SolidReferenceGroup::class + override val type: KClass = SolidReference::class private fun Object3D.replicate(): Object3D { return when (this) { is Mesh -> Mesh(geometry, material).also { it.applyMatrix4(matrix) } + else -> clone(false) }.also { obj: Object3D -> obj.name = this.name @@ -30,7 +31,7 @@ public object ThreeReferenceFactory : ThreeFactory { } } - override fun build(three: ThreePlugin, obj: SolidReferenceGroup): Object3D { + override fun build(three: ThreePlugin, obj: SolidReference): Object3D { val template = obj.prototype val cachedObject = cache.getOrPut(template) { three.buildObject3D(template) @@ -39,18 +40,20 @@ public object ThreeReferenceFactory : ThreeFactory { val object3D: Object3D = cachedObject.replicate() object3D.updatePosition(obj) - if(object3D is Mesh){ + if (object3D is Mesh) { //object3D.material = ThreeMaterials.buildMaterial(obj.getProperty(SolidMaterial.MATERIAL_KEY).node!!) object3D.applyProperties(obj) } //TODO apply child properties - obj.onPropertyChange { name-> + obj.onPropertyChange { name -> if (name.firstOrNull()?.body == REFERENCE_CHILD_PROPERTY_PREFIX) { - val childName = name.firstOrNull()?.index?.let(Name::parse) ?: error("Wrong syntax for reference child property: '$name'") + val childName = name.firstOrNull()?.index?.let(Name::parse) + ?: error("Wrong syntax for reference child property: '$name'") val propertyName = name.cutFirst() - val referenceChild = obj.children[childName] ?: error("Reference child with name '$childName' not found") + val referenceChild = + obj.children[childName] ?: error("Reference child with name '$childName' not found") val child = object3D.findChild(childName) ?: error("Object child with name '$childName' not found") child.updateProperty(referenceChild, propertyName) } else { diff --git a/visionforge-threejs/visionforge-threejs-server/build.gradle.kts b/visionforge-threejs/visionforge-threejs-server/build.gradle.kts index 67e12b10..399eb5b0 100644 --- a/visionforge-threejs/visionforge-threejs-server/build.gradle.kts +++ b/visionforge-threejs/visionforge-threejs-server/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") } val ktorVersion: String by rootProject.extra