diff --git a/.gitignore b/.gitignore index 89cc712a..33607764 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,4 @@ out/ .gradle build/ - !gradle-wrapper.jar -gradle.properties \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index e69de29b..db566d2c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -0,0 +1,14 @@ +# Changelog + +## [Unreleased] +### Added + +### Changed + +### Deprecated + +### Removed + +### Fixed + +### Security diff --git a/build.gradle.kts b/build.gradle.kts index f2da0ea9..f2a94902 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,16 +1,12 @@ -import scientifik.useFx -import scientifik.useSerialization - -val dataforgeVersion by extra("0.1.8") +import ru.mipt.npm.gradle.useFx plugins { - id("scientifik.mpp") apply false - id("scientifik.jvm") apply false - id("scientifik.js") apply false - id("scientifik.publish") apply false - id("org.jetbrains.changelog") version "0.4.0" + id("ru.mipt.npm.project") } +val dataforgeVersion by extra("0.2.0-dev-3") +val ktorVersion by extra("1.4.1") + allprojects { repositories { mavenLocal() @@ -19,7 +15,7 @@ allprojects { } group = "hep.dataforge" - version = "0.1.5-dev-2" + version = "0.2.0-dev-1" } val githubProject by extra("visionforge") @@ -28,8 +24,17 @@ val fxVersion by extra("14") subprojects { if(name.startsWith("visionforge")) { - apply(plugin = "scientifik.publish") + apply() } - useSerialization() - useFx(scientifik.FXModule.CONTROLS, version = fxVersion) + afterEvaluate { + extensions.findByType()?.run { + useSerialization() + useFx(ru.mipt.npm.gradle.FXModule.CONTROLS, version = fxVersion) + } + } +} + +apiValidation { + validationDisabled = true + ignoredPackages.add("info.laht.threekt") } \ No newline at end of file diff --git a/demo/build.gradle.kts b/demo/build.gradle.kts deleted file mode 100644 index e69de29b..00000000 diff --git a/demo/gdml/build.gradle.kts b/demo/gdml/build.gradle.kts index 1ae0ffd9..b0a00e61 100644 --- a/demo/gdml/build.gradle.kts +++ b/demo/gdml/build.gradle.kts @@ -1,19 +1,24 @@ -import scientifik.DependencyConfiguration -import scientifik.FXModule -import scientifik.useFx +import ru.mipt.npm.gradle.DependencyConfiguration +import ru.mipt.npm.gradle.FXModule +import ru.mipt.npm.gradle.useFx plugins { - id("scientifik.mpp") - id("application") + id("ru.mipt.npm.mpp") + application } -val fxVersion: String by rootProject.extra -useFx(FXModule.CONTROLS, version = fxVersion, configuration = DependencyConfiguration.IMPLEMENTATION) +kscience { + val fxVersion: String by rootProject.extra + useFx(FXModule.CONTROLS, version = fxVersion, configuration = DependencyConfiguration.IMPLEMENTATION) + application() +} kotlin { jvm { - withJava() + afterEvaluate { + withJava() + } } js { @@ -27,7 +32,7 @@ kotlin { implementation(project(":visionforge-gdml")) } } - jsMain{ + jsMain { dependencies { implementation(project(":ui:bootstrap")) implementation(npm("react-file-drop", "3.0.6")) diff --git a/demo/gdml/src/commonMain/kotlin/hep/dataforge/vision/gdml/demo/cubes.kt b/demo/gdml/src/commonMain/kotlin/hep/dataforge/vision/gdml/demo/cubes.kt index 1f0b8cf9..e37ba142 100644 --- a/demo/gdml/src/commonMain/kotlin/hep/dataforge/vision/gdml/demo/cubes.kt +++ b/demo/gdml/src/commonMain/kotlin/hep/dataforge/vision/gdml/demo/cubes.kt @@ -1,6 +1,6 @@ package hep.dataforge.vision.gdml.demo -import scientifik.gdml.* +import kscience.gdml.* fun cubes(): GDML = GDML { diff --git a/demo/gdml/src/jsMain/kotlin/hep/dataforge/vision/gdml/demo/GDMLAppComponent.kt b/demo/gdml/src/jsMain/kotlin/hep/dataforge/vision/gdml/demo/GDMLAppComponent.kt index 9cd2c2bd..2392e042 100644 --- a/demo/gdml/src/jsMain/kotlin/hep/dataforge/vision/gdml/demo/GDMLAppComponent.kt +++ b/demo/gdml/src/jsMain/kotlin/hep/dataforge/vision/gdml/demo/GDMLAppComponent.kt @@ -1,7 +1,6 @@ package hep.dataforge.vision.gdml.demo import hep.dataforge.context.Context -import hep.dataforge.meta.set import hep.dataforge.names.Name import hep.dataforge.names.isEmpty import hep.dataforge.vision.Vision @@ -18,18 +17,18 @@ import hep.dataforge.vision.solid.specifications.Canvas3DOptions import hep.dataforge.vision.solid.three.ThreeCanvas import hep.dataforge.vision.solid.three.ThreeCanvasComponent import hep.dataforge.vision.solid.three.canvasControls +import kotlinx.browser.window import kotlinx.css.FlexBasis import kotlinx.css.Overflow import kotlinx.css.flex import kotlinx.css.overflow +import kscience.gdml.GDML +import kscience.gdml.decodeFromString import org.w3c.files.FileReader import org.w3c.files.get import react.RProps import react.dom.h1 -import scientifik.gdml.GDML -import scientifik.gdml.parse import styled.css -import kotlin.browser.window import kotlin.math.PI interface GDMLAppProps : RProps { @@ -58,10 +57,10 @@ val GDMLApp = component { props -> fun loadData(name: String, data: String) { val parsedVision = when { name.endsWith(".gdml") || name.endsWith(".xml") -> { - val gdml = GDML.parse(data) + val gdml = GDML.decodeFromString(data) gdml.toVision() } - name.endsWith(".json") -> SolidGroup.parseJson(data) + name.endsWith(".json") -> SolidGroup.decodeFromString(data) else -> { window.alert("File extension is not recognized: $name") error("File extension is not recognized: $name") diff --git a/demo/gdml/src/jsMain/kotlin/hep/dataforge/vision/gdml/demo/GdmlJsDemoApp.kt b/demo/gdml/src/jsMain/kotlin/hep/dataforge/vision/gdml/demo/GdmlJsDemoApp.kt index fc0478f0..cfb23cd5 100644 --- a/demo/gdml/src/jsMain/kotlin/hep/dataforge/vision/gdml/demo/GdmlJsDemoApp.kt +++ b/demo/gdml/src/jsMain/kotlin/hep/dataforge/vision/gdml/demo/GdmlJsDemoApp.kt @@ -3,15 +3,12 @@ package hep.dataforge.vision.gdml.demo import hep.dataforge.context.Global import hep.dataforge.js.Application import hep.dataforge.js.startApplication -import hep.dataforge.vision.gdml.GDMLTransformer -import hep.dataforge.vision.gdml.LUnit import hep.dataforge.vision.gdml.toVision -import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_OPACITY_KEY +import kotlinx.browser.document import kotlinx.css.* import react.child import react.dom.render import styled.injectGlobal -import kotlin.browser.document private class GDMLDemoApp : Application { diff --git a/demo/gdml/src/jsMain/resources/index.html b/demo/gdml/src/jsMain/resources/index.html index fb53883c..14bb3178 100644 --- a/demo/gdml/src/jsMain/resources/index.html +++ b/demo/gdml/src/jsMain/resources/index.html @@ -7,7 +7,7 @@ - + diff --git a/demo/gdml/src/jvmMain/kotlin/hep/dataforge/vision/gdml/demo/readFile.kt b/demo/gdml/src/jvmMain/kotlin/hep/dataforge/vision/gdml/demo/readFile.kt index 355d6f98..e4344795 100644 --- a/demo/gdml/src/jvmMain/kotlin/hep/dataforge/vision/gdml/demo/readFile.kt +++ b/demo/gdml/src/jvmMain/kotlin/hep/dataforge/vision/gdml/demo/readFile.kt @@ -3,13 +3,12 @@ package hep.dataforge.vision.gdml.demo import hep.dataforge.meta.DFExperimental import hep.dataforge.meta.setItem import hep.dataforge.values.asValue -import hep.dataforge.vision.gdml.LUnit import hep.dataforge.vision.gdml.readFile import hep.dataforge.vision.gdml.toVision import hep.dataforge.vision.solid.SolidGroup import hep.dataforge.vision.solid.SolidManager import hep.dataforge.vision.solid.SolidMaterial -import scientifik.gdml.GDML +import kscience.gdml.GDML import java.io.File import java.util.zip.GZIPInputStream import java.util.zip.ZipInputStream @@ -32,19 +31,19 @@ fun SolidManager.Companion.readFile(file: File): SolidGroup = when { // } } } - file.extension == "json" -> SolidGroup.parseJson(file.readText()) + file.extension == "json" -> SolidGroup.decodeFromString(file.readText()) file.name.endsWith("json.zip") -> { file.inputStream().use { val unzip = ZipInputStream(it, Charsets.UTF_8) val text = unzip.readBytes().decodeToString() - SolidGroup.parseJson(text) + SolidGroup.decodeFromString(text) } } file.name.endsWith("json.gz") -> { file.inputStream().use { val unzip = GZIPInputStream(it) val text = unzip.readBytes().decodeToString() - SolidGroup.parseJson(text) + SolidGroup.decodeFromString(text) } } else -> error("Unknown extension ${file.extension}") diff --git a/demo/gdml/src/jvmMain/kotlin/hep/dataforge/vision/gdml/demo/saveToJson.kt b/demo/gdml/src/jvmMain/kotlin/hep/dataforge/vision/gdml/demo/saveToJson.kt index 5c0c09c6..798fd8b7 100644 --- a/demo/gdml/src/jvmMain/kotlin/hep/dataforge/vision/gdml/demo/saveToJson.kt +++ b/demo/gdml/src/jvmMain/kotlin/hep/dataforge/vision/gdml/demo/saveToJson.kt @@ -1,10 +1,10 @@ package hep.dataforge.vision.gdml.demo -import hep.dataforge.vision.gdml.LUnit import hep.dataforge.vision.gdml.readFile import hep.dataforge.vision.gdml.toVision -import hep.dataforge.vision.solid.stringify -import scientifik.gdml.GDML +import hep.dataforge.vision.solid.encodeToString +import kscience.gdml.GDML +import kscience.gdml.LUnit import java.io.File import java.nio.file.Paths @@ -21,7 +21,7 @@ fun main(args: Array) { lUnit = LUnit.CM } - val json = visual.stringify() + val json = visual.encodeToString() println(json) File(outputFileName).writeText(json) //File("D:\\Work\\Projects\\gdml.kt\\gdml-source\\cubes.json").writeText(json) diff --git a/demo/gdml/src/jvmTest/kotlin/hep/dataforge/vision/solid/FileSerializationTest.kt b/demo/gdml/src/jvmTest/kotlin/hep/dataforge/vision/solid/FileSerializationTest.kt index e10acbee..a1f9bab9 100644 --- a/demo/gdml/src/jvmTest/kotlin/hep/dataforge/vision/solid/FileSerializationTest.kt +++ b/demo/gdml/src/jvmTest/kotlin/hep/dataforge/vision/solid/FileSerializationTest.kt @@ -9,7 +9,7 @@ class FileSerializationTest { @Ignore fun testFileRead(){ val text = this::class.java.getResourceAsStream("/cubes.json").readBytes().decodeToString() - val visual = SolidGroup.parseJson(text) + val visual = SolidGroup.decodeFromString(text) visual["composite_001".asName()] } } \ No newline at end of file diff --git a/demo/muon-monitor/build.gradle.kts b/demo/muon-monitor/build.gradle.kts index ccb4d098..f4ba471d 100644 --- a/demo/muon-monitor/build.gradle.kts +++ b/demo/muon-monitor/build.gradle.kts @@ -1,43 +1,38 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME -import scientifik.jsDistDirectory plugins { - id("scientifik.mpp") - id("application") + id("ru.mipt.npm.mpp") + application } group = "ru.mipt.npm" -val ktorVersion = "1.3.2" +val ktorVersion: String by rootProject.extra + +kscience { + application() +} kotlin { + afterEvaluate { + val jsBrowserDistribution by tasks.getting - val installJS = tasks.getByName("jsBrowserDistribution") - - js { - browser { - dceTask { - dceOptions { - keep("ktor-ktor-io.\$\$importsForInline\$\$.ktor-ktor-io.io.ktor.utils.io") + jvm { + withJava() + compilations[MAIN_COMPILATION_NAME]?.apply { + tasks.getByName(processResourcesTaskName) { + dependsOn(jsBrowserDistribution) + afterEvaluate { + from(jsBrowserDistribution) + } } } - webpackTask { - mode = org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig.Mode.PRODUCTION - } + } } - jvm { - withJava() - compilations[MAIN_COMPILATION_NAME]?.apply { - tasks.getByName(processResourcesTaskName) { - dependsOn(installJS) - afterEvaluate { - from(project.jsDistDirectory) - } - } - } - + js { + useCommonJs() } sourceSets { @@ -58,14 +53,6 @@ kotlin { implementation(project(":ui:bootstrap")) implementation("io.ktor:ktor-client-js:$ktorVersion") implementation("io.ktor:ktor-client-serialization-js:$ktorVersion") - implementation(npm("text-encoding")) - implementation(npm("abort-controller")) - implementation(npm("bufferutil")) - implementation(npm("utf-8-validate")) - implementation(npm("fs")) -// implementation(npm("jquery")) -// implementation(npm("popper.js")) -// implementation(npm("react-is")) } } } diff --git a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt index d08788c4..61deb655 100644 --- a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt +++ b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt @@ -4,6 +4,7 @@ import hep.dataforge.context.Context import hep.dataforge.names.Name import hep.dataforge.names.NameToken import hep.dataforge.names.isEmpty +import hep.dataforge.names.length import hep.dataforge.vision.Vision import hep.dataforge.vision.bootstrap.card import hep.dataforge.vision.react.component diff --git a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt index 3fc00667..f4f93495 100644 --- a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt +++ b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt @@ -7,11 +7,11 @@ import hep.dataforge.vision.solid.SolidManager import io.ktor.client.HttpClient import io.ktor.client.features.json.JsonFeature import io.ktor.client.features.json.serializer.KotlinxSerializer +import kotlinx.browser.document import kotlinx.serialization.json.Json import react.child import react.dom.div import react.dom.render -import kotlin.browser.document private class MMDemoApp : Application { @@ -19,7 +19,7 @@ private class MMDemoApp : Application { private val connection = HttpClient { install(JsonFeature) { - serializer = KotlinxSerializer(Json(context = SolidManager.serialModule)) + serializer = KotlinxSerializer(Json { serializersModule = SolidManager.serialModule }) } } @@ -34,8 +34,8 @@ private class MMDemoApp : Application { div("container-fluid h-100") { child(MMApp) { attrs { - model = this@MMDemoApp.model - connection = this@MMDemoApp.connection + this.model = this@MMDemoApp.model + this.connection = this@MMDemoApp.connection this.context = context } } diff --git a/demo/muon-monitor/src/jsMain/resources/index.html b/demo/muon-monitor/src/jsMain/resources/index.html index 13624f25..9044e628 100644 --- a/demo/muon-monitor/src/jsMain/resources/index.html +++ b/demo/muon-monitor/src/jsMain/resources/index.html @@ -6,7 +6,7 @@ Three js demo for particle physics - + diff --git a/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/server/MMServer.kt b/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/server/MMServer.kt index d1e637b4..71d6b53a 100644 --- a/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/server/MMServer.kt +++ b/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/server/MMServer.kt @@ -10,6 +10,7 @@ import io.ktor.application.log import io.ktor.features.CallLogging import io.ktor.features.ContentNegotiation import io.ktor.features.DefaultHeaders +import io.ktor.http.ContentType import io.ktor.http.content.resources import io.ktor.http.content.static import io.ktor.response.respond @@ -19,6 +20,7 @@ import io.ktor.serialization.json import io.ktor.server.cio.CIO import io.ktor.server.engine.embeddedServer import io.ktor.util.KtorExperimentalAPI +import kotlinx.serialization.json.Json import org.apache.commons.math3.random.JDKRandomGenerator import ru.mipt.npm.muon.monitor.Model import ru.mipt.npm.muon.monitor.sim.Cos2TrackGenerator @@ -38,7 +40,7 @@ fun Application.module() { install(DefaultHeaders) install(CallLogging) install(ContentNegotiation) { - json(module = SolidManager.serialModule) + json(Json { serializersModule = SolidManager.serialModule }, ContentType.Application.Json) } install(Routing) { get("/event") { diff --git a/demo/spatial-showcase/build.gradle.kts b/demo/spatial-showcase/build.gradle.kts index b2816c18..40c4b04d 100644 --- a/demo/spatial-showcase/build.gradle.kts +++ b/demo/spatial-showcase/build.gradle.kts @@ -1,19 +1,22 @@ -import scientifik.DependencyConfiguration -import scientifik.FXModule -import scientifik.useFx +import ru.mipt.npm.gradle.* plugins { - id("scientifik.mpp") - id("application") + id("ru.mipt.npm.mpp") + application } -val fxVersion: String by rootProject.extra -useFx(FXModule.CONTROLS, version = fxVersion, configuration = DependencyConfiguration.IMPLEMENTATION) +kscience { + val fxVersion: String by rootProject.extra + useFx(FXModule.CONTROLS, version = fxVersion, configuration = DependencyConfiguration.IMPLEMENTATION) + application() +} kotlin { jvm { - withJava() + afterEvaluate { + withJava() + } } sourceSets { diff --git a/demo/spatial-showcase/src/commonMain/kotlin/hep/dataforge/vision/solid/demo/demo.kt b/demo/spatial-showcase/src/commonMain/kotlin/hep/dataforge/vision/solid/demo/demo.kt index a2786881..4f96f21b 100644 --- a/demo/spatial-showcase/src/commonMain/kotlin/hep/dataforge/vision/solid/demo/demo.kt +++ b/demo/spatial-showcase/src/commonMain/kotlin/hep/dataforge/vision/solid/demo/demo.kt @@ -8,6 +8,7 @@ import hep.dataforge.vision.Colors import hep.dataforge.vision.Vision import hep.dataforge.vision.solid.* import hep.dataforge.vision.solid.specifications.Canvas3DOptions +import hep.dataforge.vision.visible import kotlinx.coroutines.* import kotlin.math.PI import kotlin.math.cos diff --git a/demo/spatial-showcase/src/jsMain/resources/index.html b/demo/spatial-showcase/src/jsMain/resources/index.html index d709af37..278366e0 100644 --- a/demo/spatial-showcase/src/jsMain/resources/index.html +++ b/demo/spatial-showcase/src/jsMain/resources/index.html @@ -6,7 +6,7 @@ Three js demo for particle physics - +
diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 00000000..930bba55 --- /dev/null +++ b/gradle.properties @@ -0,0 +1,9 @@ +kotlin.code.style=official +kotlin.parallel.tasks.in.project=true +kotlin.mpp.enableGranularSourceSetsMetadata=true +kotlin.native.enableDependencyPropagation=false +kotlin.mpp.stability.nowarn=true + +org.gradle.jvmargs=-XX:MaxMetaspaceSize=512m +org.gradle.parallel=true +systemProp.org.gradle.internal.publish.checksums.insecure=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 6c9a2247..12d38de6 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/playground/build.gradle.kts b/playground/build.gradle.kts index 4c71daab..4eeabfa2 100644 --- a/playground/build.gradle.kts +++ b/playground/build.gradle.kts @@ -7,12 +7,12 @@ repositories{ maven("https://kotlin.bintray.com/kotlinx") maven("https://dl.bintray.com/kotlin/kotlin-eap") maven("https://dl.bintray.com/mipt-npm/dataforge") - maven("https://dl.bintray.com/mipt-npm/scientifik") + maven("https://dl.bintray.com/mipt-npm/kscience") maven("https://dl.bintray.com/mipt-npm/dev") } kotlin { - js { + js(IR) { browser {} } diff --git a/settings.gradle.kts b/settings.gradle.kts index 187e5143..40fcab11 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,32 +1,27 @@ pluginManagement { - val kotlinVersion = "1.3.72" - val toolsVersion = "0.5.2" + val kotlinVersion = "1.4.20-M1" + val toolsVersion = "0.6.3-dev-1.4.20-M1" repositories { mavenLocal() jcenter() gradlePluginPortal() - maven("https://kotlin.bintray.com/kotlinx") maven("https://dl.bintray.com/kotlin/kotlin-eap") + maven("https://dl.bintray.com/kotlin/kotlinx") maven("https://dl.bintray.com/mipt-npm/dataforge") - maven("https://dl.bintray.com/mipt-npm/scientifik") + maven("https://dl.bintray.com/mipt-npm/kscience") maven("https://dl.bintray.com/mipt-npm/dev") } plugins { + id("ru.mipt.npm.project") version toolsVersion + id("ru.mipt.npm.mpp") version toolsVersion + id("ru.mipt.npm.jvm") version toolsVersion + id("ru.mipt.npm.js") version toolsVersion + id("ru.mipt.npm.publish") version toolsVersion kotlin("jvm") version kotlinVersion - id("scientifik.mpp") version toolsVersion - id("scientifik.jvm") version toolsVersion - id("scientifik.js") version toolsVersion - id("scientifik.publish") version toolsVersion - } - - resolutionStrategy { - eachPlugin { - when (requested.id.id) { - "scientifik.mpp", "scientifik.publish", "scientifik.jvm", "scientifik.js" -> useModule("scientifik:gradle-tools:${toolsVersion}") - } - } + kotlin("js") version kotlinVersion + kotlin("multiplatform") version kotlinVersion } } @@ -34,11 +29,12 @@ pluginManagement { rootProject.name = "visionforge" + include( - ":ui", +// ":ui", ":ui:react", ":ui:ring", - ":ui:material", +// ":ui:material", ":ui:bootstrap", ":visionforge-core", ":visionforge-solid", diff --git a/ui/bootstrap/build.gradle.kts b/ui/bootstrap/build.gradle.kts index 598c1e56..b2400d0c 100644 --- a/ui/bootstrap/build.gradle.kts +++ b/ui/bootstrap/build.gradle.kts @@ -1,15 +1,9 @@ plugins { - id("scientifik.js") + id("ru.mipt.npm.js") } val dataforgeVersion: String by rootProject.extra -kotlin { - target { - useCommonJs() - } -} - dependencies{ api(project(":ui:react")) } \ No newline at end of file diff --git a/ui/bootstrap/src/main/kotlin/hep/dataforge/vision/bootstrap/bootstrap.kt b/ui/bootstrap/src/main/kotlin/hep/dataforge/vision/bootstrap/bootstrap.kt index f41c7ecc..14efcccb 100644 --- a/ui/bootstrap/src/main/kotlin/hep/dataforge/vision/bootstrap/bootstrap.kt +++ b/ui/bootstrap/src/main/kotlin/hep/dataforge/vision/bootstrap/bootstrap.kt @@ -2,6 +2,7 @@ package hep.dataforge.vision.bootstrap import hep.dataforge.names.Name import hep.dataforge.names.NameToken +import hep.dataforge.names.length import hep.dataforge.vision.Vision import hep.dataforge.vision.react.ObjectTree import kotlinx.html.* @@ -17,7 +18,7 @@ import styled.StyledDOMBuilder import styled.css import styled.styledDiv -inline fun TagConsumer.card(title: String, crossinline block: TagConsumer.() -> Unit) { +public inline fun TagConsumer.card(title: String, crossinline block: TagConsumer.() -> Unit) { div("card w-100") { div("card-body") { h3(classes = "card-title") { +title } @@ -26,7 +27,7 @@ inline fun TagConsumer.card(title: String, crossinline block: TagCo } } -inline fun RBuilder.card(title: String, classes: String? = null, crossinline block: RBuilder.() -> Unit) { +public inline fun RBuilder.card(title: String, classes: String? = null, crossinline block: RBuilder.() -> Unit) { div("card w-100 $classes") { div("card-body") { h3(classes = "card-title") { @@ -37,7 +38,7 @@ inline fun RBuilder.card(title: String, classes: String? = null, crossinline blo } } -fun TagConsumer.accordion(id: String, elements: List Unit>>) { +public fun TagConsumer.accordion(id: String, elements: List Unit>>) { div("container-fluid") { div("accordion") { this.id = id @@ -69,18 +70,18 @@ fun TagConsumer.accordion(id: String, elements: List Unit>> +public typealias AccordionBuilder = MutableList Unit>> -fun AccordionBuilder.entry(title: String, builder: DIV.() -> Unit) { +public fun AccordionBuilder.entry(title: String, builder: DIV.() -> Unit) { add(title to builder) } -fun TagConsumer.accordion(id: String, builder: AccordionBuilder.() -> Unit) { +public fun TagConsumer.accordion(id: String, builder: AccordionBuilder.() -> Unit) { val list = ArrayList Unit>>().apply(builder) accordion(id, list) } -fun RBuilder.accordion(id: String, elements: List.() -> Unit>>): ReactElement { +public fun RBuilder.accordion(id: String, elements: List.() -> Unit>>): ReactElement { return div("container-fluid") { div("accordion") { attrs { @@ -120,7 +121,7 @@ fun RBuilder.accordion(id: String, elements: List. } } -fun RBuilder.namecrumbs(name: Name?, rootTitle: String, link: (Name) -> Unit) { +public fun RBuilder.namecrumbs(name: Name?, rootTitle: String, link: (Name) -> Unit) { div("container-fluid p-0") { nav { attrs { @@ -160,20 +161,18 @@ fun RBuilder.namecrumbs(name: Name?, rootTitle: String, link: (Name) -> Unit) { } } -typealias RAccordionBuilder = MutableList.() -> Unit>> +public typealias RAccordionBuilder = MutableList.() -> Unit>> -fun RAccordionBuilder.entry(title: String, builder: RDOMBuilder
.() -> Unit) { +public fun RAccordionBuilder.entry(title: String, builder: RDOMBuilder
.() -> Unit) { add(title to builder) } -fun RBuilder.accordion(id: String, builder: RAccordionBuilder.() -> Unit): ReactElement { +public fun RBuilder.accordion(id: String, builder: RAccordionBuilder.() -> Unit): ReactElement { val list = ArrayList.() -> Unit>>().apply(builder) return accordion(id, list) } -fun joinStyles(vararg styles: String?) = styles.joinToString(separator = " ") { it ?: "" } - -enum class ContainerSize(val suffix: String) { +public enum class ContainerSize(public val suffix: String) { DEFAULT(""), SM("-sm"), MD("-md"), @@ -182,7 +181,7 @@ enum class ContainerSize(val suffix: String) { FLUID("-fluid") } -inline fun RBuilder.container( +public inline fun RBuilder.container( size: ContainerSize = ContainerSize.FLUID, block: StyledDOMBuilder
.() -> Unit ): ReactElement = styledDiv{ @@ -193,7 +192,7 @@ inline fun RBuilder.container( } -enum class GridMaxSize(val suffix: String) { +public enum class GridMaxSize(public val suffix: String) { NONE(""), SM("-sm"), MD("-md"), @@ -201,7 +200,7 @@ enum class GridMaxSize(val suffix: String) { XL("-xl") } -inline fun RBuilder.gridColumn( +public inline fun RBuilder.gridColumn( weight: Int? = null, maxSize: GridMaxSize = GridMaxSize.NONE, block: StyledDOMBuilder
.() -> Unit @@ -213,7 +212,7 @@ inline fun RBuilder.gridColumn( block() } -inline fun RBuilder.gridRow( +public inline fun RBuilder.gridRow( block: StyledDOMBuilder
.() -> Unit ): ReactElement = styledDiv{ css{ @@ -222,10 +221,10 @@ inline fun RBuilder.gridRow( block() } -fun Element.renderObjectTree( +public fun Element.renderObjectTree( vision: Vision, clickCallback: (Name) -> Unit = {} -) = render(this) { +): Unit = render(this) { card("Object tree") { child(ObjectTree) { attrs { diff --git a/ui/material/build.gradle.kts b/ui/material/build.gradle.kts index 78e48bc4..15eb5377 100644 --- a/ui/material/build.gradle.kts +++ b/ui/material/build.gradle.kts @@ -1,20 +1,14 @@ plugins { - id("scientifik.js") + id("ru.mipt.npm.js") } val dataforgeVersion: String by rootProject.extra -kotlin { - target { - useCommonJs() - } -} - dependencies{ api(project(":ui:react")) - api("subroh0508.net.kotlinmaterialui:core:0.4.0") - api("subroh0508.net.kotlinmaterialui:lab:0.4.0") + api("subroh0508.net.kotlinmaterialui:core:0.4.5") + api("subroh0508.net.kotlinmaterialui:lab:0.4.5") api(npm("@material-ui/core","4.9.14")) api(npm("@material-ui/lab","4.0.0-alpha.51")) //api(npm("@material-ui/icons","4.9.1")) diff --git a/ui/react/build.gradle.kts b/ui/react/build.gradle.kts index 64586c43..3fb049b5 100644 --- a/ui/react/build.gradle.kts +++ b/ui/react/build.gradle.kts @@ -1,11 +1,5 @@ plugins { - id("scientifik.js") -} - -kotlin { - target { - useCommonJs() - } + id("ru.mipt.npm.js") } val reactVersion by extra("16.13.1") @@ -14,7 +8,7 @@ dependencies{ api(project(":visionforge-core")) //api("org.jetbrains:kotlin-react:16.13.1-pre.104-kotlin-1.3.72") - api("org.jetbrains:kotlin-react-dom:$reactVersion-pre.104-kotlin-1.3.72") + api("org.jetbrains:kotlin-react-dom:$reactVersion-pre.123-kotlin-1.4.10") api(npm("react", reactVersion)) api(npm("react-dom", reactVersion)) diff --git a/ui/react/src/main/kotlin/hep/dataforge/vision/react/ConfigEditor.kt b/ui/react/src/main/kotlin/hep/dataforge/vision/react/ConfigEditor.kt index 712d3b60..b7c4407e 100644 --- a/ui/react/src/main/kotlin/hep/dataforge/vision/react/ConfigEditor.kt +++ b/ui/react/src/main/kotlin/hep/dataforge/vision/react/ConfigEditor.kt @@ -4,6 +4,7 @@ import hep.dataforge.meta.* import hep.dataforge.meta.descriptors.* import hep.dataforge.names.Name import hep.dataforge.names.NameToken +import hep.dataforge.names.lastOrNull import hep.dataforge.names.plus import hep.dataforge.values.Value import kotlinx.html.js.onClickFunction @@ -47,7 +48,7 @@ private fun RFBuilder.configEditorItem(props: ConfigEditorItemProps) { val defaultItem = props.default?.get(props.name) var actualItem: MetaItem? by state { item ?: defaultItem ?: descriptorItem?.defaultItem() } - val token = props.name.last()?.toString() ?: "Properties" + val token = props.name.lastOrNull()?.toString() ?: "Properties" fun update() { item = props.root[props.name] diff --git a/ui/react/src/main/kotlin/hep/dataforge/vision/react/MetaViewer.kt b/ui/react/src/main/kotlin/hep/dataforge/vision/react/MetaViewer.kt index e5a628b4..5f98e40f 100644 --- a/ui/react/src/main/kotlin/hep/dataforge/vision/react/MetaViewer.kt +++ b/ui/react/src/main/kotlin/hep/dataforge/vision/react/MetaViewer.kt @@ -9,6 +9,7 @@ import hep.dataforge.meta.descriptors.get import hep.dataforge.meta.get import hep.dataforge.names.Name import hep.dataforge.names.NameToken +import hep.dataforge.names.lastOrNull import hep.dataforge.names.plus import kotlinx.html.js.onClickFunction import org.w3c.dom.events.Event @@ -43,7 +44,7 @@ private fun RFBuilder.metaViewerItem(props: MetaViewerProps) { val descriptorItem: ItemDescriptor? = props.descriptor?.get(props.name) val actualItem = item ?: descriptorItem?.defaultItem() - val token = props.name.last()?.toString() ?: "Meta" + val token = props.name.lastOrNull()?.toString() ?: "Meta" val expanderClick: (Event) -> Unit = { expanded = !expanded diff --git a/ui/react/src/main/kotlin/hep/dataforge/vision/react/ObjectTree.kt b/ui/react/src/main/kotlin/hep/dataforge/vision/react/ObjectTree.kt index 3b2112fb..ece2a32b 100644 --- a/ui/react/src/main/kotlin/hep/dataforge/vision/react/ObjectTree.kt +++ b/ui/react/src/main/kotlin/hep/dataforge/vision/react/ObjectTree.kt @@ -1,6 +1,7 @@ package hep.dataforge.vision.react import hep.dataforge.names.Name +import hep.dataforge.names.lastOrNull import hep.dataforge.names.plus import hep.dataforge.names.startsWith import hep.dataforge.vision.Vision @@ -42,7 +43,7 @@ private fun RFBuilder.objectTree(props: ObjectTreeProps): Unit { } } - val token = props.name.last()?.toString() ?: "World" + val token = props.name.lastOrNull()?.toString() ?: "World" val obj = props.obj //display as node if any child is visible diff --git a/ui/ring/build.gradle.kts b/ui/ring/build.gradle.kts index 6cb807a3..167743be 100644 --- a/ui/ring/build.gradle.kts +++ b/ui/ring/build.gradle.kts @@ -1,22 +1,13 @@ plugins { - id("scientifik.js") + id("ru.mipt.npm.js") } val dataforgeVersion: String by rootProject.extra -kotlin { - target { - useCommonJs() - } -} - - dependencies{ api(project(":ui:react")) implementation(npm("@jetbrains/logos", "1.1.6")) implementation(npm("@jetbrains/ring-ui", "3.0.13")) - - implementation(npm("svg-inline-loader", "0.8.0")) } \ No newline at end of file diff --git a/visionforge-core/build.gradle.kts b/visionforge-core/build.gradle.kts index 2ef4cad5..546587d2 100644 --- a/visionforge-core/build.gradle.kts +++ b/visionforge-core/build.gradle.kts @@ -1,13 +1,10 @@ plugins { - id("scientifik.mpp") + id("ru.mipt.npm.mpp") } val dataforgeVersion: String by rootProject.extra kotlin { - js { - useCommonJs() - } sourceSets { commonMain { @@ -30,15 +27,15 @@ kotlin { jsMain { dependencies { api("hep.dataforge:dataforge-output-html:$dataforgeVersion") - api("org.jetbrains.kotlinx:kotlinx-html:0.6.12") + api("org.jetbrains.kotlinx:kotlinx-html:0.7.2") //api("org.jetbrains:kotlin-extensions:1.0.1-pre.105-kotlin-1.3.72") //api("org.jetbrains:kotlin-css-js:1.0.0-pre.105-kotlin-1.3.72") - api("org.jetbrains:kotlin-styled:1.0.0-pre.104-kotlin-1.3.72") + api("org.jetbrains:kotlin-styled:5.2.0-pre.123-kotlin-1.4.10") api(npm("core-js", "2.6.5")) api(npm("inline-style-prefixer", "5.1.0")) - api(npm("styled-components", "4.3.2")) + api(npm("styled-components", "5.2.0")) //api(project(":ringui-wrapper")) } } diff --git a/visionforge-core/src/commonMain/kotlin/hep/dataforge/properties/ConfigProperty.kt b/visionforge-core/src/commonMain/kotlin/hep/dataforge/properties/ConfigProperty.kt index 11936eda..550d39a7 100644 --- a/visionforge-core/src/commonMain/kotlin/hep/dataforge/properties/ConfigProperty.kt +++ b/visionforge-core/src/commonMain/kotlin/hep/dataforge/properties/ConfigProperty.kt @@ -4,7 +4,7 @@ import hep.dataforge.meta.* import hep.dataforge.names.Name @DFExperimental -class ConfigProperty(val config: Config, val name: Name) : Property?> { +internal class ConfigProperty(val config: Config, val name: Name) : Property?> { override var value: MetaItem<*>? get() = config[name] set(value) { diff --git a/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/AbstractVision.kt b/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/AbstractVision.kt index a025a87a..68e6ee85 100644 --- a/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/AbstractVision.kt +++ b/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/AbstractVision.kt @@ -87,13 +87,13 @@ abstract class AbstractVision : Vision { /** * Reset all properties to their default values */ - fun resetProperties() { + public fun resetProperties() { properties?.removeListener(this) properties = null } - companion object { - val descriptor = NodeDescriptor { + public companion object { + public val descriptor: NodeDescriptor = NodeDescriptor { value(STYLE_KEY) { type(ValueType.STRING) multiple = true diff --git a/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/AbstractVisionGroup.kt b/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/AbstractVisionGroup.kt index d1d7f523..f2c343d6 100644 --- a/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/AbstractVisionGroup.kt +++ b/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/AbstractVisionGroup.kt @@ -1,9 +1,6 @@ package hep.dataforge.vision -import hep.dataforge.names.Name -import hep.dataforge.names.NameToken -import hep.dataforge.names.asName -import hep.dataforge.names.isEmpty +import hep.dataforge.names.* import kotlinx.serialization.Transient @@ -105,7 +102,7 @@ abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup { return when { name.isEmpty() -> error("Should be unreachable") name.length == 1 -> { - val token = name.first()!! + val token = name.tokens.first() when (val current = children[token]) { null -> createGroup().also { child -> attach(child) @@ -115,7 +112,7 @@ abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup { else -> error("Can't create group with name $name because it exists and not a group") } } - else -> createGroups(name.first()!!.asName()).createGroups(name.cutFirst()) + else -> createGroups(name.tokens.first().asName()).createGroups(name.cutFirst()) } } @@ -131,7 +128,7 @@ abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup { } } name.length == 1 -> { - val token = name.first()!! + val token = name.tokens.first() if (child == null) { removeChild(token) } else { @@ -142,7 +139,7 @@ abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup { else -> { //TODO add safety check val parent = (get(name.cutLast()) as? MutableVisionGroup) ?: createGroups(name.cutLast()) - parent[name.last()!!.asName()] = child + parent[name.tokens.last().asName()] = child } } childrenChanged(name, child) diff --git a/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/StyleSheet.kt b/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/StyleSheet.kt index d4199657..0a5f27e5 100644 --- a/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/StyleSheet.kt +++ b/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/StyleSheet.kt @@ -8,20 +8,23 @@ import hep.dataforge.names.asName import kotlinx.serialization.* import kotlinx.serialization.builtins.MapSerializer import kotlinx.serialization.builtins.serializer +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder /** * A container for styles */ @Serializable -class StyleSheet private constructor(private val styleMap: MutableMap = LinkedHashMap()) { +public class StyleSheet private constructor(private val styleMap: MutableMap = LinkedHashMap()) { @Transient internal var owner: Vision? = null - constructor(owner: Vision) : this() { + public constructor(owner: Vision) : this() { this.owner = owner } - val items: Map get() = styleMap + public val items: Map get() = styleMap private fun Vision.styleChanged(key: String, oldStyle: Meta?, newStyle: Meta?) { @@ -38,14 +41,14 @@ class StyleSheet private constructor(private val styleMap: MutableMap Unit) { + public operator fun set(key: String, builder: MetaBuilder.() -> Unit) { val newStyle = get(key)?.edit(builder) ?: Meta(builder) set(key, newStyle.seal()) } + @ExperimentalSerializationApi @Serializer(StyleSheet::class) - companion object : KSerializer { + public companion object : KSerializer { private val mapSerializer = MapSerializer(String.serializer(), MetaSerializer) override val descriptor: SerialDescriptor get() = mapSerializer.descriptor @@ -91,14 +95,14 @@ class StyleSheet private constructor(private val styleMap: MutableMap> { +public fun Vision.getStyleItems(name: Name): Sequence> { return styles.asSequence().map { resolveStyle(it) }.map { @@ -109,4 +113,4 @@ fun Vision.getStyleItems(name: Name): Sequence> { /** * Collect all styles for this object in a single laminate */ -val Vision.allStyles: Laminate get() = Laminate(styles.mapNotNull(::resolveStyle)) \ No newline at end of file +public val Vision.allStyles: Laminate get() = Laminate(styles.mapNotNull(::resolveStyle)) \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/Vision.kt b/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/Vision.kt index 4d819910..7ccdd81e 100644 --- a/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/Vision.kt +++ b/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/Vision.kt @@ -5,7 +5,9 @@ import hep.dataforge.names.Name import hep.dataforge.names.asName import hep.dataforge.names.toName import hep.dataforge.provider.Type +import hep.dataforge.values.asValue import hep.dataforge.vision.Vision.Companion.TYPE +import hep.dataforge.vision.Vision.Companion.VISIBLE_KEY import kotlinx.serialization.PolymorphicSerializer import kotlinx.serialization.Transient @@ -13,28 +15,28 @@ import kotlinx.serialization.Transient * A root type for display hierarchy */ @Type(TYPE) -interface Vision : Configurable { +public interface Vision : Configurable { /** * The parent object of this one. If null, this one is a root. */ @Transient - var parent: VisionGroup? + public var parent: VisionGroup? /** * Nullable version of [config] used to check if this [Vision] has custom properties */ - val properties: Config? + public val properties: Config? /** * All properties including styles and prototypes if present, including inherited ones */ - fun getAllProperties(): Laminate + public fun getAllProperties(): Laminate /** * Get property (including styles). [inherit] toggles parent node property lookup */ - fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? + public fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? /** * Ger a property including inherited values @@ -44,46 +46,55 @@ interface Vision : Configurable { /** * Trigger property invalidation event. If [name] is empty, notify that the whole object is changed */ - fun propertyChanged(name: Name): Unit + public fun propertyChanged(name: Name): Unit /** * Add listener triggering on property change */ - fun onPropertyChange(owner: Any?, action: (Name) -> Unit): Unit + public fun onPropertyChange(owner: Any?, action: (Name) -> Unit): Unit /** * Remove change listeners with given owner. */ - fun removeChangeListener(owner: Any?) + public fun removeChangeListener(owner: Any?) /** * List of names of styles applied to this object. Order matters. Not inherited. */ - var styles: List - get() = properties[STYLE_KEY].stringList + public var styles: List + get() = properties[STYLE_KEY]?.stringList?: emptyList() set(value) { config[STYLE_KEY] = value } - companion object { - const val TYPE = "vision" - val STYLE_KEY = "@style".asName() + public companion object { + public const val TYPE: String = "vision" + public val STYLE_KEY: Name = "@style".asName() private val VISION_SERIALIZER = PolymorphicSerializer(Vision::class) - fun serializer() = VISION_SERIALIZER + public fun serializer(): PolymorphicSerializer = VISION_SERIALIZER + + public val VISIBLE_KEY: Name = "visible".asName() } } /** * Get [Vision] property using key as a String */ -fun Vision.getProperty(key: String, inherit: Boolean = true): MetaItem<*>? = +public fun Vision.getProperty(key: String, inherit: Boolean = true): MetaItem<*>? = getProperty(key.toName(), inherit) /** * Find a style with given name for given [Vision]. The style is not necessary applied to this [Vision]. */ -tailrec fun Vision.resolveStyle(name: String): Meta? = +public tailrec fun Vision.resolveStyle(name: String): Meta? = (this as? VisionGroup)?.styleSheet?.get(name) ?: parent?.resolveStyle(name) + +/** + * Control visibility of the element + */ +public var Vision.visible: Boolean? + get() = getItem(VISIBLE_KEY).boolean + set(value) = setItem(VISIBLE_KEY, value?.asValue()) diff --git a/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/VisionGroup.kt b/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/VisionGroup.kt index 43b964f2..3035e18d 100644 --- a/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/VisionGroup.kt +++ b/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/VisionGroup.kt @@ -3,14 +3,18 @@ package hep.dataforge.vision import hep.dataforge.names.* import hep.dataforge.provider.Provider +public interface VisionContainer{ + public operator fun get(name: Name): V? +} + /** * Represents a group of [Vision] instances */ -interface VisionGroup : Provider, Vision { +public interface VisionGroup : Provider, Vision, VisionContainer { /** * A map of top level named children */ - val children: Map + public val children: Map override val defaultTarget: String get() = Vision.TYPE @@ -18,17 +22,17 @@ interface VisionGroup : Provider, Vision { * A stylesheet for this group and its descendants. Stylesheet is not applied directly, * but instead is just a repository for named configurations. */ - val styleSheet: StyleSheet? + public val styleSheet: StyleSheet? /** * A map of direct children for specific target * (currently "visual" or "style") */ - override fun provideTop(target: String): Map = + override fun content(target: String): Map = when (target) { Vision.TYPE -> children.flatMap { (key, value) -> val res: Map = if (value is VisionGroup) { - value.provideTop(target).mapKeys { key + it.key } + value.content(target).mapKeys { key + it.key } } else { mapOf(key.asName() to value) } @@ -38,18 +42,18 @@ interface VisionGroup : Provider, Vision { else -> emptyMap() } - operator fun get(name: Name): Vision? { + public override operator fun get(name: Name): Vision? { return when { name.isEmpty() -> this - name.length == 1 -> children[name.first()!!] - else -> (children[name.first()!!] as? VisionGroup)?.get(name.cutFirst()) + name.length == 1 -> children[name.tokens.first()] + else -> (children[name.tokens.first()] as? VisionGroup)?.get(name.cutFirst()) } } /** * A fix for serialization bug that writes all proper parents inside the tree after deserialization */ - fun attachChildren() { + public fun attachChildren() { styleSheet?.owner = this children.values.forEach { it.parent = this @@ -57,41 +61,45 @@ interface VisionGroup : Provider, Vision { } } - companion object { - const val STYLE_TARGET = "style" + public companion object { + public const val STYLE_TARGET: String = "style" } } /** * Iterate over children of this group */ -operator fun VisionGroup.iterator(): Iterator = children.values.iterator() +public operator fun VisionGroup.iterator(): Iterator = children.values.iterator() -val VisionGroup.isEmpty: Boolean get() = this.children.isEmpty() +public val VisionGroup.isEmpty: Boolean get() = this.children.isEmpty() + +public interface VisionContainerBuilder{ + public operator fun set(name: Name, child: V?) +} /** * Mutable version of [VisionGroup] */ -interface MutableVisionGroup : VisionGroup { +public interface MutableVisionGroup : VisionGroup, VisionContainerBuilder { /** * Add listener for children structure change. * @param owner the handler to properly remove listeners * @param action First argument of the action is the name of changed child. Second argument is the new value of the object. */ - fun onChildrenChange(owner: Any?, action: (Name, Vision?) -> Unit) + public fun onChildrenChange(owner: Any?, action: (Name, Vision?) -> Unit) /** * Remove children change listener */ - fun removeChildrenChangeListener(owner: Any?) + public fun removeChildrenChangeListener(owner: Any?) - operator fun set(name: Name, child: Vision?) +// public operator fun set(name: Name, child: Vision?) } -operator fun VisionGroup.get(str: String?): Vision? = get(str?.toName() ?: Name.EMPTY) +public operator fun VisionContainer.get(str: String?): V? = get(str?.toName() ?: Name.EMPTY) -operator fun MutableVisionGroup.set(token: NameToken, child: Vision?): Unit = set(token.asName(), child) -operator fun MutableVisionGroup.set(key: String, child: Vision?): Unit = set(key.toName(), child) +public operator fun VisionContainerBuilder.set(token: NameToken, child: V?): Unit = set(token.asName(), child) +public operator fun VisionContainerBuilder.set(key: String, child: V?): Unit = set(key.toName(), child) -fun MutableVisionGroup.removeAll() = children.keys.map { it.asName() }.forEach { this[it] = null } \ No newline at end of file +public fun MutableVisionGroup.removeAll(): Unit = children.keys.map { it.asName() }.forEach { this[it] = null } \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/VisionManager.kt b/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/VisionManager.kt index 6bf7291c..39f7096f 100644 --- a/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/VisionManager.kt +++ b/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/VisionManager.kt @@ -3,35 +3,37 @@ package hep.dataforge.vision import hep.dataforge.context.* import hep.dataforge.meta.* import hep.dataforge.meta.descriptors.NodeDescriptor +import hep.dataforge.names.Name import hep.dataforge.names.toName +import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.KSerializer -import kotlinx.serialization.UnstableDefault import kotlinx.serialization.json.Json -import kotlinx.serialization.json.JsonConfiguration -import kotlinx.serialization.modules.SerialModule import kotlinx.serialization.modules.SerializersModule +import kotlinx.serialization.modules.polymorphic +import kotlinx.serialization.modules.subclass import kotlin.reflect.KClass @DFExperimental -interface VisionForm { - val type: KClass - val serializer: KSerializer +public interface VisionForm { + public val type: KClass + public val serializer: KSerializer - val name get() = serializer.descriptor.serialName.toName() + public val name: Name + get() = serializer.descriptor.serialName.toName() /** * Apply a patch to given [Vision] */ - fun patch(obj: T, meta: Meta) + public fun patch(obj: T, meta: Meta) - companion object { - const val TYPE = "visionForm" + public companion object { + public const val TYPE: String = "visionForm" } } @DFExperimental -object SimpleGroupForm: VisionForm{ +public object SimpleGroupForm : VisionForm { override val type: KClass = SimpleVisionGroup::class override val serializer: KSerializer = SimpleVisionGroup.serializer() @@ -42,86 +44,93 @@ object SimpleGroupForm: VisionForm{ } @DFExperimental -fun VisionForm.visionToMeta(vision: T, module: SerialModule, descriptor: NodeDescriptor? = null): Meta { - val engine = Json(VisionManager.jsonConfiguration, module) - val json = engine.toJson(serializer, vision) +public fun VisionForm.visionToMeta( + vision: T, + module: SerializersModule, + descriptor: NodeDescriptor? = null, +): Meta { + val engine = Json(VisionManager.jsonConfiguration) { serializersModule = module } + val json = engine.encodeToJsonElement(serializer, vision) return json.toMetaItem(descriptor).node!! } @DFExperimental -fun VisionForm.buildVision(meta: Meta, module: SerialModule, descriptor: NodeDescriptor? = null): T { - val engine = Json(VisionManager.jsonConfiguration, module) +public fun VisionForm.buildVision( + meta: Meta, + module: SerializersModule, + descriptor: NodeDescriptor? = null, +): T { + val engine = Json(VisionManager.jsonConfiguration) { serializersModule = module } val json = meta.toJson(descriptor) - return engine.fromJson(serializer, json) + return engine.decodeFromJsonElement(serializer, json) } @DFExperimental -class VisionManager(meta: Meta) : AbstractPlugin(meta) { +public class VisionManager(meta: Meta) : AbstractPlugin(meta) { override val tag: PluginTag get() = Companion.tag /** * Create a list of factories on first call and cache it */ private val forms by lazy { - context.content>(VisionForm.TYPE).mapKeys { it.value.type } + context.gather>(VisionForm.TYPE).mapKeys { it.value.type } } - val visionSerialModule + public val visionSerialModule: SerializersModule get() = SerializersModule { include(defaultSerialModule) - context.content(VISION_SERIAL_MODULE_TARGET).values.forEach { + context.gather(VISION_SERIAL_MODULE_TARGET).values.forEach { include(it) } } @Suppress("UNCHECKED_CAST") - fun resolveVisionForm(type: KClass): VisionForm? = + public fun resolveVisionForm(type: KClass): VisionForm = forms[type] as VisionForm - inline fun buildSpecificVision(meta: Meta): T { + public inline fun buildSpecificVision(meta: Meta): T { val factory = resolveVisionForm(T::class) ?: error("Could not resolve a form for ${meta["type"].string}") return factory.buildVision(meta, visionSerialModule) } - fun buildVision(meta: Meta): Vision { + @OptIn(ExperimentalSerializationApi::class) + public fun buildVision(meta: Meta): Vision { val type = meta["type"].string ?: Vision.serializer().descriptor.serialName val form = forms.values.find { it.name.toString() == type } ?: error("Could not resolve a form for type $type") return form.buildVision(meta, visionSerialModule) } - fun writeVisionToMeta(vision: T): Meta { + public fun writeVisionToMeta(vision: T): Meta { val form = resolveVisionForm(vision::class) ?: error("Could not resolve a form for $vision") - val engine = Json(VisionManager.jsonConfiguration, visionSerialModule) - val json = engine.toJson(form.serializer,vision) + val engine = Json(jsonConfiguration) { serializersModule = visionSerialModule } + val json = engine.encodeToJsonElement(form.serializer, vision) return json.toMetaItem().node!! } - fun patchVision(vision: Vision, meta: Meta) { + public fun patchVision(vision: Vision, meta: Meta) { val form = resolveVisionForm(vision::class) ?: error("Could not resolve a form for $vision") form.patch(vision, meta) } - companion object : PluginFactory { + public companion object : PluginFactory { override val tag: PluginTag = PluginTag(name = "vision", group = PluginTag.DATAFORGE_GROUP) override val type: KClass = VisionManager::class - const val VISION_SERIAL_MODULE_TARGET = "visionSerialModule" + public const val VISION_SERIAL_MODULE_TARGET: String = "visionSerialModule" override fun invoke(meta: Meta, context: Context): VisionManager = VisionManager(meta) - @OptIn(UnstableDefault::class) - val jsonConfiguration = JsonConfiguration( - prettyPrint = true, - useArrayPolymorphism = false, - encodeDefaults = false, + public val jsonConfiguration: Json = Json { + prettyPrint = true + useArrayPolymorphism = false + encodeDefaults = false ignoreUnknownKeys = true - ) + } - val defaultSerialModule = SerializersModule { - polymorphic(Vision::class, VisionGroup::class) { + public val defaultSerialModule: SerializersModule = SerializersModule { + polymorphic(Vision::class) { subclass(SimpleVisionGroup.serializer()) } } - } } \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/valueWidget.kt b/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/valueWidget.kt index 4edc70e4..f563d87c 100644 --- a/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/valueWidget.kt +++ b/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/valueWidget.kt @@ -1,27 +1,27 @@ package hep.dataforge.vision -import hep.dataforge.meta.Meta +import hep.dataforge.meta.* import hep.dataforge.meta.descriptors.ValueDescriptor -import hep.dataforge.meta.descriptors.setAttribute -import hep.dataforge.meta.get -import hep.dataforge.meta.node -import hep.dataforge.meta.string -import hep.dataforge.names.toName +import hep.dataforge.meta.descriptors.attributes /** * Extension property to access the "widget" key of [ValueDescriptor] */ -var ValueDescriptor.widget: Meta +public var ValueDescriptor.widget: Meta get() = attributes["widget"].node ?: Meta.EMPTY set(value) { - setAttribute("widget".toName(), value) + attributes { + set("widget", value) + } } /** * Extension property to access the "widget.type" key of [ValueDescriptor] */ -var ValueDescriptor.widgetType: String? +public var ValueDescriptor.widgetType: String? get() = attributes["widget.type"].string set(value) { - setAttribute("widget.type".toName(), value) + attributes{ + set("widget.type", value) + } } \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/visitor/StatisticsVisitor.kt b/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/visitor/StatisticsVisitor.kt index 21842994..89877fe6 100644 --- a/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/visitor/StatisticsVisitor.kt +++ b/visionforge-core/src/commonMain/kotlin/hep/dataforge/vision/visitor/StatisticsVisitor.kt @@ -1,6 +1,7 @@ package hep.dataforge.vision.visitor import hep.dataforge.names.Name +import hep.dataforge.names.length import hep.dataforge.vision.Vision import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.Job diff --git a/visionforge-core/src/jvmMain/kotlin/hep/dataforge/vision/editor/FXMeta.kt b/visionforge-core/src/jvmMain/kotlin/hep/dataforge/vision/editor/FXMeta.kt index 04d954b6..84a286ed 100644 --- a/visionforge-core/src/jvmMain/kotlin/hep/dataforge/vision/editor/FXMeta.kt +++ b/visionforge-core/src/jvmMain/kotlin/hep/dataforge/vision/editor/FXMeta.kt @@ -4,10 +4,7 @@ import hep.dataforge.meta.* import hep.dataforge.meta.descriptors.ItemDescriptor import hep.dataforge.meta.descriptors.NodeDescriptor import hep.dataforge.meta.descriptors.ValueDescriptor -import hep.dataforge.names.Name -import hep.dataforge.names.NameToken -import hep.dataforge.names.asName -import hep.dataforge.names.withIndex +import hep.dataforge.names.* import hep.dataforge.values.Null import hep.dataforge.values.Value import javafx.beans.binding.ListBinding @@ -137,12 +134,12 @@ class FXMetaNode>( } } -class FXMetaValue>( +public class FXMetaValue>( override val name: NameToken, override val parent: FXMetaNode ) : FXMeta() { - val descriptorProperty = parent.descriptorProperty.objectBinding { + public val descriptorProperty = parent.descriptorProperty.objectBinding { it?.values?.get(name.body) } @@ -153,24 +150,24 @@ class FXMetaValue>( //private val innerValueProperty = SimpleObjectProperty(value) - val valueProperty = descriptorProperty.objectBinding { descriptor -> + public val valueProperty = descriptorProperty.objectBinding { descriptor -> parent.node[name].value ?: descriptor?.default } override val hasValue: ObservableBooleanValue = parent.nodeProperty.booleanBinding { it[name] != null } - val value by valueProperty + public val value by valueProperty override val descriptionProperty = descriptorProperty.stringBinding { it?.info ?: "" } } -fun > FXMetaNode.remove(name: NameToken) { +public fun > FXMetaNode.remove(name: NameToken) { node?.remove(name.asName()) children.invalidate() } private fun > M.createEmptyNode(token: NameToken, append: Boolean): M { - return if (append && token.index.isNotEmpty()) { + return if (append && token.hasIndex()) { val name = token.asName() val index = (getIndexed(name).keys.mapNotNull { it.toIntOrNull() }.max() ?: -1) + 1 val newName = name.withIndex(index.toString()) diff --git a/visionforge-gdml/build.gradle.kts b/visionforge-gdml/build.gradle.kts index 874523ac..ebb6a865 100644 --- a/visionforge-gdml/build.gradle.kts +++ b/visionforge-gdml/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("scientifik.mpp") + id("ru.mipt.npm.mpp") } kotlin { @@ -7,7 +7,7 @@ kotlin { val commonMain by getting { dependencies { api(project(":visionforge-solid")) - api("scientifik:gdml:0.1.8") + api("kscience.gdml:gdml:0.2.0-dev-2") } } } diff --git a/visionforge-gdml/src/commonMain/kotlin/hep/dataforge/vision/gdml/GDMLTransformer.kt b/visionforge-gdml/src/commonMain/kotlin/hep/dataforge/vision/gdml/GDMLTransformer.kt index ceecd768..3995c92f 100644 --- a/visionforge-gdml/src/commonMain/kotlin/hep/dataforge/vision/gdml/GDMLTransformer.kt +++ b/visionforge-gdml/src/commonMain/kotlin/hep/dataforge/vision/gdml/GDMLTransformer.kt @@ -12,7 +12,7 @@ import hep.dataforge.vision.set import hep.dataforge.vision.solid.* import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY import hep.dataforge.vision.useStyle -import scientifik.gdml.* +import kscience.gdml.* import kotlin.math.cos import kotlin.math.sin import kotlin.random.Random @@ -20,7 +20,7 @@ import kotlin.random.Random private val solidsName = "solids".asName() private val volumesName = "volumes".asName() -class GDMLTransformer internal constructor(val root: GDML) { +public class GDMLTransformer internal constructor(val root: GDML) { //private val materialCache = HashMap() private val random = Random(222) diff --git a/visionforge-gdml/src/commonMain/kotlin/hep/dataforge/vision/gdml/units.kt b/visionforge-gdml/src/commonMain/kotlin/hep/dataforge/vision/gdml/units.kt deleted file mode 100644 index 3e5783ef..00000000 --- a/visionforge-gdml/src/commonMain/kotlin/hep/dataforge/vision/gdml/units.kt +++ /dev/null @@ -1,70 +0,0 @@ -package hep.dataforge.vision.gdml - -import scientifik.gdml.AUnit -import scientifik.gdml.GDMLPosition -import scientifik.gdml.GDMLRotation -import scientifik.gdml.GDMLSolid - -enum class LUnit(val value: Float) { - MM(1f), - CM(10f), - M(1000f) -} - -fun GDMLPosition.unit(): LUnit = LUnit.valueOf(unit.toUpperCase()) - -fun GDMLPosition.x(unit: LUnit): Float = if (unit.name == this.unit) { - x.toFloat() -} else { - x.toFloat() / unit.value * unit().value -} - -fun GDMLPosition.y(unit: LUnit): Float = if (unit.name == this.unit) { - y.toFloat() -} else { - y.toFloat() / unit.value * unit().value -} - -fun GDMLPosition.z(unit: LUnit): Float = if (unit.name == this.unit) { - z.toFloat() -} else { - z.toFloat() / unit.value * unit().value -} - -fun GDMLRotation.unit(): AUnit = AUnit.valueOf(unit.toUpperCase()) - -fun GDMLRotation.x(unit: AUnit = AUnit.RAD): Float = if (unit.name == this.unit) { - x.toFloat() -} else { - x.toFloat() / unit.value * unit().value -} - -fun GDMLRotation.y(unit: AUnit = AUnit.RAD): Float = if (unit.name == this.unit) { - y.toFloat() -} else { - y.toFloat() / unit.value * unit().value -} - -fun GDMLRotation.z(unit: AUnit = AUnit.RAD): Float = if (unit.name == this.unit) { - z.toFloat() -} else { - z.toFloat() / unit.value * unit().value -} - -fun GDMLSolid.lscale(unit: LUnit): Float { - val solidUnit = lunit?.let { LUnit.valueOf(it.toUpperCase()) } ?: return 1f - return if (solidUnit == unit) { - 1f - } else { - solidUnit.value / unit.value - } -} - -fun GDMLSolid.ascale(unit: AUnit = AUnit.RAD): Float { - val solidUnit = aunit?.let { AUnit.valueOf(it.toUpperCase()) } ?: return 1f - return if (solidUnit == unit) { - 1f - } else { - solidUnit.value / unit.value - } -} \ No newline at end of file diff --git a/visionforge-gdml/src/jvmMain/kotlin/hep/dataforge/vision/gdml/gdmlJVM.kt b/visionforge-gdml/src/jvmMain/kotlin/hep/dataforge/vision/gdml/gdmlJVM.kt index 1718cc74..ab58deb9 100644 --- a/visionforge-gdml/src/jvmMain/kotlin/hep/dataforge/vision/gdml/gdmlJVM.kt +++ b/visionforge-gdml/src/jvmMain/kotlin/hep/dataforge/vision/gdml/gdmlJVM.kt @@ -2,7 +2,7 @@ package hep.dataforge.vision.gdml import hep.dataforge.vision.solid.SolidGroup import nl.adaptivity.xmlutil.StAXReader -import scientifik.gdml.GDML +import kscience.gdml.GDML import java.nio.file.Files import java.nio.file.Path import java.util.concurrent.atomic.AtomicInteger diff --git a/visionforge-gdml/src/jvmTest/kotlin/hep/dataforge/vision/gdml/TestConvertor.kt b/visionforge-gdml/src/jvmTest/kotlin/hep/dataforge/vision/gdml/TestConvertor.kt index 287553a1..cf9fb7b4 100644 --- a/visionforge-gdml/src/jvmTest/kotlin/hep/dataforge/vision/gdml/TestConvertor.kt +++ b/visionforge-gdml/src/jvmTest/kotlin/hep/dataforge/vision/gdml/TestConvertor.kt @@ -1,9 +1,9 @@ package hep.dataforge.vision.gdml -import hep.dataforge.vision.solid.stringify +import hep.dataforge.vision.solid.encodeToString import nl.adaptivity.xmlutil.StAXReader import org.junit.jupiter.api.Test -import scientifik.gdml.GDML +import kscience.gdml.GDML class TestConvertor { @@ -13,7 +13,7 @@ class TestConvertor { val xmlReader = StAXReader(stream, "UTF-8") val xml = GDML.format.parse(GDML.serializer(), xmlReader) val vision = xml.toVision() - println(vision.stringify()) + println(vision.encodeToString()) } @Test @@ -33,6 +33,6 @@ class TestConvertor { val xmlReader = StAXReader(stream, "UTF-8") val xml = GDML.format.parse(GDML.serializer(), xmlReader) val visual = xml.toVision() - println(visual.stringify()) + println(visual.encodeToString()) } } \ No newline at end of file diff --git a/visionforge-gdml/src/jvmTest/kotlin/hep/dataforge/vision/gdml/bmanStatistics.kt b/visionforge-gdml/src/jvmTest/kotlin/hep/dataforge/vision/gdml/bmanStatistics.kt index d737d2ae..87b93093 100644 --- a/visionforge-gdml/src/jvmTest/kotlin/hep/dataforge/vision/gdml/bmanStatistics.kt +++ b/visionforge-gdml/src/jvmTest/kotlin/hep/dataforge/vision/gdml/bmanStatistics.kt @@ -8,7 +8,7 @@ import hep.dataforge.vision.visitor.flowStatistics import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import nl.adaptivity.xmlutil.StAXReader -import scientifik.gdml.GDML +import kscience.gdml.GDML import java.io.File import kotlin.reflect.KClass diff --git a/visionforge-solid/build.gradle.kts b/visionforge-solid/build.gradle.kts index 722cd2f3..7f08e038 100644 --- a/visionforge-solid/build.gradle.kts +++ b/visionforge-solid/build.gradle.kts @@ -1,15 +1,14 @@ -import scientifik.useSerialization +import ru.mipt.npm.gradle.KScienceVersions.coroutinesVersion plugins { - id("scientifik.mpp") + id("ru.mipt.npm.mpp") } -useSerialization() +kscience { + useSerialization() +} kotlin { - js { - useCommonJs() - } sourceSets { commonMain { @@ -22,7 +21,7 @@ kotlin { api("org.fxyz3d:fxyz3d:0.5.2") { exclude(module = "slf4j-simple") } - api("org.jetbrains.kotlinx:kotlinx-coroutines-javafx:${Scientifik.coroutinesVersion}") + api("org.jetbrains.kotlinx:kotlinx-coroutines-javafx:${coroutinesVersion}") implementation("eu.mihosoft.vrl.jcsg:jcsg:0.5.7") { exclude(module = "slf4j-simple") } @@ -37,4 +36,4 @@ kotlin { } } } -} +} \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Box.kt b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Box.kt index 1f05d4ef..5bd6aef5 100644 --- a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Box.kt +++ b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Box.kt @@ -5,6 +5,7 @@ package hep.dataforge.vision.solid import hep.dataforge.meta.Config import hep.dataforge.vision.AbstractVision import hep.dataforge.vision.MutableVisionGroup +import hep.dataforge.vision.VisionContainerBuilder import hep.dataforge.vision.set import hep.dataforge.vision.solid.Solid.Companion.solidEquals import kotlinx.serialization.SerialName @@ -13,10 +14,10 @@ import kotlinx.serialization.UseSerializers @Serializable @SerialName("solid.box") -class Box( - val xSize: Float, - val ySize: Float, - val zSize: Float +public class Box( + public val xSize: Float, + public val ySize: Float, + public val zSize: Float ) : AbstractVision(), GeometrySolid { override var position: Point3D? = null @@ -67,15 +68,15 @@ class Box( } - companion object { + public companion object { } } -inline fun MutableVisionGroup.box( +public inline fun VisionContainerBuilder.box( xSize: Number, ySize: Number, zSize: Number, name: String = "", action: Box.() -> Unit = {} -) = Box(xSize.toFloat(), ySize.toFloat(), zSize.toFloat()).apply(action).also { set(name, it) } \ No newline at end of file +): Box = Box(xSize.toFloat(), ySize.toFloat(), zSize.toFloat()).apply(action).also { set(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Composite.kt b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Composite.kt index d2049226..06da6e07 100644 --- a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Composite.kt +++ b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Composite.kt @@ -10,7 +10,7 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.UseSerializers -enum class CompositeType { +public enum class CompositeType { UNION, INTERSECT, SUBTRACT @@ -18,10 +18,10 @@ enum class CompositeType { @Serializable @SerialName("solid.composite") -class Composite( - val compositeType: CompositeType, - val first: Solid, - val second: Solid +public class Composite( + public val compositeType: CompositeType, + public val first: Solid, + public val second: Solid ) : AbstractVision(), Solid, VisionGroup { init { @@ -42,7 +42,7 @@ class Composite( get() = null } -inline fun MutableVisionGroup.composite( +public inline fun MutableVisionGroup.composite( type: CompositeType, name: String = "", builder: SolidGroup.() -> Unit @@ -67,11 +67,11 @@ inline fun MutableVisionGroup.composite( } } -inline fun MutableVisionGroup.union(name: String = "", builder: SolidGroup.() -> Unit) = +public inline fun MutableVisionGroup.union(name: String = "", builder: SolidGroup.() -> Unit): Composite = composite(CompositeType.UNION, name, builder = builder) -inline fun MutableVisionGroup.subtract(name: String = "", builder: SolidGroup.() -> Unit) = +public inline fun MutableVisionGroup.subtract(name: String = "", builder: SolidGroup.() -> Unit): Composite = composite(CompositeType.SUBTRACT, name, builder = builder) -inline fun MutableVisionGroup.intersect(name: String = "", builder: SolidGroup.() -> Unit) = +public inline fun MutableVisionGroup.intersect(name: String = "", builder: SolidGroup.() -> Unit): Composite = composite(CompositeType.INTERSECT, name, builder = builder) \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/ConeSegment.kt b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/ConeSegment.kt index 805151c9..428e6271 100644 --- a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/ConeSegment.kt +++ b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/ConeSegment.kt @@ -5,6 +5,7 @@ package hep.dataforge.vision.solid import hep.dataforge.meta.Config import hep.dataforge.vision.AbstractVision import hep.dataforge.vision.MutableVisionGroup +import hep.dataforge.vision.VisionContainerBuilder import hep.dataforge.vision.set import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -17,12 +18,12 @@ import kotlin.math.sin */ @Serializable @SerialName("solid.cone") -class ConeSegment( - var radius: Float, - var height: Float, - var upperRadius: Float, - var startAngle: Float = 0f, - var angle: Float = PI2 +public class ConeSegment( + public var radius: Float, + public var height: Float, + public var upperRadius: Float, + public var startAngle: Float = 0f, + public var angle: Float = PI2 ) : AbstractVision(), GeometrySolid { override var properties: Config? = null @@ -75,7 +76,7 @@ class ConeSegment( } -inline fun MutableVisionGroup.cylinder( +public inline fun VisionContainerBuilder.cylinder( r: Number, height: Number, name: String = "", @@ -87,7 +88,7 @@ inline fun MutableVisionGroup.cylinder( ).apply(block).also { set(name, it) } -inline fun MutableVisionGroup.cone( +public inline fun VisionContainerBuilder.cone( bottomRadius: Number, height: Number, upperRadius: Number = 0.0, diff --git a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Convex.kt b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Convex.kt index ad17c532..fd2b0389 100644 --- a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Convex.kt +++ b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Convex.kt @@ -5,6 +5,7 @@ package hep.dataforge.vision.solid import hep.dataforge.meta.Config import hep.dataforge.vision.AbstractVision import hep.dataforge.vision.MutableVisionGroup +import hep.dataforge.vision.VisionContainerBuilder import hep.dataforge.vision.set import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -12,7 +13,7 @@ import kotlinx.serialization.UseSerializers @Serializable @SerialName("solid.convex") -class Convex(val points: List) : AbstractVision(), Solid { +public class Convex(public val points: List) : AbstractVision(), Solid { override var properties: Config? = null @@ -23,17 +24,17 @@ class Convex(val points: List) : AbstractVision(), Solid { } -inline fun MutableVisionGroup.convex(name: String = "", action: ConvexBuilder.() -> Unit = {}) = +public inline fun VisionContainerBuilder.convex(name: String = "", action: ConvexBuilder.() -> Unit = {}): Convex = ConvexBuilder().apply(action).build().also { set(name, it) } -class ConvexBuilder { +public class ConvexBuilder { private val points = ArrayList() - fun point(x: Number, y: Number, z: Number) { + public fun point(x: Number, y: Number, z: Number) { points.add(Point3D(x, y, z)) } - fun build(): Convex { + public fun build(): Convex { return Convex(points) } } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Extruded.kt b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Extruded.kt index e7f92a57..8ca27740 100644 --- a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Extruded.kt +++ b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Extruded.kt @@ -4,6 +4,7 @@ package hep.dataforge.vision.solid import hep.dataforge.meta.Config import hep.dataforge.vision.AbstractVision import hep.dataforge.vision.MutableVisionGroup +import hep.dataforge.vision.VisionContainerBuilder import hep.dataforge.vision.set import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -13,21 +14,21 @@ import kotlin.math.cos import kotlin.math.sin -typealias Shape2D = List +public typealias Shape2D = List @Serializable -class Shape2DBuilder(private val points: MutableList = ArrayList()) { +public class Shape2DBuilder(private val points: MutableList = ArrayList()) { - fun point(x: Number, y: Number) { + public fun point(x: Number, y: Number) { points.add(Point2D(x, y)) } - infix fun Number.to(y: Number) = point(this, y) + public infix fun Number.to(y: Number): Unit = point(this, y) - fun build(): Shape2D = points + public fun build(): Shape2D = points } -fun Shape2DBuilder.polygon(vertices: Int, radius: Number) { +public fun Shape2DBuilder.polygon(vertices: Int, radius: Number) { require(vertices > 2) { "Polygon must have more than 2 vertices" } val angle = 2 * PI / vertices for (i in 0 until vertices) { @@ -36,13 +37,13 @@ fun Shape2DBuilder.polygon(vertices: Int, radius: Number) { } @Serializable -data class Layer(var x: Float, var y: Float, var z: Float, var scale: Float) +public data class Layer(var x: Float, var y: Float, var z: Float, var scale: Float) @Serializable @SerialName("solid.extrude") -class Extruded( - var shape: List = ArrayList(), - var layers: MutableList = ArrayList() +public class Extruded( + public var shape: List = ArrayList(), + public var layers: MutableList = ArrayList() ) : AbstractVision(), GeometrySolid { override var properties: Config? = null @@ -51,12 +52,12 @@ class Extruded( override var rotation: Point3D? = null override var scale: Point3D? = null - fun shape(block: Shape2DBuilder.() -> Unit) { + public fun shape(block: Shape2DBuilder.() -> Unit) { this.shape = Shape2DBuilder().apply(block).build() //TODO send invalidation signal } - fun layer(z: Number, x: Number = 0.0, y: Number = 0.0, scale: Number = 1.0) { + public fun layer(z: Number, x: Number = 0.0, y: Number = 0.0, scale: Number = 1.0) { layers.add(Layer(x.toFloat(), y.toFloat(), z.toFloat(), scale.toFloat())) //TODO send invalidation signal } @@ -107,10 +108,10 @@ class Extruded( geometryBuilder.cap(layers.last()) } - companion object { - const val TYPE = "geometry.3d.extruded" + public companion object { + public const val TYPE: String = "solid.extruded" } } -fun MutableVisionGroup.extrude(name: String = "", action: Extruded.() -> Unit = {}) = +public fun VisionContainerBuilder.extrude(name: String = "", action: Extruded.() -> Unit = {}): Extruded = Extruded().apply(action).also { set(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/GeometryBuilder.kt b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/GeometryBuilder.kt index b813da89..5d06ea2a 100644 --- a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/GeometryBuilder.kt +++ b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/GeometryBuilder.kt @@ -5,7 +5,7 @@ import hep.dataforge.meta.Meta /** * @param T the type of resulting geometry */ -interface GeometryBuilder { +public interface GeometryBuilder { /** * Add a face to 3D model. If one of the vertices is not present in the current geometry model list of vertices, * it is added automatically. @@ -13,12 +13,12 @@ interface GeometryBuilder { * @param normal optional external normal to the face * @param meta optional additional platform-specific parameters like color or texture index */ - fun face(vertex1: Point3D, vertex2: Point3D, vertex3: Point3D, normal: Point3D? = null, meta: Meta = Meta.EMPTY) + public fun face(vertex1: Point3D, vertex2: Point3D, vertex3: Point3D, normal: Point3D? = null, meta: Meta = Meta.EMPTY) - fun build(): T + public fun build(): T } -fun GeometryBuilder<*>.face4( +public fun GeometryBuilder<*>.face4( vertex1: Point3D, vertex2: Point3D, vertex3: Point3D, @@ -33,11 +33,11 @@ fun GeometryBuilder<*>.face4( /** * [GeometrySolid] is a [Solid] that can represent its own geometry as a set of polygons. */ -interface GeometrySolid : Solid { - fun toGeometry(geometryBuilder: GeometryBuilder) +public interface GeometrySolid : Solid { + public fun toGeometry(geometryBuilder: GeometryBuilder) } -fun GeometryBuilder.cap(shape: List, normal: Point3D? = null) { +public fun GeometryBuilder.cap(shape: List, normal: Point3D? = null) { //FIXME won't work for non-convex shapes val center = Point3D( shape.map { it.x }.average(), diff --git a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/PolyLine.kt b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/PolyLine.kt index 280e6b9b..67e22080 100644 --- a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/PolyLine.kt +++ b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/PolyLine.kt @@ -4,10 +4,12 @@ package hep.dataforge.vision.solid import hep.dataforge.meta.Config import hep.dataforge.meta.number +import hep.dataforge.names.Name import hep.dataforge.names.asName import hep.dataforge.names.plus import hep.dataforge.vision.AbstractVision import hep.dataforge.vision.MutableVisionGroup +import hep.dataforge.vision.VisionContainerBuilder import hep.dataforge.vision.set import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -15,7 +17,7 @@ import kotlinx.serialization.UseSerializers @Serializable @SerialName("solid.line") -class PolyLine(var points: List) : AbstractVision(), Solid { +public class PolyLine(public var points: List) : AbstractVision(), Solid { override var properties: Config? = null override var position: Point3D? = null @@ -23,13 +25,13 @@ class PolyLine(var points: List) : AbstractVision(), Solid { override var scale: Point3D? = null //var lineType by string() - var thickness by number(1.0, key = SolidMaterial.MATERIAL_KEY + THICKNESS_KEY) + public var thickness: Number by number(1.0, key = SolidMaterial.MATERIAL_KEY + THICKNESS_KEY) - companion object { - val THICKNESS_KEY = "thickness".asName() + public companion object { + public val THICKNESS_KEY: Name = "thickness".asName() } } -fun MutableVisionGroup.polyline(vararg points: Point3D, name: String = "", action: PolyLine.() -> Unit = {}) = +public fun VisionContainerBuilder.polyline(vararg points: Point3D, name: String = "", action: PolyLine.() -> Unit = {}): PolyLine = PolyLine(points.toList()).apply(action).also { set(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Proxy.kt b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Proxy.kt index bf2369a7..cc56f827 100644 --- a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Proxy.kt +++ b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Proxy.kt @@ -12,8 +12,8 @@ import kotlinx.serialization.Transient import kotlinx.serialization.UseSerializers import kotlin.collections.set -abstract class AbstractProxy : AbstractVision(), VisionGroup { - abstract val prototype: Vision +public abstract class AbstractProxy : AbstractVision(), VisionGroup { + public abstract val prototype: Vision override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? { return if (inherit) { @@ -33,7 +33,7 @@ abstract class AbstractProxy : AbstractVision(), VisionGroup { } override var styles: List - get() = properties[Vision.STYLE_KEY].stringList + prototype.styles + get() = (properties[Vision.STYLE_KEY]?.stringList ?: emptyList()) + prototype.styles set(value) { config[Vision.STYLE_KEY] = value } @@ -53,11 +53,11 @@ abstract class AbstractProxy : AbstractVision(), VisionGroup { */ @Serializable @SerialName("solid.proxy") -class Proxy private constructor( - val templateName: Name +public class Proxy private constructor( + public val templateName: Name ) : AbstractProxy(), Solid { - constructor(parent: SolidGroup, templateName: Name) : this(templateName) { + public constructor(parent: SolidGroup, templateName: Name) : this(templateName) { this.parent = parent } @@ -104,7 +104,7 @@ class Proxy private constructor( * A ProxyChild is created temporarily only to interact with properties, it does not store any values * (properties are stored in external cache) and created and destroyed on-demand). */ - inner class ProxyChild(val name: Name) : AbstractProxy() { + public inner class ProxyChild(public val name: Name) : AbstractProxy() { override val prototype: Vision get() = prototypeFor(name) @@ -136,12 +136,15 @@ class Proxy private constructor( } - companion object { - const val PROXY_CHILD_PROPERTY_PREFIX = "@child" + public companion object { + public const val PROXY_CHILD_PROPERTY_PREFIX: String = "@child" } } -val Vision.prototype: Vision +/** + * Get a vision prototype if it is a [Proxy] or vision itself if it is not + */ +public val Vision.prototype: Vision get() = when (this) { is AbstractProxy -> prototype else -> this @@ -150,7 +153,7 @@ val Vision.prototype: Vision /** * Create ref for existing prototype */ -fun SolidGroup.ref( +public fun SolidGroup.ref( templateName: Name, name: String = "" ): Proxy = Proxy(this, templateName).also { set(name, it) } @@ -158,7 +161,7 @@ fun SolidGroup.ref( /** * Add new proxy wrapping given object and automatically adding it to the prototypes */ -fun SolidGroup.proxy( +public fun SolidGroup.proxy( name: String, obj: Solid, templateName: Name = name.toName() @@ -173,12 +176,3 @@ fun SolidGroup.proxy( } return ref(templateName, name) } - -fun SolidGroup.proxyGroup( - name: String, - templateName: Name = name.toName(), - block: MutableVisionGroup.() -> Unit -): Proxy { - val group = SolidGroup().apply(block) - return proxy(name, group, templateName) -} diff --git a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Solid.kt b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Solid.kt index 721d38ee..fce83d6d 100644 --- a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Solid.kt +++ b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Solid.kt @@ -4,65 +4,63 @@ package hep.dataforge.vision.solid import hep.dataforge.meta.* import hep.dataforge.meta.descriptors.NodeDescriptor +import hep.dataforge.names.Name import hep.dataforge.names.asName import hep.dataforge.names.plus import hep.dataforge.output.Renderer import hep.dataforge.values.ValueType import hep.dataforge.values.asValue import hep.dataforge.vision.Vision +import hep.dataforge.vision.Vision.Companion.VISIBLE_KEY import hep.dataforge.vision.enum import hep.dataforge.vision.solid.Solid.Companion.DETAIL_KEY import hep.dataforge.vision.solid.Solid.Companion.IGNORE_KEY import hep.dataforge.vision.solid.Solid.Companion.LAYER_KEY -import hep.dataforge.vision.solid.Solid.Companion.VISIBLE_KEY import kotlinx.serialization.UseSerializers /** * Interface for 3-dimensional [Vision] */ -interface Solid : Vision { - var position: Point3D? - var rotation: Point3D? - var scale: Point3D? +public interface Solid : Vision { + public var position: Point3D? + public var rotation: Point3D? + public var scale: Point3D? override val descriptor: NodeDescriptor? get() = Companion.descriptor - companion object { - - val VISIBLE_KEY = "visible".asName() - + public companion object { // val SELECTED_KEY = "selected".asName() - val DETAIL_KEY = "detail".asName() - val LAYER_KEY = "layer".asName() - val IGNORE_KEY = "ignore".asName() + public val DETAIL_KEY: Name = "detail".asName() + public val LAYER_KEY: Name = "layer".asName() + public val IGNORE_KEY: Name = "ignore".asName() - val GEOMETRY_KEY = "geometry".asName() + public val GEOMETRY_KEY: Name = "geometry".asName() - val X_KEY = "x".asName() - val Y_KEY = "y".asName() - val Z_KEY = "z".asName() + public val X_KEY: Name = "x".asName() + public val Y_KEY: Name = "y".asName() + public val Z_KEY: Name = "z".asName() - val POSITION_KEY = "pos".asName() + public val POSITION_KEY: Name = "pos".asName() - val X_POSITION_KEY = POSITION_KEY + X_KEY - val Y_POSITION_KEY = POSITION_KEY + Y_KEY - val Z_POSITION_KEY = POSITION_KEY + Z_KEY + public val X_POSITION_KEY: Name = POSITION_KEY + X_KEY + public val Y_POSITION_KEY: Name = POSITION_KEY + Y_KEY + public val Z_POSITION_KEY: Name = POSITION_KEY + Z_KEY - val ROTATION = "rotation".asName() + public val ROTATION: Name = "rotation".asName() - val X_ROTATION_KEY = ROTATION + X_KEY - val Y_ROTATION_KEY = ROTATION + Y_KEY - val Z_ROTATION_KEY = ROTATION + Z_KEY + public val X_ROTATION_KEY: Name = ROTATION + X_KEY + public val Y_ROTATION_KEY: Name = ROTATION + Y_KEY + public val Z_ROTATION_KEY: Name = ROTATION + Z_KEY - val ROTATION_ORDER_KEY = ROTATION + "order" + public val ROTATION_ORDER_KEY: Name = ROTATION + "order" - val SCALE_KEY = "scale".asName() + public val SCALE_KEY: Name = "scale".asName() - val X_SCALE_KEY = SCALE_KEY + X_KEY - val Y_SCALE_KEY = SCALE_KEY + Y_KEY - val Z_SCALE_KEY = SCALE_KEY + Z_KEY + public val X_SCALE_KEY: Name = SCALE_KEY + X_KEY + public val Y_SCALE_KEY: Name = SCALE_KEY + Y_KEY + public val Z_SCALE_KEY: Name = SCALE_KEY + Z_KEY - val descriptor by lazy { + public val descriptor: NodeDescriptor by lazy { NodeDescriptor { value(VISIBLE_KEY) { type(ValueType.BOOLEAN) @@ -100,20 +98,20 @@ interface Solid : Vision { } /** - * Count number of layers to the top object. Return 1 if this is top layer + * Get the layer number this solid belongs to. Return 0 if layer is not defined. */ -var Solid.layer: Int +public var Solid.layer: Int get() = properties?.getItem(LAYER_KEY).int ?: 0 set(value) { config[LAYER_KEY] = value.asValue() } -fun Renderer.render(meta: Meta = Meta.EMPTY, action: SolidGroup.() -> Unit) = +public fun Renderer.render(meta: Meta = Meta.EMPTY, action: SolidGroup.() -> Unit): Unit = render(SolidGroup().apply(action), meta) // Common properties -enum class RotationOrder { +public enum class RotationOrder { XYZ, YZX, ZXY, @@ -125,7 +123,7 @@ enum class RotationOrder { /** * Rotation order */ -var Solid.rotationOrder: RotationOrder +public var Solid.rotationOrder: RotationOrder get() = getItem(Solid.ROTATION_ORDER_KEY).enum() ?: RotationOrder.XYZ set(value) = setItem(Solid.ROTATION_ORDER_KEY, value.name.asValue()) @@ -133,19 +131,15 @@ var Solid.rotationOrder: RotationOrder /** * Preferred number of polygons for displaying the object. If not defined, uses shape or renderer default. Not inherited */ -var Solid.detail: Int? +public var Solid.detail: Int? get() = getProperty(DETAIL_KEY, false).int set(value) = setItem(DETAIL_KEY, value?.asValue()) -var Vision.visible: Boolean? - get() = getItem(VISIBLE_KEY).boolean - set(value) = setItem(VISIBLE_KEY, value?.asValue()) - /** * If this property is true, the object will be ignored on render. * Property is not inherited. */ -var Vision.ignore: Boolean? +public var Vision.ignore: Boolean? get() = getProperty(IGNORE_KEY, false).boolean set(value) = setItem(IGNORE_KEY, value?.asValue()) @@ -156,21 +150,21 @@ var Vision.ignore: Boolean? private fun Solid.position(): Point3D = position ?: Point3D(0.0, 0.0, 0.0).also { position = it } -var Solid.x: Number +public var Solid.x: Number get() = position?.x ?: 0f set(value) { position().x = value.toDouble() propertyChanged(Solid.X_POSITION_KEY) } -var Solid.y: Number +public var Solid.y: Number get() = position?.y ?: 0f set(value) { position().y = value.toDouble() propertyChanged(Solid.Y_POSITION_KEY) } -var Solid.z: Number +public var Solid.z: Number get() = position?.z ?: 0f set(value) { position().z = value.toDouble() @@ -180,21 +174,21 @@ var Solid.z: Number private fun Solid.rotation(): Point3D = rotation ?: Point3D(0.0, 0.0, 0.0).also { rotation = it } -var Solid.rotationX: Number +public var Solid.rotationX: Number get() = rotation?.x ?: 0f set(value) { rotation().x = value.toDouble() propertyChanged(Solid.X_ROTATION_KEY) } -var Solid.rotationY: Number +public var Solid.rotationY: Number get() = rotation?.y ?: 0f set(value) { rotation().y = value.toDouble() propertyChanged(Solid.Y_ROTATION_KEY) } -var Solid.rotationZ: Number +public var Solid.rotationZ: Number get() = rotation?.z ?: 0f set(value) { rotation().z = value.toDouble() @@ -204,21 +198,21 @@ var Solid.rotationZ: Number private fun Solid.scale(): Point3D = scale ?: Point3D(1.0, 1.0, 1.0).also { scale = it } -var Solid.scaleX: Number +public var Solid.scaleX: Number get() = scale?.x ?: 1f set(value) { scale().x = value.toDouble() propertyChanged(Solid.X_SCALE_KEY) } -var Solid.scaleY: Number +public var Solid.scaleY: Number get() = scale?.y ?: 1f set(value) { scale().y = value.toDouble() propertyChanged(Solid.Y_SCALE_KEY) } -var Solid.scaleZ: Number +public var Solid.scaleZ: Number get() = scale?.z ?: 1f set(value) { scale().z = value.toDouble() diff --git a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/SolidGroup.kt b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/SolidGroup.kt index 83e2deff..1e2dd7a4 100644 --- a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/SolidGroup.kt +++ b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/SolidGroup.kt @@ -15,9 +15,9 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.UseSerializers import kotlin.collections.set -interface PrototypeHolder { - val parent: VisionGroup? - val prototypes: MutableVisionGroup? +public interface PrototypeHolder { + public val parent: VisionGroup? + public val prototypes: MutableVisionGroup? } /** @@ -25,7 +25,7 @@ interface PrototypeHolder { */ @Serializable @SerialName("group.solid") -class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder { +public class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder { override var styleSheet: StyleSheet? = null @@ -39,7 +39,7 @@ class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder { /** * Create or edit prototype node as a group */ - fun prototypes(builder: MutableVisionGroup.() -> Unit): Unit { + public fun prototypes(builder: MutableVisionGroup.() -> Unit): Unit { (prototypes ?: Prototypes().also { prototypes = it attach(it) @@ -79,33 +79,33 @@ class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder { override fun createGroup(): SolidGroup = SolidGroup() - companion object { + public companion object { // val PROTOTYPES_KEY = NameToken("@prototypes") @OptIn(DFExperimental::class) - fun parseJson(json: String): SolidGroup = - SolidManager.jsonForSolids.parse(serializer(), json).also { it.attachChildren() } + public fun decodeFromString(json: String): SolidGroup = + SolidManager.jsonForSolids.decodeFromString(serializer(), json).also { it.attachChildren() } } } @Suppress("FunctionName") -fun SolidGroup(block: SolidGroup.() -> Unit): SolidGroup { +public fun SolidGroup(block: SolidGroup.() -> Unit): SolidGroup { return SolidGroup().apply(block) } /** * Ger a prototype redirecting the request to the parent if prototype is not found */ -tailrec fun PrototypeHolder.getPrototype(name: Name): Solid? = +public tailrec fun PrototypeHolder.getPrototype(name: Name): Solid? = prototypes?.get(name) as? Solid ?: (parent as? PrototypeHolder)?.getPrototype(name) -fun MutableVisionGroup.group(name: Name = Name.EMPTY, action: SolidGroup.() -> Unit = {}): SolidGroup = +public fun MutableVisionGroup.group(name: Name = Name.EMPTY, action: SolidGroup.() -> Unit = {}): SolidGroup = SolidGroup().apply(action).also { set(name, it) } /** * Define a group with given [name], attach it to this parent and return it. */ -fun MutableVisionGroup.group(name: String, action: SolidGroup.() -> Unit = {}): SolidGroup = +public fun MutableVisionGroup.group(name: String, action: SolidGroup.() -> Unit = {}): SolidGroup = SolidGroup().apply(action).also { set(name, it) } /** diff --git a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/SolidLabel.kt b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/SolidLabel.kt index c740f778..c7f459a5 100644 --- a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/SolidLabel.kt +++ b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/SolidLabel.kt @@ -5,6 +5,7 @@ package hep.dataforge.vision.solid import hep.dataforge.meta.Config import hep.dataforge.vision.AbstractVision import hep.dataforge.vision.MutableVisionGroup +import hep.dataforge.vision.VisionContainerBuilder import hep.dataforge.vision.set import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -12,7 +13,7 @@ import kotlinx.serialization.UseSerializers @Serializable @SerialName("solid.label") -class SolidLabel(var text: String, var fontSize: Double, var fontFamily: String) : AbstractVision(), Solid { +public class SolidLabel(public var text: String, public var fontSize: Double, public var fontFamily: String) : AbstractVision(), Solid { override var properties: Config? = null override var position: Point3D? = null @@ -21,11 +22,10 @@ class SolidLabel(var text: String, var fontSize: Double, var fontFamily: String) } -fun MutableVisionGroup.label( +public fun VisionContainerBuilder.label( text: String, fontSize: Number = 20, fontFamily: String = "Arial", name: String = "", - action: SolidLabel.() -> Unit = {} -) = - SolidLabel(text, fontSize.toDouble(), fontFamily).apply(action).also { set(name, it) } \ No newline at end of file + action: SolidLabel.() -> Unit = {}, +): SolidLabel = SolidLabel(text, fontSize.toDouble(), fontFamily).apply(action).also { set(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/SolidManager.kt b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/SolidManager.kt index 36a46425..5cc3948c 100644 --- a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/SolidManager.kt +++ b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/SolidManager.kt @@ -12,20 +12,17 @@ import hep.dataforge.vision.Vision import hep.dataforge.vision.VisionForm import hep.dataforge.vision.VisionManager import hep.dataforge.vision.VisionManager.Companion.VISION_SERIAL_MODULE_TARGET +import kotlinx.serialization.DeserializationStrategy +import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.KSerializer -import kotlinx.serialization.UnstableDefault import kotlinx.serialization.json.Json -import kotlinx.serialization.json.JsonConfiguration -import kotlinx.serialization.modules.SerialModule -import kotlinx.serialization.modules.SerialModuleCollector -import kotlinx.serialization.modules.SerializersModule -import kotlinx.serialization.modules.contextual +import kotlinx.serialization.modules.* import kotlin.reflect.KClass @DFExperimental -private class SolidForm( +private class SolidForm( override val type: KClass, - override val serializer: KSerializer + override val serializer: KSerializer, ) : VisionForm { private fun Solid.update(meta: Meta) { @@ -46,12 +43,12 @@ private class SolidForm( } } +@OptIn(ExperimentalSerializationApi::class) @DFExperimental -@OptIn(UnstableDefault::class) -private fun SerialModule.extractFactories(): List> { +private fun SerializersModule.extractFactories(): List> { val list = ArrayList>() - val collector = object : SerialModuleCollector { + val collector = object : SerializersModuleCollector { override fun contextual(kClass: KClass, serializer: KSerializer) { //Do nothing } @@ -59,7 +56,7 @@ private fun SerialModule.extractFactories(): List> { override fun polymorphic( baseClass: KClass, actualClass: KClass, - actualSerializer: KSerializer + actualSerializer: KSerializer, ) { if (baseClass == Vision::class) { @Suppress("UNCHECKED_CAST") val factory = SolidForm( @@ -70,34 +67,41 @@ private fun SerialModule.extractFactories(): List> { } } + override fun polymorphicDefault( + baseClass: KClass, + defaultSerializerProvider: (className: String?) -> DeserializationStrategy?, + ) { + TODO("Not yet implemented") + } + } dumpTo(collector) return list } @DFExperimental -class SolidManager(meta: Meta) : AbstractPlugin(meta) { +public class SolidManager(meta: Meta) : AbstractPlugin(meta) { - val visionManager by require(VisionManager) + public val visionManager: VisionManager by require(VisionManager) override val tag: PluginTag get() = Companion.tag - override fun provideTop(target: String): Map = when (target) { + override fun content(target: String): Map = when (target) { VisionForm.TYPE -> serialModule.extractFactories().associateBy { it.name } VISION_SERIAL_MODULE_TARGET -> mapOf(tag.name.toName() to serialModule) - else -> super.provideTop(target) + else -> super.content(target) } - companion object : PluginFactory { + public companion object : PluginFactory { override val tag: PluginTag = PluginTag(name = "visual.spatial", group = PluginTag.DATAFORGE_GROUP) override val type: KClass = SolidManager::class override fun invoke(meta: Meta, context: Context): SolidManager = SolidManager(meta) - val serialModule = SerializersModule { + public val serialModule: SerializersModule = SerializersModule { contextual(Point3DSerializer) contextual(Point2DSerializer) - polymorphic(Vision::class, Solid::class) { + polymorphic(Vision::class) { subclass(SimpleVisionGroup.serializer()) subclass(SolidGroup.serializer()) subclass(Proxy.serializer()) @@ -112,15 +116,12 @@ class SolidManager(meta: Meta) : AbstractPlugin(meta) { } } - @OptIn(UnstableDefault::class) - val jsonForSolids = Json( - JsonConfiguration( - prettyPrint = true, - useArrayPolymorphism = false, - encodeDefaults = false, - ignoreUnknownKeys = true - ), - context = serialModule - ) + val jsonForSolids = Json { + prettyPrint = true + useArrayPolymorphism = false + encodeDefaults = false + ignoreUnknownKeys = true + serializersModule = this@Companion.serialModule + } } } diff --git a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/SolidMaterial.kt b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/SolidMaterial.kt index d5a29a55..d1a9b121 100644 --- a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/SolidMaterial.kt +++ b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/SolidMaterial.kt @@ -3,6 +3,7 @@ package hep.dataforge.vision.solid import hep.dataforge.meta.* import hep.dataforge.meta.descriptors.NodeDescriptor import hep.dataforge.meta.descriptors.attributes +import hep.dataforge.names.Name import hep.dataforge.names.asName import hep.dataforge.names.plus import hep.dataforge.values.ValueType @@ -13,41 +14,41 @@ import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_KEY import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_OPACITY_KEY import hep.dataforge.vision.widgetType -class SolidMaterial : Scheme() { +public class SolidMaterial : Scheme() { /** * Primary web-color for the material */ - var color by string(key = COLOR_KEY) + public var color: String? by string(key = COLOR_KEY) /** * Specular color for phong material */ - var specularColor by string(key = SPECULAR_COLOR_KEY) + public var specularColor: String? by string(key = SPECULAR_COLOR_KEY) /** * Opacity */ - var opacity by float(1f, key = OPACITY_KEY) + public var opacity: Float by float(1f, key = OPACITY_KEY) /** * Replace material by wire frame */ - var wireframe by boolean(false, WIREFRAME_KEY) + public var wireframe: Boolean by boolean(false, WIREFRAME_KEY) - companion object : SchemeSpec(::SolidMaterial) { + public companion object : SchemeSpec(::SolidMaterial) { - val MATERIAL_KEY = "material".asName() + public val MATERIAL_KEY: Name = "material".asName() internal val COLOR_KEY = "color".asName() - val MATERIAL_COLOR_KEY = MATERIAL_KEY + COLOR_KEY + public val MATERIAL_COLOR_KEY: Name = MATERIAL_KEY + COLOR_KEY internal val SPECULAR_COLOR_KEY = "specularColor".asName() - val MATERIAL_SPECULAR_COLOR_KEY = MATERIAL_KEY + SPECULAR_COLOR_KEY + public val MATERIAL_SPECULAR_COLOR_KEY: Name = MATERIAL_KEY + SPECULAR_COLOR_KEY internal val OPACITY_KEY = "opacity".asName() - val MATERIAL_OPACITY_KEY = MATERIAL_KEY + OPACITY_KEY + public val MATERIAL_OPACITY_KEY: Name = MATERIAL_KEY + OPACITY_KEY internal val WIREFRAME_KEY = "wireframe".asName() - val MATERIAL_WIREFRAME_KEY = MATERIAL_KEY + WIREFRAME_KEY + public val MATERIAL_WIREFRAME_KEY: Name = MATERIAL_KEY + WIREFRAME_KEY - val descriptor by lazy { + public val descriptor: NodeDescriptor by lazy { //must be lazy to avoid initialization bug NodeDescriptor { value(COLOR_KEY) { @@ -77,18 +78,18 @@ class SolidMaterial : Scheme() { /** * Set color as web-color */ -fun Solid.color(webColor: String) { +public fun Solid.color(webColor: String) { setItem(MATERIAL_COLOR_KEY, webColor.asValue()) } /** * Set color as integer */ -fun Solid.color(rgb: Int) { +public fun Solid.color(rgb: Int) { setItem(MATERIAL_COLOR_KEY, rgb.asValue()) } -fun Solid.color(r: UByte, g: UByte, b: UByte) = setItem( +public fun Solid.color(r: UByte, g: UByte, b: UByte): Unit = setItem( MATERIAL_COLOR_KEY, Colors.rgbToMeta(r, g, b) ) @@ -96,16 +97,16 @@ fun Solid.color(r: UByte, g: UByte, b: UByte) = setItem( /** * Web colors representation of the color in `#rrggbb` format or HTML name */ -var Solid.color: String? +public var Solid.color: String? get() = getItem(MATERIAL_COLOR_KEY)?.let { Colors.fromMeta(it) } set(value) { setItem(MATERIAL_COLOR_KEY, value?.asValue()) } -val Solid.material: SolidMaterial? +public val Solid.material: SolidMaterial? get() = getItem(MATERIAL_KEY).node?.let { SolidMaterial.wrap(it) } -fun Solid.material(builder: SolidMaterial.() -> Unit) { +public fun Solid.material(builder: SolidMaterial.() -> Unit) { val node = config[MATERIAL_KEY].node if (node != null) { SolidMaterial.update(node, builder) @@ -114,7 +115,7 @@ fun Solid.material(builder: SolidMaterial.() -> Unit) { } } -var Solid.opacity: Double? +public var Solid.opacity: Double? get() = getItem(MATERIAL_OPACITY_KEY).double set(value) { setItem(MATERIAL_OPACITY_KEY, value?.asValue()) diff --git a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Sphere.kt b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Sphere.kt index 13cb7fbd..f21dfbc6 100644 --- a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Sphere.kt +++ b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Sphere.kt @@ -5,6 +5,7 @@ package hep.dataforge.vision.solid import hep.dataforge.meta.Config import hep.dataforge.vision.AbstractVision import hep.dataforge.vision.MutableVisionGroup +import hep.dataforge.vision.VisionContainerBuilder import hep.dataforge.vision.set import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -15,12 +16,12 @@ import kotlin.math.sin @Serializable @SerialName("solid.sphere") -class Sphere( - var radius: Float, - var phiStart: Float = 0f, - var phi: Float = PI2, - var thetaStart: Float = 0f, - var theta: Float = PI.toFloat() +public class Sphere( + public var radius: Float, + public var phiStart: Float = 0f, + public var phi: Float = PI2, + public var thetaStart: Float = 0f, + public var theta: Float = PI.toFloat() ) : AbstractVision(), GeometrySolid { override var properties: Config? = null @@ -60,13 +61,13 @@ class Sphere( } } -inline fun MutableVisionGroup.sphere( +public inline fun VisionContainerBuilder.sphere( radius: Number, phi: Number = 2 * PI, theta: Number = PI, name: String = "", action: Sphere.() -> Unit = {} -) = Sphere( +): Sphere = Sphere( radius.toFloat(), phi = phi.toFloat(), theta = theta.toFloat() diff --git a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Tube.kt b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Tube.kt index a8b699c5..9bc2add9 100644 --- a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Tube.kt +++ b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/Tube.kt @@ -5,6 +5,7 @@ package hep.dataforge.vision.solid import hep.dataforge.meta.Config import hep.dataforge.vision.AbstractVision import hep.dataforge.vision.MutableVisionGroup +import hep.dataforge.vision.VisionContainerBuilder import hep.dataforge.vision.set import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -18,12 +19,12 @@ import kotlin.math.sin */ @Serializable @SerialName("solid.tube") -class Tube( - var radius: Float, - var height: Float, - var innerRadius: Float = 0f, - var startAngle: Float = 0f, - var angle: Float = PI2 +public class Tube( + public var radius: Float, + public var height: Float, + public var innerRadius: Float = 0f, + public var startAngle: Float = 0f, + public var angle: Float = PI2 ) : AbstractVision(), GeometrySolid { override var position: Point3D? = null @@ -129,7 +130,7 @@ class Tube( } -inline fun MutableVisionGroup.tube( +public inline fun VisionContainerBuilder.tube( r: Number, height: Number, innerRadius: Number = 0f, diff --git a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/geometry.kt b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/geometry.kt index 8764bc41..1eb501b0 100644 --- a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/geometry.kt +++ b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/geometry.kt @@ -1,47 +1,48 @@ package hep.dataforge.vision.solid import hep.dataforge.meta.Meta +import hep.dataforge.meta.MetaBuilder import hep.dataforge.meta.get import hep.dataforge.meta.number import kotlin.math.PI -object World { - val ZERO = Point3D(0.0, 0.0, 0.0) - val ONE = Point3D(1.0, 1.0, 1.0) +public object World { + public val ZERO: Point3D = Point3D(0.0, 0.0, 0.0) + public val ONE: Point3D = Point3D(1.0, 1.0, 1.0) } -const val PI2: Float = 2 * PI.toFloat() +public const val PI2: Float = 2 * PI.toFloat() -expect class Point2D(x: Number, y: Number) { - var x: Double - var y: Double +public expect class Point2D(x: Number, y: Number) { + public var x: Double + public var y: Double } -operator fun Point2D.component1() = x -operator fun Point2D.component2() = y +public operator fun Point2D.component1(): Double = x +public operator fun Point2D.component2(): Double = y -fun Point2D.toMeta() = Meta { +public fun Point2D.toMeta(): Meta = Meta { Solid.X_KEY put x Solid.Y_KEY put y } -fun Meta.point2D() = Point2D(this["x"].number ?: 0, this["y"].number ?: 0) +internal fun Meta.point2D(): Point2D = Point2D(this["x"].number ?: 0, this["y"].number ?: 0) -expect class Point3D(x: Number, y: Number, z: Number) { - var x: Double - var y: Double - var z: Double +public expect class Point3D(x: Number, y: Number, z: Number) { + public var x: Double + public var y: Double + public var z: Double } -expect operator fun Point3D.plus(other: Point3D): Point3D +public expect operator fun Point3D.plus(other: Point3D): Point3D -operator fun Point3D.component1() = x -operator fun Point3D.component2() = y -operator fun Point3D.component3() = z +public operator fun Point3D.component1(): Double = x +public operator fun Point3D.component2(): Double = y +public operator fun Point3D.component3(): Double = z -fun Meta.point3D() = Point3D(this["x"].number ?: 0, this["y"].number ?: 0, this["y"].number ?: 0) +internal fun Meta.point3D() = Point3D(this["x"].number ?: 0, this["y"].number ?: 0, this["y"].number ?: 0) -fun Point3D.toMeta() = Meta { +public fun Point3D.toMeta(): MetaBuilder = Meta { Solid.X_KEY put x Solid.Y_KEY put y Solid.Z_KEY put z diff --git a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/serialization.kt b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/serialization.kt index 0b0a4d0b..25724fab 100644 --- a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/serialization.kt +++ b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/serialization.kt @@ -2,6 +2,7 @@ package hep.dataforge.vision.solid import hep.dataforge.meta.DFExperimental import hep.dataforge.meta.double +import hep.dataforge.meta.transformations.MetaConverter.Companion.double import hep.dataforge.names.NameToken import hep.dataforge.vision.MutableVisionGroup import hep.dataforge.vision.Vision @@ -10,34 +11,19 @@ import kotlinx.serialization.* import kotlinx.serialization.builtins.MapSerializer import kotlinx.serialization.builtins.nullable import kotlinx.serialization.builtins.serializer +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.descriptors.buildClassSerialDescriptor +import kotlinx.serialization.descriptors.element +import kotlinx.serialization.encoding.* -inline fun Decoder.decodeStructure( - desc: SerialDescriptor, - vararg typeParams: KSerializer<*> = emptyArray(), - crossinline block: CompositeDecoder.() -> R -): R { - val decoder = beginStructure(desc, *typeParams) - val res = decoder.block() - decoder.endStructure(desc) - return res -} - -inline fun Encoder.encodeStructure( - desc: SerialDescriptor, - vararg typeParams: KSerializer<*> = emptyArray(), - block: CompositeEncoder.() -> Unit -) { - val encoder = beginStructure(desc, *typeParams) - encoder.block() - encoder.endStructure(desc) -} +@OptIn(ExperimentalSerializationApi::class) @Serializer(Point3D::class) -object Point3DSerializer : KSerializer { - override val descriptor: SerialDescriptor = SerialDescriptor("hep.dataforge.vis.spatial.Point3D") { - double("x", true) - double("y", true) - double("z", true) +public object Point3DSerializer : KSerializer { + override val descriptor: SerialDescriptor = buildClassSerialDescriptor("hep.dataforge.vis.spatial.Point3D") { + element("x") + element("y") + element("z") } override fun deserialize(decoder: Decoder): Point3D { @@ -47,7 +33,7 @@ object Point3DSerializer : KSerializer { decoder.decodeStructure(descriptor) { loop@ while (true) { when (val i = decodeElementIndex(descriptor)) { - CompositeDecoder.READ_DONE -> break@loop + CompositeDecoder.DECODE_DONE -> break@loop 0 -> x = decodeNullableSerializableElement(descriptor, 0, Double.serializer().nullable) ?: 0.0 1 -> y = decodeNullableSerializableElement(descriptor, 1, Double.serializer().nullable) ?: 0.0 2 -> z = decodeNullableSerializableElement(descriptor, 2, Double.serializer().nullable) ?: 0.0 @@ -67,11 +53,12 @@ object Point3DSerializer : KSerializer { } } +@OptIn(ExperimentalSerializationApi::class) @Serializer(Point2D::class) -object Point2DSerializer : KSerializer { - override val descriptor: SerialDescriptor = SerialDescriptor("hep.dataforge.vis.spatial.Point2D") { - double("x", true) - double("y", true) +public object Point2DSerializer : KSerializer { + override val descriptor: SerialDescriptor = buildClassSerialDescriptor("hep.dataforge.vis.spatial.Point2D") { + element("x") + element("y") } override fun deserialize(decoder: Decoder): Point2D { @@ -80,7 +67,7 @@ object Point2DSerializer : KSerializer { decoder.decodeStructure(descriptor) { loop@ while (true) { when (val i = decodeElementIndex(descriptor)) { - CompositeDecoder.READ_DONE -> break@loop + CompositeDecoder.DECODE_DONE -> break@loop 0 -> x = decodeNullableSerializableElement(descriptor, 0, Double.serializer().nullable) ?: 0.0 1 -> y = decodeNullableSerializableElement(descriptor, 1, Double.serializer().nullable) ?: 0.0 else -> throw SerializationException("Unknown index $i") @@ -98,6 +85,7 @@ object Point2DSerializer : KSerializer { } } +@OptIn(ExperimentalSerializationApi::class) @Serializer(MutableVisionGroup::class) internal object PrototypesSerializer : KSerializer { @@ -120,10 +108,10 @@ internal object PrototypesSerializer : KSerializer { } @OptIn(DFExperimental::class) -fun Vision.stringify(): String = SolidManager.jsonForSolids.stringify(Vision.serializer(), this) +public fun Vision.encodeToString(): String = SolidManager.jsonForSolids.encodeToString(Vision.serializer(), this) @OptIn(DFExperimental::class) -fun Vision.Companion.parseJson(str: String) = SolidManager.jsonForSolids.parse(serializer(), str).also { +public fun Vision.Companion.decodeFromString(str: String): Vision = SolidManager.jsonForSolids.decodeFromString(serializer(), str).also { if(it is VisionGroup){ it.attachChildren() } diff --git a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/specifications/Axes.kt b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/specifications/Axes.kt index 8a45e0a4..5e835c83 100644 --- a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/specifications/Axes.kt +++ b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/specifications/Axes.kt @@ -2,13 +2,13 @@ package hep.dataforge.vision.solid.specifications import hep.dataforge.meta.* -class Axes : Scheme() { - var visible by boolean(!config.isEmpty()) - var size by double(AXIS_SIZE) - var width by double(AXIS_WIDTH) +public class Axes : Scheme() { + public var visible: Boolean by boolean(!config.isEmpty()) + public var size: Double by double(AXIS_SIZE) + public var width: Double by double(AXIS_WIDTH) - companion object : SchemeSpec(::Axes) { - const val AXIS_SIZE = 1000.0 - const val AXIS_WIDTH = 3.0 + public companion object : SchemeSpec(::Axes) { + public const val AXIS_SIZE: Double = 1000.0 + public const val AXIS_WIDTH: Double = 3.0 } } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/specifications/Camera.kt b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/specifications/Camera.kt index dbd79bd8..396df8a4 100644 --- a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/specifications/Camera.kt +++ b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/specifications/Camera.kt @@ -6,24 +6,24 @@ import hep.dataforge.meta.double import hep.dataforge.meta.int import kotlin.math.PI -class Camera : Scheme() { - var fov by int(FIELD_OF_VIEW) +public class Camera : Scheme() { + public var fov: Int by int(FIELD_OF_VIEW) //var aspect by double(1.0) - var nearClip by double(NEAR_CLIP) - var farClip by double(FAR_CLIP) + public var nearClip: Double by double(NEAR_CLIP) + public var farClip: Double by double(FAR_CLIP) - var distance by double(INITIAL_DISTANCE) - var azimuth by double(INITIAL_AZIMUTH) - var latitude by double(INITIAL_LATITUDE) - val zenith: Double get() = PI / 2 - latitude + public var distance: Double by double(INITIAL_DISTANCE) + public var azimuth: Double by double(INITIAL_AZIMUTH) + public var latitude: Double by double(INITIAL_LATITUDE) + public val zenith: Double get() = PI / 2 - latitude - companion object : SchemeSpec(::Camera) { - const val INITIAL_DISTANCE = 300.0 - const val INITIAL_AZIMUTH = 0.0 - const val INITIAL_LATITUDE = PI / 6 - const val NEAR_CLIP = 0.1 - const val FAR_CLIP = 10000.0 - const val FIELD_OF_VIEW = 75 + public companion object : SchemeSpec(::Camera) { + public const val INITIAL_DISTANCE: Double = 300.0 + public const val INITIAL_AZIMUTH: Double = 0.0 + public const val INITIAL_LATITUDE: Double = PI / 6 + public const val NEAR_CLIP: Double = 0.1 + public const val FAR_CLIP: Double = 10000.0 + public const val FIELD_OF_VIEW: Int = 75 } } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/specifications/Canvas3DOptions.kt b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/specifications/Canvas3DOptions.kt index 9e4ceed6..33ba4bd0 100644 --- a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/specifications/Canvas3DOptions.kt +++ b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/specifications/Canvas3DOptions.kt @@ -5,11 +5,11 @@ import hep.dataforge.meta.SchemeSpec import hep.dataforge.meta.int import hep.dataforge.meta.spec -class Canvas3DOptions : Scheme() { - var axes by spec(Axes, Axes.empty()) - var camera by spec(Camera, Camera.empty()) - var controls by spec(Controls, Controls.empty()) - var minSize by int(300) +public class Canvas3DOptions : Scheme() { + public var axes: Axes by spec(Axes, Axes.empty()) + public var camera: Camera by spec(Camera, Camera.empty()) + public var controls: Controls by spec(Controls, Controls.empty()) + public var minSize: Int by int(300) - companion object : SchemeSpec(::Canvas3DOptions) + public companion object : SchemeSpec(::Canvas3DOptions) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/transform/RemoveSingleChild.kt b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/transform/RemoveSingleChild.kt index 36b6db76..2fc1ffdb 100644 --- a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/transform/RemoveSingleChild.kt +++ b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/transform/RemoveSingleChild.kt @@ -1,5 +1,6 @@ package hep.dataforge.vision.solid.transform +import hep.dataforge.meta.DFExperimental import hep.dataforge.meta.update import hep.dataforge.names.asName import hep.dataforge.vision.MutableVisionGroup @@ -7,6 +8,7 @@ import hep.dataforge.vision.Vision import hep.dataforge.vision.VisionGroup import hep.dataforge.vision.solid.* +@DFExperimental internal fun mergeChild(parent: VisionGroup, child: Vision): Vision { return child.apply { @@ -32,6 +34,7 @@ internal fun mergeChild(parent: VisionGroup, child: Vision): Vision { } } +@DFExperimental object RemoveSingleChild : VisualTreeTransform() { override fun SolidGroup.transformInPlace() { diff --git a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/transform/UnRef.kt b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/transform/UnRef.kt index 1eeec5ad..9028b667 100644 --- a/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/transform/UnRef.kt +++ b/visionforge-solid/src/commonMain/kotlin/hep/dataforge/vision/solid/transform/UnRef.kt @@ -1,5 +1,6 @@ package hep.dataforge.vision.solid.transform +import hep.dataforge.meta.DFExperimental import hep.dataforge.names.Name import hep.dataforge.names.asName import hep.dataforge.vision.MutableVisionGroup @@ -7,6 +8,7 @@ import hep.dataforge.vision.VisionGroup import hep.dataforge.vision.solid.Proxy import hep.dataforge.vision.solid.SolidGroup +@DFExperimental object UnRef : VisualTreeTransform() { private fun VisionGroup.countRefs(): Map { return children.values.fold(HashMap()) { reducer, obj -> diff --git a/visionforge-solid/src/commonTest/kotlin/hep/dataforge/vision/solid/ConvexTest.kt b/visionforge-solid/src/commonTest/kotlin/hep/dataforge/vision/solid/ConvexTest.kt index 0afb5a7c..7da077bd 100644 --- a/visionforge-solid/src/commonTest/kotlin/hep/dataforge/vision/solid/ConvexTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/hep/dataforge/vision/solid/ConvexTest.kt @@ -1,6 +1,7 @@ package hep.dataforge.vision.solid import hep.dataforge.meta.* +import kotlinx.serialization.json.toJson import kotlin.test.Test import kotlin.test.assertEquals @@ -24,7 +25,7 @@ class ConvexTest { val convex = group.children.values.first() as Convex - val json = SolidManager.jsonForSolids.toJson(Convex.serializer(), convex) + val json = SolidManager.jsonForSolids.encodeToJsonElement(Convex.serializer(), convex) val meta = json.toMetaItem().node!! val points = meta.getIndexed("points").values.map { (it as MetaItem.NodeItem<*>).node.point3D() } diff --git a/visionforge-solid/src/commonTest/kotlin/hep/dataforge/vision/solid/SerializationTest.kt b/visionforge-solid/src/commonTest/kotlin/hep/dataforge/vision/solid/SerializationTest.kt index f52b5c25..57b94441 100644 --- a/visionforge-solid/src/commonTest/kotlin/hep/dataforge/vision/solid/SerializationTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/hep/dataforge/vision/solid/SerializationTest.kt @@ -1,11 +1,26 @@ package hep.dataforge.vision.solid +import hep.dataforge.names.Name import hep.dataforge.names.toName +import hep.dataforge.vision.MutableVisionGroup import hep.dataforge.vision.Vision import hep.dataforge.vision.get import kotlin.test.Test import kotlin.test.assertEquals +/** + * Create and attach new proxied group + */ +fun SolidGroup.proxyGroup( + name: String, + templateName: Name = name.toName(), + block: MutableVisionGroup.() -> Unit +): Proxy { + val group = SolidGroup().apply(block) + return proxy(name, group, templateName) +} + + class SerializationTest { @Test fun testCubeSerialization() { @@ -14,9 +29,9 @@ class SerializationTest { x = 100 z = -100 } - val string = cube.stringify() + val string = cube.encodeToString() println(string) - val newCube = Vision.parseJson(string) + val newCube = Vision.decodeFromString(string) assertEquals(cube.config, newCube.config) } @@ -35,9 +50,9 @@ class SerializationTest { } } } - val string = group.stringify() + val string = group.encodeToString() println(string) - val reconstructed = SolidGroup.parseJson(string) + val reconstructed = SolidGroup.decodeFromString(string) assertEquals(group["cube"]?.config, reconstructed["cube"]?.config) } diff --git a/visionforge-solid/src/jsMain/kotlin/hep/dataforge/vision/solid/geometryJs.kt b/visionforge-solid/src/jsMain/kotlin/hep/dataforge/vision/solid/geometryJs.kt index 8aa5fe91..170e8249 100644 --- a/visionforge-solid/src/jsMain/kotlin/hep/dataforge/vision/solid/geometryJs.kt +++ b/visionforge-solid/src/jsMain/kotlin/hep/dataforge/vision/solid/geometryJs.kt @@ -5,10 +5,10 @@ import info.laht.threekt.math.Vector2 import info.laht.threekt.math.Vector3 import info.laht.threekt.math.plus -actual typealias Point2D = Vector2 +public actual typealias Point2D = Vector2 -actual typealias Point3D = Vector3 +public actual typealias Point3D = Vector3 -actual operator fun Point3D.plus(other: Point3D): Point3D { +public actual operator fun Point3D.plus(other: Point3D): Point3D { return this.plus(other) } \ No newline at end of file diff --git a/visionforge-solid/src/jsMain/kotlin/hep/dataforge/vision/solid/three/ThreeFactory.kt b/visionforge-solid/src/jsMain/kotlin/hep/dataforge/vision/solid/three/ThreeFactory.kt index c432fbd3..28bb21d6 100644 --- a/visionforge-solid/src/jsMain/kotlin/hep/dataforge/vision/solid/three/ThreeFactory.kt +++ b/visionforge-solid/src/jsMain/kotlin/hep/dataforge/vision/solid/three/ThreeFactory.kt @@ -8,6 +8,7 @@ import hep.dataforge.vision.solid.* import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_KEY import hep.dataforge.vision.solid.three.ThreeFactory.Companion.TYPE import hep.dataforge.vision.solid.three.ThreeMaterials.getMaterial +import hep.dataforge.vision.visible import info.laht.threekt.core.BufferGeometry import info.laht.threekt.core.Object3D import info.laht.threekt.objects.Mesh @@ -54,7 +55,7 @@ fun Object3D.updateProperty(source: Vision, propertyName: Name) { ) { //update position of mesh using this object updatePosition(source) - } else if (propertyName == Solid.VISIBLE_KEY) { + } else if (propertyName == Vision.VISIBLE_KEY) { visible = source.visible ?: true } } diff --git a/visionforge-solid/src/jsMain/kotlin/hep/dataforge/vision/solid/three/ThreePlugin.kt b/visionforge-solid/src/jsMain/kotlin/hep/dataforge/vision/solid/three/ThreePlugin.kt index d8f467fe..546cb882 100644 --- a/visionforge-solid/src/jsMain/kotlin/hep/dataforge/vision/solid/three/ThreePlugin.kt +++ b/visionforge-solid/src/jsMain/kotlin/hep/dataforge/vision/solid/three/ThreePlugin.kt @@ -5,6 +5,7 @@ import hep.dataforge.meta.Meta import hep.dataforge.names.* import hep.dataforge.vision.Vision import hep.dataforge.vision.solid.* +import hep.dataforge.vision.visible import info.laht.threekt.core.Object3D import kotlin.collections.set import kotlin.reflect.KClass @@ -30,7 +31,7 @@ class ThreePlugin : AbstractPlugin() { @Suppress("UNCHECKED_CAST") private fun findObjectFactory(type: KClass): ThreeFactory? { return (objectFactories[type] - ?: context.content>(ThreeFactory.TYPE).values.find { it.type == type }) + ?: context.gather>(ThreeFactory.TYPE).values.find { it.type == type }) as ThreeFactory? } @@ -63,7 +64,7 @@ class ThreePlugin : AbstractPlugin() { ) { //update position of mesh using this object updatePosition(obj) - } else if (name == Solid.VISIBLE_KEY) { + } else if (name == Vision.VISIBLE_KEY) { visible = obj.visible ?: true } } @@ -123,28 +124,28 @@ internal fun Object3D.getOrCreateGroup(name: Name): Object3D { return when { name.isEmpty() -> this name.length == 1 -> { - val token = name.first()!! + val token = name.tokens.first() children.find { it.name == token.toString() } ?: info.laht.threekt.objects.Group().also { group -> group.name = token.toString() this.add(group) } } - else -> getOrCreateGroup(name.first()!!.asName()).getOrCreateGroup(name.cutFirst()) + else -> getOrCreateGroup(name.tokens.first().asName()).getOrCreateGroup(name.cutFirst()) } } internal operator fun Object3D.set(name: Name, obj: Object3D) { when (name.length) { 0 -> error("Can't set object with an empty name") - 1 -> set(name.first()!!, obj) - else -> getOrCreateGroup(name.cutLast())[name.last()!!] = obj + 1 -> set(name.tokens.first(), obj) + else -> getOrCreateGroup(name.cutLast())[name.tokens.last()] = obj } } internal fun Object3D.findChild(name: Name): Object3D? { return when { name.isEmpty() -> this - name.length == 1 -> this.children.find { it.name == name.first()!!.toString() } - else -> findChild(name.first()!!.asName())?.findChild(name.cutFirst()) + name.length == 1 -> this.children.find { it.name == name.tokens.first().toString() } + else -> findChild(name.tokens.first().asName())?.findChild(name.cutFirst()) } } \ No newline at end of file diff --git a/visionforge-solid/src/jsMain/kotlin/hep/dataforge/vision/solid/three/ThreeProxyFactory.kt b/visionforge-solid/src/jsMain/kotlin/hep/dataforge/vision/solid/three/ThreeProxyFactory.kt index 832dd32d..b6321d25 100644 --- a/visionforge-solid/src/jsMain/kotlin/hep/dataforge/vision/solid/three/ThreeProxyFactory.kt +++ b/visionforge-solid/src/jsMain/kotlin/hep/dataforge/vision/solid/three/ThreeProxyFactory.kt @@ -1,5 +1,7 @@ package hep.dataforge.vision.solid.three +import hep.dataforge.names.cutFirst +import hep.dataforge.names.firstOrNull import hep.dataforge.names.toName import hep.dataforge.vision.solid.Proxy import hep.dataforge.vision.solid.Proxy.Companion.PROXY_CHILD_PROPERTY_PREFIX @@ -42,8 +44,8 @@ class ThreeProxyFactory(val three: ThreePlugin) : ThreeFactory { } obj.onPropertyChange(this) { name -> - if (name.first()?.body == PROXY_CHILD_PROPERTY_PREFIX) { - val childName = name.first()?.index?.toName() ?: error("Wrong syntax for proxy child property: '$name'") + if (name.firstOrNull()?.body == PROXY_CHILD_PROPERTY_PREFIX) { + val childName = name.firstOrNull()?.index?.toName() ?: error("Wrong syntax for proxy child property: '$name'") val propertyName = name.cutFirst() val proxyChild = obj[childName] ?: error("Proxy child with name '$childName' not found") val child = object3D.findChild(childName) ?: error("Object child with name '$childName' not found") diff --git a/visionforge-solid/src/jsMain/kotlin/hep/dataforge/vision/solid/three/outputConfig.kt b/visionforge-solid/src/jsMain/kotlin/hep/dataforge/vision/solid/three/outputConfig.kt index 2956f8cc..f4e65da1 100644 --- a/visionforge-solid/src/jsMain/kotlin/hep/dataforge/vision/solid/three/outputConfig.kt +++ b/visionforge-solid/src/jsMain/kotlin/hep/dataforge/vision/solid/three/outputConfig.kt @@ -38,7 +38,7 @@ fun RBuilder.canvasControls(canvas: ThreeCanvas) = accordion("controls") { div("row") { div("col-2") { label("checkbox-inline") { - input(type = InputType.checkBox){ + input(type = InputType.checkBox) { attrs { defaultChecked = canvas.axes.visible onChangeFunction = { @@ -55,7 +55,7 @@ fun RBuilder.canvasControls(canvas: ThreeCanvas) = accordion("controls") { attrs { onClickFunction = { val json = (canvas.content as? SolidGroup)?.let { group -> - SolidManager.jsonForSolids.stringify( + SolidManager.jsonForSolids.encodeToString( SolidGroup.serializer(), group ) @@ -76,7 +76,7 @@ fun RBuilder.canvasControls(canvas: ThreeCanvas) = accordion("controls") { (0..11).forEach { layer -> div("col-1") { label { +layer.toString() } - input(type = InputType.checkBox){ + input(type = InputType.checkBox) { attrs { if (layer == 0) { defaultChecked = true @@ -119,7 +119,7 @@ fun Element.displayCanvasControls(canvas: ThreeCanvas, block: TagConsumer - SolidManager.jsonForSolids.stringify( + SolidManager.jsonForSolids.encodeToString( SolidGroup.serializer(), group ) diff --git a/visionforge-solid/src/jvmMain/kotlin/hep/dataforge/vision/solid/fx/FX3DPlugin.kt b/visionforge-solid/src/jvmMain/kotlin/hep/dataforge/vision/solid/fx/FX3DPlugin.kt index 0b2f064f..712b2b2e 100644 --- a/visionforge-solid/src/jvmMain/kotlin/hep/dataforge/vision/solid/fx/FX3DPlugin.kt +++ b/visionforge-solid/src/jvmMain/kotlin/hep/dataforge/vision/solid/fx/FX3DPlugin.kt @@ -38,7 +38,7 @@ class FX3DPlugin : AbstractPlugin() { @Suppress("UNCHECKED_CAST") private fun findObjectFactory(type: KClass): FX3DFactory? { - return (objectFactories[type] ?: context.content>(TYPE).values.find { it.type == type }) + return (objectFactories[type] ?: context.gather>(TYPE).values.find { it.type == type }) as FX3DFactory? } diff --git a/visionforge-solid/src/jvmMain/kotlin/hep/dataforge/vision/solid/fx/FXProxyFactory.kt b/visionforge-solid/src/jvmMain/kotlin/hep/dataforge/vision/solid/fx/FXProxyFactory.kt index 6a171854..3dca5113 100644 --- a/visionforge-solid/src/jvmMain/kotlin/hep/dataforge/vision/solid/fx/FXProxyFactory.kt +++ b/visionforge-solid/src/jvmMain/kotlin/hep/dataforge/vision/solid/fx/FXProxyFactory.kt @@ -1,8 +1,6 @@ package hep.dataforge.vision.solid.fx -import hep.dataforge.names.Name -import hep.dataforge.names.isEmpty -import hep.dataforge.names.toName +import hep.dataforge.names.* import hep.dataforge.vision.Vision import hep.dataforge.vision.solid.Proxy import javafx.scene.Group @@ -17,8 +15,8 @@ class FXProxyFactory(val plugin: FX3DPlugin) : FX3DFactory { val node = plugin.buildNode(prototype) obj.onPropertyChange(this) { name-> - if (name.first()?.body == Proxy.PROXY_CHILD_PROPERTY_PREFIX) { - val childName = name.first()?.index?.toName() ?: error("Wrong syntax for proxy child property: '$name'") + if (name.firstOrNull()?.body == Proxy.PROXY_CHILD_PROPERTY_PREFIX) { + val childName = name.firstOrNull()?.index?.toName() ?: error("Wrong syntax for proxy child property: '$name'") val propertyName = name.cutFirst() val proxyChild = obj[childName] ?: error("Proxy child with name '$childName' not found") val child = node.findChild(childName) ?: error("Object child with name '$childName' not found") @@ -35,7 +33,7 @@ private fun Node.findChild(name: Name): Node? { } else { (this as? Group) ?.children - ?.find { it.properties["name"] as String == name.first()?.toString() } + ?.find { it.properties["name"] as String == name.firstOrNull()?.toString() } ?.findChild(name.cutFirst()) } } diff --git a/visionforge-solid/src/jvmMain/kotlin/hep/dataforge/vision/solid/generateSchema.kt b/visionforge-solid/src/jvmMain/kotlin/hep/dataforge/vision/solid/generateSchema.kt index 122f051b..9d3c332b 100644 --- a/visionforge-solid/src/jvmMain/kotlin/hep/dataforge/vision/solid/generateSchema.kt +++ b/visionforge-solid/src/jvmMain/kotlin/hep/dataforge/vision/solid/generateSchema.kt @@ -1,205 +1,208 @@ -package hep.dataforge.vision.solid - -import hep.dataforge.meta.JSON_PRETTY -import kotlinx.serialization.* -import kotlinx.serialization.json.* -import kotlinx.serialization.modules.SerialModule -import kotlinx.serialization.modules.SerialModuleCollector -import kotlin.reflect.KClass - -private fun SerialDescriptor.getJsonType() = when (this.kind) { - StructureKind.LIST -> "array" - PrimitiveKind.BYTE, PrimitiveKind.SHORT, PrimitiveKind.INT, PrimitiveKind.LONG, - PrimitiveKind.FLOAT, PrimitiveKind.DOUBLE -> "number" - PrimitiveKind.STRING, PrimitiveKind.CHAR, UnionKind.ENUM_KIND -> "string" - PrimitiveKind.BOOLEAN -> "boolean" - else -> "object" -} - -private fun SerialDescriptor.isVisualObject() = serialName.startsWith("solid")||serialName.startsWith("group.solid") - -private const val definitionNode = "\$defs" - -private fun SerialModule.enumerate(type: KClass<*>): Sequence { - val list = ArrayList() - fun send(descriptor: SerialDescriptor) = list.add(descriptor) - - val enumerator = object : SerialModuleCollector { - override fun contextual(kClass: KClass, serializer: KSerializer) { - if (kClass == type) { - send(serializer.descriptor) - } - } - - override fun polymorphic( - baseClass: KClass, - actualClass: KClass, - actualSerializer: KSerializer - ) { - if (baseClass == type) { - send(actualSerializer.descriptor) - } - } - - } - dumpTo(enumerator) - return list.asSequence() -} - -/** - * Creates an [JsonObject] which contains Json Schema of given [descriptor]. - * - * Schema can contain following fields: - * `description`, `type` for all descriptors; - * `properties` and `required` for objects; - * `enum` for enums; - * `items` for arrays. - * - * User can modify this schema to add additional validation keywords - * (as per [https://json-schema.org/latest/json-schema-validation.html]) - * if they want. - */ -private fun jsonSchema(descriptor: SerialDescriptor, context: SerialModule): JsonObject { - - if (descriptor.serialName in arrayOf( - "hep.dataforge.vision.solid.Point3D", - "hep.dataforge.vision.solid.Point3D?", - "hep.dataforge.vision.solid.Point2D", - "hep.dataforge.vision.solid.Point2D?", - "hep.dataforge.meta.Meta", - "hep.dataforge.meta.Meta?" - ) - ) return json { - "\$ref" to "#/$definitionNode/${descriptor.serialName.replace("?", "")}" - } - - - val properties: MutableMap = mutableMapOf() - val requiredProperties: MutableSet = mutableSetOf() - val isEnum = descriptor.kind == UnionKind.ENUM_KIND - val isPolymorphic = descriptor.kind is PolymorphicKind - - - if (!isEnum && !isPolymorphic) descriptor.elementDescriptors().forEachIndexed { index, child -> - val elementName = descriptor.getElementName(index) - - val elementSchema = when (elementName) { - "properties" -> json { - "\$ref" to "#/$definitionNode/hep.dataforge.meta.Meta" - } - "first", "second" -> json { - "\$ref" to "#/$definitionNode/children" - } - "styleSheet" -> json { - "type" to "object" - "additionalProperties" to json { - "\$ref" to "#/$definitionNode/hep.dataforge.meta.Meta" - } - } - in arrayOf("children", "prototypes") -> json { - "type" to "object" - "additionalProperties" to json { - "\$ref" to "#/$definitionNode/children" - } - } - else -> jsonSchema(child, context) - } - properties[elementName] = elementSchema - - if (!descriptor.isElementOptional(index)) requiredProperties.add(elementName) - } - - val jsonType = descriptor.getJsonType() - val objectData: MutableMap = mutableMapOf( - "description" to JsonLiteral(descriptor.serialName), - "type" to JsonLiteral(jsonType) - ) - if (isEnum) { - val allElementNames = (0 until descriptor.elementsCount).map(descriptor::getElementName) - objectData += "enum" to JsonArray(allElementNames.map(::JsonLiteral)) - } - when (jsonType) { - "object" -> { - if(descriptor.isVisualObject()) { - properties["type"] = json { - "const" to descriptor.serialName - } - } - objectData["properties"] = JsonObject(properties) - val required = requiredProperties.map { JsonLiteral(it) } - if (required.isNotEmpty()) { - objectData["required"] = JsonArray(required) - } - } - "array" -> objectData["items"] = properties.values.let { - check(it.size == 1) { "Array descriptor has returned inconsistent number of elements: expected 1, found ${it.size}" } - it.first() - } - else -> { /* no-op */ - } - } - return JsonObject(objectData) -} - -fun main() { - val context = SolidManager.serialModule - val definitions = json { - "children" to json { - "anyOf" to jsonArray { - context.enumerate(Solid::class).forEach { - if (it.serialName == "hep.dataforge.vis.spatial.SolidGroup") { - +json { - "\$ref" to "#/$definitionNode/${it.serialName}" - } - } else { - +jsonSchema(it, context) - } - } - } - } - "hep.dataforge.meta.Meta" to json { - "type" to "object" - } - "hep.dataforge.vision.solid.Point3D" to json { - "type" to "object" - "properties" to json { - "x" to json { - "type" to "number" - } - "y" to json { - "type" to "number" - } - "z" to json { - "type" to "number" - } - } - } - "hep.dataforge.vision.solid.Point2D" to json { - "type" to "object" - "properties" to json { - "x" to json { - "type" to "number" - } - "y" to json { - "type" to "number" - } - } - } - "hep.dataforge.vision.solid.SolidGroup" to jsonSchema( - SolidGroup.serializer().descriptor, - context - ) - - } - - println( - JSON_PRETTY.stringify( - JsonObjectSerializer, - json { - "\$defs" to definitions - "\$ref" to "#/$definitionNode/hep.dataforge.vision.solid.SolidGroup" - } - ) - ) -} - +//package hep.dataforge.vision.solid +// +//import hep.dataforge.meta.JSON_PRETTY +//import kotlinx.serialization.* +//import kotlinx.serialization.descriptors.PrimitiveKind +//import kotlinx.serialization.descriptors.SerialDescriptor +//import kotlinx.serialization.descriptors.StructureKind +//import kotlinx.serialization.descriptors.UnionKind +//import kotlinx.serialization.json.* +//import kotlinx.serialization.modules.SerialModule +//import kotlin.reflect.KClass +// +//private fun SerialDescriptor.getJsonType() = when (this.kind) { +// StructureKind.LIST -> "array" +// PrimitiveKind.BYTE, PrimitiveKind.SHORT, PrimitiveKind.INT, PrimitiveKind.LONG, +// PrimitiveKind.FLOAT, PrimitiveKind.DOUBLE -> "number" +// PrimitiveKind.STRING, PrimitiveKind.CHAR, UnionKind.ENUM_KIND -> "string" +// PrimitiveKind.BOOLEAN -> "boolean" +// else -> "object" +//} +// +//private fun SerialDescriptor.isVisualObject() = serialName.startsWith("solid")||serialName.startsWith("group.solid") +// +//private const val definitionNode = "\$defs" +// +//private fun SerialModule.enumerate(type: KClass<*>): Sequence { +// val list = ArrayList() +// fun send(descriptor: SerialDescriptor) = list.add(descriptor) +// +// val enumerator = object : SerialModuleCollector { +// override fun contextual(kClass: KClass, serializer: KSerializer) { +// if (kClass == type) { +// send(serializer.descriptor) +// } +// } +// +// override fun polymorphic( +// baseClass: KClass, +// actualClass: KClass, +// actualSerializer: KSerializer +// ) { +// if (baseClass == type) { +// send(actualSerializer.descriptor) +// } +// } +// +// } +// dumpTo(enumerator) +// return list.asSequence() +//} +// +///** +// * Creates an [JsonObject] which contains Json Schema of given [descriptor]. +// * +// * Schema can contain following fields: +// * `description`, `type` for all descriptors; +// * `properties` and `required` for objects; +// * `enum` for enums; +// * `items` for arrays. +// * +// * User can modify this schema to add additional validation keywords +// * (as per [https://json-schema.org/latest/json-schema-validation.html]) +// * if they want. +// */ +//private fun jsonSchema(descriptor: SerialDescriptor, context: SerialModule): JsonObject { +// +// if (descriptor.serialName in arrayOf( +// "hep.dataforge.vision.solid.Point3D", +// "hep.dataforge.vision.solid.Point3D?", +// "hep.dataforge.vision.solid.Point2D", +// "hep.dataforge.vision.solid.Point2D?", +// "hep.dataforge.meta.Meta", +// "hep.dataforge.meta.Meta?" +// ) +// ) return json { +// "\$ref" to "#/$definitionNode/${descriptor.serialName.replace("?", "")}" +// } +// +// +// val properties: MutableMap = mutableMapOf() +// val requiredProperties: MutableSet = mutableSetOf() +// val isEnum = descriptor.kind == UnionKind.ENUM_KIND +// val isPolymorphic = descriptor.kind is PolymorphicKind +// +// +// if (!isEnum && !isPolymorphic) descriptor.elementDescriptors().forEachIndexed { index, child -> +// val elementName = descriptor.getElementName(index) +// +// val elementSchema = when (elementName) { +// "properties" -> buildJsonObject { +// put("\$ref", "#/$definitionNode/hep.dataforge.meta.Meta") +// } +// "first", "second" -> buildJsonObject { +// put("\$ref", "#/$definitionNode/children") +// } +// "styleSheet" -> buildJsonObject { +// put("type", "object") +// put("additionalProperties", buildJsonObject { +// put("\$ref", "#/$definitionNode/hep.dataforge.meta.Meta") +// }) +// } +// in arrayOf("children", "prototypes") -> buildJsonObject { +// put("type", "object") +// put("additionalProperties", buildJsonObject { +// put("\$ref", "#/$definitionNode/children") +// }) +// } +// else -> jsonSchema(child, context) +// } +// properties[elementName] = elementSchema +// +// if (!descriptor.isElementOptional(index)) requiredProperties.add(elementName) +// } +// +// val jsonType = descriptor.getJsonType() +// val objectData: MutableMap = mutableMapOf( +// "description" to JsonLiteral(descriptor.serialName), +// "type" to JsonLiteral(jsonType) +// ) +// if (isEnum) { +// val allElementNames = (0 until descriptor.elementsCount).map(descriptor::getElementName) +// objectData += "enum" to JsonArray(allElementNames.map(::JsonLiteral)) +// } +// when (jsonType) { +// "object" -> { +// if(descriptor.isVisualObject()) { +// properties["type"] = json { +// "const" to descriptor.serialName +// } +// } +// objectData["properties"] = JsonObject(properties) +// val required = requiredProperties.map { JsonLiteral(it) } +// if (required.isNotEmpty()) { +// objectData["required"] = JsonArray(required) +// } +// } +// "array" -> objectData["items"] = properties.values.let { +// check(it.size == 1) { "Array descriptor has returned inconsistent number of elements: expected 1, found ${it.size}" } +// it.first() +// } +// else -> { /* no-op */ +// } +// } +// return JsonObject(objectData) +//} +// +//fun main() { +// val context = SolidManager.serialModule +// val definitions = json { +// "children" to json { +// "anyOf" to jsonArray { +// context.enumerate(Solid::class).forEach { +// if (it.serialName == "hep.dataforge.vis.spatial.SolidGroup") { +// +json { +// "\$ref" to "#/$definitionNode/${it.serialName}" +// } +// } else { +// +jsonSchema(it, context) +// } +// } +// } +// } +// "hep.dataforge.meta.Meta" to json { +// "type" to "object" +// } +// "hep.dataforge.vision.solid.Point3D" to json { +// "type" to "object" +// "properties" to json { +// "x" to json { +// "type" to "number" +// } +// "y" to json { +// "type" to "number" +// } +// "z" to json { +// "type" to "number" +// } +// } +// } +// "hep.dataforge.vision.solid.Point2D" to json { +// "type" to "object" +// "properties" to json { +// "x" to json { +// "type" to "number" +// } +// "y" to json { +// "type" to "number" +// } +// } +// } +// "hep.dataforge.vision.solid.SolidGroup" to jsonSchema( +// SolidGroup.serializer().descriptor, +// context +// ) +// +// } +// +// println( +// JSON_PRETTY.stringify( +// JsonObjectSerializer, +// json { +// "\$defs" to definitions +// "\$ref" to "#/$definitionNode/hep.dataforge.vision.solid.SolidGroup" +// } +// ) +// ) +//} +// diff --git a/visionforge-solid/src/jvmMain/kotlin/hep/dataforge/vision/solid/geometryJVM.kt b/visionforge-solid/src/jvmMain/kotlin/hep/dataforge/vision/solid/geometryJVM.kt index 96f40d81..153aace7 100644 --- a/visionforge-solid/src/jvmMain/kotlin/hep/dataforge/vision/solid/geometryJVM.kt +++ b/visionforge-solid/src/jvmMain/kotlin/hep/dataforge/vision/solid/geometryJVM.kt @@ -1,11 +1,11 @@ package hep.dataforge.vision.solid import org.fxyz3d.geometry.Point3D as FXPoint3D -actual data class Point2D(actual var x: Double, actual var y: Double) { +public actual data class Point2D(public actual var x: Double, public actual var y: Double) { actual constructor(x: Number, y: Number) : this(x.toDouble(), y.toDouble()) } -actual class Point3D(val point: FXPoint3D) { +public actual class Point3D(val point: FXPoint3D) { actual constructor(x: Number, y: Number, z: Number) : this( FXPoint3D( x.toFloat(), @@ -14,19 +14,19 @@ actual class Point3D(val point: FXPoint3D) { ) ) - actual var x: Double + public actual var x: Double inline get() = point.x.toDouble() inline set(value) { point.x = value.toFloat() } - actual var y: Double + public actual var y: Double inline get() = point.y.toDouble() inline set(value) { point.y = value.toFloat() } - actual var z: Double + public actual var z: Double inline get() = point.z.toDouble() inline set(value) { point.z = value.toFloat() @@ -45,6 +45,6 @@ actual class Point3D(val point: FXPoint3D) { } } -actual operator fun Point3D.plus(other: Point3D): Point3D { +public actual operator fun Point3D.plus(other: Point3D): Point3D { return Point3D(point.add(other.point)) } \ No newline at end of file