Encapsulate prototypes.

This commit is contained in:
Alexander Nozik 2020-12-19 17:44:24 +03:00
parent 6939fba292
commit ccb916cff7
6 changed files with 96 additions and 80 deletions

View File

@ -39,9 +39,10 @@ fun main() {
val randomI = Random.nextInt(1, 4) val randomI = Random.nextInt(1, 4)
val randomJ = Random.nextInt(1, 4) val randomJ = Random.nextInt(1, 4)
val target = "layer[$randomLayer].segment[$randomI,$randomJ]".toName() val target = "layer[$randomLayer].segment[$randomI,$randomJ]".toName()
(sat[target] as? Solid)?.color("red") val targetVision = sat[target] as Solid
targetVision.color("red")
delay(300) delay(300)
(sat[target] as? Solid)?.color("green") targetVision.color("green")
delay(10) delay(10)
} }
} }

View File

@ -11,8 +11,10 @@ import hep.dataforge.names.Name
import hep.dataforge.names.asName import hep.dataforge.names.asName
import hep.dataforge.values.ValueType import hep.dataforge.values.ValueType
import hep.dataforge.vision.Vision.Companion.STYLE_KEY import hep.dataforge.vision.Vision.Companion.STYLE_KEY
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.launch
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient import kotlinx.serialization.Transient
@ -68,7 +70,7 @@ public open class VisionBase : Vision {
yieldAll(getStyleItems(name)) yieldAll(getStyleItems(name))
} }
if (inherit ?: descriptor?.get(name)?.inherited == true) { if (inherit ?: descriptor?.get(name)?.inherited == true) {
yield(parent?.getProperty(name, inherit)) yield(parent?.getProperty(name, inherit, includeStyles, includeDefaults))
} }
yield(descriptor?.get(name)?.defaultItem()) yield(descriptor?.get(name)?.defaultItem())
}.merge() }.merge()
@ -101,8 +103,9 @@ public open class VisionBase : Vision {
if (propertyName == STYLE_KEY) { if (propertyName == STYLE_KEY) {
updateStyles(styles) updateStyles(styles)
} }
GlobalScope.launch {
_propertyInvalidationFlow.tryEmit(propertyName) _propertyInvalidationFlow.emit(propertyName)
}
} }
public fun configure(block: MutableMeta<*>.() -> Unit) { public fun configure(block: MutableMeta<*>.() -> Unit) {

View File

@ -1,8 +1,10 @@
package hep.dataforge.vision package hep.dataforge.vision
import hep.dataforge.names.* import hep.dataforge.names.*
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.launch
import kotlinx.serialization.SerialName import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.Transient import kotlinx.serialization.Transient
@ -43,7 +45,9 @@ public open class VisionGroupBase : VisionBase(), MutableVisionGroup {
* Propagate children change event upwards * Propagate children change event upwards
*/ */
private fun childrenChanged(name: NameToken, before: Vision?, after: Vision?) { private fun childrenChanged(name: NameToken, before: Vision?, after: Vision?) {
_structureChanges.tryEmit(MutableVisionGroup.StructureChange(name, before, after)) GlobalScope.launch {
_structureChanges.emit(MutableVisionGroup.StructureChange(name, before, after))
}
} }
/** /**

View File

@ -16,7 +16,11 @@ import kotlinx.serialization.encoding.Encoder
public interface PrototypeHolder { public interface PrototypeHolder {
public val parent: VisionGroup? public val parent: VisionGroup?
public val prototypes: MutableVisionGroup?
@VisionBuilder
public fun prototypes(builder: VisionContainerBuilder<Solid>.() -> Unit)
public fun getPrototype(name: Name): Solid?
} }
/** /**
@ -28,18 +32,24 @@ public class SolidGroup : VisionGroupBase(), Solid, PrototypeHolder {
override val descriptor: NodeDescriptor get() = Solid.descriptor override val descriptor: NodeDescriptor get() = Solid.descriptor
/** /**
* A container for templates visible inside this group * A container for templates visible inside this group
*/ */
@Serializable(Prototypes.Companion::class) @Serializable(Prototypes.Companion::class)
override var prototypes: MutableVisionGroup? = null @SerialName("prototypes")
private set internal var prototypes: MutableVisionGroup? = null
/**
* Ger a prototype redirecting the request to the parent if prototype is not found
*/
override fun getPrototype(name: Name): Solid? =
prototypes?.get(name) as? Solid ?: (parent as? PrototypeHolder)?.getPrototype(name)
/** /**
* Create or edit prototype node as a group * Create or edit prototype node as a group
*/ */
@VisionBuilder override fun prototypes(builder: VisionContainerBuilder<Solid>.() -> Unit): Unit {
public fun prototypes(builder: VisionContainerBuilder<Solid>.() -> Unit): Unit {
(prototypes ?: Prototypes().also { (prototypes ?: Prototypes().also {
prototypes = it prototypes = it
it.parent = this it.parent = this
@ -81,12 +91,6 @@ public fun SolidGroup(block: SolidGroup.() -> Unit): SolidGroup {
return SolidGroup().apply(block) return SolidGroup().apply(block)
} }
/**
* Ger a prototype redirecting the request to the parent if prototype is not found
*/
public tailrec fun PrototypeHolder.getPrototype(name: Name): Solid? =
prototypes?.get(name) as? Solid ?: (parent as? PrototypeHolder)?.getPrototype(name)
@VisionBuilder @VisionBuilder
public fun VisionContainerBuilder<Vision>.group( public fun VisionContainerBuilder<Vision>.group(
name: Name = Name.EMPTY, name: Name = Name.EMPTY,
@ -106,14 +110,12 @@ public fun VisionContainerBuilder<Vision>.group(name: String, action: SolidGroup
@Serializable(Prototypes.Companion::class) @Serializable(Prototypes.Companion::class)
internal class Prototypes( internal class Prototypes(
children: Map<NameToken, Vision> = emptyMap(), children: Map<NameToken, Vision> = emptyMap(),
) : VisionGroupBase(), PrototypeHolder { ) : VisionGroupBase() {
init { init {
childrenInternal.putAll(children) childrenInternal.putAll(children)
} }
override val prototypes: MutableVisionGroup get() = this
override fun attachChildren() { override fun attachChildren() {
children.values.forEach { children.values.forEach {
it.parent = parent it.parent = parent
@ -131,7 +133,7 @@ internal class Prototypes(
): MetaItem<*>? = null ): MetaItem<*>? = null
override fun setProperty(name: Name, item: MetaItem<*>?, notify: Boolean) { override fun setProperty(name: Name, item: MetaItem<*>?, notify: Boolean) {
TODO("Not yet implemented") error("Can't ser property of prototypes container")
} }
override val descriptor: NodeDescriptor? = null override val descriptor: NodeDescriptor? = null

View File

@ -90,10 +90,20 @@ public class SolidMaterial : Scheme() {
//must be lazy to avoid initialization bug //must be lazy to avoid initialization bug
NodeDescriptor { NodeDescriptor {
value(COLOR_KEY) { value(COLOR_KEY) {
inherited = true
usesStyles = true
type(ValueType.STRING, ValueType.NUMBER) type(ValueType.STRING, ValueType.NUMBER)
widgetType = "color" widgetType = "color"
} }
// value(SPECULAR_COLOR_KEY) {
// inherited = true
// usesStyles = true
// type(ValueType.STRING, ValueType.NUMBER)
// widgetType = "color"
// }
value(OPACITY_KEY) { value(OPACITY_KEY) {
inherited = true
usesStyles = true
type(ValueType.NUMBER) type(ValueType.NUMBER)
default(1.0) default(1.0)
attributes { attributes {
@ -104,6 +114,8 @@ public class SolidMaterial : Scheme() {
widgetType = "slider" widgetType = "slider"
} }
value(WIREFRAME_KEY) { value(WIREFRAME_KEY) {
inherited = true
usesStyles = true
type(ValueType.BOOLEAN) type(ValueType.BOOLEAN)
default(false) default(false)
} }
@ -124,11 +136,7 @@ public var Solid.material: SolidMaterial?
@VisionBuilder @VisionBuilder
public fun Solid.material(builder: SolidMaterial.() -> Unit) { public fun Solid.material(builder: SolidMaterial.() -> Unit) {
val node = allProperties( val node = allProperties(inherit = true).getItem(MATERIAL_KEY).node
inherit = true,
includeStyles = true,
includeDefaults = true
).getItem(MATERIAL_KEY).node
if (node != null) { if (node != null) {
SolidMaterial.update(node, builder) SolidMaterial.update(node, builder)
} else { } else {

View File

@ -46,8 +46,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer {
as ThreeFactory<Solid>? as ThreeFactory<Solid>?
} }
public fun buildObject3D(obj: Solid): Object3D { public fun buildObject3D(obj: Solid): Object3D = when (obj) {
return when (obj) {
is ThreeVision -> obj.render(this) is ThreeVision -> obj.render(this)
is SolidReferenceGroup -> ThreeReferenceFactory(this, obj) is SolidReferenceGroup -> ThreeReferenceFactory(this, obj)
is SolidGroup -> { is SolidGroup -> {
@ -118,7 +117,6 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer {
} }
} }
} }
}
public fun createCanvas( public fun createCanvas(
element: Element, element: Element,