Move all-things to Compose
This commit is contained in:
parent
381da970bf
commit
24b6856f15
@ -3,7 +3,6 @@ import space.kscience.gradle.useSPCTeam
|
||||
|
||||
plugins {
|
||||
id("space.kscience.gradle.project")
|
||||
alias(libs.plugins.versions)
|
||||
}
|
||||
|
||||
allprojects {
|
||||
|
@ -35,7 +35,7 @@ public class VirtualLimitSwitch(
|
||||
public val lockedState: DeviceState<Boolean>,
|
||||
) : DeviceBySpec<LimitSwitch>(LimitSwitch, context), LimitSwitch {
|
||||
|
||||
init {
|
||||
override suspend fun onStart() {
|
||||
lockedState.valueFlow.onEach {
|
||||
propertyChanged(LimitSwitch.locked, it)
|
||||
}.launchIn(this)
|
||||
|
@ -1,7 +1,6 @@
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
id("org.openjfx.javafxplugin") version "0.0.13"
|
||||
application
|
||||
alias(spclibs.plugins.compose)
|
||||
}
|
||||
|
||||
|
||||
@ -20,28 +19,46 @@ dependencies {
|
||||
implementation(projects.controlsOpcua)
|
||||
|
||||
implementation(spclibs.ktor.client.cio)
|
||||
implementation(libs.tornadofx)
|
||||
implementation(libs.plotlykt.server)
|
||||
// implementation("com.github.Ricky12Awesome:json-schema-serialization:0.6.6")
|
||||
|
||||
implementation(compose.runtime)
|
||||
implementation(compose.desktop.currentOs)
|
||||
implementation(compose.material3)
|
||||
// implementation("org.pushing-pixels:aurora-window:1.3.0")
|
||||
// implementation("org.pushing-pixels:aurora-component:1.3.0")
|
||||
// implementation("org.pushing-pixels:aurora-theming:1.3.0")
|
||||
|
||||
implementation(spclibs.logback.classic)
|
||||
}
|
||||
|
||||
kotlin{
|
||||
jvmToolchain(11)
|
||||
}
|
||||
|
||||
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
|
||||
kotlinOptions {
|
||||
freeCompilerArgs = freeCompilerArgs + listOf("-Xjvm-default=all", "-Xopt-in=kotlin.RequiresOptIn")
|
||||
jvmToolchain(17)
|
||||
compilerOptions {
|
||||
freeCompilerArgs.addAll("-Xjvm-default=all", "-Xopt-in=kotlin.RequiresOptIn")
|
||||
}
|
||||
}
|
||||
|
||||
javafx {
|
||||
version = "17"
|
||||
modules("javafx.controls")
|
||||
}
|
||||
|
||||
application {
|
||||
mainClass.set("space.kscience.controls.demo.DemoControllerViewKt")
|
||||
compose{
|
||||
desktop{
|
||||
application{
|
||||
mainClass = "space.kscience.controls.demo.DemoControllerViewKt"
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
//
|
||||
//tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
|
||||
// kotlinOptions {
|
||||
// freeCompilerArgs = freeCompilerArgs + listOf("-Xjvm-default=all", "-Xopt-in=kotlin.RequiresOptIn")
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//javafx {
|
||||
// version = "17"
|
||||
// modules("javafx.controls")
|
||||
//}
|
||||
//
|
||||
//application {
|
||||
// mainClass.set("space.kscience.controls.demo.DemoControllerViewKt")
|
||||
//}
|
@ -1,14 +1,19 @@
|
||||
package space.kscience.controls.demo
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.application
|
||||
import androidx.compose.ui.window.rememberWindowState
|
||||
import io.ktor.server.engine.ApplicationEngine
|
||||
import javafx.scene.Parent
|
||||
import javafx.scene.control.Slider
|
||||
import javafx.scene.layout.Priority
|
||||
import javafx.stage.Stage
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.serialization.json.Json
|
||||
import org.eclipse.milo.opcua.sdk.server.OpcUaServer
|
||||
import org.eclipse.milo.opcua.stack.core.types.builtin.LocalizedText
|
||||
@ -17,9 +22,6 @@ import space.kscience.controls.api.GetDescriptionMessage
|
||||
import space.kscience.controls.api.PropertyChangedMessage
|
||||
import space.kscience.controls.client.launchMagixService
|
||||
import space.kscience.controls.client.magixFormat
|
||||
import space.kscience.controls.demo.DemoDevice.Companion.cosScale
|
||||
import space.kscience.controls.demo.DemoDevice.Companion.sinScale
|
||||
import space.kscience.controls.demo.DemoDevice.Companion.timeScale
|
||||
import space.kscience.controls.manager.DeviceManager
|
||||
import space.kscience.controls.manager.install
|
||||
import space.kscience.controls.opcua.server.OpcUaServer
|
||||
@ -35,16 +37,15 @@ import space.kscience.magix.rsocket.rSocketWithWebSockets
|
||||
import space.kscience.magix.server.RSocketMagixFlowPlugin
|
||||
import space.kscience.magix.server.startMagixServer
|
||||
import space.kscince.magix.zmq.ZmqMagixFlowPlugin
|
||||
import tornadofx.*
|
||||
import java.awt.Desktop
|
||||
import java.net.URI
|
||||
|
||||
class DemoController : Controller(), ContextAware {
|
||||
class DemoController : ContextAware {
|
||||
|
||||
var device: DemoDevice? = null
|
||||
var magixServer: ApplicationEngine? = null
|
||||
var visualizer: ApplicationEngine? = null
|
||||
var opcUaServer: OpcUaServer = OpcUaServer {
|
||||
val opcUaServer: OpcUaServer = OpcUaServer {
|
||||
setApplicationName(LocalizedText.english("space.kscience.controls.opcua"))
|
||||
|
||||
endpoint {
|
||||
@ -60,39 +61,37 @@ class DemoController : Controller(), ContextAware {
|
||||
private val deviceManager = context.request(DeviceManager)
|
||||
|
||||
|
||||
fun init() {
|
||||
context.launch {
|
||||
device = deviceManager.install("demo", DemoDevice)
|
||||
//starting magix event loop
|
||||
magixServer = startMagixServer(
|
||||
RSocketMagixFlowPlugin(), //TCP rsocket support
|
||||
ZmqMagixFlowPlugin() //ZMQ support
|
||||
)
|
||||
//Launch a device client and connect it to the server
|
||||
val deviceEndpoint = MagixEndpoint.rSocketWithTcp("localhost")
|
||||
deviceManager.launchMagixService(deviceEndpoint)
|
||||
//connect visualization to a magix endpoint
|
||||
val visualEndpoint = MagixEndpoint.rSocketWithWebSockets("localhost")
|
||||
visualizer = startDemoDeviceServer(visualEndpoint)
|
||||
fun start(): Job = context.launch {
|
||||
device = deviceManager.install("demo", DemoDevice)
|
||||
//starting magix event loop
|
||||
magixServer = startMagixServer(
|
||||
RSocketMagixFlowPlugin(), //TCP rsocket support
|
||||
ZmqMagixFlowPlugin() //ZMQ support
|
||||
)
|
||||
//Launch a device client and connect it to the server
|
||||
val deviceEndpoint = MagixEndpoint.rSocketWithTcp("localhost")
|
||||
deviceManager.launchMagixService(deviceEndpoint)
|
||||
//connect visualization to a magix endpoint
|
||||
val visualEndpoint = MagixEndpoint.rSocketWithWebSockets("localhost")
|
||||
visualizer = startDemoDeviceServer(visualEndpoint)
|
||||
|
||||
//serve devices as OPC-UA namespace
|
||||
opcUaServer.startup()
|
||||
opcUaServer.serveDevices(deviceManager)
|
||||
//serve devices as OPC-UA namespace
|
||||
opcUaServer.startup()
|
||||
opcUaServer.serveDevices(deviceManager)
|
||||
|
||||
|
||||
val listenerEndpoint = MagixEndpoint.rSocketWithWebSockets("localhost")
|
||||
listenerEndpoint.subscribe(DeviceManager.magixFormat).onEach { (_, deviceMessage)->
|
||||
// print all messages that are not property change message
|
||||
if(deviceMessage !is PropertyChangedMessage){
|
||||
println(">> ${Json.encodeToString(DeviceMessage.serializer(), deviceMessage)}")
|
||||
}
|
||||
}.launchIn(this)
|
||||
listenerEndpoint.send(DeviceManager.magixFormat, GetDescriptionMessage(), "listener", "controls-kt")
|
||||
val listenerEndpoint = MagixEndpoint.rSocketWithWebSockets("localhost")
|
||||
listenerEndpoint.subscribe(DeviceManager.magixFormat).onEach { (_, deviceMessage) ->
|
||||
// print all messages that are not property change message
|
||||
if (deviceMessage !is PropertyChangedMessage) {
|
||||
println(">> ${Json.encodeToString(DeviceMessage.serializer(), deviceMessage)}")
|
||||
}
|
||||
}.launchIn(this)
|
||||
listenerEndpoint.send(DeviceManager.magixFormat, GetDescriptionMessage(), "listener", "controls-kt")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun shutdown() {
|
||||
fun shutdown(): Job = context.launch {
|
||||
logger.info { "Shutting down..." }
|
||||
opcUaServer.shutdown()
|
||||
logger.info { "OpcUa server stopped" }
|
||||
@ -102,92 +101,82 @@ class DemoController : Controller(), ContextAware {
|
||||
logger.info { "Magix server stopped" }
|
||||
device?.stop()
|
||||
logger.info { "Device server stopped" }
|
||||
context.close()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun DemoControls(controller: DemoController) {
|
||||
var timeScale by remember { mutableStateOf(5000f) }
|
||||
var xScale by remember { mutableStateOf(1f) }
|
||||
var yScale by remember { mutableStateOf(1f) }
|
||||
|
||||
Surface(Modifier.padding(5.dp)) {
|
||||
Column {
|
||||
Row(Modifier.fillMaxWidth()) {
|
||||
Text("Time Scale", modifier = Modifier.align(Alignment.CenterVertically).width(100.dp))
|
||||
TextField(String.format("%.2f", timeScale),{}, enabled = false, modifier = Modifier.align(Alignment.CenterVertically).width(100.dp))
|
||||
Slider(timeScale, onValueChange = { timeScale = it }, steps = 20, valueRange = 1000f..5000f)
|
||||
}
|
||||
Row(Modifier.fillMaxWidth()) {
|
||||
Text("X scale", modifier = Modifier.align(Alignment.CenterVertically).width(100.dp))
|
||||
TextField(String.format("%.2f", xScale),{}, enabled = false, modifier = Modifier.align(Alignment.CenterVertically).width(100.dp))
|
||||
Slider(xScale, onValueChange = { xScale = it }, steps = 20, valueRange = 0.1f..2.0f)
|
||||
}
|
||||
Row(Modifier.fillMaxWidth()) {
|
||||
Text("Y scale", modifier = Modifier.align(Alignment.CenterVertically).width(100.dp))
|
||||
TextField(String.format("%.2f", yScale),{}, enabled = false, modifier = Modifier.align(Alignment.CenterVertically).width(100.dp))
|
||||
Slider(yScale, onValueChange = { yScale = it }, steps = 20, valueRange = 0.1f..2.0f)
|
||||
}
|
||||
Row(Modifier.fillMaxWidth()) {
|
||||
Button(
|
||||
onClick = {
|
||||
controller.device?.run {
|
||||
launch {
|
||||
write(DemoDevice.timeScale, timeScale.toDouble())
|
||||
write(DemoDevice.sinScale, xScale.toDouble())
|
||||
write(DemoDevice.cosScale, yScale.toDouble())
|
||||
}
|
||||
}
|
||||
},
|
||||
Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text("Submit")
|
||||
}
|
||||
}
|
||||
Row(Modifier.fillMaxWidth()) {
|
||||
Button(
|
||||
onClick = {
|
||||
controller.visualizer?.run {
|
||||
val host = "localhost"//environment.connectors.first().host
|
||||
val port = environment.connectors.first().port
|
||||
val uri = URI("http", null, host, port, "/", null, null)
|
||||
Desktop.getDesktop().browse(uri)
|
||||
}
|
||||
},
|
||||
Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text("Show plots")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class DemoControllerView : View(title = " Demo controller remote") {
|
||||
private val controller: DemoController by inject()
|
||||
private var timeScaleSlider: Slider by singleAssign()
|
||||
private var xScaleSlider: Slider by singleAssign()
|
||||
private var yScaleSlider: Slider by singleAssign()
|
||||
fun main() = application {
|
||||
val controller = remember { DemoController().apply { start() } }
|
||||
|
||||
override val root: Parent = vbox {
|
||||
hbox {
|
||||
label("Time scale")
|
||||
pane {
|
||||
hgrow = Priority.ALWAYS
|
||||
}
|
||||
timeScaleSlider = slider(1000..10000, 5000) {
|
||||
isShowTickLabels = true
|
||||
isShowTickMarks = true
|
||||
}
|
||||
}
|
||||
hbox {
|
||||
label("X scale")
|
||||
pane {
|
||||
hgrow = Priority.ALWAYS
|
||||
}
|
||||
xScaleSlider = slider(0.1..2.0, 1.0) {
|
||||
isShowTickLabels = true
|
||||
isShowTickMarks = true
|
||||
}
|
||||
}
|
||||
hbox {
|
||||
label("Y scale")
|
||||
pane {
|
||||
hgrow = Priority.ALWAYS
|
||||
}
|
||||
yScaleSlider = slider(0.1..2.0, 1.0) {
|
||||
isShowTickLabels = true
|
||||
isShowTickMarks = true
|
||||
}
|
||||
}
|
||||
button("Submit") {
|
||||
useMaxWidth = true
|
||||
action {
|
||||
controller.device?.run {
|
||||
launch {
|
||||
write(timeScale, timeScaleSlider.value)
|
||||
write(sinScale, xScaleSlider.value)
|
||||
write(cosScale, yScaleSlider.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
button("Show plots") {
|
||||
useMaxWidth = true
|
||||
action {
|
||||
controller.visualizer?.run {
|
||||
val host = "localhost"//environment.connectors.first().host
|
||||
val port = environment.connectors.first().port
|
||||
val uri = URI("http", null, host, port, "/", null, null)
|
||||
Desktop.getDesktop().browse(uri)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class DemoControllerApp : App(DemoControllerView::class) {
|
||||
private val controller: DemoController by inject()
|
||||
|
||||
override fun start(stage: Stage) {
|
||||
super.start(stage)
|
||||
controller.init()
|
||||
}
|
||||
|
||||
override fun stop() {
|
||||
runBlocking {
|
||||
Window(
|
||||
title = "All things control",
|
||||
onCloseRequest = {
|
||||
controller.shutdown()
|
||||
exitApplication()
|
||||
},
|
||||
state = rememberWindowState(width = 400.dp, height = 300.dp)
|
||||
) {
|
||||
MaterialTheme {
|
||||
DemoControls(controller)
|
||||
}
|
||||
super.stop()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun main() {
|
||||
launch<DemoControllerApp>()
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
package space.kscience.controls.demo
|
||||
|
||||
//import com.github.ricky12awesome.jss.encodeToSchema
|
||||
//import com.github.ricky12awesome.jss.globalJson
|
||||
//import space.kscience.controls.api.DeviceMessage
|
||||
|
||||
//fun main() {
|
||||
// val schema = globalJson.encodeToSchema(DeviceMessage.serializer(), generateDefinitions = false)
|
||||
// println(schema)
|
||||
//}
|
@ -1,19 +1,11 @@
|
||||
plugins {
|
||||
id("space.kscience.gradle.jvm")
|
||||
application
|
||||
id("org.openjfx.javafxplugin")
|
||||
alias(spclibs.plugins.compose)
|
||||
}
|
||||
|
||||
//TODO to be moved to a separate project
|
||||
|
||||
javafx {
|
||||
version = "17"
|
||||
modules = listOf("javafx.controls")
|
||||
}
|
||||
|
||||
application{
|
||||
mainClass.set("ru.mipt.npm.devices.pimotionmaster.PiMotionMasterAppKt")
|
||||
}
|
||||
//application{
|
||||
// mainClass.set("ru.mipt.npm.devices.pimotionmaster.PiMotionMasterAppKt")
|
||||
//}
|
||||
|
||||
kotlin{
|
||||
explicitApi = null
|
||||
@ -25,5 +17,4 @@ val dataforgeVersion: String by extra
|
||||
dependencies {
|
||||
implementation(project(":controls-ports-ktor"))
|
||||
implementation(projects.controlsMagix)
|
||||
implementation(libs.tornadofx)
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ pluginManagement {
|
||||
id("space.kscience.gradle.mpp") version toolsVersion
|
||||
id("space.kscience.gradle.jvm") version toolsVersion
|
||||
id("space.kscience.gradle.js") version toolsVersion
|
||||
id("org.openjfx.javafxplugin") version "0.0.13"
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user