From 2b7971eeea7219ca1a3761821598f107de23b83f Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 27 Jan 2021 15:41:46 +0300 Subject: [PATCH] API cleanup --- README.md | 10 +-- demo/gdml/README.md | 2 +- demo/muon-monitor/README.md | 2 +- demo/spatial-showcase/README.md | 4 +- .../vision/solid/demo/VariableBox.kt | 1 + docs/{ => diagrams}/Dependency structure.vsdx | Bin .../{resources => images}/class-diag-core.png | Bin .../class-diag-solid.png | Bin docs/{resources => images}/gdml-demo.png | Bin docs/{resources => images}/muon-monitor.png | Bin .../spatial-showcase-FX.png | Bin .../spatial-showcase.png | Bin .../kotlin/hep/dataforge/vision/StyleSheet.kt | 13 ++- .../kotlin/hep/dataforge/vision/Vision.kt | 74 ++++++------------ .../kotlin/hep/dataforge/vision/VisionBase.kt | 67 ++++++++-------- .../hep/dataforge/vision/VisionChange.kt | 2 +- .../hep/dataforge/vision/VisionGroupBase.kt | 8 +- .../hep/dataforge/vision/html/HtmlTagTest.kt | 1 + .../vision/solid/FXReferenceFactory.kt | 1 + .../vision/solid/VisualObjectFXBinding.kt | 11 ++- .../dataforge/vision/gdml/GdmlOptimizer.kt | 1 + .../hep/dataforge/vision/solid/Solid.kt | 18 ++--- .../hep/dataforge/vision/solid/SolidGroup.kt | 2 - .../dataforge/vision/solid/SolidReference.kt | 48 ++++++------ .../vision/solid/SerializationTest.kt | 1 + .../vision/solid/SolidReferenceTest.kt | 5 +- .../vision/solid/three/MeshThreeFactory.kt | 1 + .../vision/solid/three/ThreeLabelFactory.kt | 1 + .../vision/solid/three/ThreeLineFactory.kt | 1 + .../vision/solid/three/ThreeMaterials.kt | 3 +- .../vision/solid/three/ThreePlugin.kt | 1 + .../solid/three/ThreeReferenceFactory.kt | 1 + 32 files changed, 135 insertions(+), 144 deletions(-) rename docs/{ => diagrams}/Dependency structure.vsdx (100%) rename docs/{resources => images}/class-diag-core.png (100%) rename docs/{resources => images}/class-diag-solid.png (100%) rename docs/{resources => images}/gdml-demo.png (100%) rename docs/{resources => images}/muon-monitor.png (100%) rename docs/{resources => images}/spatial-showcase-FX.png (100%) rename docs/{resources => images}/spatial-showcase.png (100%) diff --git a/README.md b/README.md index df55c37c..c9312320 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ The `visionforge-core` module also includes configuration editors for JS (in `js **Class diagram:** -![](docs/resources/class-diag-core.png) +![](docs/images/class-diag-core.png) ### visionforge-solid @@ -82,7 +82,7 @@ Includes common classes and serializers for 3D visualization, as well as Three.j **Class diagram:** -![](docs/resources/class-diag-solid.png) +![](docs/images/class-diag-solid.png) ##### Prototypes @@ -127,7 +127,7 @@ Some shapes will also periodically change their color and visibility. **Example view:** -![](docs/resources/spatial-showcase.png) +![](docs/images/spatial-showcase.png) ### Full-Stack Application Example - Muon Monitor Visualization @@ -139,7 +139,7 @@ A full-stack application example, showing the **Example view:** -![](docs/resources/muon-monitor.png) +![](docs/images/muon-monitor.png) ### GDML Example @@ -150,7 +150,7 @@ Visualization example for geometry defined as GDML file. ##### Example view: -![](docs/resources/gdml-demo.png) +![](docs/images/gdml-demo.png) ## Thanks and references diff --git a/demo/gdml/README.md b/demo/gdml/README.md index 9a20ac55..6ad546f1 100644 --- a/demo/gdml/README.md +++ b/demo/gdml/README.md @@ -12,4 +12,4 @@ drag-and-drop GDML file to the window to see visualization. For an example file, ##### Example view: -![](../../docs/resources/gdml-demo.png) +![](../../docs/images/gdml-demo.png) diff --git a/demo/muon-monitor/README.md b/demo/muon-monitor/README.md index 1949cb1e..87b3cf43 100644 --- a/demo/muon-monitor/README.md +++ b/demo/muon-monitor/README.md @@ -30,5 +30,5 @@ run `demo/muon-monitor/application/run` task. ##### Example view: -![](../../docs/resources/muon-monitor.png) +![](../../docs/images/muon-monitor.png) diff --git a/demo/spatial-showcase/README.md b/demo/spatial-showcase/README.md index 2b30ef3e..20866220 100644 --- a/demo/spatial-showcase/README.md +++ b/demo/spatial-showcase/README.md @@ -12,8 +12,8 @@ To see Java FX demo, run `demo/spatial-showcase/Tasks/application/run` Gradle ta ##### Example view for JS: -![](../../docs/resources/spatial-showcase.png) +![](../../docs/images/spatial-showcase.png) ##### Example view for Java FX: -![](../../docs/resources/spatial-showcase-FX.png) +![](../../docs/images/spatial-showcase-FX.png) diff --git a/demo/spatial-showcase/src/jsMain/kotlin/hep/dataforge/vision/solid/demo/VariableBox.kt b/demo/spatial-showcase/src/jsMain/kotlin/hep/dataforge/vision/solid/demo/VariableBox.kt index 206f4f0c..e90cc845 100644 --- a/demo/spatial-showcase/src/jsMain/kotlin/hep/dataforge/vision/solid/demo/VariableBox.kt +++ b/demo/spatial-showcase/src/jsMain/kotlin/hep/dataforge/vision/solid/demo/VariableBox.kt @@ -5,6 +5,7 @@ import hep.dataforge.names.plus import hep.dataforge.names.startsWith import hep.dataforge.values.asValue import hep.dataforge.vision.getProperty +import hep.dataforge.vision.onPropertyChange import hep.dataforge.vision.set import hep.dataforge.vision.setProperty import hep.dataforge.vision.solid.* diff --git a/docs/Dependency structure.vsdx b/docs/diagrams/Dependency structure.vsdx similarity index 100% rename from docs/Dependency structure.vsdx rename to docs/diagrams/Dependency structure.vsdx diff --git a/docs/resources/class-diag-core.png b/docs/images/class-diag-core.png similarity index 100% rename from docs/resources/class-diag-core.png rename to docs/images/class-diag-core.png diff --git a/docs/resources/class-diag-solid.png b/docs/images/class-diag-solid.png similarity index 100% rename from docs/resources/class-diag-solid.png rename to docs/images/class-diag-solid.png diff --git a/docs/resources/gdml-demo.png b/docs/images/gdml-demo.png similarity index 100% rename from docs/resources/gdml-demo.png rename to docs/images/gdml-demo.png diff --git a/docs/resources/muon-monitor.png b/docs/images/muon-monitor.png similarity index 100% rename from docs/resources/muon-monitor.png rename to docs/images/muon-monitor.png diff --git a/docs/resources/spatial-showcase-FX.png b/docs/images/spatial-showcase-FX.png similarity index 100% rename from docs/resources/spatial-showcase-FX.png rename to docs/images/spatial-showcase-FX.png diff --git a/docs/resources/spatial-showcase.png b/docs/images/spatial-showcase.png similarity index 100% rename from docs/resources/spatial-showcase.png rename to docs/images/spatial-showcase.png diff --git a/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/StyleSheet.kt b/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/StyleSheet.kt index 233afde7..e5f30854 100644 --- a/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/StyleSheet.kt +++ b/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/StyleSheet.kt @@ -5,14 +5,13 @@ import hep.dataforge.names.Name import hep.dataforge.names.NameToken import hep.dataforge.names.asName import hep.dataforge.names.plus -import kotlinx.coroutines.launch /** * A container for styles */ public inline class StyleSheet(private val owner: VisionGroup) { - private val styleNode get() = owner.getOwnProperty(STYLESHEET_KEY).node + private val styleNode get() = owner.ownProperties[STYLESHEET_KEY].node public val items: Map? get() = styleNode?.items?.mapValues { it.value.node ?: Meta.EMPTY } @@ -55,9 +54,7 @@ internal fun Vision.styleChanged(key: String, oldStyle: Meta?, newStyle: Meta?) val tokens: Collection = ((oldStyle?.items?.keys ?: emptySet()) + (newStyle?.items?.keys ?: emptySet())) .map { it.asName() } - parent?.scope?.launch { - tokens.forEach { parent?.notifyPropertyChanged(it) } - } + tokens.forEach { parent?.invalidateProperty(it) } } if (this is VisionGroup) { for (obj in this) { @@ -71,7 +68,7 @@ internal fun Vision.styleChanged(key: String, oldStyle: Meta?, newStyle: Meta?) * List of names of styles applied to this object. Order matters. Not inherited. */ public var Vision.styles: List - get() = getOwnProperty(Vision.STYLE_KEY)?.stringList ?: emptyList() + get() = ownProperties[Vision.STYLE_KEY]?.stringList ?: emptyList() set(value) { setProperty(Vision.STYLE_KEY, value) } @@ -86,7 +83,7 @@ public val VisionGroup.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 = (getOwnProperty(Vision.STYLE_KEY)?.stringList ?: emptyList()) + name + styles = (ownProperties[Vision.STYLE_KEY]?.stringList ?: emptyList()) + name } @@ -94,7 +91,7 @@ public fun Vision.useStyle(name: String) { * Find a style with given name for given [Vision]. The style is not necessary applied to this [Vision]. */ public tailrec fun Vision.getStyle(name: String): Meta? = - getOwnProperty(StyleSheet.STYLESHEET_KEY + name).node ?: parent?.getStyle(name) + ownProperties[StyleSheet.STYLESHEET_KEY + name].node ?: parent?.getStyle(name) /** * Resolve an item in all style layers diff --git a/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/Vision.kt b/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/Vision.kt index 9aa3d90f..7314b6c2 100644 --- a/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/Vision.kt +++ b/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/Vision.kt @@ -1,9 +1,6 @@ package hep.dataforge.vision -import hep.dataforge.meta.DFExperimental -import hep.dataforge.meta.Meta -import hep.dataforge.meta.MetaItem -import hep.dataforge.meta.MutableItemProvider +import hep.dataforge.meta.* import hep.dataforge.meta.descriptors.Described import hep.dataforge.meta.descriptors.NodeDescriptor import hep.dataforge.meta.descriptors.get @@ -12,11 +9,10 @@ import hep.dataforge.names.Name import hep.dataforge.names.asName import hep.dataforge.names.toName import hep.dataforge.vision.Vision.Companion.TYPE -import kotlinx.coroutines.* -import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.callbackFlow -import kotlinx.serialization.Transient +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach /** * A root type for display hierarchy @@ -27,26 +23,8 @@ public interface Vision : Described { /** * The parent object of this one. If null, this one is a root. */ - @Transient public var parent: VisionGroup? - /** - * Properties belonging to this [Vision] potentially including artificial properties - */ - @Transient - public val meta: Meta - - /** - * A coroutine scope for asynchronous calls and locks - */ - public val scope: CoroutineScope get() = parent?.scope ?: GlobalScope - - /** - * A fast accessor method to get own property (no inheritance or styles). - * Should be equivalent to `getProperty(name,false,false,false)`. - */ - public fun getOwnProperty(name: Name): MetaItem? - /** * Get property. * @param inherit toggles parent node property lookup. Null means inference from descriptor. Default is false. @@ -59,38 +37,32 @@ public interface Vision : Described { includeDefaults: Boolean = true, ): MetaItem? + /** + * Get an intrinsic property of this Vision excluding any inheritance or defaults. In most cases should be the same as + * `getProperty(name, false, false, false`. + */ + public fun getOwnProperty(name: Name): MetaItem? = getProperty( + name, + inherit = false, + includeStyles = false, + includeDefaults = false + ) /** * Set the property value */ public fun setProperty(name: Name, item: MetaItem?, notify: Boolean = true) - /** - * Subscribe on property updates. The subscription is bound to the given [scope] and canceled when the scope is canceled - */ - public fun onPropertyChange(scope: CoroutineScope, callback: suspend (Name) -> Unit) - /** * Flow of property invalidation events. It does not contain property values after invalidation since it is not clear * if it should include inherited properties etc. */ - @DFExperimental - @OptIn(ExperimentalCoroutinesApi::class) public val propertyChanges: Flow - get() = callbackFlow { - coroutineScope { - onPropertyChange(this) { - send(it) - } - awaitClose { cancel() } - } - } - /** * Notify all listeners that a property has been changed and should be invalidated */ - public suspend fun notifyPropertyChanged(propertyName: Name): Unit + public fun invalidateProperty(propertyName: Name): Unit /** * Update this vision using a dif represented by [VisionChange]. @@ -107,12 +79,19 @@ public interface Vision : Described { } } -public fun Vision.asyncNotifyPropertyChange(propertyName: Name) { - scope.launch { - notifyPropertyChanged(propertyName) - } +/** + * Root property node + */ +public val Vision.meta: Meta get() = ownProperties[Name.EMPTY]?.node ?: Meta.EMPTY + +/** + * Subscribe on property updates. The subscription is bound to the given [scope] and canceled when the scope is canceled + */ +public fun Vision.onPropertyChange(scope: CoroutineScope, callback: suspend (Name) -> Unit) { + propertyChanges.onEach(callback).launchIn(scope) } + /** * Own properties, excluding inheritance, styles and descriptor */ @@ -122,7 +101,6 @@ public val Vision.ownProperties: MutableItemProvider override fun setItem(name: Name, item: MetaItem?): Unit = setProperty(name, item) } - /** * Convenient accessor for all properties of a vision. * @param inherit - inherit property value from the parent by default. If null, inheritance is inferred from descriptor diff --git a/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/VisionBase.kt b/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/VisionBase.kt index 59f31c81..5dd8bf37 100644 --- a/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/VisionBase.kt +++ b/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/VisionBase.kt @@ -11,10 +11,9 @@ import hep.dataforge.values.Null import hep.dataforge.values.ValueType import hep.dataforge.vision.Vision.Companion.STYLE_KEY import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -32,13 +31,14 @@ internal data class PropertyListener( */ @Serializable @SerialName("vision") -public open class VisionBase(internal var properties: Config? = null) : Vision { +public open class VisionBase( + internal var properties: Config? = null, + @Transient public val coroutineScope: CoroutineScope = GlobalScope, +) : Vision { @Transient override var parent: VisionGroup? = null - override val meta: Meta get() = properties ?: Meta.EMPTY - @Synchronized protected fun getOrCreateConfig(): Config { if (properties == null) { @@ -51,8 +51,10 @@ public open class VisionBase(internal var properties: Config? = null) : Vision { /** * A fast accessor method to get own property (no inheritance or styles */ - override fun getOwnProperty(name: Name): MetaItem? { - return properties?.getItem(name) + override fun getOwnProperty(name: Name): MetaItem? = if (name == Name.EMPTY) { + properties?.asMetaItem() + } else { + properties?.getItem(name) } override fun getProperty( @@ -60,25 +62,27 @@ public open class VisionBase(internal var properties: Config? = null) : Vision { inherit: Boolean, includeStyles: Boolean, includeDefaults: Boolean, - ): MetaItem? = sequence { - yield(getOwnProperty(name)) - if (includeStyles) { - yieldAll(getStyleItems(name)) - } - if (inherit) { - yield(parent?.getProperty(name, inherit, includeStyles, includeDefaults)) - } - if (includeDefaults) { - yield(descriptor?.get(name)?.defaultItem()) - } - }.merge() + ): MetaItem? = if (!inherit && !includeStyles && !includeDefaults) { + getOwnProperty(name) + } else { + sequence { + yield(getOwnProperty(name)) + if (includeStyles) { + yieldAll(getStyleItems(name)) + } + if (inherit) { + yield(parent?.getProperty(name, inherit, includeStyles, includeDefaults)) + } + if (includeDefaults) { + yield(descriptor?.get(name)?.defaultItem()) + } + }.merge() + } override fun setProperty(name: Name, item: MetaItem?, notify: Boolean) { getOrCreateConfig().setItem(name, item) if (notify) { - scope.launch { - notifyPropertyChanged(name) - } + invalidateProperty(name) } } @@ -89,7 +93,7 @@ public open class VisionBase(internal var properties: Config? = null) : Vision { .flatMap { it.items.asSequence() } .distinctBy { it.key } .forEach { - notifyPropertyChanged(it.key.asName()) + invalidateProperty(it.key.asName()) } } @@ -99,17 +103,16 @@ public open class VisionBase(internal var properties: Config? = null) : Vision { private val propertyInvalidationFlow: MutableSharedFlow = MutableSharedFlow() @DFExperimental - override val propertyChanges: Flow get() = propertyInvalidationFlow + override val propertyChanges: Flow + get() = propertyInvalidationFlow - override fun onPropertyChange(scope: CoroutineScope, callback: suspend (Name) -> Unit) { - propertyInvalidationFlow.onEach(callback).launchIn(scope) - } - - override suspend fun notifyPropertyChanged(propertyName: Name) { - if (propertyName == STYLE_KEY) { - updateStyles(styles) + override fun invalidateProperty(propertyName: Name) { + coroutineScope.launch { + if (propertyName == STYLE_KEY) { + updateStyles(styles) + } + propertyInvalidationFlow.emit(propertyName) } - propertyInvalidationFlow.emit(propertyName) } override fun update(change: VisionChange) { diff --git a/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/VisionChange.kt b/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/VisionChange.kt index cb80fd7d..b94e7984 100644 --- a/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/VisionChange.kt +++ b/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/VisionChange.kt @@ -82,7 +82,7 @@ private fun CoroutineScope.collectChange( //Collect properties change source.onPropertyChange(this) { propertyName -> - val newItem = source.getOwnProperty(propertyName) + val newItem = source.ownProperties[propertyName] collector().propertyChanged(name, propertyName, newItem) } diff --git a/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/VisionGroupBase.kt b/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/VisionGroupBase.kt index 6cc2b97b..48ff4982 100644 --- a/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/VisionGroupBase.kt +++ b/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/VisionGroupBase.kt @@ -31,10 +31,10 @@ public open class VisionGroupBase( } } - override suspend fun notifyPropertyChanged(propertyName: Name) { - super.notifyPropertyChanged(propertyName) + override fun invalidateProperty(propertyName: Name) { + super.invalidateProperty(propertyName) for (obj in this) { - obj.notifyPropertyChanged(propertyName) + obj.invalidateProperty(propertyName) } } @@ -47,7 +47,7 @@ public open class VisionGroupBase( * Propagate children change event upwards */ private fun childrenChanged(name: NameToken, before: Vision?, after: Vision?) { - scope.launch { + coroutineScope.launch { _structureChanges.emit(MutableVisionGroup.StructureChange(name, before, after)) } } diff --git a/visionforge-core/src/commonTest/kotlin/hep/dataforge/vision/html/HtmlTagTest.kt b/visionforge-core/src/commonTest/kotlin/hep/dataforge/vision/html/HtmlTagTest.kt index c9429a79..a5e08500 100644 --- a/visionforge-core/src/commonTest/kotlin/hep/dataforge/vision/html/HtmlTagTest.kt +++ b/visionforge-core/src/commonTest/kotlin/hep/dataforge/vision/html/HtmlTagTest.kt @@ -4,6 +4,7 @@ import hep.dataforge.meta.DFExperimental import hep.dataforge.meta.set import hep.dataforge.vision.VisionBase import hep.dataforge.vision.configure +import hep.dataforge.vision.meta import kotlinx.html.* import kotlinx.html.stream.createHTML import kotlin.test.Test diff --git a/visionforge-fx/src/main/kotlin/hep/dataforge/vision/solid/FXReferenceFactory.kt b/visionforge-fx/src/main/kotlin/hep/dataforge/vision/solid/FXReferenceFactory.kt index 14845845..9b785323 100644 --- a/visionforge-fx/src/main/kotlin/hep/dataforge/vision/solid/FXReferenceFactory.kt +++ b/visionforge-fx/src/main/kotlin/hep/dataforge/vision/solid/FXReferenceFactory.kt @@ -2,6 +2,7 @@ package hep.dataforge.vision.solid import hep.dataforge.names.* import hep.dataforge.vision.Vision +import hep.dataforge.vision.onPropertyChange import javafx.scene.Group import javafx.scene.Node import kotlin.reflect.KClass diff --git a/visionforge-fx/src/main/kotlin/hep/dataforge/vision/solid/VisualObjectFXBinding.kt b/visionforge-fx/src/main/kotlin/hep/dataforge/vision/solid/VisualObjectFXBinding.kt index f6f72e54..2a47b447 100644 --- a/visionforge-fx/src/main/kotlin/hep/dataforge/vision/solid/VisualObjectFXBinding.kt +++ b/visionforge-fx/src/main/kotlin/hep/dataforge/vision/solid/VisualObjectFXBinding.kt @@ -4,15 +4,18 @@ import hep.dataforge.meta.* import hep.dataforge.names.Name import hep.dataforge.names.startsWith import hep.dataforge.names.toName +import hep.dataforge.values.Value import hep.dataforge.vision.Vision +import hep.dataforge.vision.onPropertyChange import javafx.application.Platform +import javafx.beans.binding.Binding import javafx.beans.binding.ObjectBinding import tornadofx.* /** * A caching binding collection for [Vision] properties */ -class VisualObjectFXBinding(val fx: FX3DPlugin, val obj: Vision) { +public class VisualObjectFXBinding(public val fx: FX3DPlugin, public val obj: Vision) { private val bindings = HashMap>() init { @@ -31,7 +34,7 @@ class VisualObjectFXBinding(val fx: FX3DPlugin, val obj: Vision) { } } - operator fun get(key: Name): ObjectBinding { + public operator fun get(key: Name): ObjectBinding { return bindings.getOrPut(key) { object : ObjectBinding() { override fun computeValue(): MetaItem? = obj.getProperty(key) @@ -39,10 +42,10 @@ class VisualObjectFXBinding(val fx: FX3DPlugin, val obj: Vision) { } } - operator fun get(key: String) = get(key.toName()) + public operator fun get(key: String) = get(key.toName()) } -fun ObjectBinding.value() = objectBinding { it.value } +public fun ObjectBinding.value(): Binding = objectBinding { it.value } fun ObjectBinding.string() = stringBinding { it.string } fun ObjectBinding.number() = objectBinding { it.number } fun ObjectBinding.double() = objectBinding { it.double } diff --git a/visionforge-gdml/src/commonMain/kotlin/hep/dataforge/vision/gdml/GdmlOptimizer.kt b/visionforge-gdml/src/commonMain/kotlin/hep/dataforge/vision/gdml/GdmlOptimizer.kt index a01e3db0..9670ea11 100644 --- a/visionforge-gdml/src/commonMain/kotlin/hep/dataforge/vision/gdml/GdmlOptimizer.kt +++ b/visionforge-gdml/src/commonMain/kotlin/hep/dataforge/vision/gdml/GdmlOptimizer.kt @@ -3,6 +3,7 @@ package hep.dataforge.vision.gdml import hep.dataforge.meta.DFExperimental import hep.dataforge.meta.itemSequence import hep.dataforge.vision.Vision +import hep.dataforge.vision.meta import hep.dataforge.vision.solid.* public expect class Counter() { diff --git a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Solid.kt b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Solid.kt index 96e4f33a..bb9a8867 100644 --- a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Solid.kt +++ b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Solid.kt @@ -152,21 +152,21 @@ public var Solid.x: Number get() = position?.x ?: 0f set(value) { position().x = value.toDouble() - asyncNotifyPropertyChange(Solid.X_POSITION_KEY) + invalidateProperty(Solid.X_POSITION_KEY) } public var Solid.y: Number get() = position?.y ?: 0f set(value) { position().y = value.toDouble() - asyncNotifyPropertyChange(Solid.Y_POSITION_KEY) + invalidateProperty(Solid.Y_POSITION_KEY) } public var Solid.z: Number get() = position?.z ?: 0f set(value) { position().z = value.toDouble() - asyncNotifyPropertyChange(Solid.Z_POSITION_KEY) + invalidateProperty(Solid.Z_POSITION_KEY) } private fun Solid.rotation(): Point3D = @@ -176,21 +176,21 @@ public var Solid.rotationX: Number get() = rotation?.x ?: 0f set(value) { rotation().x = value.toDouble() - asyncNotifyPropertyChange(Solid.X_ROTATION_KEY) + invalidateProperty(Solid.X_ROTATION_KEY) } public var Solid.rotationY: Number get() = rotation?.y ?: 0f set(value) { rotation().y = value.toDouble() - asyncNotifyPropertyChange(Solid.Y_ROTATION_KEY) + invalidateProperty(Solid.Y_ROTATION_KEY) } public var Solid.rotationZ: Number get() = rotation?.z ?: 0f set(value) { rotation().z = value.toDouble() - asyncNotifyPropertyChange(Solid.Z_ROTATION_KEY) + invalidateProperty(Solid.Z_ROTATION_KEY) } private fun Solid.scale(): Point3D = @@ -200,19 +200,19 @@ public var Solid.scaleX: Number get() = scale?.x ?: 1f set(value) { scale().x = value.toDouble() - asyncNotifyPropertyChange(Solid.X_SCALE_KEY) + invalidateProperty(Solid.X_SCALE_KEY) } public var Solid.scaleY: Number get() = scale?.y ?: 1f set(value) { scale().y = value.toDouble() - asyncNotifyPropertyChange(Solid.Y_SCALE_KEY) + invalidateProperty(Solid.Y_SCALE_KEY) } public var Solid.scaleZ: Number get() = scale?.z ?: 1f set(value) { scale().z = value.toDouble() - asyncNotifyPropertyChange(Solid.Z_SCALE_KEY) + invalidateProperty(Solid.Z_SCALE_KEY) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/SolidGroup.kt b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/SolidGroup.kt index 578a06e6..1a9db779 100644 --- a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/SolidGroup.kt +++ b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/SolidGroup.kt @@ -107,8 +107,6 @@ internal class Prototypes( } } - override fun getOwnProperty(name: Name): MetaItem? = null - override fun getProperty( name: Name, inherit: Boolean, diff --git a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/SolidReference.kt b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/SolidReference.kt index e49d8d0f..a802b955 100644 --- a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/SolidReference.kt +++ b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/SolidReference.kt @@ -3,9 +3,9 @@ package hep.dataforge.vision.solid import hep.dataforge.meta.* import hep.dataforge.meta.descriptors.NodeDescriptor import hep.dataforge.names.* -import hep.dataforge.values.Null import hep.dataforge.vision.* -import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.mapNotNull import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -18,18 +18,16 @@ private fun SolidReference.getRefProperty( inherit: Boolean, includeStyles: Boolean, includeDefaults: Boolean, -): MetaItem? { - return sequence { - yield(getOwnProperty(name)) - if (includeStyles) { - yieldAll(getStyleItems(name)) - } - yield(prototype.getProperty(name, inherit, includeStyles, includeDefaults)) - if (inherit) { - yield(parent?.getProperty(name, inherit)) - } - }.merge() -} +): MetaItem? = sequence { + yield(getOwnProperty(name)) + if (includeStyles) { + yieldAll(getStyleItems(name)) + } + yield(prototype.getProperty(name, inherit, includeStyles, includeDefaults)) + if (inherit) { + yield(parent?.getProperty(name, inherit)) + } +}.merge() /** * A reference [Solid] to reuse a template object @@ -100,8 +98,6 @@ public class SolidReferenceGroup( ReferenceChild(childName + key.asName()) } ?: emptyMap() - override val meta: Meta get() = TODO()// getChildProperty(childName, Name.EMPTY).node ?: Meta.EMPTY - override fun getOwnProperty(name: Name): MetaItem? = getChildProperty(childName, name) override fun setProperty(name: Name, item: MetaItem?, notify: Boolean) { @@ -113,7 +109,11 @@ public class SolidReferenceGroup( inherit: Boolean, includeStyles: Boolean, includeDefaults: Boolean, - ): MetaItem? = getRefProperty(name, inherit, includeStyles, includeDefaults) + ): MetaItem? = if (!inherit && !includeStyles && !includeDefaults) { + getOwnProperty(name) + } else { + getRefProperty(name, inherit, includeStyles, includeDefaults) + } override var parent: VisionGroup? get() { @@ -124,16 +124,18 @@ public class SolidReferenceGroup( error("Setting a parent for a reference child is not possible") } - override fun onPropertyChange(scope: CoroutineScope, callback: suspend (Name) -> Unit) { - this@SolidReferenceGroup.onPropertyChange(scope) { name -> + @DFExperimental + override val propertyChanges: Flow + get() = this@SolidReferenceGroup.propertyChanges.mapNotNull { name -> if (name.startsWith(childToken(childName))) { - callback(name.cutFirst()) + name.cutFirst() + } else { + null } } - } - override suspend fun notifyPropertyChanged(propertyName: Name) { - this@SolidReferenceGroup.notifyPropertyChanged(childPropertyName(childName, propertyName)) + override fun invalidateProperty(propertyName: Name) { + this@SolidReferenceGroup.invalidateProperty(childPropertyName(childName, propertyName)) } override fun update(change: VisionChange) { diff --git a/visionforge-solid/src/commonTest/kotlin/hep/dataforge/vision/solid/SerializationTest.kt b/visionforge-solid/src/commonTest/kotlin/hep/dataforge/vision/solid/SerializationTest.kt index 10531796..bafe16a8 100644 --- a/visionforge-solid/src/commonTest/kotlin/hep/dataforge/vision/solid/SerializationTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/hep/dataforge/vision/solid/SerializationTest.kt @@ -4,6 +4,7 @@ import hep.dataforge.names.Name import hep.dataforge.names.toName import hep.dataforge.vision.MutableVisionGroup import hep.dataforge.vision.get +import hep.dataforge.vision.meta import kotlin.test.Test import kotlin.test.assertEquals diff --git a/visionforge-solid/src/commonTest/kotlin/hep/dataforge/vision/solid/SolidReferenceTest.kt b/visionforge-solid/src/commonTest/kotlin/hep/dataforge/vision/solid/SolidReferenceTest.kt index 8b3c85e0..1ac2738f 100644 --- a/visionforge-solid/src/commonTest/kotlin/hep/dataforge/vision/solid/SolidReferenceTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/hep/dataforge/vision/solid/SolidReferenceTest.kt @@ -2,19 +2,18 @@ package hep.dataforge.vision.solid import hep.dataforge.vision.get import hep.dataforge.vision.style -import hep.dataforge.vision.styles import hep.dataforge.vision.useStyle import kotlin.test.Test import kotlin.test.assertEquals class SolidReferenceTest { val groupWithReference = SolidGroup { - val referenceStyle by style { + val theStyle by style { SolidMaterial.MATERIAL_COLOR_KEY put "red" } ref("test", Box(100f,100f,100f).apply { color("blue") - useStyle(referenceStyle) + useStyle(theStyle) }) } diff --git a/visionforge-threejs/src/main/kotlin/hep/dataforge/vision/solid/three/MeshThreeFactory.kt b/visionforge-threejs/src/main/kotlin/hep/dataforge/vision/solid/three/MeshThreeFactory.kt index f04e7a1a..605c658f 100644 --- a/visionforge-threejs/src/main/kotlin/hep/dataforge/vision/solid/three/MeshThreeFactory.kt +++ b/visionforge-threejs/src/main/kotlin/hep/dataforge/vision/solid/three/MeshThreeFactory.kt @@ -6,6 +6,7 @@ import hep.dataforge.names.Name import hep.dataforge.names.asName import hep.dataforge.names.plus import hep.dataforge.names.startsWith +import hep.dataforge.vision.onPropertyChange import hep.dataforge.vision.solid.Solid import hep.dataforge.vision.solid.SolidMaterial import hep.dataforge.vision.solid.layer diff --git a/visionforge-threejs/src/main/kotlin/hep/dataforge/vision/solid/three/ThreeLabelFactory.kt b/visionforge-threejs/src/main/kotlin/hep/dataforge/vision/solid/three/ThreeLabelFactory.kt index 8809ea2d..ebb6e76c 100644 --- a/visionforge-threejs/src/main/kotlin/hep/dataforge/vision/solid/three/ThreeLabelFactory.kt +++ b/visionforge-threejs/src/main/kotlin/hep/dataforge/vision/solid/three/ThreeLabelFactory.kt @@ -2,6 +2,7 @@ package hep.dataforge.vision.solid.three import hep.dataforge.context.logger +import hep.dataforge.vision.onPropertyChange import hep.dataforge.vision.solid.SolidLabel import info.laht.threekt.core.Object3D import info.laht.threekt.geometries.TextBufferGeometry diff --git a/visionforge-threejs/src/main/kotlin/hep/dataforge/vision/solid/three/ThreeLineFactory.kt b/visionforge-threejs/src/main/kotlin/hep/dataforge/vision/solid/three/ThreeLineFactory.kt index 0d7a8e5c..655b3c38 100644 --- a/visionforge-threejs/src/main/kotlin/hep/dataforge/vision/solid/three/ThreeLineFactory.kt +++ b/visionforge-threejs/src/main/kotlin/hep/dataforge/vision/solid/three/ThreeLineFactory.kt @@ -1,6 +1,7 @@ package hep.dataforge.vision.solid.three import hep.dataforge.meta.node +import hep.dataforge.vision.onPropertyChange import hep.dataforge.vision.solid.PolyLine import hep.dataforge.vision.solid.color import hep.dataforge.vision.solid.string diff --git a/visionforge-threejs/src/main/kotlin/hep/dataforge/vision/solid/three/ThreeMaterials.kt b/visionforge-threejs/src/main/kotlin/hep/dataforge/vision/solid/three/ThreeMaterials.kt index e3905a21..f41e9112 100644 --- a/visionforge-threejs/src/main/kotlin/hep/dataforge/vision/solid/three/ThreeMaterials.kt +++ b/visionforge-threejs/src/main/kotlin/hep/dataforge/vision/solid/three/ThreeMaterials.kt @@ -7,6 +7,7 @@ import hep.dataforge.values.int import hep.dataforge.values.string import hep.dataforge.vision.Colors import hep.dataforge.vision.Vision +import hep.dataforge.vision.ownProperties import hep.dataforge.vision.solid.SolidMaterial import info.laht.threekt.materials.LineBasicMaterial import info.laht.threekt.materials.Material @@ -119,7 +120,7 @@ private var Material.cached: Boolean public fun Mesh.updateMaterial(vision: Vision) { //val meta = vision.getProperty(SolidMaterial.MATERIAL_KEY, inherit = true).node - val ownMaterialMeta = vision.getOwnProperty(SolidMaterial.MATERIAL_KEY) + val ownMaterialMeta = vision.ownProperties[SolidMaterial.MATERIAL_KEY] val parentMaterialMeta = vision.parent?.getProperty( SolidMaterial.MATERIAL_KEY, inherit = true, diff --git a/visionforge-threejs/src/main/kotlin/hep/dataforge/vision/solid/three/ThreePlugin.kt b/visionforge-threejs/src/main/kotlin/hep/dataforge/vision/solid/three/ThreePlugin.kt index dc20bdce..95020784 100644 --- a/visionforge-threejs/src/main/kotlin/hep/dataforge/vision/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/main/kotlin/hep/dataforge/vision/solid/three/ThreePlugin.kt @@ -6,6 +6,7 @@ import hep.dataforge.names.* import hep.dataforge.vision.Vision import hep.dataforge.vision.VisionForge import hep.dataforge.vision.client.ElementVisionRenderer +import hep.dataforge.vision.onPropertyChange import hep.dataforge.vision.solid.* import hep.dataforge.vision.solid.specifications.Canvas3DOptions import hep.dataforge.vision.visible diff --git a/visionforge-threejs/src/main/kotlin/hep/dataforge/vision/solid/three/ThreeReferenceFactory.kt b/visionforge-threejs/src/main/kotlin/hep/dataforge/vision/solid/three/ThreeReferenceFactory.kt index cbee5aa7..d245f846 100644 --- a/visionforge-threejs/src/main/kotlin/hep/dataforge/vision/solid/three/ThreeReferenceFactory.kt +++ b/visionforge-threejs/src/main/kotlin/hep/dataforge/vision/solid/three/ThreeReferenceFactory.kt @@ -3,6 +3,7 @@ package hep.dataforge.vision.solid.three import hep.dataforge.names.cutFirst import hep.dataforge.names.firstOrNull import hep.dataforge.names.toName +import hep.dataforge.vision.onPropertyChange import hep.dataforge.vision.solid.Solid import hep.dataforge.vision.solid.SolidReferenceGroup import hep.dataforge.vision.solid.SolidReferenceGroup.Companion.REFERENCE_CHILD_PROPERTY_PREFIX