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 27f95c17..b78ec4a5 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 @@ -7,10 +7,19 @@ import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken import space.kscience.visionforge.* +/** + * A container with prototype support + */ public interface PrototypeHolder { + /** + * Build or update prototype tree + */ @VisionBuilder public fun prototypes(builder: VisionContainerBuilder.() -> Unit) + /** + * Resolve a prototype from this container. Should never return a ref. + */ public fun getPrototype(name: Name): Solid? } @@ -24,7 +33,7 @@ public class SolidGroup : VisionGroupBase(), Solid, PrototypeHolder { override val children: Map get() = super.childrenInternal.filter { it.key != PROTOTYPES_TOKEN } - public var prototypes: MutableVisionGroup? + private var prototypes: MutableVisionGroup? get() = childrenInternal[PROTOTYPES_TOKEN] as? MutableVisionGroup set(value) { set(PROTOTYPES_TOKEN, value) @@ -35,7 +44,7 @@ public class SolidGroup : VisionGroupBase(), Solid, PrototypeHolder { /** * Get a prototype redirecting the request to the parent if prototype is not found. - * If prototype is a ref, then it is unfolded until + * 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) 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 401f8097..2b7a8358 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 @@ -37,16 +37,20 @@ private fun SolidReference.getRefProperty( inherit: Boolean, includeStyles: Boolean, includeDefaults: Boolean, -): MetaItem? = buildList { - add(getOwnProperty(name)) - if (includeStyles) { - addAll(getStyleItems(name)) - } - add(prototype.getProperty(name, inherit, includeStyles, includeDefaults)) - if (inherit) { - add(parent?.getProperty(name, inherit)) - } -}.merge() +): MetaItem? = if (!inherit && !includeStyles && !includeDefaults) { + getOwnProperty(name) +} else { + buildList { + add(getOwnProperty(name)) + if (includeStyles) { + addAll(getStyleItems(name)) + } + add(prototype.getProperty(name, inherit, includeStyles, includeDefaults)) + if (inherit) { + add(parent?.getProperty(name, inherit)) + } + }.merge() +} private fun childToken(childName: Name): NameToken = NameToken(SolidReferenceGroup.REFERENCE_CHILD_PROPERTY_PREFIX, childName.toString()) @@ -102,7 +106,8 @@ public class SolidReferenceGroup( if (childName.isEmpty()) owner.prototype else { val proto = (owner.prototype as? VisionGroup)?.get(childName) ?: error("Prototype with name $childName not found in SolidReferenceGroup ${owner.refName}") - proto.unref as? Solid ?: error("Prototype with name $childName is ${proto::class} but expected Solid") + proto.unref as? Solid + ?: error("Prototype with name $childName is ${proto::class} but expected Solid") } } @@ -125,11 +130,7 @@ public class SolidReferenceGroup( inherit: Boolean, includeStyles: Boolean, includeDefaults: Boolean, - ): MetaItem? = if (!inherit && !includeStyles && !includeDefaults) { - getOwnProperty(name) - } else { - getRefProperty(name, inherit, includeStyles, includeDefaults) - } + ): MetaItem? = getRefProperty(name, inherit, includeStyles, includeDefaults) override var parent: VisionGroup? get() {