Visuliazation package. Multiple fixes to mutable and styled meta.
This commit is contained in:
parent
48c45fa51c
commit
54b30e9260
2
.gitignore
vendored
2
.gitignore
vendored
@ -7,5 +7,3 @@
|
|||||||
|
|
||||||
|
|
||||||
!gradle-wrapper.jar
|
!gradle-wrapper.jar
|
||||||
|
|
||||||
artifactory.gradle
|
|
@ -1,19 +1,25 @@
|
|||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
val kotlinVersion: String by rootProject.extra("1.3.20")
|
val kotlinVersion: String by rootProject.extra("1.3.21")
|
||||||
val ioVersion: String by rootProject.extra("0.1.4")
|
val ioVersion: String by rootProject.extra("0.1.5")
|
||||||
val coroutinesVersion: String by rootProject.extra("1.1.1")
|
val coroutinesVersion: String by rootProject.extra("1.1.1")
|
||||||
val serializationVersion: String by rootProject.extra("0.9.1")
|
val atomicfuVersion: String by rootProject.extra("0.12.1")
|
||||||
|
val dokkaVersion: String by rootProject.extra("0.9.17")
|
||||||
|
val serializationVersion: String by rootProject.extra("0.10.0")
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
jcenter()
|
||||||
|
maven("https://dl.bintray.com/kotlin/kotlin-eap")
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
|
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
|
||||||
classpath("org.jetbrains.kotlin:kotlin-serialization:$kotlinVersion")
|
|
||||||
classpath("org.jfrog.buildinfo:build-info-extractor-gradle:4+")
|
classpath("org.jfrog.buildinfo:build-info-extractor-gradle:4+")
|
||||||
|
classpath("com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4")
|
||||||
|
classpath("org.jetbrains.dokka:dokka-gradle-plugin:$dokkaVersion")
|
||||||
|
classpath("org.jetbrains.kotlin:kotlin-frontend-plugin:0.0.45")
|
||||||
|
classpath("org.openjfx:javafx-plugin:0.0.7")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,6 +29,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
|
apply(plugin = "maven")
|
||||||
apply(plugin = "maven-publish")
|
apply(plugin = "maven-publish")
|
||||||
apply(plugin = "com.jfrog.artifactory")
|
apply(plugin = "com.jfrog.artifactory")
|
||||||
|
|
||||||
@ -32,8 +39,17 @@ allprojects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "hep.dataforge"
|
group = "hep.dataforge"
|
||||||
version = "0.1.1-dev-3"
|
version = "0.1.1-dev-4"
|
||||||
|
|
||||||
|
// apply bintray configuration
|
||||||
|
apply(from = "${rootProject.rootDir}/gradle/bintray.gradle")
|
||||||
|
|
||||||
|
//apply artifactory configuration
|
||||||
|
apply(from = "${rootProject.rootDir}/gradle/artifactory.gradle")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
subprojects {
|
||||||
extensions.findByType<KotlinMultiplatformExtension>()?.apply {
|
extensions.findByType<KotlinMultiplatformExtension>()?.apply {
|
||||||
jvm {
|
jvm {
|
||||||
compilations.all {
|
compilations.all {
|
||||||
@ -48,8 +64,61 @@ allprojects {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dokka {
|
||||||
|
// outputFormat = "html"
|
||||||
|
// outputDirectory = javadoc.destinationDir
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// task dokkaJar (type: Jar, dependsOn: dokka) {
|
||||||
|
// from javadoc . destinationDir
|
||||||
|
// classifier = "javadoc"
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
if (!name.startsWith("dataforge")) return@subprojects
|
||||||
|
|
||||||
|
extensions.findByType<PublishingExtension>()?.apply {
|
||||||
|
publications.filterIsInstance<MavenPublication>().forEach { publication ->
|
||||||
|
if (publication.name == "kotlinMultiplatform") {
|
||||||
|
// for our root metadata publication, set artifactId with a package and project name
|
||||||
|
publication.artifactId = project.name
|
||||||
|
} else {
|
||||||
|
// for targets, set artifactId with a package, project name and target name (e.g. iosX64)
|
||||||
|
publication.artifactId = "${project.name}-${publication.name}"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file("artifactory.gradle").exists()) {
|
// Create empty jar for sources classifier to satisfy maven requirements
|
||||||
apply(from = "artifactory.gradle")
|
val stubSources by tasks.registering(Jar::class) {
|
||||||
|
archiveClassifier.set("sources")
|
||||||
|
//from(sourceSets.main.get().allSource)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create empty jar for javadoc classifier to satisfy maven requirements
|
||||||
|
val stubJavadoc by tasks.registering(Jar::class) {
|
||||||
|
archiveClassifier.set("javadoc")
|
||||||
|
}
|
||||||
|
|
||||||
|
extensions.findByType<KotlinMultiplatformExtension>()?.apply {
|
||||||
|
|
||||||
|
targets.forEach { target ->
|
||||||
|
val publication = publications.findByName(target.name) as MavenPublication
|
||||||
|
|
||||||
|
// Patch publications with fake javadoc
|
||||||
|
publication.artifact(stubJavadoc)
|
||||||
|
|
||||||
|
// Remove gradle metadata publishing from all targets which are not native
|
||||||
|
// if (target.platformType.name != "native") {
|
||||||
|
// publication.gradleModuleMetadataFile = null
|
||||||
|
// tasks.matching { it.name == "generateMetadataFileFor${name.capitalize()}Publication" }.all {
|
||||||
|
// onlyIf { false }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,10 +2,6 @@ plugins {
|
|||||||
kotlin("multiplatform")
|
kotlin("multiplatform")
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
|
||||||
jcenter()
|
|
||||||
}
|
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
jvm()
|
jvm()
|
||||||
js()
|
js()
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
package hep.dataforge.meta.io
|
||||||
|
|
||||||
|
import kotlinx.io.ByteBuffer
|
||||||
|
import kotlinx.io.core.Input
|
||||||
|
|
||||||
|
//TODO replace by abstraction
|
||||||
|
typealias Binary = Input
|
@ -0,0 +1,50 @@
|
|||||||
|
package hep.dataforge.meta.io
|
||||||
|
|
||||||
|
import hep.dataforge.meta.Meta
|
||||||
|
import hep.dataforge.meta.get
|
||||||
|
import hep.dataforge.meta.string
|
||||||
|
|
||||||
|
interface Envelope {
|
||||||
|
val meta: Meta
|
||||||
|
val data: Binary?
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
// /**
|
||||||
|
// * Property keys
|
||||||
|
// */
|
||||||
|
// const val TYPE_PROPERTY = "type"
|
||||||
|
// const val META_TYPE_PROPERTY = "metaType"
|
||||||
|
// const val META_LENGTH_PROPERTY = "metaLength"
|
||||||
|
// const val DATA_LENGTH_PROPERTY = "dataLength"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* meta keys
|
||||||
|
*/
|
||||||
|
const val ENVELOPE_NODE = "@envelope"
|
||||||
|
const val ENVELOPE_TYPE_KEY = "$ENVELOPE_NODE.type"
|
||||||
|
const val ENVELOPE_DATA_TYPE_KEY = "$ENVELOPE_NODE.dataType"
|
||||||
|
const val ENVELOPE_DESCRIPTION_KEY = "$ENVELOPE_NODE.description"
|
||||||
|
//const val ENVELOPE_TIME_KEY = "@envelope.time"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The purpose of the envelope
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
val Envelope.type: String? get() = meta[Envelope.ENVELOPE_TYPE_KEY].string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of data encoding
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
val Envelope.dataType: String? get() = meta[Envelope.ENVELOPE_DATA_TYPE_KEY].string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Textual user friendly description
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
val Envelope.description: String? get() = meta[Envelope.ENVELOPE_DESCRIPTION_KEY].string
|
@ -1,6 +1,7 @@
|
|||||||
package hep.dataforge.meta
|
package hep.dataforge.meta
|
||||||
|
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
|
import hep.dataforge.names.NameToken
|
||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
|
|
||||||
//TODO add validator to configuration
|
//TODO add validator to configuration
|
||||||
@ -16,7 +17,13 @@ open class Config : MutableMetaNode<Config>() {
|
|||||||
override fun wrap(name: Name, meta: Meta): Config = meta.toConfig()
|
override fun wrap(name: Name, meta: Meta): Config = meta.toConfig()
|
||||||
|
|
||||||
override fun empty(): Config = Config()
|
override fun empty(): Config = Config()
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun empty(): Config = Config()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun Config.get(token: NameToken): MetaItem<Config>? = items[token]
|
||||||
|
|
||||||
fun Meta.toConfig(): Config = this as? Config ?: Config().also { builder ->
|
fun Meta.toConfig(): Config = this as? Config ?: Config().also { builder ->
|
||||||
this.items.mapValues { entry ->
|
this.items.mapValues { entry ->
|
||||||
|
@ -2,6 +2,7 @@ package hep.dataforge.meta
|
|||||||
|
|
||||||
import hep.dataforge.values.Null
|
import hep.dataforge.values.Null
|
||||||
import hep.dataforge.values.Value
|
import hep.dataforge.values.Value
|
||||||
|
import hep.dataforge.values.asValue
|
||||||
import kotlin.jvm.JvmName
|
import kotlin.jvm.JvmName
|
||||||
import kotlin.properties.ReadOnlyProperty
|
import kotlin.properties.ReadOnlyProperty
|
||||||
import kotlin.properties.ReadWriteProperty
|
import kotlin.properties.ReadWriteProperty
|
||||||
@ -11,247 +12,348 @@ import kotlin.reflect.KProperty
|
|||||||
|
|
||||||
//TODO add caching for sealed nodes
|
//TODO add caching for sealed nodes
|
||||||
|
|
||||||
class ValueDelegate(private val key: String? = null, private val default: Value? = null) :
|
class ValueDelegate(val meta: Meta, private val key: String? = null, private val default: Value? = null) :
|
||||||
ReadOnlyProperty<Metoid, Value?> {
|
ReadOnlyProperty<Any?, Value?> {
|
||||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): Value? {
|
override fun getValue(thisRef: Any?, property: KProperty<*>): Value? {
|
||||||
return thisRef.meta[key ?: property.name]?.value ?: default
|
return meta[key ?: property.name]?.value ?: default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class StringDelegate(private val key: String? = null, private val default: String? = null) :
|
class StringDelegate(val meta: Meta, private val key: String? = null, private val default: String? = null) :
|
||||||
ReadOnlyProperty<Metoid, String?> {
|
ReadOnlyProperty<Any?, String?> {
|
||||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): String? {
|
override fun getValue(thisRef: Any?, property: KProperty<*>): String? {
|
||||||
return thisRef.meta[key ?: property.name]?.string ?: default
|
return meta[key ?: property.name]?.string ?: default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BooleanDelegate(private val key: String? = null, private val default: Boolean? = null) :
|
class BooleanDelegate(val meta: Meta, private val key: String? = null, private val default: Boolean? = null) :
|
||||||
ReadOnlyProperty<Metoid, Boolean?> {
|
ReadOnlyProperty<Metoid, Boolean?> {
|
||||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): Boolean? {
|
override fun getValue(thisRef: Metoid, property: KProperty<*>): Boolean? {
|
||||||
return thisRef.meta[key ?: property.name]?.boolean ?: default
|
return meta[key ?: property.name]?.boolean ?: default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NumberDelegate(private val key: String? = null, private val default: Number? = null) :
|
class NumberDelegate(val meta: Meta, private val key: String? = null, private val default: Number? = null) :
|
||||||
ReadOnlyProperty<Metoid, Number?> {
|
ReadOnlyProperty<Any?, Number?> {
|
||||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): Number? {
|
override fun getValue(thisRef: Any?, property: KProperty<*>): Number? {
|
||||||
return thisRef.meta[key ?: property.name]?.number ?: default
|
return meta[key ?: property.name]?.number ?: default
|
||||||
|
}
|
||||||
|
|
||||||
|
//delegates for number transformation
|
||||||
|
|
||||||
|
val double get() = DelegateWrapper(this) { it?.toDouble() }
|
||||||
|
val int get() = DelegateWrapper(this) { it?.toInt() }
|
||||||
|
val short get() = DelegateWrapper(this) { it?.toShort() }
|
||||||
|
val long get() = DelegateWrapper(this) { it?.toLong() }
|
||||||
|
}
|
||||||
|
|
||||||
|
class DelegateWrapper<T, R>(val delegate: ReadOnlyProperty<Any?, T>, val reader: (T) -> R) :
|
||||||
|
ReadOnlyProperty<Any?, R> {
|
||||||
|
override fun getValue(thisRef: Any?, property: KProperty<*>): R {
|
||||||
|
return reader(delegate.getValue(thisRef, property))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Delegates with non-null values
|
//Delegates with non-null values
|
||||||
|
|
||||||
class SafeStringDelegate(private val key: String? = null, private val default: String) :
|
class SafeStringDelegate(val meta: Meta, private val key: String? = null, private val default: String) :
|
||||||
ReadOnlyProperty<Metoid, String> {
|
ReadOnlyProperty<Any?, String> {
|
||||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): String {
|
override fun getValue(thisRef: Any?, property: KProperty<*>): String {
|
||||||
return thisRef.meta[key ?: property.name]?.string ?: default
|
return meta[key ?: property.name]?.string ?: default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SafeBooleanDelegate(private val key: String? = null, private val default: Boolean) :
|
class SafeBooleanDelegate(val meta: Meta, private val key: String? = null, private val default: Boolean) :
|
||||||
ReadOnlyProperty<Metoid, Boolean> {
|
ReadOnlyProperty<Any?, Boolean> {
|
||||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): Boolean {
|
override fun getValue(thisRef: Any?, property: KProperty<*>): Boolean {
|
||||||
return thisRef.meta[key ?: property.name]?.boolean ?: default
|
return meta[key ?: property.name]?.boolean ?: default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SafeNumberDelegate(private val key: String? = null, private val default: Number) :
|
class SafeNumberDelegate(val meta: Meta, private val key: String? = null, private val default: Number) :
|
||||||
ReadOnlyProperty<Metoid, Number> {
|
ReadOnlyProperty<Any?, Number> {
|
||||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): Number {
|
override fun getValue(thisRef: Any?, property: KProperty<*>): Number {
|
||||||
return thisRef.meta[key ?: property.name]?.number ?: default
|
return meta[key ?: property.name]?.number ?: default
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val double get() = DelegateWrapper(this) { it.toDouble() }
|
||||||
|
val int get() = DelegateWrapper(this) { it.toInt() }
|
||||||
|
val short get() = DelegateWrapper(this) { it.toShort() }
|
||||||
|
val long get() = DelegateWrapper(this) { it.toLong() }
|
||||||
}
|
}
|
||||||
|
|
||||||
class SafeEnumDelegate<E : Enum<E>>(
|
class SafeEnumDelegate<E : Enum<E>>(
|
||||||
|
val meta: Meta,
|
||||||
private val key: String? = null,
|
private val key: String? = null,
|
||||||
private val default: E,
|
private val default: E,
|
||||||
private val resolver: (String) -> E
|
private val resolver: (String) -> E
|
||||||
) : ReadOnlyProperty<Metoid, E> {
|
) : ReadOnlyProperty<Any?, E> {
|
||||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): E {
|
override fun getValue(thisRef: Any?, property: KProperty<*>): E {
|
||||||
return (thisRef.meta[key ?: property.name]?.string)?.let { resolver(it) } ?: default
|
return (meta[key ?: property.name]?.string)?.let { resolver(it) } ?: default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Child node delegate
|
//Child node delegate
|
||||||
|
|
||||||
class ChildDelegate<T>(private val key: String? = null, private val converter: (Meta) -> T) :
|
class ChildDelegate<T>(val meta: Meta, private val key: String? = null, private val converter: (Meta) -> T) :
|
||||||
ReadOnlyProperty<Metoid, T?> {
|
ReadOnlyProperty<Any?, T?> {
|
||||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): T? {
|
override fun getValue(thisRef: Any?, property: KProperty<*>): T? {
|
||||||
return thisRef.meta[key ?: property.name]?.node?.let { converter(it) }
|
return meta[key ?: property.name]?.node?.let { converter(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Read-only delegates
|
//Read-only delegates for Metas
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A property delegate that uses custom key
|
* A property delegate that uses custom key
|
||||||
*/
|
*/
|
||||||
fun Metoid.value(default: Value = Null, key: String? = null) = ValueDelegate(key, default)
|
fun Meta.value(default: Value = Null, key: String? = null) = ValueDelegate(this, key, default)
|
||||||
|
|
||||||
fun Metoid.string(default: String? = null, key: String? = null) = StringDelegate(key, default)
|
fun Meta.string(default: String? = null, key: String? = null) = StringDelegate(this, key, default)
|
||||||
|
|
||||||
fun Metoid.boolean(default: Boolean? = null, key: String? = null) = BooleanDelegate(key, default)
|
fun Meta.boolean(default: Boolean? = null, key: String? = null) = BooleanDelegate(this, key, default)
|
||||||
|
|
||||||
fun Metoid.number(default: Number? = null, key: String? = null) = NumberDelegate(key, default)
|
fun Meta.number(default: Number? = null, key: String? = null) = NumberDelegate(this, key, default)
|
||||||
|
|
||||||
fun Metoid.child(key: String? = null) = ChildDelegate(key) { it }
|
fun Meta.child(key: String? = null) = ChildDelegate(this, key) { it }
|
||||||
|
|
||||||
fun <T : Metoid> Metoid.child(key: String? = null, converter: (Meta) -> T) = ChildDelegate(key, converter)
|
|
||||||
|
|
||||||
@JvmName("safeString")
|
@JvmName("safeString")
|
||||||
fun Metoid.string(default: String, key: String? = null) = SafeStringDelegate(key, default)
|
fun Meta.string(default: String, key: String? = null) = SafeStringDelegate(this, key, default)
|
||||||
|
|
||||||
@JvmName("safeBoolean")
|
@JvmName("safeBoolean")
|
||||||
fun Metoid.boolean(default: Boolean, key: String? = null) = SafeBooleanDelegate(key, default)
|
fun Meta.boolean(default: Boolean, key: String? = null) = SafeBooleanDelegate(this, key, default)
|
||||||
|
|
||||||
@JvmName("safeNumber")
|
@JvmName("safeNumber")
|
||||||
fun Metoid.number(default: Number, key: String? = null) = SafeNumberDelegate(key, default)
|
fun Meta.number(default: Number, key: String? = null) = SafeNumberDelegate(this, key, default)
|
||||||
|
|
||||||
|
inline fun <reified E : Enum<E>> Meta.enum(default: E, key: String? = null) =
|
||||||
|
SafeEnumDelegate(this, key, default) { enumValueOf(it) }
|
||||||
|
|
||||||
inline fun <reified E : Enum<E>> Metoid.enum(default: E, key: String? = null) =
|
|
||||||
SafeEnumDelegate(key, default) { enumValueOf(it) }
|
|
||||||
|
|
||||||
/* Config delegates */
|
/* Config delegates */
|
||||||
|
|
||||||
class ValueConfigDelegate(private val key: String? = null, private val default: Value? = null) :
|
class ValueConfigDelegate<M : MutableMeta<M>>(
|
||||||
ReadWriteProperty<Configurable, Value?> {
|
val config: M,
|
||||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): Value? {
|
private val key: String? = null,
|
||||||
return thisRef.config[key ?: property.name]?.value ?: default
|
private val default: Value? = null
|
||||||
|
) : ReadWriteProperty<Any?, Value?> {
|
||||||
|
override fun getValue(thisRef: Any?, property: KProperty<*>): Value? {
|
||||||
|
return config[key ?: property.name]?.value ?: default
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setValue(thisRef: Configurable, property: KProperty<*>, value: Value?) {
|
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Value?) {
|
||||||
val name = key ?: property.name
|
val name = key ?: property.name
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
thisRef.config.remove(name)
|
config.remove(name)
|
||||||
} else {
|
} else {
|
||||||
thisRef.config[name] = value
|
config.setValue(name, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class StringConfigDelegate(private val key: String? = null, private val default: String? = null) :
|
class StringConfigDelegate<M : MutableMeta<M>>(
|
||||||
ReadWriteProperty<Configurable, String?> {
|
val config: M,
|
||||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): String? {
|
private val key: String? = null,
|
||||||
return thisRef.config[key ?: property.name]?.string ?: default
|
private val default: String? = null
|
||||||
|
) : ReadWriteProperty<Any?, String?> {
|
||||||
|
override fun getValue(thisRef: Any?, property: KProperty<*>): String? {
|
||||||
|
return config[key ?: property.name]?.string ?: default
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setValue(thisRef: Configurable, property: KProperty<*>, value: String?) {
|
override fun setValue(thisRef: Any?, property: KProperty<*>, value: String?) {
|
||||||
thisRef.config[key ?: property.name] = value
|
val name = key ?: property.name
|
||||||
|
if (value == null) {
|
||||||
|
config.remove(name)
|
||||||
|
} else {
|
||||||
|
config.setValue(name, value.asValue())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BooleanConfigDelegate(private val key: String? = null, private val default: Boolean? = null) :
|
class BooleanConfigDelegate<M : MutableMeta<M>>(
|
||||||
ReadWriteProperty<Configurable, Boolean?> {
|
val config: M,
|
||||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): Boolean? {
|
private val key: String? = null,
|
||||||
return thisRef.config[key ?: property.name]?.boolean ?: default
|
private val default: Boolean? = null
|
||||||
|
) : ReadWriteProperty<Any?, Boolean?> {
|
||||||
|
override fun getValue(thisRef: Any?, property: KProperty<*>): Boolean? {
|
||||||
|
return config[key ?: property.name]?.boolean ?: default
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setValue(thisRef: Configurable, property: KProperty<*>, value: Boolean?) {
|
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Boolean?) {
|
||||||
thisRef.config[key ?: property.name] = value
|
val name = key ?: property.name
|
||||||
|
if (value == null) {
|
||||||
|
config.remove(name)
|
||||||
|
} else {
|
||||||
|
config.setValue(name, value.asValue())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NumberConfigDelegate(private val key: String? = null, private val default: Number? = null) :
|
class NumberConfigDelegate<M : MutableMeta<M>>(
|
||||||
ReadWriteProperty<Configurable, Number?> {
|
val config: M,
|
||||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): Number? {
|
private val key: String? = null,
|
||||||
return thisRef.config[key ?: property.name]?.number ?: default
|
private val default: Number? = null
|
||||||
|
) : ReadWriteProperty<Any?, Number?> {
|
||||||
|
override fun getValue(thisRef: Any?, property: KProperty<*>): Number? {
|
||||||
|
return config[key ?: property.name]?.number ?: default
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setValue(thisRef: Configurable, property: KProperty<*>, value: Number?) {
|
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Number?) {
|
||||||
thisRef.config[key ?: property.name] = value
|
val name = key ?: property.name
|
||||||
|
if (value == null) {
|
||||||
|
config.remove(name)
|
||||||
|
} else {
|
||||||
|
config.setValue(name, value.asValue())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val double get() = ReadWriteDelegateWrapper(this, reader = { it?.toDouble() }, writer = { it })
|
||||||
|
val int get() = ReadWriteDelegateWrapper(this, reader = { it?.toInt() }, writer = { it })
|
||||||
|
val short get() = ReadWriteDelegateWrapper(this, reader = { it?.toShort() }, writer = { it })
|
||||||
|
val long get() = ReadWriteDelegateWrapper(this, reader = { it?.toLong() }, writer = { it })
|
||||||
|
}
|
||||||
|
|
||||||
//Delegates with non-null values
|
//Delegates with non-null values
|
||||||
|
|
||||||
class SafeStringConfigDelegate(private val key: String? = null, private val default: String) :
|
class SafeStringConfigDelegate<M : MutableMeta<M>>(
|
||||||
ReadWriteProperty<Configurable, String> {
|
val config: M,
|
||||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): String {
|
private val key: String? = null,
|
||||||
return thisRef.config[key ?: property.name]?.string ?: default
|
private val default: String
|
||||||
|
) : ReadWriteProperty<Any?, String> {
|
||||||
|
override fun getValue(thisRef: Any?, property: KProperty<*>): String {
|
||||||
|
return config[key ?: property.name]?.string ?: default
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setValue(thisRef: Configurable, property: KProperty<*>, value: String) {
|
override fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
|
||||||
thisRef.config[key ?: property.name] = value
|
config.setValue(key ?: property.name, value.asValue())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SafeBooleanConfigDelegate(private val key: String? = null, private val default: Boolean) :
|
class SafeBooleanConfigDelegate<M : MutableMeta<M>>(
|
||||||
ReadWriteProperty<Configurable, Boolean> {
|
val config: M,
|
||||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): Boolean {
|
private val key: String? = null,
|
||||||
return thisRef.config[key ?: property.name]?.boolean ?: default
|
private val default: Boolean
|
||||||
|
) : ReadWriteProperty<Any?, Boolean> {
|
||||||
|
override fun getValue(thisRef: Any?, property: KProperty<*>): Boolean {
|
||||||
|
return config[key ?: property.name]?.boolean ?: default
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setValue(thisRef: Configurable, property: KProperty<*>, value: Boolean) {
|
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Boolean) {
|
||||||
thisRef.config[key ?: property.name] = value
|
config.setValue(key ?: property.name, value.asValue())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SafeNumberConfigDelegate(private val key: String? = null, private val default: Number) :
|
class SafeNumberConfigDelegate<M : MutableMeta<M>>(
|
||||||
ReadWriteProperty<Configurable, Number> {
|
val config: M,
|
||||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): Number {
|
private val key: String? = null,
|
||||||
return thisRef.config[key ?: property.name]?.number ?: default
|
private val default: Number
|
||||||
|
) : ReadWriteProperty<Any?, Number> {
|
||||||
|
override fun getValue(thisRef: Any?, property: KProperty<*>): Number {
|
||||||
|
return config[key ?: property.name]?.number ?: default
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setValue(thisRef: Configurable, property: KProperty<*>, value: Number) {
|
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Number) {
|
||||||
thisRef.config[key ?: property.name] = value
|
config.setValue(key ?: property.name, value.asValue())
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class SafeEnumvConfigDelegate<E : Enum<E>>(
|
val double get() = ReadWriteDelegateWrapper(this, reader = { it.toDouble() }, writer = { it })
|
||||||
|
val int get() = ReadWriteDelegateWrapper(this, reader = { it.toInt() }, writer = { it })
|
||||||
|
val short get() = ReadWriteDelegateWrapper(this, reader = { it.toShort() }, writer = { it })
|
||||||
|
val long get() = ReadWriteDelegateWrapper(this, reader = { it.toLong() }, writer = { it })
|
||||||
|
}
|
||||||
|
|
||||||
|
class SafeEnumvConfigDelegate<M : MutableMeta<M>, E : Enum<E>>(
|
||||||
|
val config: M,
|
||||||
private val key: String? = null,
|
private val key: String? = null,
|
||||||
private val default: E,
|
private val default: E,
|
||||||
private val resolver: (String) -> E
|
private val resolver: (String) -> E
|
||||||
) : ReadWriteProperty<Configurable, E> {
|
) : ReadWriteProperty<Any?, E> {
|
||||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): E {
|
override fun getValue(thisRef: Any?, property: KProperty<*>): E {
|
||||||
return (thisRef.config[key ?: property.name]?.string)?.let { resolver(it) } ?: default
|
return (config[key ?: property.name]?.string)?.let { resolver(it) } ?: default
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setValue(thisRef: Configurable, property: KProperty<*>, value: E) {
|
override fun setValue(thisRef: Any?, property: KProperty<*>, value: E) {
|
||||||
thisRef.config[key ?: property.name] = value.name
|
config.setValue(key ?: property.name, value.name.asValue())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Child node delegate
|
//Child node delegate
|
||||||
|
|
||||||
class ChildConfigDelegate<T : Configurable>(private val key: String? = null, private val converter: (Config) -> T) :
|
class MetaNodeDelegate<M : MutableMetaNode<M>>(
|
||||||
ReadWriteProperty<Configurable, T> {
|
val config: M,
|
||||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): T {
|
private val key: String? = null
|
||||||
return converter(thisRef.config[key ?: property.name]?.node ?: Config())
|
) : ReadWriteProperty<Any?, Meta> {
|
||||||
|
override fun getValue(thisRef: Any?, property: KProperty<*>): Meta {
|
||||||
|
return config[key ?: property.name]?.node ?: EmptyMeta
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setValue(thisRef: Configurable, property: KProperty<*>, value: T) {
|
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Meta) {
|
||||||
thisRef.config[key ?: property.name] = value.config
|
config[key ?: property.name] = value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ChildConfigDelegate<M : MutableMetaNode<M>, T : Configurable>(
|
||||||
|
val config: M,
|
||||||
|
private val key: String? = null,
|
||||||
|
private val converter: (Meta) -> T
|
||||||
|
) :
|
||||||
|
ReadWriteProperty<Any?, T> {
|
||||||
|
override fun getValue(thisRef: Any?, property: KProperty<*>): T {
|
||||||
|
return converter(config[key ?: property.name]?.node ?: EmptyMeta)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
|
||||||
|
config[key ?: property.name] = value.config
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ReadWriteDelegateWrapper<T, R>(
|
||||||
|
val delegate: ReadWriteProperty<Any?, T>,
|
||||||
|
val reader: (T) -> R,
|
||||||
|
val writer: (R) -> T
|
||||||
|
) : ReadWriteProperty<Any?, R> {
|
||||||
|
override fun getValue(thisRef: Any?, property: KProperty<*>): R {
|
||||||
|
return reader(delegate.getValue(thisRef, property))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setValue(thisRef: Any?, property: KProperty<*>, value: R) {
|
||||||
|
delegate.setValue(thisRef, property, writer(value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//Read-write delegates
|
//Read-write delegates
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A property delegate that uses custom key
|
* A property delegate that uses custom key
|
||||||
*/
|
*/
|
||||||
fun Configurable.value(default: Value = Null, key: String? = null) = ValueConfigDelegate(key, default)
|
fun <M : MutableMeta<M>> M.value(default: Value = Null, key: String? = null) =
|
||||||
|
ValueConfigDelegate(this, key, default)
|
||||||
|
|
||||||
fun Configurable.string(default: String? = null, key: String? = null) = StringConfigDelegate(key, default)
|
fun <M : MutableMeta<M>> M.string(default: String? = null, key: String? = null) =
|
||||||
|
StringConfigDelegate(this, key, default)
|
||||||
|
|
||||||
fun Configurable.boolean(default: Boolean? = null, key: String? = null) = BooleanConfigDelegate(key, default)
|
fun <M : MutableMeta<M>> M.boolean(default: Boolean? = null, key: String? = null) =
|
||||||
|
BooleanConfigDelegate(this, key, default)
|
||||||
|
|
||||||
fun Configurable.number(default: Number? = null, key: String? = null) = NumberConfigDelegate(key, default)
|
fun <M : MutableMeta<M>> M.number(default: Number? = null, key: String? = null) =
|
||||||
|
NumberConfigDelegate(this, key, default)
|
||||||
|
|
||||||
fun Configurable.child(key: String? = null) = ChildConfigDelegate(key) { SimpleConfigurable(it) }
|
fun <M : MutableMetaNode<M>> M.child(key: String? = null) = MetaNodeDelegate(this, key)
|
||||||
|
|
||||||
fun <T : Configurable> Configurable.child(key: String? = null, converter: (Config) -> T) =
|
|
||||||
ChildConfigDelegate(key, converter)
|
|
||||||
|
|
||||||
//fun <T : Configurable> Configurable.spec(spec: Specification<T>, key: String? = null) = ChildConfigDelegate<T>(key) { spec.wrap(this) }
|
//fun <T : Configurable> Configurable.spec(spec: Specification<T>, key: String? = null) = ChildConfigDelegate<T>(key) { spec.wrap(this) }
|
||||||
|
|
||||||
@JvmName("safeString")
|
@JvmName("safeString")
|
||||||
fun Configurable.string(default: String, key: String? = null) = SafeStringConfigDelegate(key, default)
|
fun <M : MutableMeta<M>> M.string(default: String, key: String? = null) =
|
||||||
|
SafeStringConfigDelegate(this, key, default)
|
||||||
|
|
||||||
@JvmName("safeBoolean")
|
@JvmName("safeBoolean")
|
||||||
fun Configurable.boolean(default: Boolean, key: String? = null) = SafeBooleanConfigDelegate(key, default)
|
fun <M : MutableMeta<M>> M.boolean(default: Boolean, key: String? = null) =
|
||||||
|
SafeBooleanConfigDelegate(this, key, default)
|
||||||
|
|
||||||
@JvmName("safeNumber")
|
@JvmName("safeNumber")
|
||||||
fun Configurable.number(default: Number, key: String? = null) = SafeNumberConfigDelegate(key, default)
|
fun <M : MutableMeta<M>> M.number(default: Number, key: String? = null) =
|
||||||
|
SafeNumberConfigDelegate(this, key, default)
|
||||||
|
|
||||||
inline fun <reified E : Enum<E>> Configurable.enum(default: E, key: String? = null) =
|
inline fun <M : MutableMeta<M>, reified E : Enum<E>> M.enum(default: E, key: String? = null) =
|
||||||
SafeEnumvConfigDelegate(key, default) { enumValueOf(it) }
|
SafeEnumvConfigDelegate(this, key, default) { enumValueOf(it) }
|
@ -0,0 +1,36 @@
|
|||||||
|
package hep.dataforge.meta
|
||||||
|
|
||||||
|
import kotlin.properties.ReadWriteProperty
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extra delegates for special cases
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A delegate for a string list
|
||||||
|
*/
|
||||||
|
class StringListConfigDelegate(
|
||||||
|
val config: Config,
|
||||||
|
private val key: String? = null,
|
||||||
|
private val default: List<String> = emptyList()
|
||||||
|
) :
|
||||||
|
ReadWriteProperty<Any?, List<String>> {
|
||||||
|
override fun getValue(thisRef: Any?, property: KProperty<*>): List<String> {
|
||||||
|
return config[key ?: property.name]?.value?.list?.map { it.string } ?: default
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setValue(thisRef: Any?, property: KProperty<*>, value: List<String>) {
|
||||||
|
val name = key ?: property.name
|
||||||
|
config[name] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Configurable.stringList(vararg default: String = emptyArray(), key: String? = null) =
|
||||||
|
StringListConfigDelegate(config, key, default.toList())
|
||||||
|
|
||||||
|
|
||||||
|
fun <T : Metoid> Metoid.child(key: String? = null, converter: (Meta) -> T) = ChildDelegate(meta, key, converter)
|
||||||
|
|
||||||
|
fun <T : Configurable> Configurable.child(key: String? = null, converter: (Meta) -> T) =
|
||||||
|
ChildConfigDelegate(config, key, converter)
|
@ -3,7 +3,7 @@ package hep.dataforge.meta
|
|||||||
import hep.dataforge.names.NameToken
|
import hep.dataforge.names.NameToken
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A meta laminate consisting of multiple immutable meta layers. For mutable front layer, use [StyledConfig].
|
* A meta laminate consisting of multiple immutable meta layers. For mutable front layer, use [Styled].
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -102,10 +102,11 @@ operator fun Meta.iterator(): Iterator<Pair<Name, Value>> = asValueSequence().it
|
|||||||
/**
|
/**
|
||||||
* A meta node that ensures that all of its descendants has at least the same type
|
* A meta node that ensures that all of its descendants has at least the same type
|
||||||
*/
|
*/
|
||||||
abstract class MetaNode<M : MetaNode<M>> : Meta {
|
interface MetaNode<M : MetaNode<M>> : Meta {
|
||||||
abstract override val items: Map<NameToken, MetaItem<M>>
|
override val items: Map<NameToken, MetaItem<M>>
|
||||||
|
}
|
||||||
|
|
||||||
operator fun get(name: Name): MetaItem<M>? {
|
operator fun <M : MetaNode<M>> MetaNode<M>.get(name: Name): MetaItem<M>? {
|
||||||
return name.first()?.let { token ->
|
return name.first()?.let { token ->
|
||||||
val tail = name.cutFirst()
|
val tail = name.cutFirst()
|
||||||
when (tail.length) {
|
when (tail.length) {
|
||||||
@ -115,8 +116,12 @@ abstract class MetaNode<M : MetaNode<M>> : Meta {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun get(key: String): MetaItem<M>? = get(key.toName())
|
operator fun <M : MetaNode<M>> MetaNode<M>.get(key: String): MetaItem<M>? = get(key.toName())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Equals and hash code implementation for meta node
|
||||||
|
*/
|
||||||
|
abstract class AbstractMetaNode<M : MetaNode<M>> : MetaNode<M> {
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
if (this === other) return true
|
if (this === other) return true
|
||||||
if (other !is Meta) return false
|
if (other !is Meta) return false
|
||||||
@ -134,7 +139,8 @@ abstract class MetaNode<M : MetaNode<M>> : Meta {
|
|||||||
*
|
*
|
||||||
* If the argument is possibly mutable node, it is copied on creation
|
* If the argument is possibly mutable node, it is copied on creation
|
||||||
*/
|
*/
|
||||||
class SealedMeta internal constructor(override val items: Map<NameToken, MetaItem<SealedMeta>>) : MetaNode<SealedMeta>()
|
class SealedMeta internal constructor(override val items: Map<NameToken, MetaItem<SealedMeta>>) :
|
||||||
|
AbstractMetaNode<SealedMeta>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate sealed node from [this]. If it is already sealed return it as is
|
* Generate sealed node from [this]. If it is already sealed return it as is
|
||||||
@ -154,17 +160,19 @@ object EmptyMeta : Meta {
|
|||||||
* Unsafe methods to access values and nodes directly from [MetaItem]
|
* Unsafe methods to access values and nodes directly from [MetaItem]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
val MetaItem<*>.value
|
val MetaItem<*>?.value
|
||||||
get() = (this as? MetaItem.ValueItem)?.value
|
get() = (this as? MetaItem.ValueItem)?.value
|
||||||
?: (this.node[VALUE_KEY] as? MetaItem.ValueItem)?.value
|
?: (this?.node?.get(VALUE_KEY) as? MetaItem.ValueItem)?.value
|
||||||
?: error("Trying to interpret node meta item as value item")
|
|
||||||
val MetaItem<*>.string get() = value.string
|
val MetaItem<*>?.string get() = value?.string
|
||||||
val MetaItem<*>.boolean get() = value.boolean
|
val MetaItem<*>?.boolean get() = value?.boolean
|
||||||
val MetaItem<*>.number get() = value.number
|
val MetaItem<*>?.number get() = value?.number
|
||||||
val MetaItem<*>.double get() = number.toDouble()
|
val MetaItem<*>?.double get() = number?.toDouble()
|
||||||
val MetaItem<*>.int get() = number.toInt()
|
val MetaItem<*>?.int get() = number?.toInt()
|
||||||
val MetaItem<*>.long get() = number.toLong()
|
val MetaItem<*>?.long get() = number?.toLong()
|
||||||
val MetaItem<*>.short get() = number.toShort()
|
val MetaItem<*>?.short get() = number?.toShort()
|
||||||
|
|
||||||
|
val MetaItem<*>?.stringList get() = value?.list?.map { it.string } ?: emptyList()
|
||||||
|
|
||||||
val <M : Meta> MetaItem<M>.node: M
|
val <M : Meta> MetaItem<M>.node: M
|
||||||
get() = when (this) {
|
get() = when (this) {
|
||||||
|
@ -6,19 +6,17 @@ import hep.dataforge.names.plus
|
|||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
import hep.dataforge.values.Value
|
import hep.dataforge.values.Value
|
||||||
|
|
||||||
class MetaListener(
|
internal data class MetaListener(
|
||||||
val owner: Any? = null,
|
val owner: Any? = null,
|
||||||
val action: (name: Name, oldItem: MetaItem<*>?, newItem: MetaItem<*>?) -> Unit
|
val action: (name: Name, oldItem: MetaItem<*>?, newItem: MetaItem<*>?) -> Unit
|
||||||
) {
|
)
|
||||||
operator fun invoke(name: Name, oldItem: MetaItem<*>?, newItem: MetaItem<*>?) = action(name, oldItem, newItem)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
interface MutableMeta<M : MutableMeta<M>> : Meta {
|
interface MutableMeta<M : MutableMeta<M>> : MetaNode<M> {
|
||||||
override val items: Map<NameToken, MetaItem<M>>
|
override val items: Map<NameToken, MetaItem<M>>
|
||||||
operator fun set(name: Name, item: MetaItem<M>?)
|
operator fun set(name: Name, item: MetaItem<M>?)
|
||||||
fun onChange(owner: Any? = null, action: (Name, MetaItem<*>?, MetaItem<*>?) -> Unit)
|
fun onChange(owner: Any? = null, action: (Name, MetaItem<*>?, MetaItem<*>?) -> Unit)
|
||||||
fun removeListener(owner: Any)
|
fun removeListener(owner: Any? = null)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,7 +24,7 @@ interface MutableMeta<M : MutableMeta<M>> : Meta {
|
|||||||
*
|
*
|
||||||
* Changes in Meta are not thread safe.
|
* Changes in Meta are not thread safe.
|
||||||
*/
|
*/
|
||||||
abstract class MutableMetaNode<M : MutableMetaNode<M>> : MetaNode<M>(), MutableMeta<M> {
|
abstract class MutableMetaNode<M : MutableMetaNode<M>> : AbstractMetaNode<M>(), MutableMeta<M> {
|
||||||
private val listeners = HashSet<MetaListener>()
|
private val listeners = HashSet<MetaListener>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -39,7 +37,7 @@ abstract class MutableMetaNode<M : MutableMetaNode<M>> : MetaNode<M>(), MutableM
|
|||||||
/**
|
/**
|
||||||
* Remove all listeners belonging to given owner
|
* Remove all listeners belonging to given owner
|
||||||
*/
|
*/
|
||||||
override fun removeListener(owner: Any) {
|
override fun removeListener(owner: Any?) {
|
||||||
listeners.removeAll { it.owner === owner }
|
listeners.removeAll { it.owner === owner }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,7 +47,7 @@ abstract class MutableMetaNode<M : MutableMetaNode<M>> : MetaNode<M>(), MutableM
|
|||||||
get() = _items
|
get() = _items
|
||||||
|
|
||||||
protected fun itemChanged(name: Name, oldItem: MetaItem<*>?, newItem: MetaItem<*>?) {
|
protected fun itemChanged(name: Name, oldItem: MetaItem<*>?, newItem: MetaItem<*>?) {
|
||||||
listeners.forEach { it(name, oldItem, newItem) }
|
listeners.forEach { it.action(name, oldItem, newItem) }
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun replaceItem(key: NameToken, oldItem: MetaItem<M>?, newItem: MetaItem<M>?) {
|
protected open fun replaceItem(key: NameToken, oldItem: MetaItem<M>?, newItem: MetaItem<M>?) {
|
||||||
@ -72,12 +70,12 @@ abstract class MutableMetaNode<M : MutableMetaNode<M>> : MetaNode<M>(), MutableM
|
|||||||
* @param name the name of the node where meta should be attached. Needed for correct assignment validators and styles
|
* @param name the name of the node where meta should be attached. Needed for correct assignment validators and styles
|
||||||
* @param meta the node itself
|
* @param meta the node itself
|
||||||
*/
|
*/
|
||||||
abstract fun wrap(name: Name, meta: Meta): M
|
internal abstract fun wrap(name: Name, meta: Meta): M
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create empty node
|
* Create empty node
|
||||||
*/
|
*/
|
||||||
abstract fun empty(): M
|
internal abstract fun empty(): M
|
||||||
|
|
||||||
override operator fun set(name: Name, item: MetaItem<M>?) {
|
override operator fun set(name: Name, item: MetaItem<M>?) {
|
||||||
when (name.length) {
|
when (name.length) {
|
||||||
@ -95,20 +93,22 @@ abstract class MutableMetaNode<M : MutableMetaNode<M>> : MetaNode<M>(), MutableM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <M : MutableMeta<M>> M.remove(name: Name) = set(name, null)
|
fun <M : MutableMeta<M>> MutableMeta<M>.remove(name: Name) = set(name, null)
|
||||||
fun <M : MutableMeta<M>> M.remove(name: String) = remove(name.toName())
|
fun <M : MutableMeta<M>> MutableMeta<M>.remove(name: String) = remove(name.toName())
|
||||||
|
|
||||||
fun <M : MutableMeta<M>> M.setValue(name: Name, value: Value) = set(name, MetaItem.ValueItem(value))
|
fun <M : MutableMeta<M>> MutableMeta<M>.setValue(name: Name, value: Value) = set(name, MetaItem.ValueItem(value))
|
||||||
fun <M : MutableMeta<M>> M.setItem(name: String, item: MetaItem<M>) = set(name.toName(), item)
|
fun <M : MutableMeta<M>> MutableMeta<M>.setItem(name: String, item: MetaItem<M>) = set(name.toName(), item)
|
||||||
fun <M : MutableMeta<M>> M.setValue(name: String, value: Value) = set(name.toName(), MetaItem.ValueItem(value))
|
fun <M : MutableMeta<M>> MutableMeta<M>.setValue(name: String, value: Value) =
|
||||||
fun <M : MutableMeta<M>> M.setItem(token: NameToken, item: MetaItem<M>?) = set(token.toName(), item)
|
set(name.toName(), MetaItem.ValueItem(value))
|
||||||
|
|
||||||
fun <M : MutableMetaNode<M>> M.setNode(name: Name, node: Meta) = set(name, MetaItem.NodeItem(wrap(name, node)))
|
fun <M : MutableMeta<M>> MutableMeta<M>.setItem(token: NameToken, item: MetaItem<M>?) = set(token.toName(), item)
|
||||||
fun <M : MutableMetaNode<M>> M.setNode(name: String, node: Meta) = setNode(name.toName(), node)
|
|
||||||
|
fun <M : MutableMetaNode<M>> MutableMetaNode<M>.setNode(name: Name, node: Meta) =
|
||||||
|
set(name, MetaItem.NodeItem(wrap(name, node)))
|
||||||
|
|
||||||
|
fun <M : MutableMetaNode<M>> MutableMetaNode<M>.setNode(name: String, node: Meta) = setNode(name.toName(), node)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Universal set method
|
* Universal set method
|
||||||
@ -116,6 +116,10 @@ fun <M : MutableMetaNode<M>> M.setNode(name: String, node: Meta) = setNode(name.
|
|||||||
operator fun <M : MutableMetaNode<M>> M.set(name: Name, value: Any?) {
|
operator fun <M : MutableMetaNode<M>> M.set(name: Name, value: Any?) {
|
||||||
when (value) {
|
when (value) {
|
||||||
null -> remove(name)
|
null -> remove(name)
|
||||||
|
is MetaItem<*> -> when (value) {
|
||||||
|
is MetaItem.ValueItem<*> -> setValue(name, value.value)
|
||||||
|
is MetaItem.NodeItem<*> -> setNode(name, value.node)
|
||||||
|
}
|
||||||
is Meta -> setNode(name, value)
|
is Meta -> setNode(name, value)
|
||||||
else -> setValue(name, Value.of(value))
|
else -> setValue(name, Value.of(value))
|
||||||
}
|
}
|
@ -55,5 +55,8 @@ fun <C : Specification, S : SpecificationCompanion<C>> S.createStyle(action: C.(
|
|||||||
Config().also { update(it, action) }
|
Config().also { update(it, action) }
|
||||||
|
|
||||||
|
|
||||||
fun <C : Specification> Specification.spec(spec: SpecificationCompanion<C>, key: String? = null) =
|
fun <M : MutableMetaNode<M>, C : Specification> Specification.spec(
|
||||||
ChildConfigDelegate<C>(key) { spec.wrap(config) }
|
spec: SpecificationCompanion<C>,
|
||||||
|
key: String? = null
|
||||||
|
) =
|
||||||
|
ChildConfigDelegate(config, key) { spec.wrap(config) }
|
@ -1,68 +0,0 @@
|
|||||||
package hep.dataforge.meta
|
|
||||||
|
|
||||||
import hep.dataforge.names.Name
|
|
||||||
import hep.dataforge.names.NameToken
|
|
||||||
import hep.dataforge.names.toName
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A configuration decorator with applied style
|
|
||||||
*/
|
|
||||||
class StyledConfig(val config: Config, style: Meta = EmptyMeta) : Config() {
|
|
||||||
|
|
||||||
var style: Meta = style
|
|
||||||
set(value) {
|
|
||||||
field.items.forEach {
|
|
||||||
itemChanged(it.key.toName(), it.value, null)
|
|
||||||
}
|
|
||||||
field = value
|
|
||||||
value.items.forEach {
|
|
||||||
itemChanged(it.key.toName(), null, it.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
config.onChange { name, oldItem, newItem -> this.itemChanged(name, oldItem, newItem) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun set(name: Name, item: MetaItem<Config>?) {
|
|
||||||
when (item) {
|
|
||||||
null -> config.remove(name)
|
|
||||||
is MetaItem.ValueItem -> config.setValue(name, item.value)
|
|
||||||
is MetaItem.NodeItem -> config.setNode(name, item.node)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override val items: Map<NameToken, MetaItem<Config>>
|
|
||||||
get() = (config.items.keys + style.items.keys).associate { key ->
|
|
||||||
val value = config.items[key]
|
|
||||||
val styleValue = style[key]
|
|
||||||
val item: MetaItem<Config> = when (value) {
|
|
||||||
null -> when (styleValue) {
|
|
||||||
null -> error("Should be unreachable")
|
|
||||||
is MetaItem.ValueItem -> MetaItem.ValueItem(styleValue.value)
|
|
||||||
is MetaItem.NodeItem -> MetaItem.NodeItem<Config>(StyledConfig(config.empty(), styleValue.node))
|
|
||||||
}
|
|
||||||
is MetaItem.ValueItem -> MetaItem.ValueItem(value.value)
|
|
||||||
is MetaItem.NodeItem -> MetaItem.NodeItem(
|
|
||||||
StyledConfig(value.node, styleValue?.node ?: EmptyMeta)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
key to item
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Config.withStyle(style: Meta = EmptyMeta) = if (this is StyledConfig) {
|
|
||||||
StyledConfig(this.config, style)
|
|
||||||
} else {
|
|
||||||
StyledConfig(this, style)
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Styleable : Configurable {
|
|
||||||
override val config: StyledConfig
|
|
||||||
|
|
||||||
var style
|
|
||||||
get() = config.style
|
|
||||||
set(value) {
|
|
||||||
config.style = value
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,68 @@
|
|||||||
|
package hep.dataforge.meta
|
||||||
|
|
||||||
|
import hep.dataforge.names.Name
|
||||||
|
import hep.dataforge.names.NameToken
|
||||||
|
import kotlin.properties.ReadWriteProperty
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A meta object with read-only meta base and changeable configuration on top of it
|
||||||
|
* @param base - unchangeable base
|
||||||
|
* @param style - the style
|
||||||
|
*/
|
||||||
|
class Styled(val base: Meta, val style: Config = Config().empty()) : MutableMeta<Styled> {
|
||||||
|
override val items: Map<NameToken, MetaItem<Styled>>
|
||||||
|
get() = (base.items.keys + style.items.keys).associate { key ->
|
||||||
|
val value = base.items[key]
|
||||||
|
val styleValue = style[key]
|
||||||
|
val item: MetaItem<Styled> = when (value) {
|
||||||
|
null -> when (styleValue) {
|
||||||
|
null -> error("Should be unreachable")
|
||||||
|
is MetaItem.ValueItem -> MetaItem.ValueItem(styleValue.value)
|
||||||
|
is MetaItem.NodeItem -> MetaItem.NodeItem(Styled(style.empty(), styleValue.node))
|
||||||
|
}
|
||||||
|
is MetaItem.ValueItem -> MetaItem.ValueItem(value.value)
|
||||||
|
is MetaItem.NodeItem -> MetaItem.NodeItem(
|
||||||
|
Styled(value.node, styleValue?.node ?: Config.empty())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
key to item
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun set(name: Name, item: MetaItem<Styled>?) {
|
||||||
|
if (item == null) {
|
||||||
|
style.remove(name)
|
||||||
|
} else {
|
||||||
|
style.set(name, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onChange(owner: Any?, action: (Name, before: MetaItem<*>?, after: MetaItem<*>?) -> Unit) {
|
||||||
|
//TODO test correct behavior
|
||||||
|
style.onChange(owner) { name, before, after -> action(name, before ?: base[name], after ?: base[name]) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun removeListener(owner: Any?) {
|
||||||
|
style.removeListener(owner)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Styled.configure(meta: Meta) = apply { style.update(style) }
|
||||||
|
|
||||||
|
fun Meta.withStyle(style: Meta = EmptyMeta) = if (this is Styled) {
|
||||||
|
this.apply { this.configure(style) }
|
||||||
|
} else {
|
||||||
|
Styled(this, style.toConfig())
|
||||||
|
}
|
||||||
|
|
||||||
|
class StyledNodeDelegate(val owner: Styled, val key: String?) : ReadWriteProperty<Any?, Meta> {
|
||||||
|
override fun getValue(thisRef: Any?, property: KProperty<*>): Meta {
|
||||||
|
return owner[key ?: property.name]?.node ?: EmptyMeta
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Meta) {
|
||||||
|
owner.style[key ?: property.name] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
24
dataforge-vis/build.gradle.kts
Normal file
24
dataforge-vis/build.gradle.kts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("multiplatform")
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
jvm()
|
||||||
|
js()
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
val commonMain by getting {
|
||||||
|
dependencies {
|
||||||
|
api(project(":dataforge-io"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val jvmMain by getting {
|
||||||
|
dependencies {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val jsMain by getting {
|
||||||
|
dependencies {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
23
dataforge-vis/dataforge-vis-fx/build.gradle.kts
Normal file
23
dataforge-vis/dataforge-vis-fx/build.gradle.kts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||||
|
import org.openjfx.gradle.JavaFXOptions
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
kotlin("jvm")
|
||||||
|
id("org.openjfx.javafxplugin")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies{
|
||||||
|
api(project(":dataforge-vis:dataforge-vis-spatial"))
|
||||||
|
api("no.tornado:tornadofx:1.7.18")
|
||||||
|
implementation("org.fxyz3d:fxyz3d:0.4.0")
|
||||||
|
}
|
||||||
|
|
||||||
|
extensions.findByType<JavaFXOptions>()?.apply {
|
||||||
|
modules("javafx.controls")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<KotlinCompile> {
|
||||||
|
kotlinOptions{
|
||||||
|
jvmTarget = "1.8"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
|
import hep.dataforge.context.Context
|
||||||
|
import hep.dataforge.io.Output
|
||||||
|
import hep.dataforge.meta.Meta
|
||||||
|
import javafx.scene.*
|
||||||
|
import javafx.scene.paint.Color
|
||||||
|
import org.fxyz3d.geometry.Point3D
|
||||||
|
import org.fxyz3d.shapes.primitives.CuboidMesh
|
||||||
|
import org.fxyz3d.utils.CameraTransformer
|
||||||
|
|
||||||
|
class FXSpatialRenderer(override val context: Context) : Output<DisplayObject3D> {
|
||||||
|
|
||||||
|
private val world: Group = Group()
|
||||||
|
|
||||||
|
val camera = PerspectiveCamera()
|
||||||
|
|
||||||
|
val cameraTransform = CameraTransformer().apply {
|
||||||
|
children.add(camera)
|
||||||
|
}
|
||||||
|
|
||||||
|
val canvas: SubScene = SubScene(
|
||||||
|
Group(world, cameraTransform).apply { DepthTest.ENABLE },
|
||||||
|
1024.0,
|
||||||
|
768.0,
|
||||||
|
true,
|
||||||
|
SceneAntialiasing.BALANCED
|
||||||
|
).apply {
|
||||||
|
fill = Color.GREY
|
||||||
|
this.camera = this@FXSpatialRenderer.camera
|
||||||
|
id = "canvas"
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildObject(obj: DisplayObject3D): Node {
|
||||||
|
val center = Point3D(obj.x.toFloat(), obj.y.toFloat(), obj.z.toFloat())
|
||||||
|
return when (obj) {
|
||||||
|
is Box3D -> CuboidMesh(obj.xSize, obj.ySize, obj.zSize).apply { this.center = center }
|
||||||
|
else -> TODO()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun render(obj: DisplayObject3D, meta: Meta) {
|
||||||
|
world.children.add(buildObject(obj))
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
|
import hep.dataforge.context.Global
|
||||||
|
import hep.dataforge.meta.EmptyMeta
|
||||||
|
import javafx.scene.Parent
|
||||||
|
import tornadofx.*
|
||||||
|
|
||||||
|
|
||||||
|
class RendererDemoApp: App(RendererDemoView::class)
|
||||||
|
|
||||||
|
|
||||||
|
class RendererDemoView: View(){
|
||||||
|
val renderer = FXSpatialRenderer(Global)
|
||||||
|
override val root: Parent = borderpane{
|
||||||
|
center = renderer.canvas
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
val cube = Box3D(null, EmptyMeta).apply {
|
||||||
|
xSize = 100.0
|
||||||
|
ySize = 100.0
|
||||||
|
zSize = 100.0
|
||||||
|
}
|
||||||
|
renderer.render(cube)
|
||||||
|
|
||||||
|
renderer.camera.apply {
|
||||||
|
nearClip = 0.1
|
||||||
|
farClip = 10000.0
|
||||||
|
translateX = -200.0
|
||||||
|
translateY = -200.0
|
||||||
|
fieldOfView = 20.0
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer.cameraTransform.apply{
|
||||||
|
ry.angle = -30.0
|
||||||
|
rx.angle = -15.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
launch<RendererDemoApp>()
|
||||||
|
}
|
42
dataforge-vis/dataforge-vis-js/build.gradle.kts
Normal file
42
dataforge-vis/dataforge-vis-js/build.gradle.kts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
plugins{
|
||||||
|
kotlin("js")
|
||||||
|
id("kotlin")
|
||||||
|
}
|
||||||
|
|
||||||
|
// configure(listOf(compilations.main, compilations.test)) {
|
||||||
|
// tasks.getByName(compileKotlinTaskName).kotlinOptions {
|
||||||
|
// sourceMap = true
|
||||||
|
// moduleKind = "umd"
|
||||||
|
// metaInfo = true
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// configure(compilations.main) {
|
||||||
|
// tasks.getByName(compileKotlinTaskName).kotlinOptions {
|
||||||
|
// main = "call"
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation("info.laht.threekt:threejs-wrapper:0.88-npm-1")
|
||||||
|
}
|
||||||
|
|
||||||
|
extensions.findByType<KotlinFrontendExtension>()?.apply {
|
||||||
|
extensions.findByType<NpmExtension>()?.apply {
|
||||||
|
dependency("three")
|
||||||
|
dependency("three-orbitcontrols")
|
||||||
|
devDependency("karma")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceMaps = true
|
||||||
|
|
||||||
|
bundle("webpack") {
|
||||||
|
this as WebPackExtension
|
||||||
|
bundleName = "main"
|
||||||
|
proxyUrl = "http://localhost:8080"
|
||||||
|
contentPath = file("src/main/web")
|
||||||
|
sourceMapEnabled = true
|
||||||
|
mode = "development"
|
||||||
|
}
|
||||||
|
}
|
26
dataforge-vis/dataforge-vis-spatial/build.gradle.kts
Normal file
26
dataforge-vis/dataforge-vis-spatial/build.gradle.kts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("multiplatform")
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
jvm()
|
||||||
|
js()
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
val commonMain by getting {
|
||||||
|
dependencies {
|
||||||
|
api(project(":dataforge-vis"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val jvmMain by getting {
|
||||||
|
dependencies {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val jsMain by getting {
|
||||||
|
dependencies {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
|
import hep.dataforge.meta.Meta
|
||||||
|
import hep.dataforge.vis.DisplayLeaf
|
||||||
|
import hep.dataforge.vis.DisplayObject
|
||||||
|
import hep.dataforge.vis.double
|
||||||
|
|
||||||
|
|
||||||
|
open class DisplayObject3D(parent: DisplayObject?, type: String, meta: Meta) : DisplayLeaf(parent, type, meta) {
|
||||||
|
var x by double(0.0)
|
||||||
|
var y by double(0.0)
|
||||||
|
var z by double(0.0)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val TYPE = "geometry.spatial"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Box3D(parent: DisplayObject?, meta: Meta) : DisplayObject3D(parent,
|
||||||
|
TYPE, meta) {
|
||||||
|
var xSize by double(1.0)
|
||||||
|
var ySize by double(1.0)
|
||||||
|
var zSize by double(1.0)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val TYPE = "geometry.spatial.box"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,143 @@
|
|||||||
|
package hep.dataforge.vis
|
||||||
|
|
||||||
|
import hep.dataforge.meta.*
|
||||||
|
import hep.dataforge.names.Name
|
||||||
|
import hep.dataforge.vis.DisplayObject.Companion.DEFAULT_TYPE
|
||||||
|
import hep.dataforge.vis.DisplayObject.Companion.META_KEY
|
||||||
|
import hep.dataforge.vis.DisplayObject.Companion.TAGS_KEY
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A root type for display hierarchy
|
||||||
|
*/
|
||||||
|
interface DisplayObject {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The parent object of this one. If null, this one is a root.
|
||||||
|
*/
|
||||||
|
val parent: DisplayObject?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of this object. Uses `.` notation. Empty type means untyped group
|
||||||
|
*/
|
||||||
|
val type: String
|
||||||
|
|
||||||
|
val properties: Styled
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val DEFAULT_TYPE = ""
|
||||||
|
const val TYPE_KEY = "@type"
|
||||||
|
const val CHILDREN_KEY = "@children"
|
||||||
|
const val META_KEY = "@meta"
|
||||||
|
const val TAGS_KEY = "@tags"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DisplayGroup : DisplayObject {
|
||||||
|
|
||||||
|
val children: List<DisplayObject>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a child object and notify listeners
|
||||||
|
*/
|
||||||
|
fun addChild(obj: DisplayObject)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a specific child and notify listeners
|
||||||
|
*/
|
||||||
|
fun removeChild(obj: DisplayObject)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add listener for children change
|
||||||
|
* TODO add detailed information into change listener
|
||||||
|
*/
|
||||||
|
fun onChildrenChange(owner: Any? = null, action: () -> Unit)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove children change listener
|
||||||
|
*/
|
||||||
|
fun removeChildrenChangeListener(owner: Any? = null)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the property of this display object of parent's if not found
|
||||||
|
*/
|
||||||
|
tailrec fun DisplayObject.getProperty(name: Name): MetaItem<*>? = properties[name] ?: parent?.getProperty(name)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A change listener for [DisplayObject] configuration.
|
||||||
|
*/
|
||||||
|
fun DisplayObject.onChange(owner: Any?, action: (Name, before: MetaItem<*>?, after: MetaItem<*>?) -> Unit) =
|
||||||
|
properties.style.onChange(owner, action)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all meta listeners with matching owners
|
||||||
|
*/
|
||||||
|
fun DisplayObject.removeChangeListener(owner: Any?) =
|
||||||
|
properties.style.removeListener(owner)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Additional meta not relevant to display
|
||||||
|
*/
|
||||||
|
val DisplayObject.meta: Meta get() = properties[META_KEY]?.node ?: EmptyMeta
|
||||||
|
|
||||||
|
val DisplayObject.tags: List<String> get() = properties[TAGS_KEY].stringList
|
||||||
|
|
||||||
|
internal data class ObjectListener(
|
||||||
|
val owner: Any?,
|
||||||
|
val action: () -> Unit
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic group of display objects
|
||||||
|
*/
|
||||||
|
open class DisplayNode(
|
||||||
|
override val parent: DisplayObject?,
|
||||||
|
override val type: String = DEFAULT_TYPE,
|
||||||
|
meta: Meta = EmptyMeta
|
||||||
|
) : DisplayGroup {
|
||||||
|
|
||||||
|
private val _children = ArrayList<DisplayObject>()
|
||||||
|
override val children: List<DisplayObject> get() = _children
|
||||||
|
override val properties = Styled(meta)
|
||||||
|
private val listeners = HashSet<ObjectListener>()
|
||||||
|
|
||||||
|
override fun addChild(obj: DisplayObject) {
|
||||||
|
// val before = _children[name]
|
||||||
|
// if (obj == null) {
|
||||||
|
// _children.remove(name)
|
||||||
|
// } else {
|
||||||
|
// _children[name] = obj
|
||||||
|
// }
|
||||||
|
// listeners.forEach { it.action(name, before, obj) }
|
||||||
|
_children.add(obj)
|
||||||
|
listeners.forEach { it.action() }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun removeChild(obj: DisplayObject) {
|
||||||
|
if(_children.remove(obj)){
|
||||||
|
listeners.forEach { it.action }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onChildrenChange(owner: Any?, action: () -> Unit) {
|
||||||
|
listeners.add(ObjectListener(owner, action))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun removeChildrenChangeListener(owner: Any?) {
|
||||||
|
listeners.removeAll { it.owner === owner }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic [DisplayObject] leaf element
|
||||||
|
*/
|
||||||
|
open class DisplayLeaf(
|
||||||
|
override val parent: DisplayObject?,
|
||||||
|
override val type: String,
|
||||||
|
meta: Meta = EmptyMeta
|
||||||
|
) : DisplayObject {
|
||||||
|
final override val properties = Styled(meta)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
|||||||
|
package hep.dataforge.vis
|
||||||
|
|
||||||
|
import hep.dataforge.meta.*
|
||||||
|
import hep.dataforge.values.Null
|
||||||
|
import hep.dataforge.values.Value
|
||||||
|
import kotlin.jvm.JvmName
|
||||||
|
|
||||||
|
fun DisplayObject.value(default: Value = Null, key: String? = null) =
|
||||||
|
ValueConfigDelegate(properties, key, default)
|
||||||
|
|
||||||
|
fun DisplayObject.string(default: String? = null, key: String? = null) =
|
||||||
|
StringConfigDelegate(properties, key, default)
|
||||||
|
|
||||||
|
fun DisplayObject.boolean(default: Boolean? = null, key: String? = null) =
|
||||||
|
BooleanConfigDelegate(properties, key, default)
|
||||||
|
|
||||||
|
fun DisplayObject.number(default: Number? = null, key: String? = null) =
|
||||||
|
NumberConfigDelegate(properties, key, default)
|
||||||
|
|
||||||
|
fun DisplayObject.double(default: Double? = null, key: String? = null) =
|
||||||
|
NumberConfigDelegate(properties, key, default).double
|
||||||
|
|
||||||
|
fun DisplayObject.int(default: Int? = null, key: String? = null) =
|
||||||
|
NumberConfigDelegate(properties, key, default).int
|
||||||
|
|
||||||
|
|
||||||
|
fun DisplayObject.node(key: String? = null) = StyledNodeDelegate(properties, key)
|
||||||
|
|
||||||
|
//fun <T : Configurable> Configurable.spec(spec: Specification<T>, key: String? = null) = ChildConfigDelegate<T>(key) { spec.wrap(this) }
|
||||||
|
|
||||||
|
@JvmName("safeString")
|
||||||
|
fun DisplayObject.string(default: String, key: String? = null) =
|
||||||
|
SafeStringConfigDelegate(properties, key, default)
|
||||||
|
|
||||||
|
@JvmName("safeBoolean")
|
||||||
|
fun DisplayObject.boolean(default: Boolean, key: String? = null) =
|
||||||
|
SafeBooleanConfigDelegate(properties, key, default)
|
||||||
|
|
||||||
|
@JvmName("safeNumber")
|
||||||
|
fun DisplayObject.number(default: Number, key: String? = null) =
|
||||||
|
SafeNumberConfigDelegate(properties, key, default)
|
||||||
|
|
||||||
|
@JvmName("safeDouble")
|
||||||
|
fun DisplayObject.double(default: Double, key: String? = null) =
|
||||||
|
SafeNumberConfigDelegate(properties, key, default).double
|
||||||
|
|
||||||
|
inline fun <reified E : Enum<E>> DisplayObject.enum(default: E, key: String? = null) =
|
||||||
|
SafeEnumvConfigDelegate(properties, key, default) { enumValueOf(it) }
|
@ -0,0 +1,40 @@
|
|||||||
|
package hep.dataforge.vis
|
||||||
|
|
||||||
|
import hep.dataforge.names.Name
|
||||||
|
import hep.dataforge.names.NameToken
|
||||||
|
|
||||||
|
interface NamedObject : DisplayObject {
|
||||||
|
val name: String
|
||||||
|
|
||||||
|
operator fun get(nameToken: NameToken): DisplayGroup?
|
||||||
|
|
||||||
|
operator fun set(nameToken: NameToken, group: DisplayGroup)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively get a child
|
||||||
|
*/
|
||||||
|
tailrec operator fun NamedObject.get(name: Name): DisplayObject? = when (name.length) {
|
||||||
|
0 -> this
|
||||||
|
1 -> this[name[0]]
|
||||||
|
else -> name.first()?.let { this[it] as? NamedObject }?.get(name.cutFirst())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set given object creating intermediate empty groups if needed
|
||||||
|
* @param name - the full name of a child
|
||||||
|
* @param objFactory - a function that creates child object from parent (to avoid mutable parent parameter)
|
||||||
|
*/
|
||||||
|
fun NamedObject.set(name: Name, objFactory: (parent: DisplayObject) -> DisplayGroup): Unit = when (name.length) {
|
||||||
|
0 -> error("Can't set object with empty name")
|
||||||
|
1 -> set(name[0], objFactory(this))
|
||||||
|
else -> (this[name.first()!!] ?: DisplayNode(this))
|
||||||
|
.run {
|
||||||
|
if (this is NamedObject) {
|
||||||
|
this.set(name.cutFirst(), objFactory)
|
||||||
|
} else {
|
||||||
|
error("Can't assign child to a leaf element $this")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
gradle.properties
Normal file
7
gradle.properties
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Enable official Kotlin Code Style in the IDE.
|
||||||
|
kotlin.code.style=official
|
||||||
|
|
||||||
|
artifactoryUser=darksnake
|
||||||
|
artifactoryPassword=nortlander
|
||||||
|
bintrayUser=altavir
|
||||||
|
bintrayApiKey=9dcb7a779986e1b08898980269b6d428cadda0c3
|
31
gradle/artifactory.gradle
Normal file
31
gradle/artifactory.gradle
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
apply plugin: "com.jfrog.artifactory"
|
||||||
|
|
||||||
|
artifactory {
|
||||||
|
def artifactory_user = project.hasProperty('artifactoryUser') ? project.property('artifactoryUser') : ""
|
||||||
|
def artifactory_password = project.hasProperty('artifactoryPassword') ? project.property('artifactoryPassword') : ""
|
||||||
|
def artifactory_contextUrl = 'http://npm.mipt.ru:8081/artifactory'
|
||||||
|
|
||||||
|
contextUrl = artifactory_contextUrl //The base Artifactory URL if not overridden by the publisher/resolver
|
||||||
|
publish {
|
||||||
|
repository {
|
||||||
|
repoKey = 'gradle-dev-local'
|
||||||
|
username = artifactory_user
|
||||||
|
password = artifactory_password
|
||||||
|
}
|
||||||
|
|
||||||
|
defaults {
|
||||||
|
publications('jvm', 'js', 'kotlinMultiplatform', 'metadata')
|
||||||
|
publishBuildInfo = false
|
||||||
|
publishArtifacts = true
|
||||||
|
publishPom = true
|
||||||
|
publishIvy = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resolve {
|
||||||
|
repository {
|
||||||
|
repoKey = 'gradle-dev'
|
||||||
|
username = artifactory_user
|
||||||
|
password = artifactory_password
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
85
gradle/bintray.gradle
Normal file
85
gradle/bintray.gradle
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
apply plugin: 'com.jfrog.bintray'
|
||||||
|
|
||||||
|
def vcs = "https://github.com/mipt-npm/kmath"
|
||||||
|
|
||||||
|
def pomConfig = {
|
||||||
|
licenses {
|
||||||
|
license {
|
||||||
|
name "The Apache Software License, Version 2.0"
|
||||||
|
url "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
|
distribution "repo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
developers {
|
||||||
|
developer {
|
||||||
|
id "MIPT-NPM"
|
||||||
|
name "MIPT nuclear physics methods laboratory"
|
||||||
|
organization "MIPT"
|
||||||
|
organizationUrl "http://npm.mipt.ru"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scm {
|
||||||
|
url vcs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
project.ext.configureMavenCentralMetadata = { pom ->
|
||||||
|
def root = asNode()
|
||||||
|
root.appendNode('name', project.name)
|
||||||
|
root.appendNode('description', project.description)
|
||||||
|
root.appendNode('url', vcs)
|
||||||
|
root.children().last() + pomConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
project.ext.configurePom = pomConfig
|
||||||
|
|
||||||
|
|
||||||
|
// Configure publishing
|
||||||
|
publishing {
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
url = "https://bintray.com/mipt-npm/scientifik"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process each publication we have in this project
|
||||||
|
publications.all { publication ->
|
||||||
|
// apply changes to pom.xml files, see pom.gradle
|
||||||
|
pom.withXml(configureMavenCentralMetadata)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bintray {
|
||||||
|
user = project.hasProperty('bintrayUser') ? project.property('bintrayUser') : System.getenv('BINTRAY_USER')
|
||||||
|
key = project.hasProperty('bintrayApiKey') ? project.property('bintrayApiKey') : System.getenv('BINTRAY_API_KEY')
|
||||||
|
publish = true
|
||||||
|
override = true // for multi-platform Kotlin/Native publishing
|
||||||
|
|
||||||
|
pkg {
|
||||||
|
userOrg = "mipt-npm"
|
||||||
|
repo = "scientifik"
|
||||||
|
name = "scientifik.kmath"
|
||||||
|
issueTrackerUrl = "https://github.com/mipt-npm/kmath/issues"
|
||||||
|
licenses = ['Apache-2.0']
|
||||||
|
vcsUrl = vcs
|
||||||
|
version {
|
||||||
|
name = project.version
|
||||||
|
vcsTag = project.version
|
||||||
|
released = new Date()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bintrayUpload.dependsOn publishToMavenLocal
|
||||||
|
|
||||||
|
// This is for easier debugging of bintray uploading problems
|
||||||
|
bintrayUpload.doFirst {
|
||||||
|
publications = project.publishing.publications.findAll {
|
||||||
|
!it.name.contains('-test') && it.name != 'kotlinMultiplatform'
|
||||||
|
}.collect {
|
||||||
|
println("Uploading artifact '$it.groupId:$it.artifactId:$it.version' from publication '$it.name'")
|
||||||
|
it.name//https://github.com/bintray/gradle-bintray-plugin/issues/256
|
||||||
|
}
|
||||||
|
}
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
5
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-bin.zip
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
172
gradlew
vendored
Normal file
172
gradlew
vendored
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS='"-Xmx64m"'
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn () {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
nonstop=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
NONSTOP* )
|
||||||
|
nonstop=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=$((i+1))
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
(0) set -- ;;
|
||||||
|
(1) set -- "$args0" ;;
|
||||||
|
(2) set -- "$args0" "$args1" ;;
|
||||||
|
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Escape application args
|
||||||
|
save () {
|
||||||
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
|
echo " "
|
||||||
|
}
|
||||||
|
APP_ARGS=$(save "$@")
|
||||||
|
|
||||||
|
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||||
|
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||||
|
|
||||||
|
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||||
|
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
84
gradlew.bat
vendored
Normal file
84
gradlew.bat
vendored
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS="-Xmx64m"
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windows variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
@ -1,11 +1,22 @@
|
|||||||
pluginManagement {
|
pluginManagement {
|
||||||
repositories {
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
jcenter()
|
jcenter()
|
||||||
maven("https://plugins.gradle.org/m2/")
|
gradlePluginPortal()
|
||||||
|
maven("https://dl.bintray.com/kotlin/kotlin-eap/")
|
||||||
|
}
|
||||||
|
resolutionStrategy {
|
||||||
|
eachPlugin {
|
||||||
|
when (requested.id.id) {
|
||||||
|
"kotlinx-atomicfu" -> useModule("org.jetbrains.kotlinx:atomicfu-gradle-plugin:${requested.version}")
|
||||||
|
"kotlin-multiplatform" -> useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}")
|
||||||
|
"org.jetbrains.kotlin.frontend" -> useModule("org.jetbrains.kotlin:kotlin-frontend-plugin:0.0.45")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//enableFeaturePreview("GRADLE_METADATA")
|
enableFeaturePreview("GRADLE_METADATA")
|
||||||
|
|
||||||
rootProject.name = "dataforge-core"
|
rootProject.name = "dataforge-core"
|
||||||
include(
|
include(
|
||||||
@ -15,5 +26,8 @@ include(
|
|||||||
":dataforge-data",
|
":dataforge-data",
|
||||||
":dataforge-io",
|
":dataforge-io",
|
||||||
":dataforge-workspace",
|
":dataforge-workspace",
|
||||||
":dataforge-scripting"
|
":dataforge-scripting",
|
||||||
|
":dataforge-vis",
|
||||||
|
":dataforge-vis:dataforge-vis-spatial",
|
||||||
|
":dataforge-vis:dataforge-vis-fx"
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user