From 288307eaa833671ce5672058170799e6cd4c02c9 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sun, 6 Jun 2021 20:57:39 +0300 Subject: [PATCH] Finish ThreeCancas encapsulation --- .../visionforge/gdml/demo/GDMLAppComponent.kt | 30 +++++------ .../visionforge/gdml/demo/GdmlJsDemoApp.kt | 2 +- .../mipt/npm/muon/monitor/MMAppComponent.kt | 23 ++++---- .../visionforge/solid/demo/ThreeDemoGrid.kt | 3 +- .../visionforge/bootstrap/outputConfig.kt | 35 ++++++------- .../visionforge/bootstrap/threeControls.kt | 20 +++---- .../visionforge/react/ThreeCanvasComponent.kt | 15 ++---- .../ThreeViewWithControls.kt | 34 +++++------- .../ThreeWithControls.kt | 2 +- .../ringThreeControls.kt | 52 +++++++++---------- .../space/kscience/visionforge/Vision.kt | 5 +- .../space/kscience/visionforge/VisionBase.kt | 1 - .../kscience/visionforge/VisionChange.kt | 8 ++- .../kscience/visionforge/VisionGroupBase.kt | 2 +- .../kscience/visionforge/VisionManager.kt | 5 +- .../visionforge/solid/three/ThreeCanvas.kt | 19 +++---- .../visionforge/solid/three/ThreePlugin.kt | 9 ++-- 17 files changed, 122 insertions(+), 143 deletions(-) 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 2122e8bd..c9afca38 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 @@ -11,7 +11,6 @@ import space.kscience.dataforge.context.fetch import space.kscience.dataforge.names.Name import space.kscience.gdml.Gdml import space.kscience.gdml.decodeFromString -import space.kscience.visionforge.Vision import space.kscience.visionforge.bootstrap.gridRow import space.kscience.visionforge.bootstrap.nameCrumbs import space.kscience.visionforge.gdml.toVision @@ -21,27 +20,31 @@ import space.kscience.visionforge.ring.ringThreeControls import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.Solids import space.kscience.visionforge.solid.specifications.Canvas3DOptions -import space.kscience.visionforge.solid.three.ThreeCanvas import styled.css import styled.styledDiv external interface GDMLAppProps : RProps { var context: Context - var rootVision: Vision? + var vision: Solid? var selected: Name? } @JsExport val GDMLApp = functionalComponent("GDMLApp") { props -> var selected by useState { props.selected } - var canvas: ThreeCanvas? by useState { null } - var vision: Vision? by useState { props.rootVision } + var vision: Solid? by useState { props.vision } val onSelect: (Name?) -> Unit = { selected = it } - val visionManager = useMemo({ props.context.fetch(Solids).visionManager }, arrayOf(props.context)) + val options = useMemo { + Canvas3DOptions.invoke { + this.onSelect = onSelect + } + } + + val visionManager = useMemo(props.context) { props.context.fetch(Solids).visionManager } fun loadData(name: String, data: String) { val parsedVision = when { @@ -56,7 +59,7 @@ val GDMLApp = functionalComponent("GDMLApp") { props -> } } - vision = parsedVision + vision = parsedVision as? Solid ?: error("Parsed vision is not a solid") } gridRow { @@ -78,14 +81,9 @@ val GDMLApp = functionalComponent("GDMLApp") { props -> child(ThreeCanvasComponent) { attrs { this.context = props.context - this.obj = vision as? Solid + this.obj = vision this.selected = selected - this.options = Canvas3DOptions.invoke { - this.onSelect = onSelect - } - this.canvasCallback = { - canvas = it - } + this.options = options } } @@ -111,9 +109,7 @@ val GDMLApp = functionalComponent("GDMLApp") { props -> } } } - canvas?.let { - ringThreeControls(it, selected, onSelect) - } + ringThreeControls(options, props.vision, selected, onSelect) } } } 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 1b40155e..aefb24be 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 @@ -29,7 +29,7 @@ private class GDMLDemoApp : Application { //println(context.plugins.fetch(VisionManager).encodeToString(vision)) attrs { this.context = context - this.rootVision = vision + this.vision = vision } } } 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 8eb251ad..368bef5f 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 @@ -6,11 +6,8 @@ import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import kotlinx.css.* import kotlinx.html.js.onClickFunction -import react.RProps -import react.child +import react.* import react.dom.* -import react.functionalComponent -import react.useState import space.kscience.dataforge.context.Context import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken @@ -26,7 +23,6 @@ import space.kscience.visionforge.react.flexColumn import space.kscience.visionforge.react.objectTree import space.kscience.visionforge.solid.specifications.Camera import space.kscience.visionforge.solid.specifications.Canvas3DOptions -import space.kscience.visionforge.solid.three.ThreeCanvas import styled.css import styled.styledDiv import kotlin.math.PI @@ -49,12 +45,17 @@ private val canvasConfig = Canvas3DOptions { @JsExport val MMApp = functionalComponent("Muon monitor") { props -> var selected by useState { props.selected } - var canvas: ThreeCanvas? by useState { null } val onSelect: (Name?) -> Unit = { selected = it } + val options = useMemo { + Canvas3DOptions.invoke { + this.onSelect = onSelect + } + } + val root = props.model.root gridRow { @@ -95,9 +96,6 @@ val MMApp = functionalComponent("Muon monitor") { props -> this.options = canvasConfig.apply { this.onSelect = onSelect } - this.canvasCallback = { - canvas = it - } } } } @@ -113,11 +111,10 @@ val MMApp = functionalComponent("Muon monitor") { props -> flex(0.0, 1.0, FlexBasis.zero) } //settings - canvas?.let { - card("Canvas configuration") { - canvasControls(it) - } + card("Canvas configuration") { + canvasControls(options, root) } + card("Events") { button { +"Next" diff --git a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoGrid.kt b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoGrid.kt index 18e23381..bef5404f 100644 --- a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoGrid.kt +++ b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoGrid.kt @@ -19,7 +19,6 @@ import space.kscience.visionforge.VisionLayout import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.three.ThreeCanvas import space.kscience.visionforge.solid.three.ThreePlugin -import space.kscience.visionforge.solid.three.configure class ThreeDemoGrid(element: Element) : VisionLayout { private lateinit var navigationElement: HTMLElement @@ -71,7 +70,7 @@ class ThreeDemoGrid(element: Element) : VisionLayout { } } val element = document.getElementById("output-$name") ?: error("Element not found") - three.getOrCreateCanvas(element).also { it.configure(canvasOptions) } + three.getOrCreateCanvas(element, canvasOptions) }.render(vision) } } 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 2edbaab8..3423baf8 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 @@ -13,12 +13,11 @@ import react.* import react.dom.attrs import react.dom.button import space.kscience.dataforge.meta.withDefault +import space.kscience.visionforge.Vision import space.kscience.visionforge.react.flexColumn import space.kscience.visionforge.react.flexRow import space.kscience.visionforge.react.propertyEditor -import space.kscience.visionforge.solid.SolidGroup import space.kscience.visionforge.solid.specifications.Canvas3DOptions -import space.kscience.visionforge.solid.three.ThreeCanvas import styled.css private fun saveData(event: Event, fileName: String, mimeType: String = "text/plain", dataBuilder: () -> String) { @@ -30,37 +29,33 @@ private fun saveData(event: Event, fileName: String, mimeType: String = "text/pl fileSaver.saveAs(blob, fileName) } -public fun RBuilder.canvasControls(canvas: ThreeCanvas): ReactElement { +public fun RBuilder.canvasControls(canvasOptions: Canvas3DOptions, vision: Vision?): ReactElement { return child(CanvasControls) { attrs { - this.canvas = canvas + this.canvasOptions = canvasOptions + this.vision = vision } } } public external interface CanvasControlsProps : RProps { - public var canvas: ThreeCanvas + public var canvasOptions: Canvas3DOptions + public var vision: Vision? } public val CanvasControls: FunctionalComponent = functionalComponent("CanvasControls") { props -> - val visionManager = useMemo( - { props.canvas.three.solids.visionManager }, - arrayOf(props.canvas) - ) flexColumn { flexRow { - css{ + css { border(1.px, BorderStyle.solid, Color.blue) padding(4.px) } - button { - +"Export" - attrs { - onClickFunction = { - val json = (props.canvas.content as? SolidGroup)?.let { group -> - visionManager.encodeToString(group) - } - if (json != null) { + props.vision?.manager?.let { manager -> + button { + +"Export" + attrs { + onClickFunction = { + val json = manager.encodeToString(props.vision!!) saveData(it, "object.json", "text/json") { json } @@ -70,8 +65,8 @@ public val CanvasControls: FunctionalComponent = functional } } propertyEditor( - ownProperties = props.canvas.options, - allProperties = props.canvas.options.withDefault(Canvas3DOptions.descriptor.defaultMeta), + ownProperties = props.canvasOptions, + allProperties = props.canvasOptions.withDefault(Canvas3DOptions.descriptor.defaultMeta), descriptor = Canvas3DOptions.descriptor, expanded = false ) diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/threeControls.kt b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/threeControls.kt index a0af57aa..dc384067 100644 --- a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/threeControls.kt +++ b/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/threeControls.kt @@ -9,23 +9,23 @@ import space.kscience.dataforge.names.isEmpty import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionGroup import space.kscience.visionforge.react.objectTree -import space.kscience.visionforge.solid.three.ThreeCanvas +import space.kscience.visionforge.solid.specifications.Canvas3DOptions import styled.css import styled.styledDiv public external interface ThreeControlsProps : RProps { - public var canvas: ThreeCanvas + public var canvasOptions: Canvas3DOptions + public var vision: Vision? public var selected: Name? public var onSelect: (Name) -> Unit } @JsExport public val ThreeControls: FunctionalComponent = functionalComponent { props -> - val vision = props.canvas.content tabPane(if (props.selected != null) "Properties" else null) { tab("Canvas") { card("Canvas configuration") { - canvasControls(props.canvas) + canvasControls(props.canvasOptions, props.vision) } } tab("Tree") { @@ -38,7 +38,7 @@ public val ThreeControls: FunctionalComponent = functionalCo css { flex(1.0, 1.0, FlexBasis.inherit) } - props.canvas.content?.let { + props.vision?.let { objectTree(it, props.selected, props.onSelect) } } @@ -47,8 +47,8 @@ public val ThreeControls: FunctionalComponent = functionalCo props.selected.let { selected -> val selectedObject: Vision? = when { selected == null -> null - selected.isEmpty() -> vision - else -> (vision as? VisionGroup)?.get(selected) + selected.isEmpty() -> props.vision + else -> (props.vision as? VisionGroup)?.get(selected) } if (selectedObject != null) { visionPropertyEditor(selectedObject, key = selected) @@ -62,13 +62,15 @@ public val ThreeControls: FunctionalComponent = functionalCo } public fun RBuilder.threeControls( - canvas: ThreeCanvas, + canvasOptions: Canvas3DOptions, + vision: Vision?, selected: Name?, onSelect: (Name) -> Unit = {}, builder: TabBuilder.() -> Unit = {}, ): ReactElement = child(ThreeControls) { attrs { - this.canvas = canvas + this.canvasOptions = canvasOptions + this.vision = vision this.selected = selected this.onSelect = onSelect } diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt b/ui/react/src/main/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt index f18854a6..1b1d6ce6 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt +++ b/ui/react/src/main/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt @@ -14,16 +14,14 @@ import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.specifications.Canvas3DOptions import space.kscience.visionforge.solid.three.ThreeCanvas import space.kscience.visionforge.solid.three.ThreePlugin -import space.kscience.visionforge.solid.three.configure import styled.css import styled.styledDiv public external interface ThreeCanvasProps : RProps { public var context: Context + public var options: Canvas3DOptions public var obj: Solid? - public var options: Canvas3DOptions? public var selected: Name? - public var canvasCallback: ((ThreeCanvas?) -> Unit)? } public external interface ThreeCanvasState : RState { @@ -42,20 +40,13 @@ public val ThreeCanvasComponent: FunctionalComponent = functio useEffect(listOf(props.obj, props.options, elementRef)) { if (canvas == null) { val element = elementRef.current as? HTMLElement ?: error("Canvas element not found") - val newCanvas: ThreeCanvas = three.getOrCreateCanvas(element) - props.options?.let { - newCanvas.configure(it) - } - props.canvasCallback?.invoke(newCanvas) - canvas = newCanvas + canvas = three.getOrCreateCanvas(element, props.options) } } useEffect(listOf(canvas, props.obj)) { props.obj?.let { obj -> - if (canvas?.content != obj) { - canvas?.render(obj) - } + canvas?.render(obj) } } 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 2b1dca09..59099f60 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 @@ -1,10 +1,7 @@ package space.kscience.visionforge.ring import kotlinx.css.* -import react.RProps -import react.child -import react.functionalComponent -import react.useState +import react.* import ringui.grid.ringCol import ringui.grid.ringGrid import ringui.grid.ringRow @@ -14,25 +11,27 @@ import space.kscience.visionforge.Vision import space.kscience.visionforge.react.ThreeCanvasComponent import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.specifications.Canvas3DOptions -import space.kscience.visionforge.solid.three.ThreeCanvas import styled.css import styled.styledDiv -public external interface GdmlViewProps : RProps { +public external interface ThreeWithControlsProps : RProps { public var context: Context - public var rootVision: Vision? + public var vision: Vision? public var selected: Name? } @JsExport -public val ThreeViewWithControls: (props: GdmlViewProps) -> dynamic = - functionalComponent("ThreeViewWithControls") { props -> +public val ThreeViewWithControls: (props: ThreeWithControlsProps) -> dynamic = + functionalComponent("ThreeViewWithControls") { props -> var selected by useState { props.selected } - var canvas: ThreeCanvas? by useState { null } - val onSelect: (Name?) -> Unit = { selected = it } + val options = useMemo { + Canvas3DOptions.invoke { + this.onSelect = onSelect + } + } styledDiv { css { @@ -50,14 +49,9 @@ public val ThreeViewWithControls: (props: GdmlViewProps) -> dynamic = child(ThreeCanvasComponent) { attrs { this.context = props.context - this.obj = props.rootVision as? Solid + this.obj = props.vision as? Solid this.selected = selected - this.options = Canvas3DOptions.invoke { - this.onSelect = onSelect - } - this.canvasCallback = { - canvas = it - } + this.options = options } } @@ -76,9 +70,7 @@ public val ThreeViewWithControls: (props: GdmlViewProps) -> dynamic = height = 100.pct overflowY = Overflow.auto } - canvas?.let { - ringThreeControls(it, selected, onSelect) - } + ringThreeControls(options, props.vision, selected, onSelect) } } } diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControls.kt b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControls.kt index 6d7aaa0b..6af8450c 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControls.kt +++ b/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControls.kt @@ -28,7 +28,7 @@ public class ThreeWithControls : AbstractPlugin(), ElementVisionRenderer { child(ThreeViewWithControls) { attrs { this.context = this@ThreeWithControls.context - this.rootVision = vision + this.vision = vision } } } 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 1a0d101c..c88838d6 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 @@ -18,13 +18,12 @@ import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.isEmpty import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionGroup +import space.kscience.visionforge.encodeToString import space.kscience.visionforge.react.flexColumn import space.kscience.visionforge.react.flexRow import space.kscience.visionforge.react.objectTree import space.kscience.visionforge.react.propertyEditor -import space.kscience.visionforge.solid.SolidGroup import space.kscience.visionforge.solid.specifications.Canvas3DOptions -import space.kscience.visionforge.solid.three.ThreeCanvas import styled.css import styled.styledDiv @@ -37,48 +36,45 @@ internal fun saveData(event: Event, fileName: String, mimeType: String = "text/p fileSaver.saveAs(blob, fileName) } -internal fun RBuilder.canvasControls(canvas: ThreeCanvas): ReactElement { +internal fun RBuilder.canvasControls(options: Canvas3DOptions, vision: Vision?): ReactElement { return child(CanvasControls) { attrs { - this.canvas = canvas + this.options = options + this.vision = vision } } } internal external interface CanvasControlsProps : RProps { - public var canvas: ThreeCanvas + public var options: Canvas3DOptions + public var vision: Vision? } internal val CanvasControls: FunctionalComponent = functionalComponent("CanvasControls") { props -> - val visionManager = useMemo( - { props.canvas.three.solids.visionManager }, - arrayOf(props.canvas) - ) flexColumn { flexRow { css { border(1.px, BorderStyle.solid, Color.blue) padding(4.px) } - button { - +"Export" - attrs { - onClickFunction = { - val json = (props.canvas.content as? SolidGroup)?.let { group -> - visionManager.encodeToString(group) - } - if (json != null) { + props.vision?.let { vision -> + button { + +"Export" + attrs { + onClickFunction = { + val json = vision.encodeToString() saveData(it, "object.json", "text/json") { json } + } } } } } propertyEditor( - ownProperties = props.canvas.options, - allProperties = props.canvas.options.withDefault(Canvas3DOptions.descriptor.defaultMeta), + ownProperties = props.options, + allProperties = props.options.withDefault(Canvas3DOptions.descriptor.defaultMeta), descriptor = Canvas3DOptions.descriptor, expanded = false ) @@ -88,18 +84,18 @@ internal val CanvasControls: FunctionalComponent = function public external interface ThreeControlsProps : RProps { - public var canvas: ThreeCanvas + public var canvasOptions: Canvas3DOptions + public var vision: Vision? public var selected: Name? public var onSelect: (Name) -> Unit } @JsExport public val ThreeControls: FunctionalComponent = functionalComponent { props -> - val vision = props.canvas.content ringSmartTabs(if (props.selected != null) "Properties" else null) { ringTab("Canvas") { ringIsland("Canvas configuration") { - canvasControls(props.canvas) + canvasControls(props.canvasOptions, props.vision) } } ringTab("Tree") { @@ -113,7 +109,7 @@ public val ThreeControls: FunctionalComponent = functionalCo css { flex(1.0, 1.0, FlexBasis.inherit) } - props.canvas.content?.let { + props.vision?.let { objectTree(it, props.selected, props.onSelect) } } @@ -123,8 +119,8 @@ public val ThreeControls: FunctionalComponent = functionalCo props.selected.let { selected -> val selectedObject: Vision? = when { selected == null -> null - selected.isEmpty() -> vision - else -> (vision as? VisionGroup)?.get(selected) + selected.isEmpty() -> props.vision + else -> (props.vision as? VisionGroup)?.get(selected) } if (selectedObject != null) { ringPropertyEditor(selectedObject, key = selected) @@ -136,13 +132,15 @@ public val ThreeControls: FunctionalComponent = functionalCo } public fun RBuilder.ringThreeControls( - canvas: ThreeCanvas, + canvasOptions: Canvas3DOptions, + vision: Vision?, selected: Name?, onSelect: (Name) -> Unit = {}, builder: RBuilder.() -> Unit = {}, ): ReactElement = child(ThreeControls) { attrs { - this.canvas = canvas + this.canvasOptions = canvasOptions + this.vision = vision this.selected = selected this.onSelect = onSelect } 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 23779bd1..07f063ca 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt @@ -27,6 +27,9 @@ public interface Vision : Described, CoroutineScope { */ public var parent: VisionGroup? + /** + * Owner [VisionManager]. Used to define coroutine scope a serialization + */ public val manager: VisionManager? get() = parent?.manager override val coroutineContext: CoroutineContext @@ -69,7 +72,7 @@ public interface Vision : Described, CoroutineScope { /** * Notify all listeners that a property has been changed and should be invalidated */ - public fun invalidateProperty(propertyName: Name): Unit + public fun invalidateProperty(propertyName: Name) /** * Update this vision using a dif represented by [VisionChange]. diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionBase.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionBase.kt index 47ed889e..c9b68219 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionBase.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionBase.kt @@ -92,7 +92,6 @@ public open class VisionBase : Vision { } } - //TODO check memory consumption for the flow @Transient private val propertyInvalidationFlow: MutableSharedFlow = MutableSharedFlow() 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 25e0dc8e..85b147ab 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt @@ -64,9 +64,15 @@ private fun Vision.isolate(manager: VisionManager): Vision { return manager.decodeFromJson(json) } +/** + * @param void flag showing that this vision child should be removed + * @param vision a new value for vision content + * @param properties updated properties + * @param children a map of children changed in ths [VisionChange]. If a child to be removed, set [void] flag to true. + */ @Serializable public data class VisionChange( - public val reset: Boolean = false, + public val void: Boolean = false, public val vision: Vision? = null, @Serializable(MetaSerializer::class) public val properties: Meta? = null, public val children: Map? = null, diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroupBase.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroupBase.kt index 3e43c81d..44800673 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroupBase.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroupBase.kt @@ -134,7 +134,7 @@ public open class VisionGroupBase( override fun update(change: VisionChange) { change.children?.forEach { (name, change) -> when { - change.reset -> set(name, null) + change.void -> set(name, null) change.vision != null -> set(name, change.vision) else -> get(name)?.update(change) } 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 d45cc906..b3e9faf4 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt @@ -95,4 +95,7 @@ public abstract class VisionPlugin(meta: Meta = Meta.EMPTY) : AbstractPlugin(met /** * Fetch a [VisionManager] from this plugin or create a child plugin with a [VisionManager] */ -public val Context.visionManager: VisionManager get() = fetch(VisionManager) \ No newline at end of file +public val Context.visionManager: VisionManager get() = fetch(VisionManager) + +public fun Vision.encodeToString(): String = + manager?.encodeToString(this) ?: error("VisionManager not defined in Vision") \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt index e62b4cb2..6a978e9e 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt +++ b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt @@ -39,9 +39,8 @@ import kotlin.math.sin */ public class ThreeCanvas( public val three: ThreePlugin, + public val options: Canvas3DOptions = Canvas3DOptions() ) { - public val options = Canvas3DOptions() - private var boundingBox: Box3? = null private var root: Object3D? = null set(value) { @@ -52,9 +51,6 @@ public class ThreeCanvas( private val raycaster = Raycaster() private val mousePosition: Vector2 = Vector2() - public var content: Solid? = null - private set - private val scene: Scene = Scene().apply { options.useProperty(Canvas3DOptions::axes, this) { axesConfig -> getObjectByName(AXES_NAME)?.let { remove(it) } @@ -251,7 +247,6 @@ public class ThreeCanvas( val object3D = three.buildObject3D(vision) object3D.name = "@root" scene.add(object3D) - content = vision root = object3D } @@ -315,9 +310,9 @@ public class ThreeCanvas( } } -public fun ThreeCanvas.configure(options: Canvas3DOptions) { - this.options.update(options.toMeta()) - options.onChange(this) { name, _, newItem -> - options[name] = newItem - } -} \ No newline at end of file +//public fun ThreeCanvas.configure(newOptions: Canvas3DOptions) { +// this.options.update(newOptions.toMeta()) +// options.onChange(this) { name, _, newItem -> +// this.options[name] = newItem +// } +//} \ No newline at end of file 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 3c4e8d7a..4d1f63b3 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 @@ -116,9 +116,12 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { public fun getOrCreateCanvas( element: Element, - ): ThreeCanvas = canvasCache.getOrPut(element){ThreeCanvas(this).apply { - attach(element) - }} + options: Canvas3DOptions = Canvas3DOptions(), + ): ThreeCanvas = canvasCache.getOrPut(element) { + ThreeCanvas(this, options).apply { + attach(element) + } + } override fun content(target: String): Map { return when (target) {