forked from kscience/visionforge
Refactor server API
This commit is contained in:
parent
fef1df3ab4
commit
d28873e796
@ -31,7 +31,7 @@ fun main() {
|
||||
|
||||
val form = VisionOfHtmlForm("form").apply {
|
||||
onPropertyChange(visionManager.context) {
|
||||
println(this)
|
||||
println(values)
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,7 +71,7 @@ fun main() {
|
||||
value = "Submit"
|
||||
}
|
||||
}
|
||||
|
||||
println(form.values)
|
||||
vision(form)
|
||||
}
|
||||
|
||||
|
@ -55,6 +55,8 @@ public class VisionChangeBuilder : MutableVisionContainer<Vision> {
|
||||
private var propertyChange = MutableMeta()
|
||||
private val children: HashMap<Name, VisionChangeBuilder> = HashMap()
|
||||
|
||||
public operator fun get(name: Name): VisionChangeBuilder? = children[name]
|
||||
|
||||
public fun isEmpty(): Boolean = propertyChange.isEmpty() && propertyChange.isEmpty() && children.isEmpty()
|
||||
|
||||
@Synchronized
|
||||
@ -153,7 +155,7 @@ private fun CoroutineScope.collectChange(
|
||||
*/
|
||||
public fun Vision.flowChanges(
|
||||
collectionDuration: Duration,
|
||||
sendInitial: Boolean = false
|
||||
sendInitial: Boolean = false,
|
||||
): Flow<VisionChange> = flow {
|
||||
val manager = manager ?: error("Orphan vision could not collect changes")
|
||||
coroutineScope {
|
||||
@ -161,7 +163,7 @@ public fun Vision.flowChanges(
|
||||
val mutex = Mutex()
|
||||
collectChange(Name.EMPTY, this@flowChanges, mutex, collector)
|
||||
|
||||
if(sendInitial) {
|
||||
if (sendInitial) {
|
||||
//Send initial vision state
|
||||
val initialChange = VisionChange(vision = deepCopy(manager))
|
||||
emit(initialChange)
|
||||
|
@ -69,9 +69,9 @@ public class VisionClient : AbstractPlugin() {
|
||||
changeCollector.propertyChanged(visionName, propertyName, item)
|
||||
}
|
||||
|
||||
public fun visionChanged(name: Name?, child: Vision?) {
|
||||
changeCollector.setChild(name, child)
|
||||
}
|
||||
// public fun visionChanged(name: Name?, child: Vision?) {
|
||||
// changeCollector.setChild(name, child)
|
||||
// }
|
||||
|
||||
private fun renderVision(element: Element, name: Name, vision: Vision, outputMeta: Meta) {
|
||||
vision.setAsRoot(visionManager)
|
||||
@ -79,7 +79,7 @@ public class VisionClient : AbstractPlugin() {
|
||||
renderer.render(element, name, vision, outputMeta)
|
||||
}
|
||||
|
||||
private fun updateVision(element: Element, name: Name, vision: Vision?, outputMeta: Meta) {
|
||||
private fun startVisionUpdate(element: Element, name: Name, vision: Vision?, outputMeta: Meta) {
|
||||
element.attributes[OUTPUT_CONNECT_ATTRIBUTE]?.let { attr ->
|
||||
val wsUrl = if (attr.value.isBlank() || attr.value == VisionTagConsumer.AUTO_DATA_ATTRIBUTE) {
|
||||
val endpoint = resolveEndpoint(element)
|
||||
@ -130,9 +130,10 @@ public class VisionClient : AbstractPlugin() {
|
||||
feedbackJob = visionManager.context.launch {
|
||||
while (isActive) {
|
||||
delay(feedbackAggregationTime.milliseconds)
|
||||
if (!changeCollector.isEmpty()) {
|
||||
send(visionManager.encodeToString(changeCollector.deepCopy(visionManager)))
|
||||
changeCollector.reset()
|
||||
val change = changeCollector[name] ?: continue
|
||||
if (!change.isEmpty()) {
|
||||
send(visionManager.encodeToString(change.deepCopy(visionManager)))
|
||||
change.reset()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -192,7 +193,7 @@ public class VisionClient : AbstractPlugin() {
|
||||
response.text().then { text ->
|
||||
val vision = visionManager.decodeFromString(text)
|
||||
renderVision(element, name, vision, outputMeta)
|
||||
updateVision(element, name, vision, outputMeta)
|
||||
startVisionUpdate(element, name, vision, outputMeta)
|
||||
}
|
||||
} else {
|
||||
logger.error { "Failed to fetch initial vision state from $fetchUrl" }
|
||||
@ -208,12 +209,12 @@ public class VisionClient : AbstractPlugin() {
|
||||
}
|
||||
logger.info { "Found embedded vision for output with name $name" }
|
||||
renderVision(element, name, embeddedVision, outputMeta)
|
||||
updateVision(element, name, embeddedVision, outputMeta)
|
||||
startVisionUpdate(element, name, embeddedVision, outputMeta)
|
||||
}
|
||||
|
||||
//Try to load vision via websocket
|
||||
element.attributes[OUTPUT_CONNECT_ATTRIBUTE] != null -> {
|
||||
updateVision(element, name, null, outputMeta)
|
||||
startVisionUpdate(element, name, null, outputMeta)
|
||||
}
|
||||
|
||||
else -> error("No embedded vision data / fetch url for $name")
|
||||
|
@ -93,12 +93,12 @@ public fun Application.serveVisionData(
|
||||
webSocket("ws") {
|
||||
val name: String = call.request.queryParameters.getOrFail("name")
|
||||
application.log.debug("Opened server socket for $name")
|
||||
val vision: Vision = resolveVision(Name.parse(name)) ?: error("Plot with id='$name' not registered")
|
||||
val vision: Vision = resolveVision(Name.parse(name)) ?: error("Vision with id='$name' not registered")
|
||||
|
||||
launch {
|
||||
for(frame in incoming) {
|
||||
val data = frame.data.decodeToString()
|
||||
application.log.debug("Received update: \n$data")
|
||||
application.log.debug("Received update for $name: \n$data")
|
||||
val change = configuration.visionManager.jsonFormat.decodeFromString(
|
||||
VisionChange.serializer(), data
|
||||
)
|
||||
@ -113,7 +113,7 @@ public fun Application.serveVisionData(
|
||||
VisionChange.serializer(),
|
||||
update
|
||||
)
|
||||
application.log.debug("Sending update: \n$json")
|
||||
application.log.debug("Sending update for $name: \n$json")
|
||||
outgoing.send(Frame.Text(json))
|
||||
}.collect()
|
||||
}
|
||||
@ -145,27 +145,6 @@ public fun Application.serveVisionData(
|
||||
data: Map<Name, Vision>,
|
||||
): Unit = serveVisionData(configuration) { data[it] }
|
||||
|
||||
//
|
||||
///**
|
||||
// * Compile a fragment to string and serve visions from it
|
||||
// */
|
||||
//public fun Route.serveVisionsFromFragment(
|
||||
// consumer: TagConsumer<*>,
|
||||
// sererPageUrl: Url,
|
||||
// visionManager: VisionManager,
|
||||
// fragment: HtmlVisionFragment,
|
||||
//): Unit {
|
||||
// val visions = consumer.visionFragment(
|
||||
// visionManager.context,
|
||||
// embedData = true,
|
||||
// fetchUpdatesUrl = "$serverUrl$route/ws",
|
||||
// fragment = fragment
|
||||
// )
|
||||
//
|
||||
// serveVisionData(visionManager, visions)
|
||||
//}
|
||||
|
||||
|
||||
/**
|
||||
* Serve a page, potentially containing any number of visions at a given [route] with given [header].
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user