forked from kscience/visionforge
Change collector update
This commit is contained in:
parent
fdc221dfa1
commit
dfac01d352
@ -3,8 +3,10 @@
|
|||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
### Added
|
### Added
|
||||||
- Server module
|
- Server module
|
||||||
|
- Change collector
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
- Vision does not implement ItemProvider anymore. Property changes are done via `getProperty`/`setProperty` and `property` delegate.
|
||||||
|
|
||||||
### Deprecated
|
### Deprecated
|
||||||
|
|
||||||
|
@ -4,8 +4,8 @@ plugins {
|
|||||||
id("ru.mipt.npm.project")
|
id("ru.mipt.npm.project")
|
||||||
}
|
}
|
||||||
|
|
||||||
val dataforgeVersion by extra("0.2.0-dev-4")
|
val dataforgeVersion by extra("0.2.0-dev-7")
|
||||||
val ktorVersion by extra("1.4.1")
|
val ktorVersion by extra("1.4.2")
|
||||||
val kotlinWrappersVersion by extra("pre.129-kotlin-1.4.10")
|
val kotlinWrappersVersion by extra("pre.129-kotlin-1.4.10")
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
package hep.dataforge.vision
|
package hep.dataforge.vision
|
||||||
|
|
||||||
import hep.dataforge.meta.Meta
|
|
||||||
import hep.dataforge.meta.get
|
|
||||||
import hep.dataforge.meta.node
|
|
||||||
import hep.dataforge.names.*
|
import hep.dataforge.names.*
|
||||||
import kotlinx.serialization.Transient
|
import kotlinx.serialization.Transient
|
||||||
|
|
||||||
@ -10,7 +7,7 @@ import kotlinx.serialization.Transient
|
|||||||
/**
|
/**
|
||||||
* Abstract implementation of mutable group of [Vision]
|
* Abstract implementation of mutable group of [Vision]
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup {
|
public abstract class AbstractVisionGroup : VisionBase(), MutableVisionGroup {
|
||||||
|
|
||||||
//protected abstract val _children: MutableMap<NameToken, T>
|
//protected abstract val _children: MutableMap<NameToken, T>
|
||||||
|
|
||||||
@ -19,13 +16,13 @@ public abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup
|
|||||||
*/
|
*/
|
||||||
abstract override val children: Map<NameToken, Vision>
|
abstract override val children: Map<NameToken, Vision>
|
||||||
|
|
||||||
abstract override var styleSheet: StyleSheet?
|
final override var styleSheet: StyleSheet? = null
|
||||||
protected set
|
private set
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update or create stylesheet
|
* Update or create stylesheet
|
||||||
*/
|
*/
|
||||||
public fun styleSheet(block: StyleSheet.() -> Unit) {
|
public open fun styleSheet(block: StyleSheet.() -> Unit) {
|
||||||
if (styleSheet == null) {
|
if (styleSheet == null) {
|
||||||
styleSheet = StyleSheet(this@AbstractVisionGroup)
|
styleSheet = StyleSheet(this@AbstractVisionGroup)
|
||||||
}
|
}
|
||||||
@ -84,17 +81,18 @@ public abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup
|
|||||||
* Add a static child. Statics could not be found by name, removed or replaced. Changing statics also do not trigger events.
|
* Add a static child. Statics could not be found by name, removed or replaced. Changing statics also do not trigger events.
|
||||||
*/
|
*/
|
||||||
protected open fun addStatic(child: Vision): Unit {
|
protected open fun addStatic(child: Vision): Unit {
|
||||||
setChild(NameToken("@static", index = child.hashCode().toString()), child)
|
attach(NameToken("@static", index = child.hashCode().toString()), child)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract fun createGroup(): AbstractVisionGroup
|
protected abstract fun createGroup(): AbstractVisionGroup
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set this node as parent for given node
|
* Set parent for given child and attach it
|
||||||
*/
|
*/
|
||||||
protected fun attach(child: Vision) {
|
protected fun attach(token: NameToken, child: Vision) {
|
||||||
if (child.parent == null) {
|
if (child.parent == null) {
|
||||||
child.parent = this
|
child.parent = this
|
||||||
|
setChild(token, child)
|
||||||
} else if (child.parent !== this) {
|
} else if (child.parent !== this) {
|
||||||
error("Can't reassign existing parent for $child")
|
error("Can't reassign existing parent for $child")
|
||||||
}
|
}
|
||||||
@ -110,8 +108,7 @@ public abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup
|
|||||||
val token = name.tokens.first()
|
val token = name.tokens.first()
|
||||||
when (val current = children[token]) {
|
when (val current = children[token]) {
|
||||||
null -> createGroup().also { child ->
|
null -> createGroup().also { child ->
|
||||||
attach(child)
|
attach(token, child)
|
||||||
setChild(token, child)
|
|
||||||
}
|
}
|
||||||
is AbstractVisionGroup -> current
|
is AbstractVisionGroup -> current
|
||||||
else -> error("Can't create group with name $name because it exists and not a group")
|
else -> error("Can't create group with name $name because it exists and not a group")
|
||||||
@ -129,7 +126,6 @@ public abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup
|
|||||||
when {
|
when {
|
||||||
name.isEmpty() -> {
|
name.isEmpty() -> {
|
||||||
if (child != null) {
|
if (child != null) {
|
||||||
attach(child)
|
|
||||||
addStatic(child)
|
addStatic(child)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -138,8 +134,7 @@ public abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup
|
|||||||
if (child == null) {
|
if (child == null) {
|
||||||
removeChild(token)
|
removeChild(token)
|
||||||
} else {
|
} else {
|
||||||
attach(child)
|
attach(token, child)
|
||||||
setChild(token, child)
|
|
||||||
}
|
}
|
||||||
childrenChanged(token, child)
|
childrenChanged(token, child)
|
||||||
}
|
}
|
||||||
@ -151,11 +146,23 @@ public abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun update(meta: Meta) {
|
override fun update(change: Vision) {
|
||||||
val styleMeta = meta.get("styleSheet").node
|
if (change is VisionGroup) {
|
||||||
if (styleMeta != null) {
|
//update stylesheet
|
||||||
this.styleSheet?.update(styleMeta)
|
val changeStyleSheet = change.styleSheet
|
||||||
}
|
if (changeStyleSheet != null) {
|
||||||
super.update(meta)
|
styleSheet {
|
||||||
|
update(changeStyleSheet)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
change.children.forEach { (token, child) ->
|
||||||
|
when {
|
||||||
|
child is NullVision -> removeChild(token)
|
||||||
|
children.containsKey(token) -> children[token]!!.update(child)
|
||||||
|
else -> attach(token, child)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
super.update(change)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,17 +1,13 @@
|
|||||||
package hep.dataforge.vision
|
package hep.dataforge.vision
|
||||||
|
|
||||||
import hep.dataforge.meta.Config
|
|
||||||
import hep.dataforge.names.NameToken
|
import hep.dataforge.names.NameToken
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("group")
|
@SerialName("vision.group")
|
||||||
public class SimpleVisionGroup : AbstractVisionGroup() {
|
public class SimpleVisionGroup : AbstractVisionGroup() {
|
||||||
|
|
||||||
override var styleSheet: StyleSheet? = null
|
|
||||||
|
|
||||||
@SerialName("children")
|
@SerialName("children")
|
||||||
private val _children = HashMap<NameToken, Vision>()
|
private val _children = HashMap<NameToken, Vision>()
|
||||||
override val children: Map<NameToken, Vision> get() = _children
|
override val children: Map<NameToken, Vision> get() = _children
|
||||||
|
@ -5,7 +5,10 @@ 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.asName
|
import hep.dataforge.names.asName
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.KSerializer
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlinx.serialization.Transient
|
||||||
|
import kotlinx.serialization.UseSerializers
|
||||||
import kotlinx.serialization.builtins.MapSerializer
|
import kotlinx.serialization.builtins.MapSerializer
|
||||||
import kotlinx.serialization.builtins.serializer
|
import kotlinx.serialization.builtins.serializer
|
||||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||||
@ -15,7 +18,7 @@ import kotlinx.serialization.encoding.Encoder
|
|||||||
/**
|
/**
|
||||||
* A container for styles
|
* A container for styles
|
||||||
*/
|
*/
|
||||||
@Serializable
|
@Serializable(StyleSheet.Companion::class)
|
||||||
public class StyleSheet private constructor(private val styleMap: MutableMap<String, Meta>) {
|
public class StyleSheet private constructor(private val styleMap: MutableMap<String, Meta>) {
|
||||||
@Transient
|
@Transient
|
||||||
internal var owner: Vision? = null
|
internal var owner: Vision? = null
|
||||||
@ -30,7 +33,8 @@ public class StyleSheet private constructor(private val styleMap: MutableMap<Str
|
|||||||
private fun Vision.styleChanged(key: String, oldStyle: Meta?, newStyle: Meta?) {
|
private fun Vision.styleChanged(key: String, oldStyle: Meta?, newStyle: Meta?) {
|
||||||
if (styles.contains(key)) {
|
if (styles.contains(key)) {
|
||||||
//TODO optimize set concatenation
|
//TODO optimize set concatenation
|
||||||
val tokens: Collection<Name> = ((oldStyle?.items?.keys ?: emptySet()) + (newStyle?.items?.keys ?: emptySet()))
|
val tokens: Collection<Name> =
|
||||||
|
((oldStyle?.items?.keys ?: emptySet()) + (newStyle?.items?.keys ?: emptySet()))
|
||||||
.map { it.asName() }
|
.map { it.asName() }
|
||||||
tokens.forEach { parent?.propertyChanged(it) }
|
tokens.forEach { parent?.propertyChanged(it) }
|
||||||
}
|
}
|
||||||
@ -73,8 +77,17 @@ public class StyleSheet private constructor(private val styleMap: MutableMap<Str
|
|||||||
set(key, newStyle.seal())
|
set(key, newStyle.seal())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExperimentalSerializationApi
|
public fun update(key: String, meta: Meta) {
|
||||||
@Serializer(StyleSheet::class)
|
val existing = get(key)
|
||||||
|
set(key, existing?.edit { this.update(meta) } ?: meta)
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun update(other: StyleSheet) {
|
||||||
|
other.items.forEach { (key, value) ->
|
||||||
|
update(key, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public companion object : KSerializer<StyleSheet> {
|
public companion object : KSerializer<StyleSheet> {
|
||||||
private val mapSerializer = MapSerializer(String.serializer(), MetaSerializer)
|
private val mapSerializer = MapSerializer(String.serializer(), MetaSerializer)
|
||||||
override val descriptor: SerialDescriptor get() = mapSerializer.descriptor
|
override val descriptor: SerialDescriptor get() = mapSerializer.descriptor
|
||||||
@ -91,11 +104,6 @@ public class StyleSheet private constructor(private val styleMap: MutableMap<Str
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun StyleSheet.update(styleMeta: Meta){
|
|
||||||
TODO()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add style name to the list of styles to be resolved later. The style with given name does not necessary exist at the moment.
|
* Add style name to the list of styles to be resolved later. The style with given name does not necessary exist at the moment.
|
||||||
*/
|
*/
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package hep.dataforge.vision
|
package hep.dataforge.vision
|
||||||
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
|
import hep.dataforge.meta.descriptors.Described
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
@ -9,14 +10,15 @@ import hep.dataforge.values.asValue
|
|||||||
import hep.dataforge.vision.Vision.Companion.TYPE
|
import hep.dataforge.vision.Vision.Companion.TYPE
|
||||||
import hep.dataforge.vision.Vision.Companion.VISIBLE_KEY
|
import hep.dataforge.vision.Vision.Companion.VISIBLE_KEY
|
||||||
import kotlinx.serialization.PolymorphicSerializer
|
import kotlinx.serialization.PolymorphicSerializer
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
import kotlinx.serialization.Transient
|
import kotlinx.serialization.Transient
|
||||||
|
import kotlin.properties.ReadWriteProperty
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A root type for display hierarchy
|
* A root type for display hierarchy
|
||||||
*/
|
*/
|
||||||
@Type(TYPE)
|
@Type(TYPE)
|
||||||
public interface Vision : Configurable {
|
public interface Vision : Configurable, Described {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The parent object of this one. If null, this one is a root.
|
* The parent object of this one. If null, this one is a root.
|
||||||
@ -37,12 +39,7 @@ public interface Vision : Configurable {
|
|||||||
/**
|
/**
|
||||||
* Get property (including styles). [inherit] toggles parent node property lookup
|
* Get property (including styles). [inherit] toggles parent node property lookup
|
||||||
*/
|
*/
|
||||||
public fun getProperty(name: Name, inherit: Boolean): MetaItem<*>?
|
public fun getProperty(name: Name, inherit: Boolean = true): MetaItem<*>?
|
||||||
|
|
||||||
/**
|
|
||||||
* Ger a property including inherited values
|
|
||||||
*/
|
|
||||||
override fun getItem(name: Name): MetaItem<*>? = getProperty(name, true)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trigger property invalidation event. If [name] is empty, notify that the whole object is changed
|
* Trigger property invalidation event. If [name] is empty, notify that the whole object is changed
|
||||||
@ -71,7 +68,7 @@ public interface Vision : Configurable {
|
|||||||
/**
|
/**
|
||||||
* Update this vision using external meta. Children are not updated.
|
* Update this vision using external meta. Children are not updated.
|
||||||
*/
|
*/
|
||||||
public fun update(meta: Meta)
|
public fun update(change: Vision)
|
||||||
|
|
||||||
public companion object {
|
public companion object {
|
||||||
public const val TYPE: String = "vision"
|
public const val TYPE: String = "vision"
|
||||||
@ -89,16 +86,61 @@ public interface Vision : Configurable {
|
|||||||
public fun Vision.getProperty(key: String, inherit: Boolean = true): MetaItem<*>? =
|
public fun Vision.getProperty(key: String, inherit: Boolean = true): MetaItem<*>? =
|
||||||
getProperty(key.toName(), inherit)
|
getProperty(key.toName(), inherit)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A convenience method to pair [getProperty]
|
||||||
|
*/
|
||||||
|
public fun Vision.setProperty(key: Name, value: Any?) {
|
||||||
|
config[key] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A convenience method to pair [getProperty]
|
||||||
|
*/
|
||||||
|
public fun Vision.setProperty(key: String, value: Any?) {
|
||||||
|
config[key] = value
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a style with given name for given [Vision]. The style is not necessary applied to this [Vision].
|
* Find a style with given name for given [Vision]. The style is not necessary applied to this [Vision].
|
||||||
*/
|
*/
|
||||||
public tailrec fun Vision.resolveStyle(name: String): Meta? =
|
public tailrec fun Vision.resolveStyle(name: String): Meta? =
|
||||||
(this as? VisionGroup)?.styleSheet?.get(name) ?: parent?.resolveStyle(name)
|
(this as? VisionGroup)?.styleSheet?.get(name) ?: parent?.resolveStyle(name)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Control visibility of the element
|
* Control visibility of the element
|
||||||
*/
|
*/
|
||||||
public var Vision.visible: Boolean?
|
public var Vision.visible: Boolean?
|
||||||
get() = getItem(VISIBLE_KEY).boolean
|
get() = getProperty(VISIBLE_KEY).boolean
|
||||||
set(value) = setItem(VISIBLE_KEY, value?.asValue())
|
set(value) = config.setValue(VISIBLE_KEY, value?.asValue())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convinience delegate for properties
|
||||||
|
*/
|
||||||
|
public fun Vision.property(
|
||||||
|
default: MetaItem<*>? = null,
|
||||||
|
key: Name? = null,
|
||||||
|
inherit: Boolean = true,
|
||||||
|
): MutableItemDelegate =
|
||||||
|
object : ReadWriteProperty<Any?, MetaItem<*>?> {
|
||||||
|
override fun getValue(thisRef: Any?, property: KProperty<*>): MetaItem<*>? {
|
||||||
|
val name = key ?: property.name.toName()
|
||||||
|
return getProperty(name, inherit) ?: default
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setValue(thisRef: Any?, property: KProperty<*>, value: MetaItem<*>?) {
|
||||||
|
val name = key ?: property.name.toName()
|
||||||
|
setProperty(name, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO replace by value
|
||||||
|
fun Vision.properties(inherit: Boolean = true): MutableItemProvider = object : MutableItemProvider {
|
||||||
|
override fun getItem(name: Name): MetaItem<*>? {
|
||||||
|
return getProperty(name, inherit)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setItem(name: Name, item: MetaItem<*>?) {
|
||||||
|
setProperty(name, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -2,20 +2,24 @@ package hep.dataforge.vision
|
|||||||
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
import hep.dataforge.meta.descriptors.NodeDescriptor
|
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||||
|
import hep.dataforge.meta.descriptors.defaultItem
|
||||||
|
import hep.dataforge.meta.descriptors.get
|
||||||
import hep.dataforge.names.Name
|
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.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.Transient
|
import kotlinx.serialization.Transient
|
||||||
|
|
||||||
internal data class PropertyListener(
|
internal data class PropertyListener(
|
||||||
val owner: Any? = null,
|
val owner: Any? = null,
|
||||||
val action: (name: Name) -> Unit
|
val action: (name: Name) -> Unit,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
public open class AbstractVision : Vision {
|
@SerialName("vision")
|
||||||
|
public open class VisionBase : Vision {
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
override var parent: VisionGroup? = null
|
override var parent: VisionGroup? = null
|
||||||
@ -26,6 +30,8 @@ public open class AbstractVision : Vision {
|
|||||||
override var properties: Config? = null
|
override var properties: Config? = null
|
||||||
protected set
|
protected set
|
||||||
|
|
||||||
|
override val descriptor: NodeDescriptor? get() = null
|
||||||
|
|
||||||
protected fun updateStyles(names: List<String>) {
|
protected fun updateStyles(names: List<String>) {
|
||||||
names.mapNotNull { resolveStyle(it) }.asSequence()
|
names.mapNotNull { resolveStyle(it) }.asSequence()
|
||||||
.flatMap { it.items.asSequence() }
|
.flatMap { it.items.asSequence() }
|
||||||
@ -76,12 +82,14 @@ public open class AbstractVision : Vision {
|
|||||||
sequence {
|
sequence {
|
||||||
yield(properties?.get(name))
|
yield(properties?.get(name))
|
||||||
yieldAll(getStyleItems(name))
|
yieldAll(getStyleItems(name))
|
||||||
|
yield(descriptor?.get(name)?.defaultItem())
|
||||||
yield(parent?.getProperty(name, inherit))
|
yield(parent?.getProperty(name, inherit))
|
||||||
}.merge()
|
}.merge()
|
||||||
} else {
|
} else {
|
||||||
sequence {
|
sequence {
|
||||||
yield(properties?.get(name))
|
yield(properties?.get(name))
|
||||||
yieldAll(getStyleItems(name))
|
yieldAll(getStyleItems(name))
|
||||||
|
yield(descriptor?.get(name)?.defaultItem())
|
||||||
}.merge()
|
}.merge()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,8 +102,10 @@ public open class AbstractVision : Vision {
|
|||||||
properties = null
|
properties = null
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun update(meta: Meta) {
|
override fun update(change: Vision) {
|
||||||
meta[Vision::properties.name].node?.let { configure(it) }
|
if (change.properties != null) {
|
||||||
|
config.update(change.config)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public companion object {
|
public companion object {
|
@ -1,50 +0,0 @@
|
|||||||
package hep.dataforge.vision
|
|
||||||
|
|
||||||
import hep.dataforge.meta.Config
|
|
||||||
import hep.dataforge.meta.Meta
|
|
||||||
import hep.dataforge.meta.get
|
|
||||||
import hep.dataforge.meta.set
|
|
||||||
import hep.dataforge.names.NameToken
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
import kotlinx.coroutines.sync.Mutex
|
|
||||||
|
|
||||||
|
|
||||||
//public class VisionChange(public val properties: Meta, public val childrenChange: Map<NameToken, VisionChange>)
|
|
||||||
|
|
||||||
public class VisionChangeCollector(
|
|
||||||
public val manager: VisionManager,
|
|
||||||
public val scope: CoroutineScope,
|
|
||||||
public val vision: Vision,
|
|
||||||
public val lock: Mutex = Mutex()
|
|
||||||
) {
|
|
||||||
private val collector: Config = Config()
|
|
||||||
private val childrenCollectors = HashMap<NameToken, VisionChangeCollector>()
|
|
||||||
|
|
||||||
init {
|
|
||||||
vision.onPropertyChange(this) { propertyName ->
|
|
||||||
collector[propertyName] = vision.properties?.get(propertyName)
|
|
||||||
}
|
|
||||||
if (vision is VisionGroup) {
|
|
||||||
vision.children.forEach { (token, child) ->
|
|
||||||
childrenCollectors[token] = VisionChangeCollector(manager, scope, child, lock)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (vision is MutableVisionGroup) {
|
|
||||||
TODO("Tread vision structure change")
|
|
||||||
// vision.onChildrenChange(this) { childName, child ->
|
|
||||||
// if(child == null){
|
|
||||||
// childrenCollectors[childName] = null
|
|
||||||
// } else {
|
|
||||||
// childrenCollectors[childName] = manager.encodeToMeta(child)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//
|
|
||||||
//fun collectUpdates(manager: VisionManager, scope: CoroutineScope, vision: Vision): Flow<Meta> {
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// vision.
|
|
||||||
//}
|
|
@ -3,10 +3,6 @@ package hep.dataforge.vision
|
|||||||
import hep.dataforge.context.*
|
import hep.dataforge.context.*
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
import hep.dataforge.meta.descriptors.NodeDescriptor
|
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||||
import hep.dataforge.names.asName
|
|
||||||
import hep.dataforge.values.Null
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.json.JsonElement
|
import kotlinx.serialization.json.JsonElement
|
||||||
import kotlinx.serialization.modules.SerializersModule
|
import kotlinx.serialization.modules.SerializersModule
|
||||||
@ -52,30 +48,30 @@ public class VisionManager(meta: Meta) : AbstractPlugin(meta) {
|
|||||||
encodeToJsonElement(vision).toMetaItem(descriptor).node
|
encodeToJsonElement(vision).toMetaItem(descriptor).node
|
||||||
?: error("Expected node, but value found. Check your serializer!")
|
?: error("Expected node, but value found. Check your serializer!")
|
||||||
|
|
||||||
public fun updateVision(vision: Vision, meta: Meta) {
|
// public fun updateVision(vision: Vision, meta: Meta) {
|
||||||
vision.update(meta)
|
// vision.update(meta)
|
||||||
if (vision is MutableVisionGroup) {
|
// if (vision is MutableVisionGroup) {
|
||||||
val children by meta.node()
|
// val children by meta.node()
|
||||||
children?.items?.forEach { (token, item) ->
|
// children?.items?.forEach { (token, item) ->
|
||||||
when {
|
// when {
|
||||||
item.value == Null -> vision[token] = null //Null means removal
|
// item.value == Null -> vision[token] = null //Null means removal
|
||||||
item.node != null -> {
|
// item.node != null -> {
|
||||||
val node = item.node!!
|
// val node = item.node!!
|
||||||
val type by node.string()
|
// val type by node.string()
|
||||||
if (type != null) {
|
// if (type != null) {
|
||||||
//If the type is present considering it as new node, not an update
|
// //If the type is present considering it as new node, not an update
|
||||||
vision[token.asName()] = decodeFromMeta(node)
|
// vision[token.asName()] = decodeFromMeta(node)
|
||||||
} else {
|
// } else {
|
||||||
val existing = vision.children[token]
|
// val existing = vision.children[token]
|
||||||
if (existing != null) {
|
// if (existing != null) {
|
||||||
updateVision(existing, node)
|
// updateVision(existing, node)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
public companion object : PluginFactory<VisionManager> {
|
public companion object : PluginFactory<VisionManager> {
|
||||||
override val tag: PluginTag = PluginTag(name = "vision", group = PluginTag.DATAFORGE_GROUP)
|
override val tag: PluginTag = PluginTag(name = "vision", group = PluginTag.DATAFORGE_GROUP)
|
||||||
|
@ -0,0 +1,106 @@
|
|||||||
|
package hep.dataforge.vision
|
||||||
|
|
||||||
|
import hep.dataforge.meta.*
|
||||||
|
import hep.dataforge.meta.descriptors.ItemDescriptor
|
||||||
|
import hep.dataforge.names.Name
|
||||||
|
import hep.dataforge.names.NameToken
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.flow
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlin.time.Duration
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An empty vision existing only for Vision tree change representation. [NullVision] should not be used outside update logic.
|
||||||
|
*/
|
||||||
|
@Serializable
|
||||||
|
@SerialName("vision.null")
|
||||||
|
public object NullVision : Vision {
|
||||||
|
|
||||||
|
@Suppress("SetterBackingFieldAssignment")
|
||||||
|
override var parent: VisionGroup? = null
|
||||||
|
set(value) {
|
||||||
|
//do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
override val properties: Config? = null
|
||||||
|
|
||||||
|
override fun getAllProperties(): Laminate = Laminate(Meta.EMPTY)
|
||||||
|
|
||||||
|
override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? = null
|
||||||
|
|
||||||
|
override fun propertyChanged(name: Name) {}
|
||||||
|
|
||||||
|
override fun onPropertyChange(owner: Any?, action: (Name) -> Unit) {}
|
||||||
|
|
||||||
|
override fun removeChangeListener(owner: Any?) {}
|
||||||
|
|
||||||
|
override fun update(change: Vision) {
|
||||||
|
error("Null vision should be removed, not updated")
|
||||||
|
}
|
||||||
|
|
||||||
|
override val config: Config get() = Config()
|
||||||
|
override val descriptor: ItemDescriptor? get() = null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Vision.collectChange(scope: CoroutineScope, collector: Vision): Job = scope.launch {
|
||||||
|
//Store job to be able to cancel collection jobs
|
||||||
|
//TODO add lock for concurrent modification protection?
|
||||||
|
val jobStore = HashMap<NameToken, Job>()
|
||||||
|
|
||||||
|
if (this is VisionGroup) {
|
||||||
|
check(collector is MutableVisionGroup) { "Collector for a group should be a group" }
|
||||||
|
//Subscribe for children changes
|
||||||
|
children.forEach { (token, child) ->
|
||||||
|
val childCollector: Vision = if (child is VisionGroup) {
|
||||||
|
SimpleVisionGroup()
|
||||||
|
} else {
|
||||||
|
VisionBase()
|
||||||
|
}
|
||||||
|
val job = child.collectChange(this, childCollector)
|
||||||
|
jobStore[token] = job
|
||||||
|
//TODO add lazy child addition
|
||||||
|
collector[token] = childCollector
|
||||||
|
}
|
||||||
|
|
||||||
|
//Subscribe for structure change
|
||||||
|
if (this is MutableVisionGroup) {
|
||||||
|
onChildrenChange(this) { token, child ->
|
||||||
|
//Cancel collector job to avoid leaking
|
||||||
|
jobStore[token]?.cancel()
|
||||||
|
if (child != null) {
|
||||||
|
//Collect to existing Vision
|
||||||
|
val job = child.collectChange(this, child)
|
||||||
|
jobStore[token] = job
|
||||||
|
collector[token] = child
|
||||||
|
} else{
|
||||||
|
collector[token] = NullVision
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Collect properties change
|
||||||
|
collector.onPropertyChange(collector) { propertyName ->
|
||||||
|
collector.config[propertyName] = properties?.get(propertyName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun Vision.flowChanges(scope: CoroutineScope, collectionDuration: Duration): Flow<Vision> = flow {
|
||||||
|
//emit initial visual tree
|
||||||
|
emit(this@flowChanges)
|
||||||
|
while (true) {
|
||||||
|
val collector: Vision = if (this is VisionGroup) {
|
||||||
|
SimpleVisionGroup()
|
||||||
|
} else {
|
||||||
|
VisionBase()
|
||||||
|
}
|
||||||
|
val collectorJob = collectChange(scope, collector)
|
||||||
|
kotlinx.coroutines.delay(collectionDuration)
|
||||||
|
emit(collector)
|
||||||
|
collectorJob.cancel()
|
||||||
|
}
|
||||||
|
}
|
@ -1,63 +1,8 @@
|
|||||||
//import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME
|
//import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("ru.mipt.npm.mpp")
|
id("ru.mipt.npm.jvm")
|
||||||
// application
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val ktorVersion: String by rootProject.extra
|
val ktorVersion: String by rootProject.extra
|
||||||
|
|
||||||
//kscience {
|
|
||||||
// application()
|
|
||||||
//}
|
|
||||||
|
|
||||||
kotlin {
|
|
||||||
// afterEvaluate {
|
|
||||||
// val jsBrowserDistribution by tasks.getting
|
|
||||||
//
|
|
||||||
// jvm {
|
|
||||||
// withJava()
|
|
||||||
// compilations[MAIN_COMPILATION_NAME]?.apply {
|
|
||||||
// tasks.getByName<ProcessResources>(processResourcesTaskName) {
|
|
||||||
// dependsOn(jsBrowserDistribution)
|
|
||||||
// afterEvaluate {
|
|
||||||
// from(jsBrowserDistribution)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
sourceSets {
|
|
||||||
commonMain {
|
|
||||||
dependencies {
|
|
||||||
implementation(project(":visionforge-core"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
jvmMain {
|
|
||||||
dependencies {
|
|
||||||
implementation("io.ktor:ktor-server-cio:$ktorVersion")
|
|
||||||
implementation("io.ktor:ktor-serialization:$ktorVersion")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
jsMain {
|
|
||||||
dependencies {
|
|
||||||
implementation("io.ktor:ktor-client-js:$ktorVersion")
|
|
||||||
implementation("io.ktor:ktor-client-serialization-js:$ktorVersion")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//distributions {
|
|
||||||
// main {
|
|
||||||
// contents {
|
|
||||||
// from("$buildDir/libs") {
|
|
||||||
// rename("${rootProject.name}-jvm", rootProject.name)
|
|
||||||
// into("lib")
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
@ -1,15 +1,20 @@
|
|||||||
package hep.dataforge.vision.solid
|
package hep.dataforge.vision.solid
|
||||||
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.vision.AbstractVision
|
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||||
|
import hep.dataforge.meta.float
|
||||||
|
import hep.dataforge.meta.get
|
||||||
|
import hep.dataforge.meta.node
|
||||||
import hep.dataforge.vision.Vision
|
import hep.dataforge.vision.Vision
|
||||||
|
import hep.dataforge.vision.VisionBase
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.UseSerializers
|
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("solid")
|
@SerialName("solid")
|
||||||
public open class BasicSolid: AbstractVision(), Solid {
|
public open class BasicSolid : VisionBase(), Solid {
|
||||||
|
override val descriptor: NodeDescriptor get() = Solid.descriptor
|
||||||
|
|
||||||
@Serializable(Point3DSerializer::class)
|
@Serializable(Point3DSerializer::class)
|
||||||
override var position: Point3D? = null
|
override var position: Point3D? = null
|
||||||
|
|
||||||
@ -19,16 +24,16 @@ public open class BasicSolid: AbstractVision(), Solid {
|
|||||||
@Serializable(Point3DSerializer::class)
|
@Serializable(Point3DSerializer::class)
|
||||||
override var scale: Point3D? = null
|
override var scale: Point3D? = null
|
||||||
|
|
||||||
override fun update(meta: Meta) {
|
override fun update(change: Vision) {
|
||||||
fun Meta.toVector(default: Float = 0f) = Point3D(
|
fun Meta.toVector(default: Float = 0f) = Point3D(
|
||||||
this[Solid.X_KEY].float ?: default,
|
this[Solid.X_KEY].float ?: default,
|
||||||
this[Solid.Y_KEY].float ?: default,
|
this[Solid.Y_KEY].float ?: default,
|
||||||
this[Solid.Z_KEY].float ?: default
|
this[Solid.Z_KEY].float ?: default
|
||||||
)
|
)
|
||||||
|
|
||||||
meta[Solid.POSITION_KEY].node?.toVector()?.let { position = it }
|
change.properties[Solid.POSITION_KEY].node?.toVector()?.let { position = it }
|
||||||
meta[Solid.ROTATION].node?.toVector()?.let { rotation = it }
|
change.properties[Solid.ROTATION].node?.toVector()?.let { rotation = it }
|
||||||
meta[Solid.SCALE_KEY].node?.toVector(1f)?.let { scale = it }
|
change.properties[Solid.SCALE_KEY].node?.toVector(1f)?.let { scale = it }
|
||||||
super.update(meta)
|
super.update(change)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -7,6 +7,7 @@ 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.vision.VisionContainerBuilder
|
import hep.dataforge.vision.VisionContainerBuilder
|
||||||
|
import hep.dataforge.vision.properties
|
||||||
import hep.dataforge.vision.set
|
import hep.dataforge.vision.set
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
@ -17,7 +18,7 @@ import kotlinx.serialization.UseSerializers
|
|||||||
public class PolyLine(public var points: List<Point3D>) : BasicSolid(), Solid {
|
public class PolyLine(public var points: List<Point3D>) : BasicSolid(), Solid {
|
||||||
|
|
||||||
//var lineType by string()
|
//var lineType by string()
|
||||||
public var thickness: Number by number(1.0, key = SolidMaterial.MATERIAL_KEY + THICKNESS_KEY)
|
public var thickness: Number by properties().number(1.0, key = SolidMaterial.MATERIAL_KEY + THICKNESS_KEY)
|
||||||
|
|
||||||
public companion object {
|
public companion object {
|
||||||
public val THICKNESS_KEY: Name = "thickness".asName()
|
public val THICKNESS_KEY: Name = "thickness".asName()
|
||||||
|
@ -10,14 +10,14 @@ import kotlinx.serialization.Transient
|
|||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
|
|
||||||
public abstract class AbstractProxy : BasicSolid(), VisionGroup {
|
public abstract class AbstractProxy : BasicSolid(), VisionGroup {
|
||||||
public abstract val prototype: Vision
|
public abstract val prototype: Solid
|
||||||
|
|
||||||
override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? {
|
override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? {
|
||||||
return if (inherit) {
|
return if (inherit) {
|
||||||
sequence {
|
sequence {
|
||||||
yield(properties?.get(name))
|
yield(properties?.get(name))
|
||||||
yieldAll(getStyleItems(name))
|
yieldAll(getStyleItems(name))
|
||||||
yield(prototype.getItem(name))
|
yield(prototype.getProperty(name))
|
||||||
yield(parent?.getProperty(name, inherit))
|
yield(parent?.getProperty(name, inherit))
|
||||||
}.merge()
|
}.merge()
|
||||||
} else {
|
} else {
|
||||||
@ -42,7 +42,7 @@ public abstract class AbstractProxy : BasicSolid(), VisionGroup {
|
|||||||
//do nothing
|
//do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
override val descriptor: NodeDescriptor? get() = prototype.descriptor
|
override val descriptor: NodeDescriptor get() = prototype.descriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,13 +82,11 @@ public class Proxy private constructor(
|
|||||||
return NameToken(PROXY_CHILD_PROPERTY_PREFIX, childName.toString()) + propertyName
|
return NameToken(PROXY_CHILD_PROPERTY_PREFIX, childName.toString()) + propertyName
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun prototypeFor(name: Name): Vision {
|
private fun prototypeFor(name: Name): Solid {
|
||||||
return (prototype as? VisionGroup)?.get(name)
|
return (prototype as? SolidGroup)?.get(name) as? Solid
|
||||||
?: error("Prototype with name $name not found in $this")
|
?: error("Prototype with name $name not found in $this")
|
||||||
}
|
}
|
||||||
|
|
||||||
override val descriptor: NodeDescriptor? get() = prototype.descriptor
|
|
||||||
|
|
||||||
//override fun findAllStyles(): Laminate = Laminate((styles + prototype.styles).mapNotNull { findStyle(it) })
|
//override fun findAllStyles(): Laminate = Laminate((styles + prototype.styles).mapNotNull { findStyle(it) })
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -97,7 +95,7 @@ public class Proxy private constructor(
|
|||||||
*/
|
*/
|
||||||
public inner class ProxyChild(public val name: Name) : AbstractProxy() {
|
public inner class ProxyChild(public val name: Name) : AbstractProxy() {
|
||||||
|
|
||||||
override val prototype: Vision get() = prototypeFor(name)
|
override val prototype: Solid get() = prototypeFor(name)
|
||||||
|
|
||||||
override val styleSheet: StyleSheet get() = this@Proxy.styleSheet
|
override val styleSheet: StyleSheet get() = this@Proxy.styleSheet
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@ import hep.dataforge.vision.enum
|
|||||||
import hep.dataforge.vision.solid.Solid.Companion.DETAIL_KEY
|
import hep.dataforge.vision.solid.Solid.Companion.DETAIL_KEY
|
||||||
import hep.dataforge.vision.solid.Solid.Companion.IGNORE_KEY
|
import hep.dataforge.vision.solid.Solid.Companion.IGNORE_KEY
|
||||||
import hep.dataforge.vision.solid.Solid.Companion.LAYER_KEY
|
import hep.dataforge.vision.solid.Solid.Companion.LAYER_KEY
|
||||||
import kotlinx.serialization.UseSerializers
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for 3-dimensional [Vision]
|
* Interface for 3-dimensional [Vision]
|
||||||
@ -24,7 +23,7 @@ public interface Solid : Vision {
|
|||||||
public var rotation: Point3D?
|
public var rotation: Point3D?
|
||||||
public var scale: Point3D?
|
public var scale: Point3D?
|
||||||
|
|
||||||
override val descriptor: NodeDescriptor? get() = Companion.descriptor
|
override val descriptor: NodeDescriptor get() = Companion.descriptor
|
||||||
|
|
||||||
public companion object {
|
public companion object {
|
||||||
// val SELECTED_KEY = "selected".asName()
|
// val SELECTED_KEY = "selected".asName()
|
||||||
@ -123,7 +122,7 @@ public enum class RotationOrder {
|
|||||||
*/
|
*/
|
||||||
public var Solid.rotationOrder: RotationOrder
|
public var Solid.rotationOrder: RotationOrder
|
||||||
get() = getItem(Solid.ROTATION_ORDER_KEY).enum<RotationOrder>() ?: RotationOrder.XYZ
|
get() = getItem(Solid.ROTATION_ORDER_KEY).enum<RotationOrder>() ?: RotationOrder.XYZ
|
||||||
set(value) = setItem(Solid.ROTATION_ORDER_KEY, value.name.asValue())
|
set(value) = setValue(Solid.ROTATION_ORDER_KEY, value.name.asValue())
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -131,7 +130,7 @@ public var Solid.rotationOrder: RotationOrder
|
|||||||
*/
|
*/
|
||||||
public var Solid.detail: Int?
|
public var Solid.detail: Int?
|
||||||
get() = getProperty(DETAIL_KEY, false).int
|
get() = getProperty(DETAIL_KEY, false).int
|
||||||
set(value) = setItem(DETAIL_KEY, value?.asValue())
|
set(value) = setValue(DETAIL_KEY, value?.asValue())
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If this property is true, the object will be ignored on render.
|
* If this property is true, the object will be ignored on render.
|
||||||
@ -139,7 +138,7 @@ public var Solid.detail: Int?
|
|||||||
*/
|
*/
|
||||||
public var Vision.ignore: Boolean?
|
public var Vision.ignore: Boolean?
|
||||||
get() = getProperty(IGNORE_KEY, false).boolean
|
get() = getProperty(IGNORE_KEY, false).boolean
|
||||||
set(value) = setItem(IGNORE_KEY, value?.asValue())
|
set(value) = setValue(IGNORE_KEY, value?.asValue())
|
||||||
|
|
||||||
//var VisualObject.selected: Boolean?
|
//var VisualObject.selected: Boolean?
|
||||||
// get() = getProperty(SELECTED_KEY).boolean
|
// get() = getProperty(SELECTED_KEY).boolean
|
||||||
|
@ -1,16 +1,12 @@
|
|||||||
package hep.dataforge.vision.solid
|
package hep.dataforge.vision.solid
|
||||||
|
|
||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
import hep.dataforge.meta.DFExperimental
|
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.NameToken
|
import hep.dataforge.names.NameToken
|
||||||
import hep.dataforge.names.asName
|
|
||||||
import hep.dataforge.vision.*
|
import hep.dataforge.vision.*
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.Serializer
|
|
||||||
import kotlinx.serialization.UseSerializers
|
|
||||||
import kotlinx.serialization.json.Json
|
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
|
|
||||||
public interface PrototypeHolder {
|
public interface PrototypeHolder {
|
||||||
@ -25,7 +21,7 @@ public interface PrototypeHolder {
|
|||||||
@SerialName("group.solid")
|
@SerialName("group.solid")
|
||||||
public class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder {
|
public class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder {
|
||||||
|
|
||||||
override var styleSheet: StyleSheet? = null
|
override val descriptor: NodeDescriptor get() = Solid.descriptor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A container for templates visible inside this group
|
* A container for templates visible inside this group
|
||||||
@ -44,9 +40,6 @@ public class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder {
|
|||||||
}).run(builder)
|
}).run(builder)
|
||||||
}
|
}
|
||||||
|
|
||||||
//FIXME to be lifted to AbstractVisualGroup after https://github.com/Kotlin/kotlinx.serialization/issues/378 is fixed
|
|
||||||
override var properties: Config? = null
|
|
||||||
|
|
||||||
@Serializable(Point3DSerializer::class)
|
@Serializable(Point3DSerializer::class)
|
||||||
override var position: Point3D? = null
|
override var position: Point3D? = null
|
||||||
|
|
||||||
@ -111,12 +104,10 @@ public fun MutableVisionGroup.group(name: String, action: SolidGroup.() -> Unit
|
|||||||
* A special class which works as a holder for prototypes
|
* A special class which works as a holder for prototypes
|
||||||
*/
|
*/
|
||||||
internal class Prototypes(
|
internal class Prototypes(
|
||||||
override var children: MutableMap<NameToken, Vision> = LinkedHashMap()
|
override var children: MutableMap<NameToken, Vision> = LinkedHashMap(),
|
||||||
) : AbstractVisionGroup(), MutableVisionGroup, PrototypeHolder {
|
) : AbstractVisionGroup(), MutableVisionGroup, PrototypeHolder {
|
||||||
|
|
||||||
override var styleSheet: StyleSheet?
|
override fun styleSheet(block: StyleSheet.() -> Unit) {
|
||||||
get() = null
|
|
||||||
set(_) {
|
|
||||||
error("Can't define stylesheet for prototypes block")
|
error("Can't define stylesheet for prototypes block")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,8 @@
|
|||||||
package hep.dataforge.vision.solid
|
package hep.dataforge.vision.solid
|
||||||
|
|
||||||
import hep.dataforge.meta.DFExperimental
|
|
||||||
import hep.dataforge.meta.double
|
|
||||||
import hep.dataforge.meta.transformations.MetaConverter.Companion.double
|
|
||||||
import hep.dataforge.names.NameToken
|
import hep.dataforge.names.NameToken
|
||||||
import hep.dataforge.vision.MutableVisionGroup
|
import hep.dataforge.vision.MutableVisionGroup
|
||||||
import hep.dataforge.vision.Vision
|
import hep.dataforge.vision.Vision
|
||||||
import hep.dataforge.vision.VisionGroup
|
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.builtins.MapSerializer
|
import kotlinx.serialization.builtins.MapSerializer
|
||||||
import kotlinx.serialization.builtins.nullable
|
import kotlinx.serialization.builtins.nullable
|
||||||
@ -18,7 +14,6 @@ import kotlinx.serialization.encoding.*
|
|||||||
|
|
||||||
|
|
||||||
@OptIn(ExperimentalSerializationApi::class)
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
@Serializer(Point3D::class)
|
|
||||||
public object Point3DSerializer : KSerializer<Point3D> {
|
public object Point3DSerializer : KSerializer<Point3D> {
|
||||||
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("hep.dataforge.vis.spatial.Point3D") {
|
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("hep.dataforge.vis.spatial.Point3D") {
|
||||||
element<Double>("x")
|
element<Double>("x")
|
||||||
@ -54,7 +49,6 @@ public object Point3DSerializer : KSerializer<Point3D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalSerializationApi::class)
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
@Serializer(Point2D::class)
|
|
||||||
public object Point2DSerializer : KSerializer<Point2D> {
|
public object Point2DSerializer : KSerializer<Point2D> {
|
||||||
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("hep.dataforge.vis.spatial.Point2D") {
|
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("hep.dataforge.vis.spatial.Point2D") {
|
||||||
element<Double>("x")
|
element<Double>("x")
|
||||||
@ -85,8 +79,6 @@ public object Point2DSerializer : KSerializer<Point2D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalSerializationApi::class)
|
|
||||||
@Serializer(MutableVisionGroup::class)
|
|
||||||
internal object PrototypesSerializer : KSerializer<MutableVisionGroup> {
|
internal object PrototypesSerializer : KSerializer<MutableVisionGroup> {
|
||||||
|
|
||||||
private val mapSerializer: KSerializer<Map<NameToken, Vision>> =
|
private val mapSerializer: KSerializer<Map<NameToken, Vision>> =
|
||||||
|
Loading…
Reference in New Issue
Block a user