forked from kscience/visionforge
Add property flows
This commit is contained in:
parent
0ea1ee056a
commit
ecf4a6a198
@ -352,14 +352,14 @@ private fun SolidGroup.addRootVolume(
|
||||
}
|
||||
block()
|
||||
}
|
||||
set(combinedName?.let { Name.parse(it) }, group)
|
||||
setChild(combinedName?.let { Name.parse(it) }, group)
|
||||
} else {
|
||||
val templateName = volumesName + volume.name
|
||||
val existing = getPrototype(templateName)
|
||||
if (existing == null) {
|
||||
context.prototypeHolder.prototypes {
|
||||
val group = buildVolume(volume, context)
|
||||
set(templateName, group)
|
||||
setChild(templateName, group)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@ import space.kscience.dataforge.meta.string
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.gdml.GdmlShowCase
|
||||
import space.kscience.visionforge.Vision
|
||||
import space.kscience.visionforge.get
|
||||
import space.kscience.visionforge.getChild
|
||||
import space.kscience.visionforge.solid.Solid
|
||||
import space.kscience.visionforge.solid.SolidMaterial
|
||||
import space.kscience.visionforge.solid.material
|
||||
@ -18,7 +18,7 @@ class GDMLVisionTest {
|
||||
|
||||
@Test
|
||||
fun testCubesStyles(){
|
||||
val segment = cubes.children["composite-000.segment-0"] as Solid
|
||||
val segment = cubes.children.getChild("composite-000.segment-0") as Solid
|
||||
println(segment.properties.getValue(Vision.STYLE_KEY))
|
||||
// println(segment.computePropertyNode(SolidMaterial.MATERIAL_KEY))
|
||||
// println(segment.computeProperty(SolidMaterial.MATERIAL_COLOR_KEY))
|
||||
|
@ -48,6 +48,7 @@ kotlin {
|
||||
implementation("io.ktor:ktor-server-cio:${ktorVersion}")
|
||||
implementation("io.ktor:ktor-server-content-negotiation:${ktorVersion}")
|
||||
implementation("io.ktor:ktor-serialization-kotlinx-json:${ktorVersion}")
|
||||
implementation("ch.qos.logback:logback-classic:1.2.11")
|
||||
}
|
||||
}
|
||||
jsMain {
|
||||
|
@ -3,7 +3,10 @@ package space.kscience.visionforge.solid.demo
|
||||
import space.kscience.dataforge.meta.Meta
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.visionforge.Vision
|
||||
import space.kscience.visionforge.solid.Solids
|
||||
|
||||
public interface VisionLayout<in V: Vision> {
|
||||
val solids: Solids
|
||||
|
||||
public fun render(name: Name, vision: V, meta: Meta = Meta.EMPTY)
|
||||
}
|
@ -5,6 +5,7 @@ import space.kscience.dataforge.meta.Meta
|
||||
import space.kscience.dataforge.meta.invoke
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.visionforge.Colors
|
||||
import space.kscience.visionforge.setAsRoot
|
||||
import space.kscience.visionforge.solid.*
|
||||
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
||||
import space.kscience.visionforge.visible
|
||||
@ -22,6 +23,7 @@ fun VisionLayout<Solid>.demo(name: String, title: String = name, block: SolidGro
|
||||
ambientLight{
|
||||
color.set(Colors.white)
|
||||
}
|
||||
setAsRoot(solids.visionManager)
|
||||
}
|
||||
render(Name.parse(name), vision, meta)
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ import space.kscience.dataforge.meta.get
|
||||
import space.kscience.dataforge.meta.string
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.visionforge.solid.Solid
|
||||
import space.kscience.visionforge.solid.Solids
|
||||
import space.kscience.visionforge.solid.three.ThreeCanvas
|
||||
import space.kscience.visionforge.solid.three.ThreePlugin
|
||||
|
||||
@ -27,6 +28,8 @@ class ThreeDemoGrid(element: Element) : VisionLayout<Solid> {
|
||||
|
||||
private val three = Global.fetch(ThreePlugin)
|
||||
|
||||
override val solids: Solids get() = three.solids
|
||||
|
||||
init {
|
||||
element.clear()
|
||||
element.append {
|
||||
|
@ -9,7 +9,7 @@ import space.kscience.dataforge.meta.number
|
||||
import space.kscience.dataforge.names.asName
|
||||
import space.kscience.dataforge.names.startsWith
|
||||
import space.kscience.visionforge.onPropertyChange
|
||||
import space.kscience.visionforge.set
|
||||
import space.kscience.visionforge.setChild
|
||||
import space.kscience.visionforge.solid.SolidGroup
|
||||
import space.kscience.visionforge.solid.layer
|
||||
import space.kscience.visionforge.solid.three.*
|
||||
@ -20,7 +20,7 @@ internal fun SolidGroup.varBox(
|
||||
ySize: Number,
|
||||
name: String = "",
|
||||
action: VariableBox.() -> Unit = {},
|
||||
): VariableBox = VariableBox(xSize, ySize).apply(action).also { set(name, it) }
|
||||
): VariableBox = VariableBox(xSize, ySize).apply(action).also { setChild(name, it) }
|
||||
|
||||
internal class VariableBox(val xSize: Number, val ySize: Number) : ThreeJsVision() {
|
||||
|
||||
@ -59,7 +59,7 @@ internal class VariableBox(val xSize: Number, val ySize: Number) : ThreeJsVision
|
||||
material.color.setRGB(r.toFloat() / 256, g.toFloat() / 256, b.toFloat() / 256)
|
||||
mesh.updateMatrix()
|
||||
}
|
||||
name.startsWith(MeshThreeFactory.EDGES_KEY) -> mesh.applyEdges(this@VariableBox)
|
||||
name.startsWith(ThreeMeshFactory.EDGES_KEY) -> mesh.applyEdges(this@VariableBox)
|
||||
else -> mesh.updateProperty(this@VariableBox, name)
|
||||
}
|
||||
}
|
||||
|
@ -10,9 +10,11 @@ import space.kscience.dataforge.names.Name
|
||||
import space.kscience.visionforge.solid.FX3DPlugin
|
||||
import space.kscience.visionforge.solid.FXCanvas3D
|
||||
import space.kscience.visionforge.solid.Solid
|
||||
import space.kscience.visionforge.solid.Solids
|
||||
import tornadofx.*
|
||||
|
||||
class FXDemoGrid : View(title = "DataForge-vis FX demo"), VisionLayout<Solid> {
|
||||
|
||||
private val outputs = FXCollections.observableHashMap<Name, FXCanvas3D>()
|
||||
|
||||
override val root: Parent = borderpane {
|
||||
@ -24,6 +26,9 @@ class FXDemoGrid : View(title = "DataForge-vis FX demo"), VisionLayout<Solid> {
|
||||
}
|
||||
|
||||
private val fx3d = Global.fetch(FX3DPlugin)
|
||||
override val solids: Solids get() = fx3d.solids
|
||||
|
||||
|
||||
|
||||
override fun render(name: Name, vision: Solid, meta: Meta) {
|
||||
outputs.getOrPut(name) { FXCanvas3D(fx3d, canvasOptions) }.render(vision)
|
||||
|
@ -13,6 +13,11 @@ kotlin {
|
||||
api("org.jetbrains.kotlin-wrappers:kotlin-css")
|
||||
}
|
||||
}
|
||||
commonTest{
|
||||
dependencies{
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:${space.kscience.gradle.KScienceVersions.coroutinesVersion}")
|
||||
}
|
||||
}
|
||||
jsMain {
|
||||
dependencies {
|
||||
api("org.jetbrains.kotlin-wrappers:kotlin-extensions")
|
||||
|
@ -11,10 +11,8 @@ import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
||||
import space.kscience.dataforge.misc.Type
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.dataforge.names.asName
|
||||
import space.kscience.dataforge.names.startsWith
|
||||
import space.kscience.visionforge.AbstractVisionGroup.Companion.updateProperties
|
||||
import space.kscience.visionforge.Vision.Companion.TYPE
|
||||
import kotlin.reflect.KProperty1
|
||||
|
||||
/**
|
||||
* A root type for display hierarchy
|
||||
@ -73,18 +71,3 @@ public fun Vision.onPropertyChange(
|
||||
): Job = properties.changes.onEach {
|
||||
callback(it)
|
||||
}.launchIn(scope ?: error("Orphan Vision can't observe properties"))
|
||||
|
||||
|
||||
public fun <V : Vision, T> V.useProperty(
|
||||
property: KProperty1<V, T>,
|
||||
scope: CoroutineScope? = manager?.context,
|
||||
callBack: V.(T) -> Unit,
|
||||
): Job {
|
||||
//Pass initial value.
|
||||
callBack(property.get(this))
|
||||
return properties.changes.onEach { name ->
|
||||
if (name.startsWith(property.name.asName())) {
|
||||
callBack(property.get(this@useProperty))
|
||||
}
|
||||
}.launchIn(scope ?: error("Orphan Vision can't observe properties"))
|
||||
}
|
@ -47,7 +47,7 @@ public class VisionChangeBuilder(private val manager: VisionManager) : MutableVi
|
||||
}
|
||||
}
|
||||
|
||||
override fun set(name: Name?, child: Vision?) {
|
||||
override fun setChild(name: Name?, child: Vision?) {
|
||||
if (name == null) error("Static children are not allowed in VisionChange")
|
||||
getOrPutChild(name).apply {
|
||||
vision = child
|
||||
@ -109,7 +109,7 @@ private fun CoroutineScope.collectChange(
|
||||
if (after != null) {
|
||||
collectChange(fullName, after, collector)
|
||||
}
|
||||
collector()[fullName] = after
|
||||
collector().setChild(fullName, after)
|
||||
}?.launchIn(this)
|
||||
}
|
||||
|
||||
|
@ -11,12 +11,12 @@ import kotlin.jvm.Synchronized
|
||||
public annotation class VisionBuilder
|
||||
|
||||
public interface VisionContainer<out V : Vision> {
|
||||
public operator fun get(name: Name): V?
|
||||
public fun getChild(name: Name): V?
|
||||
}
|
||||
|
||||
public interface MutableVisionContainer<in V : Vision> {
|
||||
//TODO add documentation
|
||||
public operator fun set(name: Name?, child: V?)
|
||||
public fun setChild(name: Name?, child: V?)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -33,10 +33,10 @@ public interface VisionChildren : VisionContainer<Vision> {
|
||||
|
||||
public operator fun get(token: NameToken): Vision?
|
||||
|
||||
override fun get(name: Name): Vision? = when (name.length) {
|
||||
override fun getChild(name: Name): Vision? = when (name.length) {
|
||||
0 -> group
|
||||
1 -> get(name.first())
|
||||
else -> get(name.first())?.children?.get(name.cutFirst())
|
||||
else -> get(name.first())?.children?.getChild(name.cutFirst())
|
||||
}
|
||||
|
||||
public companion object {
|
||||
@ -49,6 +49,10 @@ public interface VisionChildren : VisionContainer<Vision> {
|
||||
}
|
||||
}
|
||||
|
||||
public operator fun VisionChildren.get(name: Name): Vision? = getChild(name)
|
||||
public operator fun VisionChildren.get(name: String): Vision? = getChild(name)
|
||||
|
||||
|
||||
public fun VisionChildren.isEmpty(): Boolean = keys.isEmpty()
|
||||
|
||||
public inline fun VisionChildren.forEach(block: (NameToken, Vision) -> Unit) {
|
||||
@ -61,7 +65,7 @@ public interface MutableVisionChildren : VisionChildren, MutableVisionContainer<
|
||||
|
||||
public operator fun set(token: NameToken, value: Vision?)
|
||||
|
||||
override fun set(name: Name?, child: Vision?) {
|
||||
override fun setChild(name: Name?, child: Vision?) {
|
||||
when {
|
||||
name == null -> {
|
||||
if (child != null) {
|
||||
@ -81,7 +85,7 @@ public interface MutableVisionChildren : VisionChildren, MutableVisionContainer<
|
||||
val parent: MutableVisionGroup = currentParent as? MutableVisionGroup ?: group.createGroup().also {
|
||||
set(name.first(), it)
|
||||
}
|
||||
parent.children[name.cutFirst()] = child
|
||||
parent.children.setChild(name.cutFirst(), child)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -89,6 +93,15 @@ public interface MutableVisionChildren : VisionChildren, MutableVisionContainer<
|
||||
public fun clear()
|
||||
}
|
||||
|
||||
public operator fun MutableVisionChildren.set(name: Name?, vision: Vision?) {
|
||||
setChild(name, vision)
|
||||
}
|
||||
|
||||
public operator fun MutableVisionChildren.set(name: String?, vision: Vision?) {
|
||||
setChild(name, vision)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a static child. Statics could not be found by name, removed or replaced. Changing statics also do not trigger events.
|
||||
*/
|
||||
@ -102,11 +115,11 @@ public fun VisionChildren.asSequence(): Sequence<Pair<NameToken, Vision>> = sequ
|
||||
|
||||
public operator fun VisionChildren.iterator(): Iterator<Pair<NameToken, Vision>> = asSequence().iterator()
|
||||
|
||||
public operator fun <V : Vision> VisionContainer<V>.get(str: String): V? = get(Name.parse(str))
|
||||
public fun <V : Vision> VisionContainer<V>.getChild(str: String): V? = getChild(Name.parse(str))
|
||||
|
||||
public operator fun <V : Vision> MutableVisionContainer<V>.set(
|
||||
public fun <V : Vision> MutableVisionContainer<V>.setChild(
|
||||
str: String?, vision: V?,
|
||||
): Unit = set(str?.parseAsName(), vision)
|
||||
): Unit = setChild(str?.parseAsName(), vision)
|
||||
|
||||
internal abstract class VisionChildrenImpl(
|
||||
override val group: MutableVisionGroup,
|
||||
|
@ -10,7 +10,6 @@ import space.kscience.dataforge.names.Name
|
||||
import space.kscience.dataforge.names.NameToken
|
||||
import space.kscience.dataforge.names.plus
|
||||
import space.kscience.visionforge.Vision.Companion.STYLE_KEY
|
||||
import kotlin.js.JsName
|
||||
|
||||
|
||||
public interface VisionGroup : Vision {
|
||||
@ -35,9 +34,9 @@ public abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup
|
||||
override fun update(change: VisionChange) {
|
||||
change.children?.forEach { (name, change) ->
|
||||
when {
|
||||
change.delete -> children[name] = null
|
||||
change.vision != null -> children[name] = change.vision
|
||||
else -> children[name]?.update(change)
|
||||
change.delete -> children.setChild(name, null)
|
||||
change.vision != null -> children.setChild(name, change.vision)
|
||||
else -> children.getChild(name)?.update(change)
|
||||
}
|
||||
}
|
||||
change.properties?.let {
|
||||
@ -87,12 +86,28 @@ public abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup
|
||||
*/
|
||||
@Serializable
|
||||
@SerialName("vision.group")
|
||||
public class SimpleVisionGroup : AbstractVisionGroup() {
|
||||
public class SimpleVisionGroup : AbstractVisionGroup(), MutableVisionContainer<Vision> {
|
||||
override fun createGroup(): SimpleVisionGroup = SimpleVisionGroup()
|
||||
|
||||
override fun setChild(name: Name?, child: Vision?) {
|
||||
children.setChild(name, child)
|
||||
}
|
||||
}
|
||||
|
||||
@JsName("createVisionGroup")
|
||||
public fun VisionGroup(): VisionGroup = SimpleVisionGroup()
|
||||
@VisionBuilder
|
||||
public fun MutableVisionContainer<Vision>.group(
|
||||
name: Name? = null,
|
||||
builder: SimpleVisionGroup.() -> Unit = {},
|
||||
): SimpleVisionGroup = SimpleVisionGroup().apply(builder).also { setChild(name, it) }
|
||||
|
||||
/**
|
||||
* Define a group with given [name], attach it to this parent and return it.
|
||||
*/
|
||||
@VisionBuilder
|
||||
public fun MutableVisionContainer<Vision>.group(
|
||||
name: String,
|
||||
builder: SimpleVisionGroup.() -> Unit = {},
|
||||
): SimpleVisionGroup = SimpleVisionGroup().apply(builder).also { setChild(name, it) }
|
||||
|
||||
//fun VisualObject.findStyle(styleName: Name): Meta? {
|
||||
// if (this is VisualGroup) {
|
||||
|
@ -19,7 +19,7 @@ import space.kscience.visionforge.html.VisionOfNumberField
|
||||
import space.kscience.visionforge.html.VisionOfTextField
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
public class VisionManager(meta: Meta) : AbstractPlugin(meta) {
|
||||
public class VisionManager(meta: Meta) : AbstractPlugin(meta), MutableVisionContainer<Vision> {
|
||||
override val tag: PluginTag get() = Companion.tag
|
||||
|
||||
/**
|
||||
@ -58,6 +58,10 @@ public class VisionManager(meta: Meta) : AbstractPlugin(meta) {
|
||||
public fun encodeToMeta(vision: Vision, descriptor: MetaDescriptor? = null): Meta =
|
||||
encodeToJsonElement(vision).toMeta(descriptor)
|
||||
|
||||
override fun setChild(name: Name?, child: Vision?) {
|
||||
child?.setAsRoot(this)
|
||||
}
|
||||
|
||||
public companion object : PluginFactory<VisionManager> {
|
||||
override val tag: PluginTag = PluginTag(name = "vision", group = PluginTag.DATAFORGE_GROUP)
|
||||
override val type: KClass<out VisionManager> = VisionManager::class
|
||||
|
@ -73,6 +73,19 @@ public interface MutableVisionProperties : VisionProperties {
|
||||
)
|
||||
}
|
||||
|
||||
public fun MutableVisionProperties.remove(name: Name){
|
||||
setProperty(name, null)
|
||||
}
|
||||
|
||||
public fun MutableVisionProperties.remove(name: String){
|
||||
remove(name.parseAsName())
|
||||
}
|
||||
|
||||
@VisionBuilder
|
||||
public operator fun MutableVisionProperties.invoke(block: MutableMeta.() -> Unit) {
|
||||
root(inherit = false, includeStyles = false).apply(block)
|
||||
}
|
||||
|
||||
private class VisionPropertiesItem(
|
||||
val properties: MutableVisionProperties,
|
||||
val nodeName: Name,
|
||||
@ -190,7 +203,7 @@ public abstract class AbstractVisionProperties(
|
||||
}
|
||||
|
||||
@Transient
|
||||
private val _changes = MutableSharedFlow<Name>(10)
|
||||
private val _changes = MutableSharedFlow<Name>()
|
||||
override val changes: SharedFlow<Name> get() = _changes
|
||||
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
|
@ -0,0 +1,55 @@
|
||||
package space.kscience.visionforge
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import space.kscience.dataforge.meta.Meta
|
||||
import space.kscience.dataforge.meta.Value
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.dataforge.names.parseAsName
|
||||
import space.kscience.dataforge.names.startsWith
|
||||
|
||||
/**
|
||||
* Create a flow of a specific property
|
||||
*/
|
||||
public fun Vision.flowProperty(
|
||||
propertyName: Name,
|
||||
inherit: Boolean? = null,
|
||||
includeStyles: Boolean? = null,
|
||||
): Flow<Meta> = flow {
|
||||
//Pass initial value.
|
||||
emit(properties.getProperty(propertyName, inherit, includeStyles))
|
||||
properties.changes.collect { name ->
|
||||
if (name.startsWith(propertyName)) {
|
||||
emit(properties.getProperty(propertyName, inherit, includeStyles))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public fun Vision.flowProperty(
|
||||
propertyName: String,
|
||||
inherit: Boolean? = null,
|
||||
includeStyles: Boolean? = null,
|
||||
): Flow<Meta> = flowProperty(propertyName.parseAsName(), inherit, includeStyles)
|
||||
|
||||
/**
|
||||
* Flow the value of specific property
|
||||
*/
|
||||
public fun Vision.flowPropertyValue(
|
||||
propertyName: Name,
|
||||
inherit: Boolean? = null,
|
||||
includeStyles: Boolean? = null,
|
||||
): Flow<Value?> = flow {
|
||||
//Pass initial value.
|
||||
emit(properties.getValue(propertyName, inherit, includeStyles))
|
||||
properties.changes.collect { name ->
|
||||
if (name.startsWith(propertyName)) {
|
||||
emit(properties.getValue(propertyName, inherit, includeStyles))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public fun Vision.flowPropertyValue(
|
||||
propertyName: String,
|
||||
inherit: Boolean? = null,
|
||||
includeStyles: Boolean? = null,
|
||||
): Flow<Value?> = flowPropertyValue(propertyName.parseAsName(), inherit, includeStyles)
|
@ -0,0 +1,54 @@
|
||||
package space.kscience.visionforge
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import space.kscience.dataforge.meta.Meta
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.dataforge.names.asName
|
||||
import space.kscience.dataforge.names.parseAsName
|
||||
import space.kscience.dataforge.names.startsWith
|
||||
import kotlin.reflect.KProperty1
|
||||
|
||||
|
||||
/**
|
||||
* Call [callBack] on initial value of the property and then on all subsequent values after change
|
||||
*/
|
||||
public fun Vision.useProperty(
|
||||
propertyName: Name,
|
||||
inherit: Boolean? = null,
|
||||
includeStyles: Boolean? = null,
|
||||
scope: CoroutineScope? = manager?.context,
|
||||
callBack: (Meta) -> Unit,
|
||||
): Job {
|
||||
//Pass initial value.
|
||||
callBack(properties.getProperty(propertyName, inherit, includeStyles))
|
||||
return properties.changes.onEach { name ->
|
||||
if (name.startsWith(propertyName)) {
|
||||
callBack(properties.getProperty(propertyName, inherit, includeStyles))
|
||||
}
|
||||
}.launchIn(scope ?: error("Orphan Vision can't observe properties"))
|
||||
}
|
||||
|
||||
public fun Vision.useProperty(
|
||||
propertyName: String,
|
||||
inherit: Boolean? = null,
|
||||
includeStyles: Boolean? = null,
|
||||
scope: CoroutineScope? = manager?.context,
|
||||
callBack: (Meta) -> Unit,
|
||||
): Job = useProperty(propertyName.parseAsName(),inherit, includeStyles, scope, callBack)
|
||||
|
||||
public fun <V : Vision, T> V.useProperty(
|
||||
property: KProperty1<V, T>,
|
||||
scope: CoroutineScope? = manager?.context,
|
||||
callBack: V.(T) -> Unit,
|
||||
): Job {
|
||||
//Pass initial value.
|
||||
callBack(property.get(this))
|
||||
return properties.changes.onEach { name ->
|
||||
if (name.startsWith(property.name.asName())) {
|
||||
callBack(property.get(this@useProperty))
|
||||
}
|
||||
}.launchIn(scope ?: error("Orphan Vision can't observe properties"))
|
||||
}
|
@ -30,7 +30,7 @@ fun FlowContent.renderVisionFragment(
|
||||
|
||||
|
||||
@DFExperimental
|
||||
private fun VisionOutput.base(block: VisionGroup.() -> Unit) = VisionGroup().apply(block)
|
||||
private fun VisionOutput.base(block: VisionGroup.() -> Unit) = context.visionManager.group().apply(block)
|
||||
|
||||
@DFExperimental
|
||||
class HtmlTagTest {
|
||||
|
@ -1,10 +1,14 @@
|
||||
package space.kscience.visionforge.meta
|
||||
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.collectIndexed
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import space.kscience.dataforge.context.Global
|
||||
import space.kscience.dataforge.context.fetch
|
||||
import space.kscience.dataforge.meta.*
|
||||
import space.kscience.visionforge.VisionGroup
|
||||
import space.kscience.visionforge.getProperty
|
||||
import space.kscience.visionforge.getValue
|
||||
import space.kscience.visionforge.set
|
||||
import space.kscience.visionforge.*
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertNotEquals
|
||||
@ -17,9 +21,12 @@ private class TestScheme : Scheme() {
|
||||
}
|
||||
|
||||
internal class VisionPropertyTest {
|
||||
|
||||
private val manager = Global.fetch(VisionManager)
|
||||
|
||||
@Test
|
||||
fun testPropertyWrite() {
|
||||
val vision = VisionGroup()
|
||||
val vision = manager.group()
|
||||
vision.properties["fff"] = 2
|
||||
vision.properties["fff.ddd"] = false
|
||||
|
||||
@ -29,7 +36,7 @@ internal class VisionPropertyTest {
|
||||
|
||||
@Test
|
||||
fun testPropertyEdit() {
|
||||
val vision = VisionGroup()
|
||||
val vision = manager.group()
|
||||
vision.properties.getProperty("fff.ddd").apply {
|
||||
value = 2.asValue()
|
||||
}
|
||||
@ -39,10 +46,78 @@ internal class VisionPropertyTest {
|
||||
|
||||
@Test
|
||||
fun testPropertyUpdate() {
|
||||
val vision = VisionGroup()
|
||||
val vision = manager.group()
|
||||
vision.properties.getProperty("fff").updateWith(TestScheme) {
|
||||
ddd = 2
|
||||
}
|
||||
assertEquals(2, vision.properties.getValue("fff.ddd")?.int)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testChildrenPropertyPropagation() = runTest(dispatchTimeoutMs = 200) {
|
||||
val group = Global.fetch(VisionManager).group {
|
||||
properties {
|
||||
"test" put 11
|
||||
}
|
||||
group("child") {
|
||||
properties {
|
||||
"test" put 22
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val child = group.children["child"]!!
|
||||
|
||||
var value: Value? = null
|
||||
|
||||
var callCounter = 0
|
||||
|
||||
child.useProperty("test", inherit = true) {
|
||||
callCounter++
|
||||
value = it.value
|
||||
}
|
||||
|
||||
assertEquals(22, value?.int)
|
||||
assertEquals(1, callCounter)
|
||||
|
||||
child.properties.remove("test")
|
||||
|
||||
//Need this to avoid the race
|
||||
delay(20)
|
||||
|
||||
assertEquals(11, child.properties.getProperty("test", inherit = true).int)
|
||||
assertEquals(11, value?.int)
|
||||
assertEquals(2, callCounter)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testChildrenPropertyFlow() = runTest(dispatchTimeoutMs = 200) {
|
||||
val group = Global.fetch(VisionManager).group {
|
||||
properties {
|
||||
"test" put 11
|
||||
}
|
||||
group("child") {
|
||||
properties {
|
||||
"test" put 22
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val child = group.children["child"]!!
|
||||
|
||||
launch {
|
||||
child.flowPropertyValue("test", inherit = true).collectIndexed { index, value ->
|
||||
if (index == 0) {
|
||||
assertEquals(22, value?.int)
|
||||
} else if (index == 1) {
|
||||
assertEquals(11, value?.int)
|
||||
cancel()
|
||||
}
|
||||
}
|
||||
}
|
||||
//wait for subscription to be created
|
||||
delay(10)
|
||||
|
||||
child.properties.remove("test")
|
||||
}
|
||||
}
|
@ -22,7 +22,7 @@ public class FXReferenceFactory(public val plugin: FX3DPlugin) : FX3DFactory<Sol
|
||||
if (name.firstOrNull()?.body == REFERENCE_CHILD_PROPERTY_PREFIX) {
|
||||
val childName = name.firstOrNull()?.index?.let(Name::parse) ?: error("Wrong syntax for reference child property: '$name'")
|
||||
val propertyName = name.cutFirst()
|
||||
val referenceChild = obj.children[childName] ?: error("Reference child with name '$childName' not found")
|
||||
val referenceChild = obj.children.getChild(childName) ?: error("Reference child with name '$childName' not found")
|
||||
val child = node.findChild(childName) ?: error("Object child with name '$childName' not found")
|
||||
child.updateProperty(referenceChild, propertyName)
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) {
|
||||
): SolidReference {
|
||||
val templateName = volumesName + volume.name.asName()
|
||||
if (proto[templateName] == null) {
|
||||
proto[templateName] = volume(root, volume)
|
||||
proto.setChild(templateName, volume(root, volume))
|
||||
}
|
||||
val ref = group.ref(templateName, physVolume.name).withPosition(root, physVolume)
|
||||
referenceStore.getOrPut(templateName) { ArrayList() }.add(ref)
|
||||
@ -302,7 +302,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) {
|
||||
when (settings.volumeAction(volume)) {
|
||||
GdmlLoaderOptions.Action.ADD -> {
|
||||
val group: SolidGroup = volume(root, volume)
|
||||
this[physVolume.name] = group.withPosition(root, physVolume)
|
||||
this.setChild(physVolume.name, group.withPosition(root, physVolume))
|
||||
}
|
||||
GdmlLoaderOptions.Action.PROTOTYPE -> {
|
||||
proxyVolume(root, this, physVolume, volume)
|
||||
@ -357,7 +357,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) {
|
||||
final.prototypes {
|
||||
proto.items.forEach { (token, item) ->
|
||||
item.parent = null
|
||||
set(token.asName(), item as? Solid)
|
||||
setChild(token.asName(), item as? Solid)
|
||||
}
|
||||
}
|
||||
settings.styleCache.forEach {
|
||||
@ -385,7 +385,7 @@ public fun Gdml.toVision(block: GdmlLoaderOptions.() -> Unit = {}): SolidGroup {
|
||||
public fun SolidGroup.gdml(gdml: Gdml, key: String? = null, transformer: GdmlLoaderOptions.() -> Unit = {}) {
|
||||
val vision = gdml.toVision(transformer)
|
||||
//println(Visual3DPlugin.json.stringify(VisualGroup3D.serializer(), visual))
|
||||
children[key] = vision
|
||||
children.setChild(key, vision)
|
||||
}
|
||||
|
||||
@VisionBuilder
|
||||
|
@ -4,7 +4,7 @@ import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.gdml.*
|
||||
import space.kscience.visionforge.Vision
|
||||
import space.kscience.visionforge.get
|
||||
import space.kscience.visionforge.getChild
|
||||
import space.kscience.visionforge.solid.*
|
||||
import space.kscience.visionforge.visionManager
|
||||
import kotlin.test.Test
|
||||
@ -26,7 +26,7 @@ class TestCubes {
|
||||
val smallBoxPrototype = vision.getPrototype(Name.parse("solids.smallBox")) as? Box
|
||||
assertNotNull(smallBoxPrototype)
|
||||
assertEquals(30.0, smallBoxPrototype.xSize.toDouble())
|
||||
val smallBoxVision = vision.children["composite-111.smallBox"]?.prototype as? Box
|
||||
val smallBoxVision = vision.children.getChild("composite-111.smallBox")?.prototype as? Box
|
||||
assertNotNull(smallBoxVision)
|
||||
assertEquals(30.0, smallBoxVision.xSize.toDouble())
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
import space.kscience.gradle.KScienceVersions
|
||||
|
||||
plugins {
|
||||
id("space.kscience.gradle.mpp")
|
||||
}
|
||||
@ -17,7 +19,7 @@ kotlin {
|
||||
}
|
||||
commonTest{
|
||||
dependencies{
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:${KScienceVersions.coroutinesVersion}")
|
||||
}
|
||||
}
|
||||
jvmTest{
|
||||
|
@ -35,7 +35,7 @@ public inline fun MutableVisionContainer<Solid>.composite(
|
||||
|
||||
res.properties.setProperty(Name.EMPTY, group.properties.own)
|
||||
|
||||
set(name, res)
|
||||
setChild(name, res)
|
||||
return res
|
||||
}
|
||||
|
||||
@ -57,7 +57,7 @@ public fun SolidGroup.smartComposite(
|
||||
}
|
||||
this
|
||||
} else {
|
||||
children[name] = group
|
||||
children.setChild(name, group)
|
||||
group
|
||||
}
|
||||
} else {
|
||||
|
@ -4,7 +4,7 @@ import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import space.kscience.visionforge.MutableVisionContainer
|
||||
import space.kscience.visionforge.VisionBuilder
|
||||
import space.kscience.visionforge.set
|
||||
import space.kscience.visionforge.setChild
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
@ -76,7 +76,7 @@ public inline fun MutableVisionContainer<Solid>.cylinder(
|
||||
r.toFloat(),
|
||||
height.toFloat(),
|
||||
r.toFloat()
|
||||
).apply(block).also { set(name, it) }
|
||||
).apply(block).also { setChild(name, it) }
|
||||
|
||||
@VisionBuilder
|
||||
public inline fun MutableVisionContainer<Solid>.cone(
|
||||
@ -93,4 +93,4 @@ public inline fun MutableVisionContainer<Solid>.cone(
|
||||
topRadius = upperRadius.toFloat(),
|
||||
startAngle = startAngle.toFloat(),
|
||||
angle = angle.toFloat()
|
||||
).apply(block).also { set(name, it) }
|
||||
).apply(block).also { setChild(name, it) }
|
@ -4,7 +4,7 @@ import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import space.kscience.visionforge.MutableVisionContainer
|
||||
import space.kscience.visionforge.VisionBuilder
|
||||
import space.kscience.visionforge.set
|
||||
import space.kscience.visionforge.setChild
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
@ -139,7 +139,7 @@ public inline fun MutableVisionContainer<Solid>.tube(
|
||||
topInnerRadius = innerRadius.toFloat(),
|
||||
startAngle = startAngle.toFloat(),
|
||||
angle = angle.toFloat()
|
||||
).apply(block).also { set(name, it) }
|
||||
).apply(block).also { setChild(name, it) }
|
||||
|
||||
@VisionBuilder
|
||||
public inline fun MutableVisionContainer<Solid>.coneSurface(
|
||||
@ -160,4 +160,4 @@ public inline fun MutableVisionContainer<Solid>.coneSurface(
|
||||
topInnerRadius = topInnerRadius.toFloat(),
|
||||
startAngle = startAngle.toFloat(),
|
||||
angle = angle.toFloat()
|
||||
).apply(block).also { set(name, it) }
|
||||
).apply(block).also { setChild(name, it) }
|
@ -3,7 +3,7 @@ package space.kscience.visionforge.solid
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import space.kscience.visionforge.MutableVisionContainer
|
||||
import space.kscience.visionforge.set
|
||||
import space.kscience.visionforge.setChild
|
||||
|
||||
@Serializable
|
||||
@SerialName("solid.convex")
|
||||
@ -12,7 +12,7 @@ public class Convex(public val points: List<Point3D>) : SolidBase<Convex>()
|
||||
public inline fun MutableVisionContainer<Solid>.convex(
|
||||
name: String? = null,
|
||||
action: ConvexBuilder.() -> Unit = {},
|
||||
): Convex = ConvexBuilder().apply(action).build().also { set(name, it) }
|
||||
): Convex = ConvexBuilder().apply(action).build().also { setChild(name, it) }
|
||||
|
||||
public class ConvexBuilder {
|
||||
private val points = ArrayList<Point3D>()
|
||||
|
@ -115,4 +115,4 @@ public class ExtrudeBuilder(
|
||||
public fun MutableVisionContainer<Solid>.extruded(
|
||||
name: String? = null,
|
||||
action: ExtrudeBuilder.() -> Unit = {},
|
||||
): Extruded = ExtrudeBuilder().apply(action).build().also { set(name, it) }
|
||||
): Extruded = ExtrudeBuilder().apply(action).build().also { setChild(name, it) }
|
@ -4,7 +4,7 @@ import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import space.kscience.visionforge.MutableVisionContainer
|
||||
import space.kscience.visionforge.VisionBuilder
|
||||
import space.kscience.visionforge.set
|
||||
import space.kscience.visionforge.setChild
|
||||
|
||||
public interface Hexagon : GeometrySolid {
|
||||
public val node1: Point3D
|
||||
@ -58,7 +58,7 @@ public inline fun MutableVisionContainer<Solid>.box(
|
||||
zSize: Number,
|
||||
name: String? = null,
|
||||
block: Box.() -> Unit = {},
|
||||
): Box = Box(xSize.toFloat(), ySize.toFloat(), zSize.toFloat()).apply(block).also { set(name, it) }
|
||||
): Box = Box(xSize.toFloat(), ySize.toFloat(), zSize.toFloat()).apply(block).also { setChild(name, it) }
|
||||
|
||||
@Serializable
|
||||
@SerialName("solid.hexagon")
|
||||
@ -85,4 +85,4 @@ public inline fun MutableVisionContainer<Solid>.hexagon(
|
||||
node8: Point3D,
|
||||
name: String? = null,
|
||||
action: Hexagon.() -> Unit = {},
|
||||
): Hexagon = GenericHexagon(node1, node2, node3, node4, node5, node6, node7, node8).apply(action).also { set(name, it) }
|
||||
): Hexagon = GenericHexagon(node1, node2, node3, node4, node5, node6, node7, node8).apply(action).also { setChild(name, it) }
|
@ -55,7 +55,7 @@ public class AmbientLightSource : LightSource()
|
||||
public fun MutableVisionContainer<Solid>.ambientLight(
|
||||
name: String? = "@ambientLight",
|
||||
block: AmbientLightSource.() -> Unit = {},
|
||||
): AmbientLightSource = AmbientLightSource().apply(block).also { set(name, it) }
|
||||
): AmbientLightSource = AmbientLightSource().apply(block).also { setChild(name, it) }
|
||||
|
||||
@Serializable
|
||||
@SerialName("solid.light.point")
|
||||
@ -71,5 +71,5 @@ public fun MutableVisionContainer<Solid>.pointLight(
|
||||
block: PointLightSource.() -> Unit = {},
|
||||
): PointLightSource = PointLightSource().apply(block).also {
|
||||
it.position = Point3D(x, y, z)
|
||||
set(name, it)
|
||||
setChild(name, it)
|
||||
}
|
@ -18,4 +18,4 @@ public fun MutableVisionContainer<Solid>.polyline(
|
||||
vararg points: Point3D,
|
||||
name: String? = null,
|
||||
action: PolyLine.() -> Unit = {},
|
||||
): PolyLine = PolyLine(points.toList()).apply(action).also { set(name, it) }
|
||||
): PolyLine = PolyLine(points.toList()).apply(action).also { setChild(name, it) }
|
@ -38,7 +38,7 @@ public class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder, Mutable
|
||||
it to value
|
||||
}.toMap()
|
||||
|
||||
public operator fun get(name: Name): Solid? = children[name] as? Solid
|
||||
public operator fun get(name: Name): Solid? = children.getChild(name) as? Solid
|
||||
|
||||
private var prototypes: SolidGroup?
|
||||
get() = items[PROTOTYPES_TOKEN] as? SolidGroup
|
||||
@ -70,8 +70,8 @@ public class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder, Mutable
|
||||
// super.update(change)
|
||||
// }
|
||||
|
||||
override fun set(name: Name?, child: Solid?) {
|
||||
children[name] = child
|
||||
override fun setChild(name: Name?, child: Solid?) {
|
||||
children.setChild(name, child)
|
||||
}
|
||||
|
||||
public companion object {
|
||||
@ -85,7 +85,7 @@ public inline fun SolidGroup(block: SolidGroup.() -> Unit): SolidGroup = SolidGr
|
||||
public fun MutableVisionContainer<Solid>.group(
|
||||
name: Name? = null,
|
||||
builder: SolidGroup.() -> Unit = {},
|
||||
): SolidGroup = SolidGroup(builder).also { set(name, it) }
|
||||
): SolidGroup = SolidGroup(builder).also { setChild(name, it) }
|
||||
|
||||
/**
|
||||
* Define a group with given [name], attach it to this parent and return it.
|
||||
@ -94,4 +94,4 @@ public fun MutableVisionContainer<Solid>.group(
|
||||
public fun MutableVisionContainer<Solid>.group(
|
||||
name: String,
|
||||
action: SolidGroup.() -> Unit = {},
|
||||
): SolidGroup = SolidGroup(action).also { set(name, it) }
|
||||
): SolidGroup = SolidGroup(action).also { setChild(name, it) }
|
||||
|
@ -4,7 +4,7 @@ import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import space.kscience.visionforge.MutableVisionContainer
|
||||
import space.kscience.visionforge.VisionBuilder
|
||||
import space.kscience.visionforge.set
|
||||
import space.kscience.visionforge.setChild
|
||||
|
||||
@Serializable
|
||||
@SerialName("solid.label")
|
||||
@ -21,4 +21,4 @@ public fun MutableVisionContainer<Solid>.label(
|
||||
fontFamily: String = "Arial",
|
||||
name: String? = null,
|
||||
action: SolidLabel.() -> Unit = {},
|
||||
): SolidLabel = SolidLabel(text, fontSize.toDouble(), fontFamily).apply(action).also { set(name, it) }
|
||||
): SolidLabel = SolidLabel(text, fontSize.toDouble(), fontFamily).apply(action).also { setChild(name, it) }
|
@ -97,7 +97,7 @@ internal class SolidReferenceChild(
|
||||
) : Solid, VisionGroup {
|
||||
|
||||
val prototype: Solid
|
||||
get() = owner.prototype.children?.get(childName) as? Solid
|
||||
get() = owner.prototype.children?.getChild(childName) as? Solid
|
||||
?: error("Prototype with name $childName not found")
|
||||
|
||||
override val descriptor: MetaDescriptor get() = prototype.descriptor
|
||||
@ -137,7 +137,7 @@ internal class SolidReferenceChild(
|
||||
when {
|
||||
change.delete -> error("Deleting children inside ref is not allowed.")
|
||||
change.vision != null -> error("Updating content of the ref is not allowed")
|
||||
else -> children[name]?.update(change)
|
||||
else -> children.getChild(name)?.update(change)
|
||||
}
|
||||
}
|
||||
change.properties?.let {
|
||||
@ -176,7 +176,7 @@ internal class SolidReferenceChild(
|
||||
public fun MutableVisionContainer<Solid>.ref(
|
||||
templateName: Name,
|
||||
name: String? = null,
|
||||
): SolidReference = SolidReference(templateName).also { set(name, it) }
|
||||
): SolidReference = SolidReference(templateName).also { setChild(name, it) }
|
||||
|
||||
public fun MutableVisionContainer<Solid>.ref(
|
||||
templateName: String,
|
||||
@ -195,7 +195,7 @@ public fun SolidGroup.newRef(
|
||||
val existing = prototypeHolder.getPrototype(prototypeName)
|
||||
if (existing == null) {
|
||||
prototypeHolder.prototypes {
|
||||
set(prototypeName, obj)
|
||||
setChild(prototypeName, obj)
|
||||
}
|
||||
} else if (existing != obj) {
|
||||
error("Can't add different prototype on top of existing one")
|
||||
|
@ -4,7 +4,7 @@ import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import space.kscience.visionforge.MutableVisionContainer
|
||||
import space.kscience.visionforge.VisionBuilder
|
||||
import space.kscience.visionforge.set
|
||||
import space.kscience.visionforge.setChild
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
@ -58,4 +58,4 @@ public inline fun MutableVisionContainer<Solid>.sphere(
|
||||
action: Sphere.() -> Unit = {},
|
||||
): Sphere = Sphere(
|
||||
radius.toFloat(),
|
||||
).apply(action).also { set(name, it) }
|
||||
).apply(action).also { setChild(name, it) }
|
@ -4,7 +4,7 @@ import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import space.kscience.visionforge.MutableVisionContainer
|
||||
import space.kscience.visionforge.VisionBuilder
|
||||
import space.kscience.visionforge.set
|
||||
import space.kscience.visionforge.setChild
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
@ -85,4 +85,4 @@ public inline fun MutableVisionContainer<Solid>.sphereLayer(
|
||||
phi.toFloat(),
|
||||
thetaStart.toFloat(),
|
||||
theta.toFloat()
|
||||
).apply(action).also { set(name, it) }
|
||||
).apply(action).also { setChild(name, it) }
|
@ -39,7 +39,7 @@ internal object RemoveSingleChild : VisualTreeTransform<SolidGroup>() {
|
||||
val child: Solid = parent.items.values.first()
|
||||
val newParent = child.updateFrom(parent)
|
||||
newParent.parent = null
|
||||
children[childName.asName()] = newParent
|
||||
children.setChild(childName.asName(), newParent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,14 +4,8 @@ import space.kscience.dataforge.misc.DFExperimental
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.visionforge.solid.SolidGroup
|
||||
import space.kscience.visionforge.solid.SolidReference
|
||||
import kotlin.collections.HashMap
|
||||
import kotlin.collections.Map
|
||||
import kotlin.collections.component1
|
||||
import kotlin.collections.component2
|
||||
import kotlin.collections.filter
|
||||
import kotlin.collections.filterIsInstance
|
||||
import kotlin.collections.fold
|
||||
import kotlin.collections.forEach
|
||||
import kotlin.collections.set
|
||||
|
||||
@DFExperimental
|
||||
@ -33,7 +27,7 @@ internal object UnRef : VisualTreeTransform<SolidGroup>() {
|
||||
|
||||
private fun SolidGroup.unref(name: Name) {
|
||||
(this as? SolidGroup)?.prototypes{
|
||||
set(name, null)
|
||||
setChild(name, null)
|
||||
}
|
||||
items.filter { (it.value as? SolidReference)?.prototypeName == name }.forEach { (key, value) ->
|
||||
val reference = value as SolidReference
|
||||
|
@ -1,7 +1,7 @@
|
||||
package space.kscience.visionforge.solid
|
||||
|
||||
import space.kscience.visionforge.Colors
|
||||
import space.kscience.visionforge.get
|
||||
import space.kscience.visionforge.getChild
|
||||
import kotlin.math.PI
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
@ -45,7 +45,7 @@ class GroupTest {
|
||||
}
|
||||
|
||||
assertEquals(3, group.items.count())
|
||||
assertEquals(300.0, (group.children["intersect"] as Solid).y.toDouble())
|
||||
assertEquals(-300.0, (group.children["subtract"] as Solid).y.toDouble())
|
||||
assertEquals(300.0, (group.children.getChild("intersect") as Solid).y.toDouble())
|
||||
assertEquals(-300.0, (group.children.getChild("subtract") as Solid).y.toDouble())
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ package space.kscience.visionforge.solid
|
||||
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.visionforge.Colors
|
||||
import space.kscience.visionforge.get
|
||||
import space.kscience.visionforge.getChild
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@ -52,7 +52,7 @@ class SerializationTest {
|
||||
val string = Solids.encodeToString(group)
|
||||
println(string)
|
||||
val reconstructed = Solids.decodeFromString(string) as SolidGroup
|
||||
assertEquals(group.children["cube"]?.properties?.own, reconstructed.children["cube"]?.properties?.own)
|
||||
assertEquals(group.children.getChild("cube")?.properties?.own, reconstructed.children.getChild("cube")?.properties?.own)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -66,7 +66,7 @@ class SerializationTest {
|
||||
val serialized = Solids.encodeToString(group)
|
||||
|
||||
val reconstructed = Solids.decodeFromString(serialized) as SolidGroup
|
||||
assertEquals(100.0, (reconstructed.children["@ambientLight"] as AmbientLightSource).intensity.toDouble())
|
||||
assertEquals(100.0, (reconstructed.children.getChild("@ambientLight") as AmbientLightSource).intensity.toDouble())
|
||||
}
|
||||
|
||||
}
|
@ -3,7 +3,7 @@ package space.kscience.visionforge.solid
|
||||
import space.kscience.dataforge.context.Global
|
||||
import space.kscience.dataforge.context.fetch
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
import space.kscience.visionforge.get
|
||||
import space.kscience.visionforge.getChild
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@ -25,8 +25,8 @@ class SolidPluginTest {
|
||||
val reconstructed = visionManager.decodeFromMeta(meta) as SolidGroup
|
||||
|
||||
assertEquals(
|
||||
visionManager.encodeToJsonElement(vision.children["aBox"]!!),
|
||||
visionManager.encodeToJsonElement(reconstructed.children["aBox"]!!)
|
||||
visionManager.encodeToJsonElement(vision.children.getChild("aBox")!!),
|
||||
visionManager.encodeToJsonElement(reconstructed.children.getChild("aBox")!!)
|
||||
)
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ package space.kscience.visionforge.solid
|
||||
import kotlinx.serialization.json.encodeToJsonElement
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
import space.kscience.dataforge.names.get
|
||||
import space.kscience.visionforge.get
|
||||
import space.kscience.visionforge.getChild
|
||||
import space.kscience.visionforge.style
|
||||
import space.kscience.visionforge.useStyle
|
||||
import kotlin.test.Test
|
||||
@ -24,7 +24,7 @@ class SolidReferenceTest {
|
||||
|
||||
@Test
|
||||
fun testReferenceProperty(){
|
||||
assertEquals("blue", (groupWithReference.children["test"] as Solid).color.string)
|
||||
assertEquals("blue", (groupWithReference.children.getChild("test") as Solid).color.string)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -32,6 +32,6 @@ class SolidReferenceTest {
|
||||
val serialized = Solids.jsonForSolids.encodeToJsonElement(groupWithReference)
|
||||
val deserialized = Solids.jsonForSolids.decodeFromJsonElement(SolidGroup.serializer(), serialized)
|
||||
assertEquals(groupWithReference.items["test"]?.color.string, deserialized.items["test"]?.color.string)
|
||||
assertEquals("blue", (deserialized.children["test"] as Solid).color.string)
|
||||
assertEquals("blue", (deserialized.children.getChild("test") as Solid).color.string)
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@ import space.kscience.dataforge.meta.Meta
|
||||
import space.kscience.dataforge.meta.asValue
|
||||
import space.kscience.dataforge.names.asName
|
||||
import space.kscience.visionforge.VisionChange
|
||||
import space.kscience.visionforge.get
|
||||
import space.kscience.visionforge.getChild
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
@ -29,9 +29,9 @@ internal class VisionUpdateTest {
|
||||
propertyChanged("origin".asName(), SolidMaterial.MATERIAL_COLOR_KEY, Meta("red".asValue()))
|
||||
}
|
||||
targetVision.update(dif)
|
||||
assertTrue { targetVision.children["top"] is SolidGroup }
|
||||
assertEquals("red", (targetVision.children["origin"] as Solid).color.string) // Should work
|
||||
assertEquals("#00007b", (targetVision.children["top"] as Solid).color.string) // new item always takes precedence
|
||||
assertTrue { targetVision.children.getChild("top") is SolidGroup }
|
||||
assertEquals("red", (targetVision.children.getChild("origin") as Solid).color.string) // Should work
|
||||
assertEquals("#00007b", (targetVision.children.getChild("top") as Solid).color.string) // new item always takes precedence
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -10,6 +10,6 @@ kotlin{
|
||||
|
||||
dependencies {
|
||||
api(project(":visionforge-solid"))
|
||||
implementation(npm("three", "0.137.4"))
|
||||
implementation(npm("three", "0.137.5"))
|
||||
implementation(npm("three-csg-ts", "3.1.10"))
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import info.laht.threekt.geometries.BoxGeometry
|
||||
import space.kscience.visionforge.solid.Box
|
||||
import space.kscience.visionforge.solid.detail
|
||||
|
||||
public object ThreeBoxFactory : MeshThreeFactory<Box>(Box::class) {
|
||||
public object ThreeBoxFactory : ThreeMeshFactory<Box>(Box::class) {
|
||||
override fun buildGeometry(obj: Box): BoxGeometry =
|
||||
obj.detail?.let { detail ->
|
||||
BoxGeometry(obj.xSize, obj.ySize, obj.zSize, detail, detail, detail)
|
||||
|
@ -50,7 +50,7 @@ public class ThreeCompositeFactory(public val three: ThreePlugin) : ThreeFactory
|
||||
obj.onPropertyChange { name ->
|
||||
when {
|
||||
//name.startsWith(WIREFRAME_KEY) -> mesh.applyWireFrame(obj)
|
||||
name.startsWith(MeshThreeFactory.EDGES_KEY) -> applyEdges(obj)
|
||||
name.startsWith(ThreeMeshFactory.EDGES_KEY) -> applyEdges(obj)
|
||||
else -> updateProperty(obj, name)
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ import space.kscience.visionforge.solid.detail
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.pow
|
||||
|
||||
public object ThreeConeFactory : MeshThreeFactory<ConeSegment>(ConeSegment::class) {
|
||||
public object ThreeConeFactory : ThreeMeshFactory<ConeSegment>(ConeSegment::class) {
|
||||
override fun buildGeometry(obj: ConeSegment): BufferGeometry {
|
||||
val cylinder = obj.detail?.let {
|
||||
val segments = it.toDouble().pow(0.5).toInt()
|
||||
|
@ -3,7 +3,7 @@ package space.kscience.visionforge.solid.three
|
||||
import info.laht.threekt.external.geometries.ConvexBufferGeometry
|
||||
import space.kscience.visionforge.solid.Convex
|
||||
|
||||
public object ThreeConvexFactory : MeshThreeFactory<Convex>(Convex::class) {
|
||||
public object ThreeConvexFactory : ThreeMeshFactory<Convex>(Convex::class) {
|
||||
override fun buildGeometry(obj: Convex): ConvexBufferGeometry {
|
||||
val vectors = obj.points.map { it.toVector() }.toTypedArray()
|
||||
return ConvexBufferGeometry(vectors)
|
||||
|
@ -75,7 +75,7 @@ public fun Object3D.updateProperty(source: Vision, propertyName: Name) {
|
||||
/**
|
||||
* Generic factory for elements which provide inside geometry builder
|
||||
*/
|
||||
public object ThreeShapeFactory : MeshThreeFactory<GeometrySolid>(GeometrySolid::class) {
|
||||
public object ThreeShapeFactory : ThreeMeshFactory<GeometrySolid>(GeometrySolid::class) {
|
||||
override fun buildGeometry(obj: GeometrySolid): BufferGeometry = ThreeGeometryBuilder().apply {
|
||||
obj.toGeometry(this)
|
||||
}.build()
|
||||
|
@ -15,14 +15,14 @@ import space.kscience.visionforge.set
|
||||
import space.kscience.visionforge.solid.Solid
|
||||
import space.kscience.visionforge.solid.SolidMaterial
|
||||
import space.kscience.visionforge.solid.layer
|
||||
import space.kscience.visionforge.solid.three.MeshThreeFactory.Companion.EDGES_ENABLED_KEY
|
||||
import space.kscience.visionforge.solid.three.MeshThreeFactory.Companion.EDGES_MATERIAL_KEY
|
||||
import space.kscience.visionforge.solid.three.ThreeMeshFactory.Companion.EDGES_ENABLED_KEY
|
||||
import space.kscience.visionforge.solid.three.ThreeMeshFactory.Companion.EDGES_MATERIAL_KEY
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* Basic geometry-based factory
|
||||
*/
|
||||
public abstract class MeshThreeFactory<in T : Solid>(
|
||||
public abstract class ThreeMeshFactory<in T : Solid>(
|
||||
override val type: KClass<in T>,
|
||||
) : ThreeFactory<T> {
|
||||
/**
|
@ -82,7 +82,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer {
|
||||
}.launchIn(context)
|
||||
|
||||
obj.children.changes.onEach { childName ->
|
||||
val child = obj.children[childName]
|
||||
val child = obj.children.getChild(childName)
|
||||
|
||||
//removing old object
|
||||
findChild(childName)?.let { oldChild ->
|
||||
|
@ -53,7 +53,7 @@ public object ThreeReferenceFactory : ThreeFactory<SolidReference> {
|
||||
?: error("Wrong syntax for reference child property: '$name'")
|
||||
val propertyName = name.cutFirst()
|
||||
val referenceChild =
|
||||
obj.children[childName] ?: error("Reference child with name '$childName' not found")
|
||||
obj.children.getChild(childName) ?: error("Reference child with name '$childName' not found")
|
||||
val child = object3D.findChild(childName) ?: error("Object child with name '$childName' not found")
|
||||
child.updateProperty(referenceChild, propertyName)
|
||||
} else {
|
||||
|
@ -5,7 +5,7 @@ import info.laht.threekt.geometries.SphereGeometry
|
||||
import space.kscience.visionforge.solid.Sphere
|
||||
import space.kscience.visionforge.solid.detail
|
||||
|
||||
public object ThreeSphereFactory : MeshThreeFactory<Sphere>(Sphere::class) {
|
||||
public object ThreeSphereFactory : ThreeMeshFactory<Sphere>(Sphere::class) {
|
||||
override fun buildGeometry(obj: Sphere): BufferGeometry {
|
||||
return obj.detail?.let {detail ->
|
||||
SphereGeometry(
|
||||
|
Loading…
Reference in New Issue
Block a user