forked from kscience/visionforge
Cleanup groups
This commit is contained in:
parent
e19ec02ff3
commit
ca985a6a66
@ -11,8 +11,7 @@ import kotlinx.serialization.Transient
|
||||
/**
|
||||
* Abstract implementation of mutable group of [VisualObject]
|
||||
*/
|
||||
abstract class AbstractVisualGroup : AbstractVisualObject(),
|
||||
MutableVisualGroup {
|
||||
abstract class AbstractVisualGroup : AbstractVisualObject(), MutableVisualGroup {
|
||||
|
||||
//protected abstract val _children: MutableMap<NameToken, T>
|
||||
|
||||
@ -21,6 +20,17 @@ abstract class AbstractVisualGroup : AbstractVisualObject(),
|
||||
*/
|
||||
abstract override val children: Map<NameToken, VisualObject>
|
||||
|
||||
abstract override var styleSheet: StyleSheet?
|
||||
protected set
|
||||
|
||||
/**
|
||||
* Update or create stylesheet
|
||||
*/
|
||||
fun styleSheet(block: StyleSheet.() -> Unit) {
|
||||
val res = styleSheet ?: StyleSheet(this).also { styleSheet = it }
|
||||
res.block()
|
||||
}
|
||||
|
||||
override fun propertyChanged(name: Name, before: MetaItem<*>?, after: MetaItem<*>?) {
|
||||
super.propertyChanged(name, before, after)
|
||||
forEach {
|
||||
|
@ -0,0 +1,31 @@
|
||||
package hep.dataforge.vis
|
||||
|
||||
import hep.dataforge.meta.Config
|
||||
import hep.dataforge.names.NameToken
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
|
||||
@Serializable
|
||||
@SerialName("group")
|
||||
class SimpleVisualGroup : AbstractVisualGroup() {
|
||||
|
||||
override var styleSheet: StyleSheet? = null
|
||||
|
||||
//FIXME to be lifted to AbstractVisualGroup after https://github.com/Kotlin/kotlinx.serialization/issues/378 is fixed
|
||||
override var properties: Config? = null
|
||||
|
||||
@SerialName("children")
|
||||
private val _children = HashMap<NameToken, VisualObject>()
|
||||
override val children: Map<NameToken, VisualObject> get() = _children
|
||||
|
||||
override fun removeChild(token: NameToken) {
|
||||
_children.remove(token)?.apply { parent = null }
|
||||
}
|
||||
|
||||
override fun setChild(token: NameToken, child: VisualObject) {
|
||||
_children[token] = child
|
||||
}
|
||||
|
||||
override fun createGroup(): SimpleVisualGroup = SimpleVisualGroup()
|
||||
}
|
@ -9,6 +9,7 @@ import hep.dataforge.names.asName
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.provider.Type
|
||||
import hep.dataforge.vis.VisualObject.Companion.TYPE
|
||||
import kotlinx.serialization.PolymorphicSerializer
|
||||
import kotlinx.serialization.Transient
|
||||
|
||||
//private fun Laminate.withTop(meta: Meta): Laminate = Laminate(listOf(meta) + layers)
|
||||
@ -64,6 +65,10 @@ interface VisualObject : Configurable {
|
||||
const val TYPE = "visual"
|
||||
val STYLE_KEY = "@style".asName()
|
||||
|
||||
private val VISUAL_OBJECT_SERIALIZER = PolymorphicSerializer(VisualObject::class)
|
||||
|
||||
fun serializer() = VISUAL_OBJECT_SERIALIZER
|
||||
|
||||
//const val META_KEY = "@meta"
|
||||
//const val TAGS_KEY = "@tags"
|
||||
|
||||
|
@ -154,11 +154,10 @@ val VisualObject.prototype: VisualObject
|
||||
/**
|
||||
* Create ref for existing prototype
|
||||
*/
|
||||
inline fun VisualGroup3D.ref(
|
||||
fun VisualGroup3D.ref(
|
||||
templateName: Name,
|
||||
name: String = "",
|
||||
block: Proxy.() -> Unit = {}
|
||||
) = Proxy(this, templateName).apply(block).also { set(name, it) }
|
||||
name: String = ""
|
||||
): Proxy = Proxy(this, templateName).also { set(name, it) }
|
||||
|
||||
/**
|
||||
* Add new proxy wrapping given object and automatically adding it to the prototypes
|
||||
@ -166,8 +165,7 @@ inline fun VisualGroup3D.ref(
|
||||
fun VisualGroup3D.proxy(
|
||||
name: String,
|
||||
obj: VisualObject3D,
|
||||
templateName: Name = name.toName(),
|
||||
block: Proxy.() -> Unit = {}
|
||||
templateName: Name = name.toName()
|
||||
): Proxy {
|
||||
val existing = getPrototype(templateName)
|
||||
if (existing == null) {
|
||||
@ -177,5 +175,14 @@ fun VisualGroup3D.proxy(
|
||||
} else if (existing != obj) {
|
||||
error("Can't add different prototype on top of existing one")
|
||||
}
|
||||
return ref(templateName, name, block)
|
||||
return ref(templateName, name)
|
||||
}
|
||||
|
||||
fun VisualGroup3D.proxyGroup(
|
||||
name: String,
|
||||
templateName: Name = name.toName(),
|
||||
block: MutableVisualGroup.() -> Unit
|
||||
): Proxy {
|
||||
val group = VisualGroup3D().apply(block)
|
||||
return proxy(name, group, templateName)
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import hep.dataforge.context.PluginTag
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.vis.SimpleVisualGroup
|
||||
import hep.dataforge.vis.Visual
|
||||
import hep.dataforge.vis.VisualObject
|
||||
import kotlinx.serialization.json.Json
|
||||
@ -38,23 +39,26 @@ class Visual3D(meta: Meta) : AbstractPlugin(meta) {
|
||||
contextual(Point2DSerializer)
|
||||
|
||||
polymorphic(VisualObject::class, VisualObject3D::class) {
|
||||
VisualGroup3D::class with VisualGroup3D.serializer()
|
||||
Proxy::class with Proxy.serializer()
|
||||
Composite::class with Composite.serializer()
|
||||
Tube::class with Tube.serializer()
|
||||
Box::class with Box.serializer()
|
||||
Convex::class with Convex.serializer()
|
||||
Extruded::class with Extruded.serializer()
|
||||
subclass(SimpleVisualGroup.serializer())
|
||||
subclass(VisualGroup3D.serializer())
|
||||
subclass(Proxy.serializer())
|
||||
subclass(Composite.serializer())
|
||||
subclass(Tube.serializer())
|
||||
subclass(Box.serializer())
|
||||
subclass(Convex.serializer())
|
||||
subclass(Extruded.serializer())
|
||||
subclass(PolyLine.serializer())
|
||||
subclass(Label3D.serializer())
|
||||
subclass(Sphere.serializer())
|
||||
}
|
||||
}
|
||||
|
||||
val json = Json(
|
||||
internal val json = Json(
|
||||
JsonConfiguration(
|
||||
prettyPrint = true,
|
||||
useArrayPolymorphism = false,
|
||||
encodeDefaults = false
|
||||
encodeDefaults = false,
|
||||
ignoreUnknownKeys = true
|
||||
),
|
||||
context = serialModule
|
||||
)
|
||||
|
@ -27,7 +27,6 @@ interface PrototypeHolder {
|
||||
class VisualGroup3D : AbstractVisualGroup(), VisualObject3D, PrototypeHolder {
|
||||
|
||||
override var styleSheet: StyleSheet? = null
|
||||
private set
|
||||
|
||||
/**
|
||||
* A container for templates visible inside this group
|
||||
@ -63,14 +62,6 @@ class VisualGroup3D : AbstractVisualGroup(), VisualObject3D, PrototypeHolder {
|
||||
super.attachChildren()
|
||||
}
|
||||
|
||||
/**
|
||||
* Update or create stylesheet
|
||||
*/
|
||||
fun styleSheet(block: StyleSheet.() -> Unit) {
|
||||
val res = styleSheet ?: StyleSheet(this).also { styleSheet = it }
|
||||
res.block()
|
||||
}
|
||||
|
||||
override fun removeChild(token: NameToken) {
|
||||
_children.remove(token)?.apply { parent = null }
|
||||
}
|
||||
@ -86,20 +77,6 @@ class VisualGroup3D : AbstractVisualGroup(), VisualObject3D, PrototypeHolder {
|
||||
|
||||
override fun createGroup(): VisualGroup3D = VisualGroup3D()
|
||||
|
||||
// return when {
|
||||
// name.isEmpty() -> error("Should be unreachable")
|
||||
// name.length == 1 -> {
|
||||
// val token = name.first()!!
|
||||
// when (val current = children[token]) {
|
||||
// null -> VisualGroup3D().also { setChild(token, it) }
|
||||
// is VisualGroup3D -> current
|
||||
// else -> error("Can't create group with name $name because it exists and not a group")
|
||||
// }
|
||||
// }
|
||||
// else -> createGroup(name.first()!!.asName()).createGroup(name.cutFirst())
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
companion object {
|
||||
// val PROTOTYPES_KEY = NameToken("@prototypes")
|
||||
@ -109,8 +86,6 @@ class VisualGroup3D : AbstractVisualGroup(), VisualObject3D, PrototypeHolder {
|
||||
}
|
||||
}
|
||||
|
||||
fun VisualGroup3D.stringify(): String = Visual3D.json.stringify(VisualGroup3D.serializer(),this)
|
||||
|
||||
/**
|
||||
* Ger a prototype redirecting the request to the parent if prototype is not found
|
||||
*/
|
||||
@ -129,7 +104,11 @@ internal class Prototypes(
|
||||
override var children: MutableMap<NameToken, VisualObject> = LinkedHashMap()
|
||||
) : AbstractVisualGroup(), MutableVisualGroup, PrototypeHolder {
|
||||
|
||||
override val styleSheet: StyleSheet? get() = null
|
||||
override var styleSheet: StyleSheet?
|
||||
get() = null
|
||||
set(value) {
|
||||
error("Can't define stylesheet for prototypes block")
|
||||
}
|
||||
|
||||
override fun removeChild(token: NameToken) {
|
||||
children.remove(token)
|
||||
@ -140,9 +119,13 @@ internal class Prototypes(
|
||||
children[token] = child
|
||||
}
|
||||
|
||||
override fun createGroup(): Prototypes = Prototypes()
|
||||
override fun createGroup() = SimpleVisualGroup()
|
||||
|
||||
override var properties: Config? = null
|
||||
override var properties: Config?
|
||||
get() = null
|
||||
set(value) {
|
||||
error("Can't define properties for prototypes block")
|
||||
}
|
||||
|
||||
override val prototypes: MutableVisualGroup get() = this
|
||||
|
||||
|
@ -3,6 +3,7 @@ package hep.dataforge.vis.spatial
|
||||
import hep.dataforge.meta.double
|
||||
import hep.dataforge.names.NameToken
|
||||
import hep.dataforge.vis.MutableVisualGroup
|
||||
import hep.dataforge.vis.VisualGroup
|
||||
import hep.dataforge.vis.VisualObject
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.builtins.MapSerializer
|
||||
@ -98,11 +99,13 @@ object Point2DSerializer : KSerializer<Point2D> {
|
||||
|
||||
@Serializer(MutableVisualGroup::class)
|
||||
internal object PrototypesSerializer : KSerializer<MutableVisualGroup> {
|
||||
|
||||
private val mapSerializer: KSerializer<Map<NameToken, VisualObject>> =
|
||||
MapSerializer(
|
||||
NameToken.serializer(),
|
||||
PolymorphicSerializer(VisualObject::class)
|
||||
VisualObject.serializer()
|
||||
)
|
||||
|
||||
override val descriptor: SerialDescriptor get() = mapSerializer.descriptor
|
||||
|
||||
override fun deserialize(decoder: Decoder): MutableVisualGroup {
|
||||
@ -113,6 +116,12 @@ internal object PrototypesSerializer : KSerializer<MutableVisualGroup> {
|
||||
override fun serialize(encoder: Encoder, value: MutableVisualGroup) {
|
||||
mapSerializer.serialize(encoder, value.children)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
fun VisualObject.stringify(): String = Visual3D.json.stringify(VisualObject.serializer(), this)
|
||||
|
||||
fun VisualObject.Companion.parseJson(str: String) = Visual3D.json.parse(VisualObject.serializer(), str).also {
|
||||
if(it is VisualGroup){
|
||||
it.attachChildren()
|
||||
}
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.vis.VisualObject
|
||||
import hep.dataforge.vis.get
|
||||
import hep.dataforge.vis.spatial.Visual3D.Companion.json
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@ -13,9 +14,9 @@ class SerializationTest {
|
||||
x = 100
|
||||
z = -100
|
||||
}
|
||||
val string = json.stringify(Box.serializer(), cube)
|
||||
val string = cube.stringify()
|
||||
println(string)
|
||||
val newCube = json.parse(Box.serializer(), string)
|
||||
val newCube = VisualObject.parseJson(string)
|
||||
assertEquals(cube.config, newCube.config)
|
||||
}
|
||||
|
||||
@ -26,9 +27,13 @@ class SerializationTest {
|
||||
x = 100
|
||||
z = -100
|
||||
}
|
||||
|
||||
val group = VisualGroup3D().apply {
|
||||
proxy("cube", cube)
|
||||
proxyGroup("pg", "pg.content".toName()){
|
||||
sphere(50){
|
||||
x = -100
|
||||
}
|
||||
}
|
||||
}
|
||||
val string = group.stringify()
|
||||
println(string)
|
||||
|
Loading…
Reference in New Issue
Block a user