Server is alive!

This commit is contained in:
Alexander Nozik 2020-12-09 19:06:17 +03:00
parent faddb8a393
commit 6a742658af
10 changed files with 45 additions and 36 deletions

View File

@ -2,7 +2,7 @@ plugins {
id("ru.mipt.npm.project")
}
val dataforgeVersion by extra("0.2.0")
val dataforgeVersion by extra("0.2.1-dev-4")
val ktorVersion by extra("1.4.2")
val htmlVersion by extra("0.7.2")
val kotlinWrappersVersion by extra("pre.129-kotlin-1.4.20")

View File

@ -3,8 +3,8 @@ package ru.mipt.npm.sat
import hep.dataforge.context.Global
import hep.dataforge.names.asName
import hep.dataforge.names.toName
import hep.dataforge.vision.VisionManager
import hep.dataforge.vision.get
import hep.dataforge.vision.server.close
import hep.dataforge.vision.server.serve
import hep.dataforge.vision.server.show
@ -40,11 +40,12 @@ fun main() {
vision("main".asName(), sat)
}
launch {
delay(1000)
while (isActive) {
val currentLayer = Random.nextInt(10)
(sat["layer[$currentLayer]"] as? Solid)?.color(123)
val target = "layer[${Random.nextInt(1,10)}].segment[${Random.nextInt(3)},${Random.nextInt(3)}]".toName()
(sat[target] as? Solid)?.color("red")
delay(300)
(sat["layer[$currentLayer]"] as? Solid)?.color = null
(sat[target] as? Solid)?.color = "green"
}
}
}

View File

@ -1,11 +1,11 @@
package hep.dataforge.vision
import hep.dataforge.meta.Meta
import hep.dataforge.meta.MetaItem
import hep.dataforge.meta.get
import hep.dataforge.meta.number
import hep.dataforge.values.ValueType
import hep.dataforge.values.int
import hep.dataforge.values.string
import kotlin.math.max
/**

View File

@ -3,10 +3,9 @@ package hep.dataforge.vision
import hep.dataforge.meta.*
import hep.dataforge.names.Name
import hep.dataforge.names.plus
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.serialization.*
@ -15,7 +14,7 @@ import kotlin.time.Duration
/**
* An update for a [Vision] or a [VisionGroup]
*/
public class VisionChangeBuilder: VisionContainerBuilder<Vision> {
public class VisionChangeBuilder : VisionContainerBuilder<Vision> {
private val propertyChange = HashMap<Name, Config>()
private val childrenChange = HashMap<Name, Vision?>()
@ -47,7 +46,8 @@ private fun Vision.isolate(manager: VisionManager): Vision {
@Serializable
public data class VisionChange(
val propertyChange: Map<Name, @Serializable(MetaSerializer::class) Meta>,
val childrenChange: Map<Name, Vision?>) {
val childrenChange: Map<Name, Vision?>,
) {
public fun isEmpty(): Boolean = propertyChange.isEmpty() && childrenChange.isEmpty()
/**
@ -64,7 +64,7 @@ private fun CoroutineScope.collectChange(
name: Name,
source: Vision,
mutex: Mutex,
collector: ()->VisionChangeBuilder,
collector: () -> VisionChangeBuilder,
) {
//Collect properties change
source.config.onChange(mutex) { propertyName, oldItem, newItem ->
@ -107,17 +107,19 @@ public fun Vision.flowChanges(
val mutex = Mutex()
var collector = VisionChangeBuilder()
scope.collectChange(Name.EMPTY, this@flowChanges, mutex){collector}
scope.collectChange(Name.EMPTY, this@flowChanges, mutex) { collector }
while (true) {
while (currentCoroutineContext().isActive) {
//Wait for changes to accumulate
kotlinx.coroutines.delay(collectionDuration)
delay(collectionDuration)
//Propagate updates only if something is changed
if (!collector.isEmpty()) {
//emit changes
emit(collector.isolate(manager))
//Reset the collector
collector = VisionChangeBuilder()
mutex.withLock {
emit(collector.isolate(manager))
//Reset the collector
collector = VisionChangeBuilder()
}
}
}
}

View File

@ -6,6 +6,7 @@ import hep.dataforge.names.asName
import hep.dataforge.values.Null
import hep.dataforge.values.Value
import hep.dataforge.values.asValue
import hep.dataforge.values.string
import javafx.scene.control.ColorPicker
import javafx.scene.paint.Color
import org.slf4j.LoggerFactory
@ -22,7 +23,7 @@ public class ColorValueChooser : ValueChooserBase<ColorPicker>() {
this.value = Color.valueOf(value.string)
}
} catch (ex: Exception) {
LoggerFactory.getLogger(javaClass).warn("Invalid color field value: " + value.string)
LoggerFactory.getLogger(javaClass).warn("Invalid color field value: $value")
}
}
}

View File

@ -12,6 +12,7 @@ import hep.dataforge.names.Name
import hep.dataforge.names.asName
import hep.dataforge.values.Value
import hep.dataforge.values.parseValue
import hep.dataforge.values.string
import javafx.collections.FXCollections
import javafx.scene.control.ComboBox
import javafx.util.StringConverter

View File

@ -17,6 +17,7 @@
package hep.dataforge.vision.editor
import hep.dataforge.meta.Meta
import hep.dataforge.values.string
import hep.dataforge.vision.dfIconView
import javafx.beans.property.SimpleStringProperty
import javafx.scene.control.TreeItem

View File

@ -5,38 +5,40 @@ import hep.dataforge.meta.double
import hep.dataforge.meta.get
import hep.dataforge.meta.int
import hep.dataforge.values.ValueType
import hep.dataforge.values.int
import hep.dataforge.values.string
import hep.dataforge.vision.Colors
import javafx.scene.paint.Color
import javafx.scene.paint.Material
import javafx.scene.paint.PhongMaterial
object FXMaterials {
val RED = PhongMaterial().apply {
public object FXMaterials {
public val RED: PhongMaterial = PhongMaterial().apply {
diffuseColor = Color.DARKRED
specularColor = Color.WHITE
}
val WHITE = PhongMaterial().apply {
public val WHITE: PhongMaterial = PhongMaterial().apply {
diffuseColor = Color.WHITE
specularColor = Color.LIGHTBLUE
}
val GREY = PhongMaterial().apply {
public val GREY: PhongMaterial = PhongMaterial().apply {
diffuseColor = Color.DARKGREY
specularColor = Color.WHITE
}
val BLUE = PhongMaterial(Color.BLUE)
public val BLUE: PhongMaterial = PhongMaterial(Color.BLUE)
}
/**
* Infer color based on meta item
* @param opacity default opacity
*/
fun MetaItem<*>.color(opacity: Double = 1.0): Color {
public fun MetaItem<*>.color(opacity: Double = 1.0): Color {
return when (this) {
is MetaItem.ValueItem -> if (this.value.type == ValueType.NUMBER) {
val int = value.number.toInt()
val int = value.int
val red = int and 0x00ff0000 shr 16
val green = int and 0x0000ff00 shr 8
val blue = int and 0x000000ff

View File

@ -37,7 +37,9 @@ import io.ktor.util.error
import io.ktor.websocket.WebSockets
import io.ktor.websocket.webSocket
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.html.*
import kotlinx.html.stream.createHTML
import java.awt.Desktop
@ -115,15 +117,12 @@ public class VisionServer internal constructor(
application.log.debug("Opened server socket for $name")
val vision: Vision = visions[name.toName()] ?: error("Plot with id='$name' not registered")
try {
vision.flowChanges(visionManager, updateInterval.milliseconds).collect { update ->
val json = VisionManager.defaultJson.encodeToString(VisionChange.serializer(), update)
outgoing.send(Frame.Text(json))
}
} catch (ex: Throwable) {
application.log.error("Closed server socket for $name with exception $ex")
vision.flowChanges(visionManager, updateInterval.milliseconds).onEach { update ->
val json = VisionManager.defaultJson.encodeToString(VisionChange.serializer(), update)
outgoing.send(Frame.Text(json))
}.catch { ex ->
application.log.error(ex)
}
}.launchIn(visionManager.context).join()
}
//Plots in their json representation
get("vision") {
@ -208,7 +207,7 @@ public fun Application.visionModule(context: Context, route: String = DEFAULT_PA
public fun VisionManager.serve(
host: String = "localhost",
port: Int = 7777,
block: VisionServer.()->Unit
block: VisionServer.() -> Unit,
): ApplicationEngine = context.embeddedServer(CIO, port, host) {
visionModule(context).apply(block)
}.start()

View File

@ -2,6 +2,8 @@ package hep.dataforge.vision.solid.three
import hep.dataforge.meta.*
import hep.dataforge.values.ValueType
import hep.dataforge.values.int
import hep.dataforge.values.string
import hep.dataforge.vision.Colors
import hep.dataforge.vision.Vision
import hep.dataforge.vision.solid.SolidMaterial
@ -90,7 +92,7 @@ public object ThreeMaterials {
public fun MetaItem<*>.getColor(): Color {
return when (this) {
is MetaItem.ValueItem -> if (this.value.type == ValueType.NUMBER) {
val int = value.number.toInt()
val int = value.int
Color(int)
} else {
Color(this.value.string)