New properties #34

Merged
altavir merged 19 commits from new-properties into dev 2020-12-29 13:35:01 +03:00
33 changed files with 156 additions and 161 deletions
Showing only changes of commit 25a47a9719 - Show all commits

View File

@ -2,8 +2,8 @@ plugins {
id("ru.mipt.npm.project")
}
val dataforgeVersion by extra("0.2.1-dev-5")
val ktorVersion by extra("1.4.3")
val dataforgeVersion by extra("0.3.0-dev")
val ktorVersion by extra("1.5.0")
val htmlVersion by extra("0.7.2")
val kotlinWrappersVersion by extra("pre.129-kotlin-1.4.20")
val fxVersion by extra("14")

View File

@ -1,7 +1,6 @@
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.readFile
import hep.dataforge.vision.gdml.toVision

View File

@ -39,15 +39,18 @@ fun Page<Solid>.showcase() {
demo("shapes", "Basic shapes") {
box(100.0, 100.0, 100.0) {
z = -110.0
color("teal")
}
sphere(50.0) {
x = 110
detail = 16
color("red")
}
tube(50, height = 10, innerRadius = 25, angle = PI) {
y = 110
detail = 16
rotationX = PI / 4
color("blue")
}
}
@ -55,6 +58,7 @@ fun Page<Solid>.showcase() {
val group = group {
box(100, 100, 100) {
z = 110.0
opacity = 0.5
}
box(100, 100, 100) {
@ -155,7 +159,7 @@ fun Page<Solid>.showcaseCSG() {
detail = 32
}
color(Colors.lightgreen)
opacity = 0.3
opacity = 0.5
}
composite(CompositeType.SUBTRACT) {
y = -300
@ -173,9 +177,11 @@ fun Page<Solid>.showcaseCSG() {
demo("CSG.custom", "CSG with manually created object") {
intersect {
tube(60, 10) {
detail = 64
detail = 32
}
box(100, 100, 100)
color("red")
opacity = 0.5
}
}
}

View File

@ -9,7 +9,6 @@ import hep.dataforge.vision.set
import hep.dataforge.vision.setProperty
import hep.dataforge.vision.solid.*
import hep.dataforge.vision.solid.Solid.Companion.GEOMETRY_KEY
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY
import hep.dataforge.vision.solid.three.*
import info.laht.threekt.core.BufferGeometry
import info.laht.threekt.core.Object3D
@ -30,8 +29,6 @@ internal class VariableBox(xSize: Number, ySize: Number, zSize: Number) : ThreeV
scaleX = xSize
scaleY = ySize
scaleZ = zSize
// getProperty(MeshThreeFactory.EDGES_ENABLED_KEY, inherit = false, includeStyles = false)
// getProperty(MeshThreeFactory.WIREFRAME_ENABLED_KEY, inherit = false, includeStyles = false)
}
override fun render(three: ThreePlugin): Object3D {
@ -69,11 +66,8 @@ internal class VariableBox(xSize: Number, ySize: Number, zSize: Number) : ThreeV
mesh.scale.set(newXSize, newYSize, newZSize)
mesh.updateMatrix()
}
//name.startsWith(MeshThreeFactory.WIREFRAME_KEY) -> mesh.applyWireFrame(this@VariableBox)
name.startsWith(MeshThreeFactory.EDGES_KEY) -> mesh.applyEdges(this@VariableBox)
name.startsWith(MATERIAL_COLOR_KEY) -> {
mesh.updateMaterial(this)
}
//name.startsWith(MATERIAL_COLOR_KEY) -> mesh.updateMaterialProperty(this, name)
else -> mesh.updateProperty(this@VariableBox, name)
}
}

View File

@ -1,7 +1,8 @@
package hep.dataforge.vision.react
import hep.dataforge.meta.Meta
import hep.dataforge.meta.MetaItem
import hep.dataforge.meta.NodeItem
import hep.dataforge.meta.ValueItem
import hep.dataforge.meta.descriptors.ItemDescriptor
import hep.dataforge.meta.descriptors.NodeDescriptor
import hep.dataforge.meta.descriptors.defaultItem
@ -51,7 +52,7 @@ private fun RBuilder.metaViewerItem(props: MetaViewerProps) {
}
when (actualItem) {
is MetaItem.NodeItem -> {
is NodeItem -> {
styledDiv {
css {
+TreeStyles.treeLeaf
@ -108,7 +109,7 @@ private fun RBuilder.metaViewerItem(props: MetaViewerProps) {
}
}
}
is MetaItem.ValueItem -> {
is ValueItem -> {
styledDiv {
css {
+TreeStyles.treeLeaf

View File

@ -9,6 +9,7 @@ import hep.dataforge.names.plus
import hep.dataforge.values.Value
import hep.dataforge.vision.hidden
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
@ -65,12 +66,12 @@ private val PropertyEditorItem: FunctionalComponent<PropertyEditorProps> =
private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) {
var expanded: Boolean by useState { true }
val itemName by useState { props.name ?: Name.EMPTY }
var item: MetaItem<*>? by useState { props.provider.getItem(itemName) }
var item: MetaItem? by useState { props.provider.getItem(itemName) }
val descriptorItem: ItemDescriptor? = props.descriptor?.get(itemName)
if(descriptorItem?.hidden == true) return //fail fast for hidden property
var actualItem: MetaItem<Meta>? by useState {
var actualItem: MetaItem? by useState {
item ?: props.defaultProvider?.getItem(itemName) ?: descriptorItem?.defaultItem()
}
@ -110,7 +111,7 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) {
update()
}
if (actualItem is MetaItem.NodeItem) {
if (actualItem is NodeItem) {
styledDiv {
css {
+TreeStyles.treeLeaf
@ -248,6 +249,7 @@ public fun RBuilder.propertyEditor(
}
}
@OptIn(ExperimentalCoroutinesApi::class)
private fun Config.flowUpdates(): Flow<Name> = callbackFlow {
onChange(this) { name, _, _ ->
launch {

View File

@ -17,7 +17,7 @@ public object TreeStyles : StyleSheet("treeStyles", true) {
/**
* Style the caret/arrow
*/
public val treeCaret by css {
public val treeCaret: RuleSet by css {
cursor = Cursor.pointer
userSelect = UserSelect.none
/* Create the caret/arrow with a unicode, and style it */
@ -32,7 +32,7 @@ public object TreeStyles : StyleSheet("treeStyles", true) {
/**
* Rotate the caret/arrow icon when clicked on (using JavaScript)
*/
val treeCaredDown by css {
public val treeCaredDown:RuleSet by css {
before {
content = "\u25B6".quoted
color = Color.black
@ -42,7 +42,7 @@ public object TreeStyles : StyleSheet("treeStyles", true) {
}
}
val treeItem by css {
public val treeItem:RuleSet by css {
alignItems = Align.center
paddingLeft = 10.px
borderLeftStyle = BorderStyle.dashed
@ -53,27 +53,27 @@ public object TreeStyles : StyleSheet("treeStyles", true) {
borderBottomColor = Color.lightGray
}
val treeLeaf by css {
public val treeLeaf:RuleSet by css {
display = Display.flex
flexDirection = FlexDirection.row
flexWrap = FlexWrap.nowrap
//alignItems = Align.center
}
val treeLabel by css {
public val treeLabel:RuleSet by css {
overflow = Overflow.hidden
flex(flexGrow = 1.0, flexShrink = 1.0)
}
val treeLabelInactive by css {
public val treeLabelInactive: RuleSet by css {
color = Color.lightGray
}
val treeLabelSelected by css {
public val treeLabelSelected:RuleSet by css {
backgroundColor = Color.lightBlue
}
val linkButton by css {
public val linkButton:RuleSet by css {
backgroundColor = Color.white
border = "none"
padding(left = 4.pt, right = 4.pt, top = 0.pt, bottom = 0.pt)
@ -86,7 +86,7 @@ public object TreeStyles : StyleSheet("treeStyles", true) {
}
}
val removeButton by css {
public val removeButton:RuleSet by css {
backgroundColor = Color.white
borderStyle = BorderStyle.solid
borderRadius = 2.px
@ -104,7 +104,7 @@ public object TreeStyles : StyleSheet("treeStyles", true) {
}
}
val resizeableInput by css {
public val resizeableInput: RuleSet by css {
overflow = Overflow.hidden
maxWidth = 120.pt
flex(flexGrow = 2.0, flexShrink = 2.0, flexBasis = 60.pt)

View File

@ -20,7 +20,7 @@ import styled.styledInput
import styled.styledSelect
public external interface ValueChooserProps : RProps {
var item: MetaItem<*>?
var item: MetaItem?
var descriptor: ValueDescriptor?
var valueChanged: ((Value?) -> Unit)?
}
@ -140,7 +140,7 @@ class ValueChooserComponent(props: ValueChooserProps) : RComponent<ValueChooserP
internal fun RBuilder.valueChooser(
name: Name,
item: MetaItem<*>?,
item: MetaItem?,
descriptor: ValueDescriptor? = null,
callback: (Value?) -> Unit
) {

View File

@ -1,8 +1,6 @@
package hep.dataforge.vision
import hep.dataforge.meta.MetaItem
import hep.dataforge.meta.get
import hep.dataforge.meta.number
import hep.dataforge.meta.*
import hep.dataforge.values.ValueType
import hep.dataforge.values.int
import hep.dataforge.values.string
@ -192,9 +190,9 @@ public object Colors {
/**
* Convert color represented as Meta to string of format #rrggbb
*/
fun fromMeta(item: MetaItem<*>): String {
fun fromMeta(item: MetaItem): String {
return when (item) {
is MetaItem.NodeItem<*> -> {
is NodeItem -> {
val node = item.node
rgbToString(
node[RED_KEY].number?.toByte()?.toUByte() ?: 0u,
@ -202,7 +200,7 @@ public object Colors {
node[BLUE_KEY].number?.toByte()?.toUByte() ?: 0u
)
}
is MetaItem.ValueItem -> {
is ValueItem -> {
if (item.value.type == ValueType.NUMBER) {
rgbToString(item.value.int)
} else {

View File

@ -40,7 +40,7 @@ public inline class StyleSheet(private val owner: VisionGroup) {
* Create and set a style
*/
public operator fun set(key: String, builder: MetaBuilder.() -> Unit) {
val newStyle = get(key)?.edit(builder) ?: Meta(builder)
val newStyle = get(key)?.builder()?.apply(builder) ?: Meta(builder)
set(key, newStyle.seal())
}
@ -99,7 +99,7 @@ public tailrec fun Vision.getStyle(name: String): Meta? =
/**
* Resolve an item in all style layers
*/
public fun Vision.getStyleItems(name: Name): Sequence<MetaItem<*>> {
public fun Vision.getStyleItems(name: Name): Sequence<MetaItem> {
return styles.asSequence().map {
getStyle(it)
}.map {

View File

@ -1,5 +1,6 @@
package hep.dataforge.vision
import hep.dataforge.meta.Meta
import hep.dataforge.meta.MetaItem
import hep.dataforge.meta.MutableItemProvider
import hep.dataforge.meta.descriptors.Described
@ -28,6 +29,12 @@ public interface Vision : Described {
@Transient
public var parent: VisionGroup?
/**
* Properties belonging to this [Vision] potentially including artificial properties
*/
@Transient
public val meta: Meta
/**
* A coroutine scope for asynchronous calls and locks
*/
@ -37,7 +44,7 @@ public interface Vision : Described {
* A fast accessor method to get own property (no inheritance or styles).
* Should be equivalent to `getProperty(name,false,false,false)`.
*/
public fun getOwnProperty(name: Name): MetaItem<*>?
public fun getOwnProperty(name: Name): MetaItem?
/**
* Get property.
@ -49,13 +56,13 @@ public interface Vision : Described {
inherit: Boolean = false,
includeStyles: Boolean = true,
includeDefaults: Boolean = true,
): MetaItem<*>?
): MetaItem?
/**
* Set the property value
*/
public fun setProperty(name: Name, item: MetaItem<*>?, notify: Boolean = true)
public fun setProperty(name: Name, item: MetaItem?, notify: Boolean = true)
/**
* Subscribe on property updates. The subscription is bound to the given [scope] and canceled when the scope is canceled
@ -109,8 +116,8 @@ public fun Vision.asyncNotifyPropertyChange(propertyName: Name) {
*/
public val Vision.ownProperties: MutableItemProvider
get() = object : MutableItemProvider {
override fun getItem(name: Name): MetaItem<*>? = getOwnProperty(name)
override fun setItem(name: Name, item: MetaItem<*>?): Unit = setProperty(name, item)
override fun getItem(name: Name): MetaItem? = getOwnProperty(name)
override fun setItem(name: Name, item: MetaItem?): Unit = setProperty(name, item)
}
@ -123,14 +130,14 @@ public fun Vision.allProperties(
includeStyles: Boolean? = null,
includeDefaults: Boolean = true,
): MutableItemProvider = object : MutableItemProvider {
override fun getItem(name: Name): MetaItem<*>? = getProperty(
override fun getItem(name: Name): MetaItem? = getProperty(
name,
inherit = inherit ?: (descriptor?.get(name)?.inherited != false),
includeStyles = includeStyles ?: (descriptor?.get(name)?.usesStyles == true),
includeDefaults = includeDefaults
)
override fun setItem(name: Name, item: MetaItem<*>?): Unit = setProperty(name, item)
override fun setItem(name: Name, item: MetaItem?): Unit = setProperty(name, item)
}
/**
@ -141,7 +148,7 @@ public fun Vision.getProperty(
inherit: Boolean = false,
includeStyles: Boolean = true,
includeDefaults: Boolean = true,
): MetaItem<*>? = getProperty(key.toName(), inherit, includeStyles, includeDefaults)
): MetaItem? = getProperty(key.toName(), inherit, includeStyles, includeDefaults)
/**
* A convenience method to pair [getProperty]

View File

@ -1,9 +1,6 @@
package hep.dataforge.vision
import hep.dataforge.meta.Config
import hep.dataforge.meta.MetaItem
import hep.dataforge.meta.MutableMeta
import hep.dataforge.meta.asMetaItem
import hep.dataforge.meta.*
import hep.dataforge.meta.descriptors.NodeDescriptor
import hep.dataforge.meta.descriptors.defaultItem
import hep.dataforge.meta.descriptors.get
@ -40,14 +37,14 @@ public open class VisionBase : Vision {
/**
* Object own properties excluding styles and inheritance
*/
public var properties: Config? = null
private set
internal var properties: Config? = null
override val meta: Meta get() = properties ?: Meta.EMPTY
@Synchronized
private fun getOrCreateConfig(): Config {
if (properties == null) {
val newProperties = Config()
properties = newProperties
newProperties.onChange(this) { name, oldItem, newItem ->
if (oldItem != newItem) {
scope.launch {
@ -55,6 +52,7 @@ public open class VisionBase : Vision {
}
}
}
properties = newProperties
}
return properties!!
}
@ -62,7 +60,7 @@ public open class VisionBase : Vision {
/**
* A fast accessor method to get own property (no inheritance or styles
*/
override fun getOwnProperty(name: Name): MetaItem<*>? {
override fun getOwnProperty(name: Name): MetaItem? {
return properties?.getItem(name)
}
@ -71,7 +69,7 @@ public open class VisionBase : Vision {
inherit: Boolean,
includeStyles: Boolean,
includeDefaults: Boolean,
): MetaItem<*>? = sequence {
): MetaItem? = sequence {
yield(getOwnProperty(name))
if (includeStyles) {
yieldAll(getStyleItems(name))
@ -83,7 +81,7 @@ public open class VisionBase : Vision {
}.merge()
@Synchronized
override fun setProperty(name: Name, item: MetaItem<*>?, notify: Boolean) {
override fun setProperty(name: Name, item: MetaItem?, notify: Boolean) {
getOrCreateConfig().setItem(name, item)
if (notify) {
scope.launch {
@ -121,23 +119,17 @@ public open class VisionBase : Vision {
propertyInvalidationFlow.emit(propertyName)
}
public fun configure(block: suspend MutableMeta<*>.() -> Unit) {
scope.launch {
getOrCreateConfig().block()
}
}
override fun update(change: VisionChange) {
fun updateProperties(at: Name, item: MetaItem<*>) {
fun updateProperties(at: Name, item: MetaItem) {
when (item) {
is MetaItem.ValueItem -> {
is ValueItem -> {
if (item.value == Null) {
setProperty(at, null)
} else
setProperty(at, item)
}
is MetaItem.NodeItem -> item.node.items.forEach { (token, childItem) ->
is NodeItem -> item.node.items.forEach { (token, childItem) ->
updateProperties(at + token, childItem)
}
}

View File

@ -29,7 +29,7 @@ public class VisionChangeBuilder : VisionContainerBuilder<Vision> {
private fun getOrPutChild(visionName: Name): VisionChangeBuilder =
children.getOrPut(visionName) { VisionChangeBuilder() }
public fun propertyChanged(visionName: Name, propertyName: Name, item: MetaItem<*>?) {
public fun propertyChanged(visionName: Name, propertyName: Name, item: MetaItem?) {
if (visionName == Name.EMPTY) {
//Write property removal as [Null]
propertyChange[propertyName] = (item ?: Null.asMetaItem())

View File

@ -12,7 +12,7 @@ public interface VisionPropertyContainer<out T> {
inherit: Boolean = false,
includeStyles: Boolean = true,
includeDefaults: Boolean = true,
): MetaItem<*>?
): MetaItem?
public fun setProperty(name: Name, item: MetaItem<*>?, notify: Boolean = true)
public fun setProperty(name: Name, item: MetaItem?, notify: Boolean = true)
}

View File

@ -6,20 +6,16 @@ import hep.dataforge.values.asValue
@DslMarker
public annotation class VisionBuilder
public fun Sequence<MetaItem<*>?>.merge(): MetaItem<*>? = when (val first = firstOrNull { it != null }) {
public fun Sequence<MetaItem?>.merge(): MetaItem? = when (val first = firstOrNull { it != null }) {
null -> null
is MetaItem.ValueItem -> first //fast search for first entry if it is value
is MetaItem.NodeItem -> {
is ValueItem -> first //fast search for first entry if it is value
is NodeItem -> {
//merge nodes if first encountered node is meta
val laminate: Laminate = Laminate(mapNotNull { it.node }.toList())
MetaItem.NodeItem(laminate)
NodeItem(laminate)
}
}
@DFExperimental
public val Vision.properties: Config?
get() = (this as? VisionBase)?.properties
/**
* Control visibility of the element
*/
@ -29,4 +25,4 @@ public var Vision.visible: Boolean?
public fun Vision.configure(meta: Meta?): Unit = update(VisionChange(properties = meta))
public fun Vision.configure(block: MutableMeta<*>.() -> Unit): Unit = configure(Meta(block))
public fun Vision.configure(block: MetaBuilder.() -> Unit): Unit = configure(Meta(block))

View File

@ -3,6 +3,7 @@ package hep.dataforge.vision.html
import hep.dataforge.meta.DFExperimental
import hep.dataforge.meta.set
import hep.dataforge.vision.VisionBase
import hep.dataforge.vision.configure
import kotlinx.html.*
import kotlinx.html.stream.createHTML
import kotlin.test.Test
@ -34,7 +35,7 @@ class HtmlTagTest {
div {
h2 { +"Properties" }
ul {
(vision as? VisionBase)?.properties?.items?.forEach {
(vision as? VisionBase)?.meta?.items?.forEach {
li {
a { +it.key.toString() }
p { +it.value.toString() }

View File

@ -134,11 +134,11 @@ public class VisionClient : AbstractPlugin() {
stringData
)
if(change.vision!= null){
if (change.vision != null) {
renderVision(element, change.vision, outputMeta)
}
logger.info { "Got update ${change.toString()} for output with name $name" }
logger.debug { "Got update $change for output with name $name" }
visionMap[element]?.update(change)
?: console.info("Target vision for element $element with name $name not found")
} else {

View File

@ -18,7 +18,7 @@ import tornadofx.*
/**
* A display for meta and descriptor
*/
sealed class FXMeta<M : MetaNode<M>> : Comparable<FXMeta<*>> {
sealed class FXMeta<M : TypedMeta<M>> : Comparable<FXMeta<*>> {
abstract val name: NameToken
abstract val parent: FXMetaNode<M>?
abstract val descriptionProperty: ObservableStringValue
@ -35,7 +35,7 @@ sealed class FXMeta<M : MetaNode<M>> : Comparable<FXMeta<*>> {
}
companion object {
fun <M : MetaNode<M>> root(
fun <M : TypedMeta<M>> root(
node: M,
descriptor: NodeDescriptor? = null,
rootName: String = "root"
@ -47,7 +47,7 @@ sealed class FXMeta<M : MetaNode<M>> : Comparable<FXMeta<*>> {
}
}
class FXMetaNode<M : MetaNode<M>>(
class FXMetaNode<M : TypedMeta<M>>(
override val name: NameToken,
override val parent: FXMetaNode<M>?,
nodeValue: M? = null,
@ -89,7 +89,7 @@ class FXMetaNode<M : MetaNode<M>>(
init {
bind(nodeProperty, descriptorProperty)
val listener: (Name, MetaItem<*>?, MetaItem<*>?) -> Unit = { name, _, _ ->
val listener: (Name, MetaItem?, MetaItem?) -> Unit = { name, _, _ ->
if (name.length == 1) invalidate()
}
@ -115,7 +115,7 @@ class FXMetaNode<M : MetaNode<M>>(
val actualItem = node?.items?.get(token)
val actualDescriptor = descriptor?.items?.get(token.body)
if (actualItem is MetaItem.NodeItem || actualDescriptor is NodeDescriptor) {
if (actualItem is NodeItem || actualDescriptor is NodeDescriptor) {
FXMetaNode(token, this@FXMetaNode)
} else {
FXMetaValue(token, this@FXMetaNode)
@ -134,7 +134,7 @@ class FXMetaNode<M : MetaNode<M>>(
}
}
public class FXMetaValue<M : MetaNode<M>>(
public class FXMetaValue<M : TypedMeta<M>>(
override val name: NameToken,
override val parent: FXMetaNode<M>
) : FXMeta<M>() {
@ -151,10 +151,10 @@ public class FXMetaValue<M : MetaNode<M>>(
//private val innerValueProperty = SimpleObjectProperty(value)
public val valueProperty = descriptorProperty.objectBinding { descriptor ->
parent.node[name].value ?: descriptor?.default
parent.node?.get(name).value ?: descriptor?.default
}
override val hasValue: ObservableBooleanValue = parent.nodeProperty.booleanBinding { it[name] != null }
override val hasValue: ObservableBooleanValue = parent.nodeProperty.booleanBinding { it?.get(name) != null }
public val value by valueProperty
@ -169,12 +169,12 @@ public fun <M : MutableMeta<M>> FXMetaNode<M>.remove(name: NameToken) {
private fun <M : MutableMeta<M>> M.createEmptyNode(token: NameToken, append: Boolean): M {
return if (append && token.hasIndex()) {
val name = token.asName()
val index = (getIndexed(name).keys.mapNotNull { it.toIntOrNull() }.max() ?: -1) + 1
val index = (getIndexed(name).keys.mapNotNull { it?.toIntOrNull() }.maxOrNull() ?: -1) + 1
val newName = name.withIndex(index.toString())
set(newName, Meta.EMPTY)
get(newName).node!!
} else {
this.setNode(token.asName(), Meta.EMPTY)
this.set(token.asName(), Meta.EMPTY)
//FIXME possible concurrency bug
get(token).node!!
}

View File

@ -1,9 +1,6 @@
package hep.dataforge.vision.solid
import hep.dataforge.meta.MetaItem
import hep.dataforge.meta.double
import hep.dataforge.meta.get
import hep.dataforge.meta.int
import hep.dataforge.meta.*
import hep.dataforge.values.ValueType
import hep.dataforge.values.int
import hep.dataforge.values.string
@ -35,9 +32,9 @@ public object FXMaterials {
* Infer color based on meta item
* @param opacity default opacity
*/
public fun MetaItem<*>.color(opacity: Double = 1.0): Color {
public fun MetaItem.color(opacity: Double = 1.0): Color {
return when (this) {
is MetaItem.ValueItem -> if (this.value.type == ValueType.NUMBER) {
is ValueItem -> if (this.value.type == ValueType.NUMBER) {
val int = value.int
val red = int and 0x00ff0000 shr 16
val green = int and 0x0000ff00 shr 8
@ -46,7 +43,7 @@ public fun MetaItem<*>.color(opacity: Double = 1.0): Color {
} else {
Color.web(this.value.string)
}
is MetaItem.NodeItem -> {
is NodeItem -> {
Color.rgb(
node[Colors.RED_KEY]?.int ?: 0,
node[Colors.GREEN_KEY]?.int ?: 0,
@ -60,11 +57,11 @@ public fun MetaItem<*>.color(opacity: Double = 1.0): Color {
/**
* Infer FX material based on meta item
*/
public fun MetaItem<*>?.material(): Material {
public fun MetaItem?.material(): Material {
return when (this) {
null -> FXMaterials.GREY
is MetaItem.ValueItem -> PhongMaterial(color())
is MetaItem.NodeItem -> PhongMaterial().apply {
is ValueItem -> PhongMaterial(color())
is NodeItem -> PhongMaterial().apply {
val opacity = node[SolidMaterial.OPACITY_KEY].double ?: 1.0
diffuseColor = node[SolidMaterial.COLOR_KEY]?.color(opacity) ?: Color.DARKGREY
specularColor = node[SolidMaterial.SPECULAR_COLOR_KEY]?.color(opacity) ?: Color.WHITE

View File

@ -13,7 +13,7 @@ import tornadofx.*
* A caching binding collection for [Vision] properties
*/
class VisualObjectFXBinding(val fx: FX3DPlugin, val obj: Vision) {
private val bindings = HashMap<Name, ObjectBinding<MetaItem<*>?>>()
private val bindings = HashMap<Name, ObjectBinding<MetaItem?>>()
init {
obj.onPropertyChange(fx.context) { name ->
@ -31,10 +31,10 @@ class VisualObjectFXBinding(val fx: FX3DPlugin, val obj: Vision) {
}
}
operator fun get(key: Name): ObjectBinding<MetaItem<*>?> {
operator fun get(key: Name): ObjectBinding<MetaItem?> {
return bindings.getOrPut(key) {
object : ObjectBinding<MetaItem<*>?>() {
override fun computeValue(): MetaItem<*>? = obj.getProperty(key)
object : ObjectBinding<MetaItem?>() {
override fun computeValue(): MetaItem? = obj.getProperty(key)
}
}
}
@ -42,19 +42,19 @@ class VisualObjectFXBinding(val fx: FX3DPlugin, val obj: Vision) {
operator fun get(key: String) = get(key.toName())
}
fun ObjectBinding<MetaItem<*>?>.value() = objectBinding { it.value }
fun ObjectBinding<MetaItem<*>?>.string() = stringBinding { it.string }
fun ObjectBinding<MetaItem<*>?>.number() = objectBinding { it.number }
fun ObjectBinding<MetaItem<*>?>.double() = objectBinding { it.double }
fun ObjectBinding<MetaItem<*>?>.float() = objectBinding { it.float }
fun ObjectBinding<MetaItem<*>?>.int() = objectBinding { it.int }
fun ObjectBinding<MetaItem<*>?>.long() = objectBinding { it.long }
fun ObjectBinding<MetaItem<*>?>.node() = objectBinding { it.node }
fun ObjectBinding<MetaItem?>.value() = objectBinding { it.value }
fun ObjectBinding<MetaItem?>.string() = stringBinding { it.string }
fun ObjectBinding<MetaItem?>.number() = objectBinding { it.number }
fun ObjectBinding<MetaItem?>.double() = objectBinding { it.double }
fun ObjectBinding<MetaItem?>.float() = objectBinding { it.float }
fun ObjectBinding<MetaItem?>.int() = objectBinding { it.int }
fun ObjectBinding<MetaItem?>.long() = objectBinding { it.long }
fun ObjectBinding<MetaItem?>.node() = objectBinding { it.node }
fun ObjectBinding<MetaItem<*>?>.string(default: String) = stringBinding { it.string ?: default }
fun ObjectBinding<MetaItem<*>?>.double(default: Double) = doubleBinding { it.double ?: default }
fun ObjectBinding<MetaItem<*>?>.float(default: Float) = floatBinding { it.float ?: default }
fun ObjectBinding<MetaItem<*>?>.int(default: Int) = integerBinding { it.int ?: default }
fun ObjectBinding<MetaItem<*>?>.long(default: Long) = longBinding { it.long ?: default }
fun ObjectBinding<MetaItem?>.string(default: String) = stringBinding { it.string ?: default }
fun ObjectBinding<MetaItem?>.double(default: Double) = doubleBinding { it.double ?: default }
fun ObjectBinding<MetaItem?>.float(default: Float) = floatBinding { it.float ?: default }
fun ObjectBinding<MetaItem?>.int(default: Int) = integerBinding { it.int ?: default }
fun ObjectBinding<MetaItem?>.long(default: Long) = longBinding { it.long ?: default }
fun <T> ObjectBinding<MetaItem<*>?>.transform(transform: (MetaItem<*>) -> T) = objectBinding { it?.let(transform) }
fun <T> ObjectBinding<MetaItem?>.transform(transform: (MetaItem) -> T) = objectBinding { it?.let(transform) }

View File

@ -1,9 +1,8 @@
package hep.dataforge.vision.gdml
import hep.dataforge.meta.DFExperimental
import hep.dataforge.meta.sequence
import hep.dataforge.meta.itemSequence
import hep.dataforge.vision.Vision
import hep.dataforge.vision.properties
import hep.dataforge.vision.solid.*
public expect class Counter() {
@ -27,7 +26,7 @@ internal fun Vision.updateFrom(other: Vision): Vision {
scaleY = scaleY.toDouble() * other.scaleY.toDouble()
scaleZ = scaleZ.toDouble() * other.scaleZ.toDouble()
}
other.properties?.sequence()?.forEach { (name, item) ->
other.meta.itemSequence().forEach { (name, item) ->
if (getProperty(name) == null) {
setProperty(name, item)
}

View File

@ -1,6 +1,5 @@
package hep.dataforge.vision.solid
import hep.dataforge.meta.Meta
import hep.dataforge.meta.update
import hep.dataforge.names.NameToken
import hep.dataforge.vision.*
@ -39,18 +38,20 @@ public inline fun VisionContainerBuilder<Solid>.composite(
val group = SolidGroup().apply(builder)
val children = group.children.values.filterIsInstance<Solid>()
if (children.size != 2) error("Composite requires exactly two children")
return Composite(type, children[0], children[1]).also {
it.configure { update(group.properties ?: Meta.EMPTY) }
return Composite(type, children[0], children[1]).also { composite ->
composite.configure {
update(group.meta)
}
if (group.position != null) {
it.position = group.position
composite.position = group.position
}
if (group.rotation != null) {
it.rotation = group.rotation
composite.rotation = group.rotation
}
if (group.scale != null) {
it.scale = group.scale
composite.scale = group.scale
}
set(name, it)
set(name, composite)
}
}

View File

@ -85,7 +85,7 @@ public interface Solid : Vision {
if (first.position != second.position) return false
if (first.rotation != second.rotation) return false
if (first.scale != second.scale) return false
if (first.properties != second.properties) return false
if (first.meta != second.meta) return false
return true
}

View File

@ -106,16 +106,16 @@ internal class Prototypes(
}
}
override fun getOwnProperty(name: Name): MetaItem<*>? = null
override fun getOwnProperty(name: Name): MetaItem? = null
override fun getProperty(
name: Name,
inherit: Boolean,
includeStyles: Boolean,
includeDefaults: Boolean,
): MetaItem<*>? = null
): MetaItem? = null
override fun setProperty(name: Name, item: MetaItem<*>?, notify: Boolean) {
override fun setProperty(name: Name, item: MetaItem?, notify: Boolean) {
error("Can't ser property of prototypes container")
}

View File

@ -19,12 +19,12 @@ public class SolidMaterial : Scheme() {
/**
* Primary web-color for the material
*/
public var color: ColorAccessor = ColorAccessor(config, COLOR_KEY)
public var color: ColorAccessor = ColorAccessor(items, COLOR_KEY)
/**
* Specular color for phong material
*/
public var specularColor: ColorAccessor = ColorAccessor(config, SPECULAR_COLOR_KEY)
public var specularColor: ColorAccessor = ColorAccessor(items, SPECULAR_COLOR_KEY)
/**
* Opacity
@ -100,16 +100,17 @@ public val Solid.color: ColorAccessor
public var Solid.material: SolidMaterial?
get() = getProperty(MATERIAL_KEY, inherit = true).node?.let { SolidMaterial.read(it) }
set(value) = setProperty(MATERIAL_KEY, value?.config)
set(value) = setProperty(MATERIAL_KEY, value?.rootNode)
@VisionBuilder
public fun Solid.material(builder: SolidMaterial.() -> Unit) {
val node = allProperties(inherit = true).getItem(MATERIAL_KEY).node
if (node != null) {
SolidMaterial.update(node, builder)
} else {
setProperty(MATERIAL_KEY, SolidMaterial(builder))
}
setProperty(MATERIAL_KEY, SolidMaterial(builder))
// val node = getOwnProperty(MATERIAL_KEY).node
// if (node != null) {
// configure(SolidMaterial(builder).config)
// } else {
// setProperty(MATERIAL_KEY, SolidMaterial(builder))
// }
}
public var Solid.opacity: Number?

View File

@ -17,7 +17,7 @@ private fun SolidReference.getRefProperty(
inherit: Boolean,
includeStyles: Boolean,
includeDefaults: Boolean,
): MetaItem<*>? {
): MetaItem? {
return sequence {
yield(getOwnProperty(name))
if (includeStyles) {
@ -59,11 +59,11 @@ public class SolidReferenceGroup(
private fun childPropertyName(childName: Name, propertyName: Name): Name =
childToken(childName) + propertyName
private fun getChildProperty(childName: Name, propertyName: Name): MetaItem<*>? {
private fun getChildProperty(childName: Name, propertyName: Name): MetaItem? {
return getOwnProperty(childPropertyName(childName, propertyName))
}
private fun setChildProperty(childName: Name, propertyName: Name, item: MetaItem<*>?, notify: Boolean) {
private fun setChildProperty(childName: Name, propertyName: Name, item: MetaItem?, notify: Boolean) {
setProperty(childPropertyName(childName, propertyName), item, notify)
}
@ -79,7 +79,7 @@ public class SolidReferenceGroup(
inherit: Boolean,
includeStyles: Boolean,
includeDefaults: Boolean,
): MetaItem<*>? = getRefProperty(name, inherit, includeStyles, includeDefaults)
): MetaItem? = getRefProperty(name, inherit, includeStyles, includeDefaults)
override val descriptor: NodeDescriptor get() = prototype.descriptor
@ -99,9 +99,11 @@ public class SolidReferenceGroup(
ReferenceChild(childName + key.asName())
} ?: emptyMap()
override fun getOwnProperty(name: Name): MetaItem<*>? = getChildProperty(childName, name)
override val meta: Meta get() =TODO()// getChildProperty(childName, Name.EMPTY).node ?: Meta.EMPTY
override fun setProperty(name: Name, item: MetaItem<*>?, notify: Boolean) {
override fun getOwnProperty(name: Name): MetaItem? = getChildProperty(childName, name)
override fun setProperty(name: Name, item: MetaItem?, notify: Boolean) {
setChildProperty(childName, name, item, notify)
}
@ -110,7 +112,7 @@ public class SolidReferenceGroup(
inherit: Boolean,
includeStyles: Boolean,
includeDefaults: Boolean,
): MetaItem<*>? = getRefProperty(name, inherit, includeStyles, includeDefaults)
): MetaItem? = getRefProperty(name, inherit, includeStyles, includeDefaults)
override var parent: VisionGroup?
get() {

View File

@ -3,7 +3,7 @@ package hep.dataforge.vision.solid.specifications
import hep.dataforge.meta.*
public class Axes : Scheme() {
public var visible: Boolean by boolean(!config.isEmpty())
public var visible: Boolean by boolean(rootNode?.isEmpty() != false)
public var size: Double by double(AXIS_SIZE)
public var width: Double by double(AXIS_WIDTH)

View File

@ -9,7 +9,7 @@ import hep.dataforge.vision.solid.*
internal fun mergeChild(parent: VisionGroup, child: Vision): Vision {
return child.apply {
configure(parent.properties)
configure(parent.meta)
//parent.properties?.let { config.update(it) }

View File

@ -28,7 +28,7 @@ class ConvexTest {
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() }
val points = meta.getIndexed("points").values.map { (it as NodeItem<*>).node.point3D() }
assertEquals(8, points.count())
assertEquals(8, convex.points.size)

View File

@ -4,7 +4,6 @@ import hep.dataforge.names.Name
import hep.dataforge.names.toName
import hep.dataforge.vision.MutableVisionGroup
import hep.dataforge.vision.get
import hep.dataforge.vision.properties
import kotlin.test.Test
import kotlin.test.assertEquals
@ -33,7 +32,7 @@ class SerializationTest {
val string = SolidManager.encodeToString(cube)
println(string)
val newCube = SolidManager.decodeFromString(string)
assertEquals(cube.properties, newCube.properties)
assertEquals(cube.meta, newCube.meta)
}
@Test
@ -54,7 +53,7 @@ class SerializationTest {
val string = SolidManager.encodeToString(group)
println(string)
val reconstructed = SolidManager.decodeFromString(string) as SolidGroup
assertEquals(group["cube"]?.properties, reconstructed["cube"]?.properties)
assertEquals(group["cube"]?.meta, reconstructed["cube"]?.meta)
}
}

View File

@ -1,6 +1,6 @@
package hep.dataforge.vision.solid.three
import hep.dataforge.meta.getItem
import hep.dataforge.meta.get
import hep.dataforge.meta.string
import hep.dataforge.names.Name
import hep.dataforge.names.plus
@ -177,7 +177,7 @@ public class ThreeCanvas(
}
private fun addControls(element: Node, controls: Controls) {
when (controls.getItem("type").string) {
when (controls.get("type").string) {
"trackball" -> TrackballControls(camera, element)
else -> OrbitControls(camera, element)
}

View File

@ -109,15 +109,15 @@ public object ThreeMaterials {
/**
* Infer color based on meta item
*/
public fun MetaItem<*>.getColor(): Color {
public fun MetaItem.getColor(): Color {
return when (this) {
is MetaItem.ValueItem -> if (this.value.type == ValueType.NUMBER) {
is ValueItem -> if (this.value.type == ValueType.NUMBER) {
val int = value.int
Color(int)
} else {
Color(this.value.string)
}
is MetaItem.NodeItem -> {
is NodeItem -> {
Color(
node[Colors.RED_KEY]?.int ?: 0,
node[Colors.GREEN_KEY]?.int ?: 0,
@ -160,7 +160,7 @@ public fun Mesh.updateMaterial(vision: Vision) {
}
public fun Mesh.updateMaterialProperty(vision: Vision, propertyName: Name) {
if (material.cached) {
if (material.cached || propertyName == SolidMaterial.MATERIAL_KEY) {
//generate a new material since cached material should not be changed
updateMaterial(vision)
} else {

View File

@ -17,7 +17,7 @@ import kotlin.math.PI
public val Solid.euler: Euler get() = Euler(rotationX, rotationY, rotationZ, rotationOrder.name)
public val MetaItem<*>.vector: Vector3 get() = Vector3(node["x"].float ?: 0f, node["y"].float ?: 0f, node["z"].float ?: 0f)
public val MetaItem.vector: Vector3 get() = Vector3(node["x"].float ?: 0f, node["y"].float ?: 0f, node["z"].float ?: 0f)
public fun Geometry.toBufferGeometry(): BufferGeometry = BufferGeometry().apply { fromGeometry(this@toBufferGeometry) }