forked from kscience/visionforge
Fix attachment of children on Vision deserialization
This commit is contained in:
parent
a85cd828e6
commit
face7bfd0c
@ -0,0 +1,17 @@
|
|||||||
|
package ru.mipt.npm.sat
|
||||||
|
|
||||||
|
import hep.dataforge.context.Global
|
||||||
|
import hep.dataforge.vision.solid.SolidManager
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class GeometrySerializationTest {
|
||||||
|
@Test
|
||||||
|
fun testSerialization(){
|
||||||
|
val geometry = visionOfSatellite()
|
||||||
|
val manager = Global.plugins.fetch(SolidManager)
|
||||||
|
val string = manager.visionManager.encodeToString(geometry)
|
||||||
|
val reconstructed = manager.visionManager.decodeFromString(string)
|
||||||
|
assertEquals(geometry.config,reconstructed.config)
|
||||||
|
}
|
||||||
|
}
|
@ -10,7 +10,6 @@ import hep.dataforge.provider.Type
|
|||||||
import hep.dataforge.values.asValue
|
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.Transient
|
import kotlinx.serialization.Transient
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -75,8 +74,6 @@ public interface Vision : Configurable, Described {
|
|||||||
public const val TYPE: String = "vision"
|
public const val TYPE: String = "vision"
|
||||||
public val STYLE_KEY: Name = "@style".asName()
|
public val STYLE_KEY: Name = "@style".asName()
|
||||||
|
|
||||||
public fun serializer(): PolymorphicSerializer<Vision> = PolymorphicSerializer(Vision::class)
|
|
||||||
|
|
||||||
public val VISIBLE_KEY: Name = "visible".asName()
|
public val VISIBLE_KEY: Name = "visible".asName()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ 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 kotlinx.serialization.PolymorphicSerializer
|
||||||
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
|
||||||
@ -24,17 +25,24 @@ public class VisionManager(meta: Meta) : AbstractPlugin(meta) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public val jsonFormat: Json
|
private val jsonFormat: Json
|
||||||
get() = Json(defaultJson) {
|
get() = Json(defaultJson) {
|
||||||
serializersModule = this@VisionManager.serializersModule
|
serializersModule = this@VisionManager.serializersModule
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun decodeFromString(string: String): Vision = jsonFormat.decodeFromString(Vision.serializer(), string)
|
public fun decodeFromString(string: String): Vision = jsonFormat.decodeFromString(visionSerializer, string).also {
|
||||||
public fun encodeToString(vision: Vision): String = jsonFormat.encodeToString(Vision.serializer(), vision)
|
(it as? VisionGroup)?.attachChildren()
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun encodeToString(vision: Vision): String = jsonFormat.encodeToString(visionSerializer, vision)
|
||||||
|
|
||||||
|
public fun decodeFromJson(json: JsonElement): Vision =
|
||||||
|
jsonFormat.decodeFromJsonElement(visionSerializer, json).also {
|
||||||
|
(it as? VisionGroup)?.attachChildren()
|
||||||
|
}
|
||||||
|
|
||||||
public fun decodeFromJson(json: JsonElement): Vision = jsonFormat.decodeFromJsonElement(Vision.serializer(), json)
|
|
||||||
public fun encodeToJsonElement(vision: Vision): JsonElement =
|
public fun encodeToJsonElement(vision: Vision): JsonElement =
|
||||||
jsonFormat.encodeToJsonElement(Vision.serializer(), vision)
|
jsonFormat.encodeToJsonElement(visionSerializer, vision)
|
||||||
|
|
||||||
//TODO remove double transformation with dedicated Meta serial format
|
//TODO remove double transformation with dedicated Meta serial format
|
||||||
public fun decodeFromMeta(meta: Meta, descriptor: NodeDescriptor? = null): Vision =
|
public fun decodeFromMeta(meta: Meta, descriptor: NodeDescriptor? = null): Vision =
|
||||||
@ -67,5 +75,7 @@ public class VisionManager(meta: Meta) : AbstractPlugin(meta) {
|
|||||||
encodeDefaults = false
|
encodeDefaults = false
|
||||||
ignoreUnknownKeys = true
|
ignoreUnknownKeys = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal val visionSerializer: PolymorphicSerializer<Vision> = PolymorphicSerializer(Vision::class)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,6 +5,7 @@ import hep.dataforge.meta.descriptors.NodeDescriptor
|
|||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.isEmpty
|
import hep.dataforge.names.isEmpty
|
||||||
import hep.dataforge.names.plus
|
import hep.dataforge.names.plus
|
||||||
|
import hep.dataforge.vision.VisionManager.Companion.visionSerializer
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.flow
|
import kotlinx.coroutines.flow.flow
|
||||||
@ -54,10 +55,13 @@ public abstract class EmptyVision : Vision {
|
|||||||
@SerialName("vision.null")
|
@SerialName("vision.null")
|
||||||
public object NullVision : EmptyVision()
|
public object NullVision : EmptyVision()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialization proxy is used to create immutable reference for a given vision
|
||||||
|
*/
|
||||||
@Serializable(VisionSerializationProxy.Companion::class)
|
@Serializable(VisionSerializationProxy.Companion::class)
|
||||||
private class VisionSerializationProxy(val ref: Vision) : EmptyVision() {
|
private class VisionSerializationProxy(val ref: Vision) : EmptyVision() {
|
||||||
companion object : KSerializer<VisionSerializationProxy> {
|
companion object : KSerializer<VisionSerializationProxy> {
|
||||||
override val descriptor: SerialDescriptor = Vision.serializer().descriptor
|
override val descriptor: SerialDescriptor = visionSerializer.descriptor
|
||||||
|
|
||||||
@OptIn(ExperimentalSerializationApi::class)
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
override fun serialize(encoder: Encoder, value: VisionSerializationProxy) {
|
override fun serialize(encoder: Encoder, value: VisionSerializationProxy) {
|
||||||
@ -67,7 +71,7 @@ private class VisionSerializationProxy(val ref: Vision) : EmptyVision() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun deserialize(decoder: Decoder): VisionSerializationProxy =
|
override fun deserialize(decoder: Decoder): VisionSerializationProxy =
|
||||||
VisionSerializationProxy(Vision.serializer().deserialize(decoder))
|
VisionSerializationProxy(visionSerializer.deserialize(decoder))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,14 +47,17 @@ public class VisionClient : AbstractPlugin() {
|
|||||||
if (!element.classList.contains(HtmlOutputScope.OUTPUT_CLASS)) error("The element $element is not an output element")
|
if (!element.classList.contains(HtmlOutputScope.OUTPUT_CLASS)) error("The element $element is not an output element")
|
||||||
val endpoint = resolveEndpoint(element)
|
val endpoint = resolveEndpoint(element)
|
||||||
console.info("Vision server is resolved to $endpoint")
|
console.info("Vision server is resolved to $endpoint")
|
||||||
|
|
||||||
val fetchUrl = URL(endpoint).apply {
|
val fetchUrl = URL(endpoint).apply {
|
||||||
searchParams.append("name", name)
|
searchParams.append("name", name)
|
||||||
pathname += "/vision"
|
pathname += "/vision"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.info("Fetching vision data from $fetchUrl")
|
||||||
window.fetch(fetchUrl).then { response ->
|
window.fetch(fetchUrl).then { response ->
|
||||||
if (response.ok) {
|
if (response.ok) {
|
||||||
response.text().then { text ->
|
response.text().then { text ->
|
||||||
val vision = visionManager.jsonFormat.decodeFromString(Vision.serializer(), text)
|
val vision = visionManager.decodeFromString(text)
|
||||||
|
|
||||||
val renderer = findRendererFor(vision) ?: error("Could nof find renderer for $vision")
|
val renderer = findRendererFor(vision) ?: error("Could nof find renderer for $vision")
|
||||||
renderer.render(element, vision)
|
renderer.render(element, vision)
|
||||||
@ -68,7 +71,7 @@ public class VisionClient : AbstractPlugin() {
|
|||||||
onmessage = { messageEvent ->
|
onmessage = { messageEvent ->
|
||||||
val stringData: String? = messageEvent.data as? String
|
val stringData: String? = messageEvent.data as? String
|
||||||
if (stringData != null) {
|
if (stringData != null) {
|
||||||
val update = visionManager.jsonFormat.decodeFromString(Vision.serializer(), text)
|
val update = visionManager.decodeFromString(text)
|
||||||
vision.update(update)
|
vision.update(update)
|
||||||
} else {
|
} else {
|
||||||
console.error("WebSocket message data is not a string")
|
console.error("WebSocket message data is not a string")
|
||||||
|
@ -130,7 +130,7 @@ public class VisionServer internal constructor(
|
|||||||
outgoing.send(Frame.Text(json))
|
outgoing.send(Frame.Text(json))
|
||||||
}
|
}
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
application.log.debug("Closed server socket for $name")
|
application.log.debug("Closed server socket for $name with exception $ex")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//Plots in their json representation
|
//Plots in their json representation
|
||||||
|
@ -6,6 +6,7 @@ import hep.dataforge.names.Name
|
|||||||
import hep.dataforge.names.NameToken
|
import hep.dataforge.names.NameToken
|
||||||
import hep.dataforge.vision.*
|
import hep.dataforge.vision.*
|
||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
|
import kotlinx.serialization.PolymorphicSerializer
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.builtins.MapSerializer
|
import kotlinx.serialization.builtins.MapSerializer
|
||||||
@ -126,7 +127,7 @@ internal class Prototypes(
|
|||||||
private val mapSerializer: KSerializer<Map<NameToken, Vision>> =
|
private val mapSerializer: KSerializer<Map<NameToken, Vision>> =
|
||||||
MapSerializer(
|
MapSerializer(
|
||||||
NameToken.serializer(),
|
NameToken.serializer(),
|
||||||
Vision.serializer()
|
PolymorphicSerializer(Vision::class)
|
||||||
)
|
)
|
||||||
|
|
||||||
override val descriptor: SerialDescriptor get() = mapSerializer.descriptor
|
override val descriptor: SerialDescriptor get() = mapSerializer.descriptor
|
||||||
|
@ -9,6 +9,7 @@ import hep.dataforge.names.Name
|
|||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
import hep.dataforge.vision.*
|
import hep.dataforge.vision.*
|
||||||
import hep.dataforge.vision.VisionManager.Companion.VISION_SERIALIZER_MODULE_TARGET
|
import hep.dataforge.vision.VisionManager.Companion.VISION_SERIALIZER_MODULE_TARGET
|
||||||
|
import kotlinx.serialization.PolymorphicSerializer
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.modules.PolymorphicModuleBuilder
|
import kotlinx.serialization.modules.PolymorphicModuleBuilder
|
||||||
import kotlinx.serialization.modules.SerializersModule
|
import kotlinx.serialization.modules.SerializersModule
|
||||||
@ -64,9 +65,9 @@ public class SolidManager(meta: Meta) : AbstractPlugin(meta) {
|
|||||||
serializersModule = serializersModuleForSolids
|
serializersModule = serializersModuleForSolids
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun encodeToString(solid: Solid): String = jsonForSolids.encodeToString(Vision.serializer(), solid)
|
internal fun encodeToString(solid: Solid): String = jsonForSolids.encodeToString(PolymorphicSerializer(Vision::class), solid)
|
||||||
|
|
||||||
public fun decodeFromString(str: String): Vision = jsonForSolids.decodeFromString(Vision.serializer(), str).also {
|
internal fun decodeFromString(str: String): Vision = jsonForSolids.decodeFromString(PolymorphicSerializer(Vision::class), str).also {
|
||||||
if(it is VisionGroup){
|
if(it is VisionGroup){
|
||||||
it.attachChildren()
|
it.attachChildren()
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user