Handle property clearing in updates.
This commit is contained in:
parent
66ea23ad60
commit
216be4a6a1
@ -3,6 +3,7 @@ package ru.mipt.npm.sat
|
|||||||
|
|
||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
import hep.dataforge.vision.solid.Solid
|
import hep.dataforge.vision.solid.Solid
|
||||||
|
import hep.dataforge.vision.solid.clear
|
||||||
import hep.dataforge.vision.solid.color
|
import hep.dataforge.vision.solid.color
|
||||||
import hep.dataforge.vision.solid.invoke
|
import hep.dataforge.vision.solid.invoke
|
||||||
import hep.dataforge.vision.three.server.*
|
import hep.dataforge.vision.three.server.*
|
||||||
@ -42,7 +43,7 @@ fun main() {
|
|||||||
val targetVision = sat[target] as Solid
|
val targetVision = sat[target] as Solid
|
||||||
targetVision.color("red")
|
targetVision.color("red")
|
||||||
delay(300)
|
delay(300)
|
||||||
targetVision.color("darkgreen")
|
targetVision.color.clear()
|
||||||
delay(10)
|
delay(10)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,6 +57,9 @@ public interface Vision : Described {
|
|||||||
*/
|
*/
|
||||||
public fun setProperty(name: Name, item: MetaItem<*>?, notify: Boolean = true)
|
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)
|
public fun onPropertyChange(scope: CoroutineScope, callback: suspend (Name) -> Unit)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -81,7 +84,7 @@ public interface Vision : Described {
|
|||||||
public suspend fun notifyPropertyChanged(propertyName: Name): Unit
|
public suspend fun notifyPropertyChanged(propertyName: Name): Unit
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update this vision using external meta. Children are not updated.
|
* Update this vision using a dif represented by [VisionChange].
|
||||||
*/
|
*/
|
||||||
public fun update(change: VisionChange)
|
public fun update(change: VisionChange)
|
||||||
|
|
||||||
|
@ -3,12 +3,14 @@ package hep.dataforge.vision
|
|||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
import hep.dataforge.meta.MetaItem
|
import hep.dataforge.meta.MetaItem
|
||||||
import hep.dataforge.meta.MutableMeta
|
import hep.dataforge.meta.MutableMeta
|
||||||
|
import hep.dataforge.meta.asMetaItem
|
||||||
import hep.dataforge.meta.descriptors.NodeDescriptor
|
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||||
import hep.dataforge.meta.descriptors.defaultItem
|
import hep.dataforge.meta.descriptors.defaultItem
|
||||||
import hep.dataforge.meta.descriptors.get
|
import hep.dataforge.meta.descriptors.get
|
||||||
import hep.dataforge.meta.update
|
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
|
import hep.dataforge.names.plus
|
||||||
|
import hep.dataforge.values.Null
|
||||||
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.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@ -27,6 +29,7 @@ internal data class PropertyListener(
|
|||||||
val action: (name: Name) -> Unit,
|
val action: (name: Name) -> Unit,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("vision")
|
@SerialName("vision")
|
||||||
public open class VisionBase : Vision {
|
public open class VisionBase : Vision {
|
||||||
@ -100,6 +103,8 @@ public open class VisionBase : Vision {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//TODO check memory consumption for the flow
|
||||||
@Transient
|
@Transient
|
||||||
private val propertyInvalidationFlow: MutableSharedFlow<Name> = MutableSharedFlow()
|
private val propertyInvalidationFlow: MutableSharedFlow<Name> = MutableSharedFlow()
|
||||||
|
|
||||||
@ -116,13 +121,30 @@ public open class VisionBase : Vision {
|
|||||||
propertyInvalidationFlow.emit(propertyName)
|
propertyInvalidationFlow.emit(propertyName)
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun configure(block: MutableMeta<*>.() -> Unit) {
|
public fun configure(block: suspend MutableMeta<*>.() -> Unit) {
|
||||||
getOrCreateConfig().block()
|
scope.launch {
|
||||||
|
getOrCreateConfig().block()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun update(change: VisionChange) {
|
override fun update(change: VisionChange) {
|
||||||
|
|
||||||
|
fun updateProperties(at: Name, item: MetaItem<*>) {
|
||||||
|
when (item) {
|
||||||
|
is MetaItem.ValueItem -> {
|
||||||
|
if (item.value == Null) {
|
||||||
|
setProperty(at, null)
|
||||||
|
} else
|
||||||
|
setProperty(at, item)
|
||||||
|
}
|
||||||
|
is MetaItem.NodeItem -> item.node.items.forEach { (token, childItem) ->
|
||||||
|
updateProperties(at + token, childItem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
change.properties?.let {
|
change.properties?.let {
|
||||||
getOrCreateConfig().update(it)
|
updateProperties(Name.EMPTY, it.asMetaItem())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package hep.dataforge.vision
|
|||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.plus
|
import hep.dataforge.names.plus
|
||||||
|
import hep.dataforge.values.Null
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.flow
|
import kotlinx.coroutines.flow.flow
|
||||||
@ -30,7 +31,8 @@ public class VisionChangeBuilder : VisionContainerBuilder<Vision> {
|
|||||||
|
|
||||||
public fun propertyChanged(visionName: Name, propertyName: Name, item: MetaItem<*>?) {
|
public fun propertyChanged(visionName: Name, propertyName: Name, item: MetaItem<*>?) {
|
||||||
if (visionName == Name.EMPTY) {
|
if (visionName == Name.EMPTY) {
|
||||||
propertyChange[propertyName] = item
|
//Write property removal as [Null]
|
||||||
|
propertyChange[propertyName] = (item ?: Null.asMetaItem())
|
||||||
} else {
|
} else {
|
||||||
getOrPutChild(visionName).propertyChanged(Name.EMPTY, propertyName, item)
|
getOrPutChild(visionName).propertyChanged(Name.EMPTY, propertyName, item)
|
||||||
}
|
}
|
||||||
@ -112,6 +114,10 @@ public fun Vision.flowChanges(
|
|||||||
coroutineScope {
|
coroutineScope {
|
||||||
collectChange(Name.EMPTY, this@flowChanges) { collector }
|
collectChange(Name.EMPTY, this@flowChanges) { collector }
|
||||||
|
|
||||||
|
//Send initial vision state
|
||||||
|
val initialChange = VisionChange(vision = isolate(manager))
|
||||||
|
emit(initialChange)
|
||||||
|
|
||||||
while (currentCoroutineContext().isActive) {
|
while (currentCoroutineContext().isActive) {
|
||||||
//Wait for changes to accumulate
|
//Wait for changes to accumulate
|
||||||
delay(collectionDuration)
|
delay(collectionDuration)
|
||||||
|
@ -134,14 +134,6 @@ public class VisionServer internal constructor(
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
withContext(visionManager.context.coroutineContext) {
|
withContext(visionManager.context.coroutineContext) {
|
||||||
|
|
||||||
val initialVision = VisionChange(vision = vision)
|
|
||||||
val initialJson = visionManager.jsonFormat.encodeToString(
|
|
||||||
VisionChange.serializer(),
|
|
||||||
initialVision
|
|
||||||
)
|
|
||||||
outgoing.send(Frame.Text(initialJson))
|
|
||||||
|
|
||||||
vision.flowChanges(visionManager, updateInterval.milliseconds).collect { update ->
|
vision.flowChanges(visionManager, updateInterval.milliseconds).collect { update ->
|
||||||
val json = visionManager.jsonFormat.encodeToString(
|
val json = visionManager.jsonFormat.encodeToString(
|
||||||
VisionChange.serializer(),
|
VisionChange.serializer(),
|
||||||
|
@ -0,0 +1,51 @@
|
|||||||
|
package hep.dataforge.vision.solid
|
||||||
|
|
||||||
|
import hep.dataforge.meta.MutableItemProvider
|
||||||
|
import hep.dataforge.meta.set
|
||||||
|
import hep.dataforge.meta.value
|
||||||
|
import hep.dataforge.names.Name
|
||||||
|
import hep.dataforge.values.Value
|
||||||
|
import hep.dataforge.values.asValue
|
||||||
|
import hep.dataforge.values.string
|
||||||
|
import hep.dataforge.vision.Colors
|
||||||
|
import hep.dataforge.vision.VisionBuilder
|
||||||
|
|
||||||
|
@VisionBuilder
|
||||||
|
public class ColorAccessor(private val parent: MutableItemProvider, private val colorKey: Name) {
|
||||||
|
public var value: Value?
|
||||||
|
get() = parent.getItem(colorKey).value
|
||||||
|
set(value) {
|
||||||
|
parent[colorKey] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public var ColorAccessor?.string: String?
|
||||||
|
get() = this?.value?.string
|
||||||
|
set(value) {
|
||||||
|
this?.value = value?.asValue()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set [webcolor](https://en.wikipedia.org/wiki/Web_colors) as string
|
||||||
|
*/
|
||||||
|
public operator fun ColorAccessor?.invoke(webColor: String) {
|
||||||
|
this?.value = webColor.asValue()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set color as RGB integer
|
||||||
|
*/
|
||||||
|
public operator fun ColorAccessor?.invoke(rgb: Int) {
|
||||||
|
this?.value = Colors.rgbToString(rgb).asValue()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set color as RGB
|
||||||
|
*/
|
||||||
|
public operator fun ColorAccessor?.invoke(r: UByte, g: UByte, b: UByte) {
|
||||||
|
this?.value = Colors.rgbToString(r, g, b).asValue()
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun ColorAccessor?.clear(){
|
||||||
|
this?.value = null
|
||||||
|
}
|
@ -6,51 +6,13 @@ import hep.dataforge.meta.descriptors.attributes
|
|||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
import hep.dataforge.names.plus
|
import hep.dataforge.names.plus
|
||||||
import hep.dataforge.values.Value
|
|
||||||
import hep.dataforge.values.ValueType
|
import hep.dataforge.values.ValueType
|
||||||
import hep.dataforge.values.asValue
|
import hep.dataforge.values.asValue
|
||||||
import hep.dataforge.values.string
|
|
||||||
import hep.dataforge.vision.*
|
import hep.dataforge.vision.*
|
||||||
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY
|
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY
|
||||||
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_KEY
|
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_KEY
|
||||||
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_OPACITY_KEY
|
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_OPACITY_KEY
|
||||||
|
|
||||||
@VisionBuilder
|
|
||||||
public class ColorAccessor(private val parent: MutableItemProvider, private val colorKey: Name) {
|
|
||||||
public var value: Value?
|
|
||||||
get() = parent.getItem(colorKey).value
|
|
||||||
set(value) {
|
|
||||||
parent[colorKey] = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public var ColorAccessor?.string: String?
|
|
||||||
get() = this?.value?.string
|
|
||||||
set(value) {
|
|
||||||
this?.value = value?.asValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set [webcolor](https://en.wikipedia.org/wiki/Web_colors) as string
|
|
||||||
*/
|
|
||||||
public operator fun ColorAccessor?.invoke(webColor: String) {
|
|
||||||
this?.value = webColor.asValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set color as RGB integer
|
|
||||||
*/
|
|
||||||
public operator fun ColorAccessor?.invoke(rgb: Int) {
|
|
||||||
this?.value = Colors.rgbToString(rgb).asValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set color as RGB
|
|
||||||
*/
|
|
||||||
public operator fun ColorAccessor?.invoke(r: UByte, g: UByte, b: UByte) {
|
|
||||||
this?.value = Colors.rgbToString(r, g, b).asValue()
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisionBuilder
|
@VisionBuilder
|
||||||
public class SolidMaterial : Scheme() {
|
public class SolidMaterial : Scheme() {
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user