Replace empty names by nulls in vision group builders

This commit is contained in:
Alexander Nozik 2021-03-01 21:09:53 +03:00
parent 78a04728ba
commit 0e488563a9
27 changed files with 69 additions and 98 deletions

View File

@ -12,6 +12,7 @@
- JavaFX support moved to a separate module
- Threejs support moved to a separate module
- \[Format breaking change!\] Stylesheets are moved into properties under `@stylesheet` key
- VisionGroup builder accepts `null` as name for statics instead of `""`
### Deprecated

View File

@ -33,4 +33,6 @@ tasks.withType<Test> {
tasks.processJupyterApiResources {
libraryProducers = listOf("hep.dataforge.playground.VisionForgePlayGroundForJupyter")
}
}
tasks.findByName("shadowJar")?.dependsOn("processJupyterApiResources")

View File

@ -20,7 +20,6 @@ import kotlinx.html.stream.createHTML
import kotlinx.html.unsafe
import kscience.plotly.Plot
import org.jetbrains.kotlinx.jupyter.api.HTML
import org.jetbrains.kotlinx.jupyter.api.Notebook
import org.jetbrains.kotlinx.jupyter.api.annotations.JupyterLibrary
import org.jetbrains.kotlinx.jupyter.api.libraries.*
import space.kscience.gdml.Gdml
@ -44,11 +43,11 @@ internal class VisionForgePlayGroundForJupyter : JupyterIntegration() {
}
script {
type = "text/javascript"
unsafe { +"VisionForge.renderVisionsAt(\"$id\");" }
unsafe { +"renderVisionsAt(\"$id\");" }
}
}
override fun Builder.onLoaded(notebook: Notebook?) {
override fun Builder.onLoaded() {
resource(jsResource)
onLoaded {

View File

@ -2,62 +2,12 @@ package hep.dataforge.vision.examples
import hep.dataforge.misc.DFExperimental
import hep.dataforge.vision.VisionForge
import hep.dataforge.vision.gdml.GdmlShowcase.cubes
import hep.dataforge.vision.gdml.toVision
import hep.dataforge.vision.html.ResourceLocation
import hep.dataforge.vision.html.fragment
import hep.dataforge.vision.invoke
import hep.dataforge.vision.solid.Solids
import space.kscience.gdml.*
internal val cubes = Gdml {
val center = define.position("center")
structure {
val air = materials.composite("G4_AIR") {}
val tubeMaterial = materials.composite("tube") {}
val boxMaterial = materials.composite("box") {}
val segment = solids.tube("segment", 20, 5.0) {
rmin = 17
deltaphi = 60
aunit = AUnit.DEG.title
}
val worldBox = solids.box("largeBox", 200, 200, 200)
val smallBox = solids.box("smallBox", 30, 30, 30)
val segmentVolume = volume("segment", tubeMaterial, segment) {}
val circle = volume("composite", boxMaterial, smallBox) {
for (i in 0 until 6) {
physVolume(segmentVolume) {
positionref = center
rotation {
z = 60 * i
unit = AUnit.DEG.title
}
}
}
}
world = volume("world", air, worldBox) {
for (i in 0 until 3) {
for (j in 0 until 3) {
for (k in 0 until 3) {
physVolume(circle) {
position {
x = (-50 + i * 50)
y = (-50 + j * 50)
z = (-50 + k * 50)
}
rotation {
x = i * 120
y = j * 120
z = 120 * k
}
}
}
}
}
}
}
}
@DFExperimental
fun main() = VisionForge(Solids) {

View File

@ -15,7 +15,7 @@ pluginManagement {
id("ru.mipt.npm.gradle.js") version toolsVersion
id("ru.mipt.npm.gradle.publish") version toolsVersion
kotlin("jvm") version kotlinVersion
kotlin("jupyter.api") version "0.8.3.218"
kotlin("jupyter.api") version "0.8.3.236"
kotlin("js") version kotlinVersion
kotlin("multiplatform") version kotlinVersion
}

View File

@ -39,7 +39,8 @@ public class VisionChangeBuilder : VisionContainerBuilder<Vision> {
}
}
override fun set(name: Name, child: Vision?) {
override fun set(name: Name?, child: Vision?) {
if(name == null) error("Static children are not allowed in VisionChange")
getOrPutChild(name).apply {
vision = child
reset = vision == null

View File

@ -4,7 +4,6 @@ import hep.dataforge.context.Context
import hep.dataforge.context.PluginManager
import hep.dataforge.misc.DFExperimental
@DFExperimental
public expect object VisionForge
@DFExperimental

View File

@ -58,7 +58,7 @@ public operator fun VisionGroup.iterator(): Iterator<Vision> = children.values.i
public val VisionGroup.isEmpty: Boolean get() = this.children.isEmpty()
public interface VisionContainerBuilder<in V : Vision> {
public operator fun set(name: Name, child: V?)
public operator fun set(name: Name?, child: V?)
}
/**
@ -79,6 +79,6 @@ public operator fun <V : Vision> VisionContainer<V>.get(str: String): V? = get(s
public operator fun <V : Vision> VisionContainerBuilder<V>.set(token: NameToken, child: V?): Unit =
set(token.asName(), child)
public operator fun <V : Vision> VisionContainerBuilder<V>.set(key: String, child: V?): Unit = set(key.toName(), child)
public operator fun <V : Vision> VisionContainerBuilder<V>.set(key: String?, child: V?): Unit = set(key?.toName(), child)
public fun MutableVisionGroup.removeAll(): Unit = children.keys.map { it.asName() }.forEach { this[it] = null }

View File

@ -111,13 +111,14 @@ public open class VisionGroupBase(
* Add named or unnamed child to the group. If key is null the child is considered unnamed. Both key and value are not
* allowed to be null in the same time. If name is present and [child] is null, the appropriate element is removed.
*/
override fun set(name: Name, child: Vision?): Unit {
override fun set(name: Name?, child: Vision?): Unit {
when {
name.isEmpty() -> {
name == null -> {
if (child != null) {
addStatic(child)
}
}
name.isEmpty() -> error("Empty names are not allowed in VisionGroup::set")
name.length == 1 -> {
val token = name.tokens.first()
attachChild(token, child)

View File

@ -7,7 +7,7 @@ import kotlinx.browser.window
@JsExport
@DFExperimental
public actual object VisionForge{
public actual object VisionForge {
/**
* Render all visions in this [window] using current global state of [VisionForge]
*/
@ -30,12 +30,30 @@ public actual object VisionForge{
}
}
private val visionForgeContext = Context("VisionForge"){
private val visionForgeContext = Context("VisionForge") {
plugin(VisionClient)
}
@DFExperimental
public actual val VisionForge.context: Context get() = visionForgeContext
public actual val VisionForge.context: Context
get() = visionForgeContext
@DFExperimental
public val VisionForge.visionClient: VisionClient get() = plugins.fetch(VisionClient)
public val VisionForge.visionClient: VisionClient
get() = plugins.fetch(VisionClient)
/**
* Render all visions in this [window] using current global state of [VisionForge]
*/
@DFExperimental
@JsExport
public fun renderVisionsInWindow(): Unit = VisionForge.renderVisionsInWindow()
/**
* Render all visions in an element with a given [id]
*/
@DFExperimental
@JsExport
public fun renderVisionsAt(id: String): Unit = VisionForge.renderVisionsAt(id)

View File

@ -4,7 +4,6 @@ import hep.dataforge.context.Context
import hep.dataforge.context.PluginFactory
import hep.dataforge.misc.DFExperimental
@DFExperimental
public actual object VisionForge
@DFExperimental

View File

@ -7,7 +7,7 @@ kotlin {
val commonMain by getting {
dependencies {
api(project(":visionforge-solid"))
api("space.kscience:gdml:0.3.0-dev")
api("space.kscience:gdml:0.3.0")
}
}
}

View File

@ -3,7 +3,7 @@ package hep.dataforge.vision.gdml
import space.kscience.gdml.*
public object GdmlShowcase {
public val cubes = Gdml {
public val cubes: Gdml = Gdml {
val center = define.position("center")
structure {
val air = materials.composite("G4_AIR") {}

View File

@ -76,7 +76,7 @@ private class GdmlTransformer(val settings: GdmlTransformerSettings) {
if (proto[templateName] == null) {
proto[templateName] = volume(root, volume)
}
val ref = group.ref(templateName, physVolume.name ?: "").withPosition(root, physVolume)
val ref = group.ref(templateName, physVolume.name).withPosition(root, physVolume)
referenceStore.getOrPut(templateName) { ArrayList() }.add(ref)
return ref
}
@ -148,7 +148,7 @@ private class GdmlTransformer(val settings: GdmlTransformerSettings) {
fun SolidGroup.addSolid(
root: Gdml,
solid: GdmlSolid,
name: String = "",
name: String? = null,
): Solid {
//context.solidAdded(solid)
val lScale = solid.lscale(settings.lUnit)
@ -253,14 +253,15 @@ private class GdmlTransformer(val settings: GdmlTransformerSettings) {
fun SolidGroup.addSolidWithCaching(
root: Gdml,
solid: GdmlSolid,
name: String = solid.name,
name: String?,
): Solid? {
require(name != ""){"Can't use empty solid name. Use null instead."}
return when (settings.solidAction(solid)) {
GdmlTransformerSettings.Action.ADD -> {
addSolid(root, solid, name)
}
GdmlTransformerSettings.Action.PROTOTYPE -> {
proxySolid(root, this, solid, name)
proxySolid(root, this, solid, name ?: solid.name)
}
GdmlTransformerSettings.Action.REJECT -> {
//ignore
@ -280,7 +281,7 @@ private class GdmlTransformer(val settings: GdmlTransformerSettings) {
if (volume is GdmlVolume && volume.physVolumes.isEmpty() && volume.placement == null) {
val solid = volume.solidref.resolve(root)
?: error("Solid with tag ${volume.solidref.ref} for volume ${volume.name} not defined")
addSolidWithCaching(root, solid, physVolume.name ?: "")?.apply {
addSolidWithCaching(root, solid, physVolume.name)?.apply {
configureSolid(root, this, volume, solid)
withPosition(root, physVolume)
}
@ -309,7 +310,7 @@ private class GdmlTransformer(val settings: GdmlTransformerSettings) {
?: error("Volume with ref ${divisionVolume.volumeref.ref} could not be resolved")
//TODO add divisions
set(Name.EMPTY, volume(root, volume))
set(null, volume(root, volume))
}
private fun volume(
@ -320,7 +321,7 @@ private class GdmlTransformer(val settings: GdmlTransformerSettings) {
val solid: GdmlSolid = group.solidref.resolve(root)
?: error("Solid with tag ${group.solidref.ref} for volume ${group.name} not defined")
addSolidWithCaching(root, solid)?.apply {
addSolidWithCaching(root, solid, null)?.apply {
configureSolid(root, this, group, solid)
}
@ -381,7 +382,7 @@ public fun Gdml.toVision(block: GdmlTransformerSettings.() -> Unit = {}): SolidG
/**
* Append Gdml node to the group
*/
public fun SolidGroup.gdml(gdml: Gdml, key: String = "", transformer: GdmlTransformerSettings.() -> Unit = {}) {
public fun SolidGroup.gdml(gdml: Gdml, key: String? = null, transformer: GdmlTransformerSettings.() -> Unit = {}) {
val visual = gdml.toVision(transformer)
//println(Visual3DPlugin.json.stringify(VisualGroup3D.serializer(), visual))
set(key, visual)

View File

@ -11,7 +11,7 @@ public actual typealias Counter = AtomicInteger
public fun Gdml.Companion.readFile(file: Path): Gdml {
val xmlReader = StAXReader(Files.newInputStream(file), "UTF-8")
return format.parse(Gdml.serializer(), xmlReader)
return format.decodeFromReader(Gdml.serializer(), xmlReader)
}
public fun SolidGroup.gdml(file: Path, key: String = "", transformer: GdmlTransformerSettings.() -> Unit = {}) {

View File

@ -7,6 +7,7 @@ import space.kscience.gdml.Gdml
import space.kscience.gdml.decodeFromStream
import kotlin.test.assertNotNull
@Suppress("UNUSED_VARIABLE")
class TestConvertor {
@Test

View File

@ -45,6 +45,6 @@ public inline fun VisionContainerBuilder<Solid>.box(
xSize: Number,
ySize: Number,
zSize: Number,
name: String = "",
name: String? = null,
action: Box.() -> Unit = {}
): Box = Box(xSize.toFloat(), ySize.toFloat(), zSize.toFloat()).apply(action).also { set(name, it) }

View File

@ -32,7 +32,7 @@ public class Composite(
@VisionBuilder
public inline fun VisionContainerBuilder<Solid>.composite(
type: CompositeType,
name: String = "",
name: String? = null,
builder: SolidGroup.() -> Unit,
): Composite {
val group = SolidGroup().apply(builder)
@ -56,16 +56,16 @@ public inline fun VisionContainerBuilder<Solid>.composite(
}
@VisionBuilder
public inline fun VisionContainerBuilder<Solid>.union(name: String = "", builder: SolidGroup.() -> Unit): Composite =
public inline fun VisionContainerBuilder<Solid>.union(name: String? = null, builder: SolidGroup.() -> Unit): Composite =
composite(CompositeType.UNION, name, builder = builder)
@VisionBuilder
public inline fun VisionContainerBuilder<Solid>.subtract(name: String = "", builder: SolidGroup.() -> Unit): Composite =
public inline fun VisionContainerBuilder<Solid>.subtract(name: String? = null, builder: SolidGroup.() -> Unit): Composite =
composite(CompositeType.SUBTRACT, name, builder = builder)
@VisionBuilder
public inline fun VisionContainerBuilder<Solid>.intersect(
name: String = "",
name: String? = null,
builder: SolidGroup.() -> Unit,
): Composite =
composite(CompositeType.INTERSECT, name, builder = builder)

View File

@ -67,7 +67,7 @@ public class ConeSegment(
public inline fun VisionContainerBuilder<Solid>.cylinder(
r: Number,
height: Number,
name: String = "",
name: String? = null,
block: ConeSegment.() -> Unit = {}
): ConeSegment = ConeSegment(
r.toFloat(),
@ -80,7 +80,7 @@ public inline fun VisionContainerBuilder<Solid>.cone(
bottomRadius: Number,
height: Number,
upperRadius: Number = 0.0,
name: String = "",
name: String? = null,
block: ConeSegment.() -> Unit = {}
): ConeSegment = ConeSegment(
bottomRadius.toFloat(),

View File

@ -9,7 +9,7 @@ import kotlinx.serialization.Serializable
@SerialName("solid.convex")
public class Convex(public val points: List<Point3D>) : SolidBase(), Solid
public inline fun VisionContainerBuilder<Solid>.convex(name: String = "", action: ConvexBuilder.() -> Unit = {}): Convex =
public inline fun VisionContainerBuilder<Solid>.convex(name: String? = null, action: ConvexBuilder.() -> Unit = {}): Convex =
ConvexBuilder().apply(action).build().also { set(name, it) }
public class ConvexBuilder {

View File

@ -104,5 +104,5 @@ public class Extruded(
}
@VisionBuilder
public fun VisionContainerBuilder<Solid>.extrude(name: String = "", action: Extruded.() -> Unit = {}): Extruded =
public fun VisionContainerBuilder<Solid>.extrude(name: String? = null, action: Extruded.() -> Unit = {}): Extruded =
Extruded().apply(action).also { set(name, it) }

View File

@ -16,7 +16,8 @@ import kotlinx.serialization.Serializable
public class PolyLine(public var points: List<Point3D>) : SolidBase(), Solid {
//var lineType by string()
public var thickness: Number by allProperties(inherit = false).number(1.0, key = SolidMaterial.MATERIAL_KEY + THICKNESS_KEY)
public var thickness: Number by allProperties(inherit = false).number(1.0,
key = SolidMaterial.MATERIAL_KEY + THICKNESS_KEY)
public companion object {
public val THICKNESS_KEY: Name = "thickness".asName()
@ -27,7 +28,6 @@ public class PolyLine(public var points: List<Point3D>) : SolidBase(), Solid {
@VisionBuilder
public fun VisionContainerBuilder<Solid>.polyline(
vararg points: Point3D,
name: String = "",
name: String? = null,
action: PolyLine.() -> Unit = {},
): PolyLine =
PolyLine(points.toList()).apply(action).also { set(name, it) }
): PolyLine = PolyLine(points.toList()).apply(action).also { set(name, it) }

View File

@ -83,10 +83,9 @@ public fun SolidGroup(block: SolidGroup.() -> Unit): SolidGroup {
@VisionBuilder
public fun VisionContainerBuilder<Vision>.group(
name: Name = Name.EMPTY,
name: Name? = null,
action: SolidGroup.() -> Unit = {},
): SolidGroup =
SolidGroup().apply(action).also { set(name, it) }
): SolidGroup = SolidGroup().apply(action).also { set(name, it) }
/**
* Define a group with given [name], attach it to this parent and return it.

View File

@ -19,6 +19,6 @@ public fun VisionContainerBuilder<Solid>.label(
text: String,
fontSize: Number = 20,
fontFamily: String = "Arial",
name: String = "",
name: String? = null,
action: SolidLabel.() -> Unit = {},
): SolidLabel = SolidLabel(text, fontSize.toDouble(), fontFamily).apply(action).also { set(name, it) }

View File

@ -170,7 +170,7 @@ public val Vision.prototype: Vision
*/
public fun SolidGroup.ref(
templateName: Name,
name: String = "",
name: String? = null,
): SolidReferenceGroup = SolidReferenceGroup(templateName).also { set(name, it) }
/**

View File

@ -56,7 +56,7 @@ public inline fun VisionContainerBuilder<Solid>.sphere(
radius: Number,
phi: Number = 2 * PI,
theta: Number = PI,
name: String = "",
name: String? = null,
action: Sphere.() -> Unit = {},
): Sphere = Sphere(
radius.toFloat(),

View File

@ -126,7 +126,7 @@ public inline fun VisionContainerBuilder<Solid>.tube(
innerRadius: Number = 0f,
startAngle: Number = 0f,
angle: Number = 2 * PI,
name: String = "",
name: String? = null,
block: Tube.() -> Unit = {},
): Tube = Tube(
r.toFloat(),