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
|
||||
|
||||
artifactory.gradle
|
@ -1,19 +1,25 @@
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
|
||||
|
||||
buildscript {
|
||||
val kotlinVersion: String by rootProject.extra("1.3.20")
|
||||
val ioVersion: String by rootProject.extra("0.1.4")
|
||||
val kotlinVersion: String by rootProject.extra("1.3.21")
|
||||
val ioVersion: String by rootProject.extra("0.1.5")
|
||||
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 {
|
||||
jcenter()
|
||||
maven("https://dl.bintray.com/kotlin/kotlin-eap")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
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("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 {
|
||||
apply(plugin = "maven")
|
||||
apply(plugin = "maven-publish")
|
||||
apply(plugin = "com.jfrog.artifactory")
|
||||
|
||||
@ -32,8 +39,17 @@ allprojects {
|
||||
}
|
||||
|
||||
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 {
|
||||
jvm {
|
||||
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}"
|
||||
}
|
||||
}
|
||||
|
||||
// Create empty jar for sources classifier to satisfy maven requirements
|
||||
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 }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (file("artifactory.gradle").exists()) {
|
||||
apply(from = "artifactory.gradle")
|
||||
}
|
||||
|
||||
|
@ -2,10 +2,6 @@ plugins {
|
||||
kotlin("multiplatform")
|
||||
}
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvm()
|
||||
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
|
||||
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.NameToken
|
||||
import hep.dataforge.names.toName
|
||||
|
||||
//TODO add validator to configuration
|
||||
@ -16,8 +17,14 @@ open class Config : MutableMetaNode<Config>() {
|
||||
override fun wrap(name: Name, meta: Meta): Config = meta.toConfig()
|
||||
|
||||
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 ->
|
||||
this.items.mapValues { entry ->
|
||||
val item = entry.value
|
||||
|
@ -2,6 +2,7 @@ package hep.dataforge.meta
|
||||
|
||||
import hep.dataforge.values.Null
|
||||
import hep.dataforge.values.Value
|
||||
import hep.dataforge.values.asValue
|
||||
import kotlin.jvm.JvmName
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
import kotlin.properties.ReadWriteProperty
|
||||
@ -11,247 +12,348 @@ import kotlin.reflect.KProperty
|
||||
|
||||
//TODO add caching for sealed nodes
|
||||
|
||||
class ValueDelegate(private val key: String? = null, private val default: Value? = null) :
|
||||
ReadOnlyProperty<Metoid, Value?> {
|
||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): Value? {
|
||||
return thisRef.meta[key ?: property.name]?.value ?: default
|
||||
class ValueDelegate(val meta: Meta, private val key: String? = null, private val default: Value? = null) :
|
||||
ReadOnlyProperty<Any?, Value?> {
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Value? {
|
||||
return meta[key ?: property.name]?.value ?: default
|
||||
}
|
||||
}
|
||||
|
||||
class StringDelegate(private val key: String? = null, private val default: String? = null) :
|
||||
ReadOnlyProperty<Metoid, String?> {
|
||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): String? {
|
||||
return thisRef.meta[key ?: property.name]?.string ?: default
|
||||
class StringDelegate(val meta: Meta, private val key: String? = null, private val default: String? = null) :
|
||||
ReadOnlyProperty<Any?, String?> {
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>): String? {
|
||||
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?> {
|
||||
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) :
|
||||
ReadOnlyProperty<Metoid, Number?> {
|
||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): Number? {
|
||||
return thisRef.meta[key ?: property.name]?.number ?: default
|
||||
class NumberDelegate(val meta: Meta, private val key: String? = null, private val default: Number? = null) :
|
||||
ReadOnlyProperty<Any?, Number?> {
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Number? {
|
||||
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
|
||||
|
||||
class SafeStringDelegate(private val key: String? = null, private val default: String) :
|
||||
ReadOnlyProperty<Metoid, String> {
|
||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): String {
|
||||
return thisRef.meta[key ?: property.name]?.string ?: default
|
||||
class SafeStringDelegate(val meta: Meta, private val key: String? = null, private val default: String) :
|
||||
ReadOnlyProperty<Any?, String> {
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>): String {
|
||||
return meta[key ?: property.name]?.string ?: default
|
||||
}
|
||||
}
|
||||
|
||||
class SafeBooleanDelegate(private val key: String? = null, private val default: Boolean) :
|
||||
ReadOnlyProperty<Metoid, Boolean> {
|
||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): Boolean {
|
||||
return thisRef.meta[key ?: property.name]?.boolean ?: default
|
||||
class SafeBooleanDelegate(val meta: Meta, private val key: String? = null, private val default: Boolean) :
|
||||
ReadOnlyProperty<Any?, Boolean> {
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Boolean {
|
||||
return meta[key ?: property.name]?.boolean ?: default
|
||||
}
|
||||
}
|
||||
|
||||
class SafeNumberDelegate(private val key: String? = null, private val default: Number) :
|
||||
ReadOnlyProperty<Metoid, Number> {
|
||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): Number {
|
||||
return thisRef.meta[key ?: property.name]?.number ?: default
|
||||
class SafeNumberDelegate(val meta: Meta, private val key: String? = null, private val default: Number) :
|
||||
ReadOnlyProperty<Any?, Number> {
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Number {
|
||||
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>>(
|
||||
val meta: Meta,
|
||||
private val key: String? = null,
|
||||
private val default: E,
|
||||
private val resolver: (String) -> E
|
||||
) : ReadOnlyProperty<Metoid, E> {
|
||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): E {
|
||||
return (thisRef.meta[key ?: property.name]?.string)?.let { resolver(it) } ?: default
|
||||
) : ReadOnlyProperty<Any?, E> {
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>): E {
|
||||
return (meta[key ?: property.name]?.string)?.let { resolver(it) } ?: default
|
||||
}
|
||||
}
|
||||
|
||||
//Child node delegate
|
||||
|
||||
class ChildDelegate<T>(private val key: String? = null, private val converter: (Meta) -> T) :
|
||||
ReadOnlyProperty<Metoid, T?> {
|
||||
override fun getValue(thisRef: Metoid, property: KProperty<*>): T? {
|
||||
return thisRef.meta[key ?: property.name]?.node?.let { converter(it) }
|
||||
class ChildDelegate<T>(val meta: Meta, private val key: String? = null, private val converter: (Meta) -> T) :
|
||||
ReadOnlyProperty<Any?, T?> {
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>): T? {
|
||||
return meta[key ?: property.name]?.node?.let { converter(it) }
|
||||
}
|
||||
}
|
||||
|
||||
//Read-only delegates
|
||||
//Read-only delegates for Metas
|
||||
|
||||
/**
|
||||
* 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 <T : Metoid> Metoid.child(key: String? = null, converter: (Meta) -> T) = ChildDelegate(key, converter)
|
||||
fun Meta.child(key: String? = null) = ChildDelegate(this, key) { it }
|
||||
|
||||
@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")
|
||||
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")
|
||||
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 */
|
||||
|
||||
class ValueConfigDelegate(private val key: String? = null, private val default: Value? = null) :
|
||||
ReadWriteProperty<Configurable, Value?> {
|
||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): Value? {
|
||||
return thisRef.config[key ?: property.name]?.value ?: default
|
||||
class ValueConfigDelegate<M : MutableMeta<M>>(
|
||||
val config: M,
|
||||
private val key: String? = null,
|
||||
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
|
||||
if (value == null) {
|
||||
thisRef.config.remove(name)
|
||||
config.remove(name)
|
||||
} else {
|
||||
thisRef.config[name] = value
|
||||
config.setValue(name, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class StringConfigDelegate(private val key: String? = null, private val default: String? = null) :
|
||||
ReadWriteProperty<Configurable, String?> {
|
||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): String? {
|
||||
return thisRef.config[key ?: property.name]?.string ?: default
|
||||
class StringConfigDelegate<M : MutableMeta<M>>(
|
||||
val config: M,
|
||||
private val key: String? = null,
|
||||
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?) {
|
||||
thisRef.config[key ?: property.name] = value
|
||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: String?) {
|
||||
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) :
|
||||
ReadWriteProperty<Configurable, Boolean?> {
|
||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): Boolean? {
|
||||
return thisRef.config[key ?: property.name]?.boolean ?: default
|
||||
class BooleanConfigDelegate<M : MutableMeta<M>>(
|
||||
val config: M,
|
||||
private val key: String? = null,
|
||||
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?) {
|
||||
thisRef.config[key ?: property.name] = value
|
||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Boolean?) {
|
||||
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) :
|
||||
ReadWriteProperty<Configurable, Number?> {
|
||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): Number? {
|
||||
return thisRef.config[key ?: property.name]?.number ?: default
|
||||
class NumberConfigDelegate<M : MutableMeta<M>>(
|
||||
val config: M,
|
||||
private val key: String? = null,
|
||||
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?) {
|
||||
thisRef.config[key ?: property.name] = value
|
||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Number?) {
|
||||
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
|
||||
|
||||
class SafeStringConfigDelegate(private val key: String? = null, private val default: String) :
|
||||
ReadWriteProperty<Configurable, String> {
|
||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): String {
|
||||
return thisRef.config[key ?: property.name]?.string ?: default
|
||||
class SafeStringConfigDelegate<M : MutableMeta<M>>(
|
||||
val config: M,
|
||||
private val key: String? = null,
|
||||
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) {
|
||||
thisRef.config[key ?: property.name] = value
|
||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
|
||||
config.setValue(key ?: property.name, value.asValue())
|
||||
}
|
||||
}
|
||||
|
||||
class SafeBooleanConfigDelegate(private val key: String? = null, private val default: Boolean) :
|
||||
ReadWriteProperty<Configurable, Boolean> {
|
||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): Boolean {
|
||||
return thisRef.config[key ?: property.name]?.boolean ?: default
|
||||
class SafeBooleanConfigDelegate<M : MutableMeta<M>>(
|
||||
val config: M,
|
||||
private val key: String? = null,
|
||||
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) {
|
||||
thisRef.config[key ?: property.name] = value
|
||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Boolean) {
|
||||
config.setValue(key ?: property.name, value.asValue())
|
||||
}
|
||||
}
|
||||
|
||||
class SafeNumberConfigDelegate(private val key: String? = null, private val default: Number) :
|
||||
ReadWriteProperty<Configurable, Number> {
|
||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): Number {
|
||||
return thisRef.config[key ?: property.name]?.number ?: default
|
||||
class SafeNumberConfigDelegate<M : MutableMeta<M>>(
|
||||
val config: M,
|
||||
private val key: String? = null,
|
||||
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) {
|
||||
thisRef.config[key ?: property.name] = value
|
||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Number) {
|
||||
config.setValue(key ?: property.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 })
|
||||
}
|
||||
|
||||
class SafeEnumvConfigDelegate<E : Enum<E>>(
|
||||
class SafeEnumvConfigDelegate<M : MutableMeta<M>, E : Enum<E>>(
|
||||
val config: M,
|
||||
private val key: String? = null,
|
||||
private val default: E,
|
||||
private val resolver: (String) -> E
|
||||
) : ReadWriteProperty<Configurable, E> {
|
||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): E {
|
||||
return (thisRef.config[key ?: property.name]?.string)?.let { resolver(it) } ?: default
|
||||
) : ReadWriteProperty<Any?, E> {
|
||||
override fun getValue(thisRef: Any?, property: KProperty<*>): E {
|
||||
return (config[key ?: property.name]?.string)?.let { resolver(it) } ?: default
|
||||
}
|
||||
|
||||
override fun setValue(thisRef: Configurable, property: KProperty<*>, value: E) {
|
||||
thisRef.config[key ?: property.name] = value.name
|
||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: E) {
|
||||
config.setValue(key ?: property.name, value.name.asValue())
|
||||
}
|
||||
}
|
||||
|
||||
//Child node delegate
|
||||
|
||||
class ChildConfigDelegate<T : Configurable>(private val key: String? = null, private val converter: (Config) -> T) :
|
||||
ReadWriteProperty<Configurable, T> {
|
||||
override fun getValue(thisRef: Configurable, property: KProperty<*>): T {
|
||||
return converter(thisRef.config[key ?: property.name]?.node ?: Config())
|
||||
class MetaNodeDelegate<M : MutableMetaNode<M>>(
|
||||
val config: M,
|
||||
private val key: String? = null
|
||||
) : 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) {
|
||||
thisRef.config[key ?: property.name] = value.config
|
||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Meta) {
|
||||
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
|
||||
|
||||
/**
|
||||
* 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 <T : Configurable> Configurable.child(key: String? = null, converter: (Config) -> T) =
|
||||
ChildConfigDelegate(key, converter)
|
||||
fun <M : MutableMetaNode<M>> M.child(key: String? = null) = MetaNodeDelegate(this, key)
|
||||
|
||||
//fun <T : Configurable> Configurable.spec(spec: Specification<T>, key: String? = null) = ChildConfigDelegate<T>(key) { spec.wrap(this) }
|
||||
|
||||
@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")
|
||||
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")
|
||||
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) =
|
||||
SafeEnumvConfigDelegate(key, default) { enumValueOf(it) }
|
||||
inline fun <M : MutableMeta<M>, reified E : Enum<E>> M.enum(default: E, key: String? = null) =
|
||||
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
|
||||
|
||||
/**
|
||||
* 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,21 +102,26 @@ 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
|
||||
*/
|
||||
abstract class MetaNode<M : MetaNode<M>> : Meta {
|
||||
abstract override val items: Map<NameToken, MetaItem<M>>
|
||||
interface MetaNode<M : MetaNode<M>> : Meta {
|
||||
override val items: Map<NameToken, MetaItem<M>>
|
||||
}
|
||||
|
||||
operator fun get(name: Name): MetaItem<M>? {
|
||||
return name.first()?.let { token ->
|
||||
val tail = name.cutFirst()
|
||||
when (tail.length) {
|
||||
0 -> items[token]
|
||||
else -> items[token]?.node?.get(tail)
|
||||
}
|
||||
operator fun <M : MetaNode<M>> MetaNode<M>.get(name: Name): MetaItem<M>? {
|
||||
return name.first()?.let { token ->
|
||||
val tail = name.cutFirst()
|
||||
when (tail.length) {
|
||||
0 -> items[token]
|
||||
else -> items[token]?.node?.get(tail)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
if (this === other) return true
|
||||
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
|
||||
*/
|
||||
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
|
||||
@ -154,17 +160,19 @@ object EmptyMeta : Meta {
|
||||
* Unsafe methods to access values and nodes directly from [MetaItem]
|
||||
*/
|
||||
|
||||
val MetaItem<*>.value
|
||||
val MetaItem<*>?.value
|
||||
get() = (this as? MetaItem.ValueItem)?.value
|
||||
?: (this.node[VALUE_KEY] as? MetaItem.ValueItem)?.value
|
||||
?: error("Trying to interpret node meta item as value item")
|
||||
val MetaItem<*>.string get() = value.string
|
||||
val MetaItem<*>.boolean get() = value.boolean
|
||||
val MetaItem<*>.number get() = value.number
|
||||
val MetaItem<*>.double get() = number.toDouble()
|
||||
val MetaItem<*>.int get() = number.toInt()
|
||||
val MetaItem<*>.long get() = number.toLong()
|
||||
val MetaItem<*>.short get() = number.toShort()
|
||||
?: (this?.node?.get(VALUE_KEY) as? MetaItem.ValueItem)?.value
|
||||
|
||||
val MetaItem<*>?.string get() = value?.string
|
||||
val MetaItem<*>?.boolean get() = value?.boolean
|
||||
val MetaItem<*>?.number get() = value?.number
|
||||
val MetaItem<*>?.double get() = number?.toDouble()
|
||||
val MetaItem<*>?.int get() = number?.toInt()
|
||||
val MetaItem<*>?.long get() = number?.toLong()
|
||||
val MetaItem<*>?.short get() = number?.toShort()
|
||||
|
||||
val MetaItem<*>?.stringList get() = value?.list?.map { it.string } ?: emptyList()
|
||||
|
||||
val <M : Meta> MetaItem<M>.node: M
|
||||
get() = when (this) {
|
||||
|
@ -6,19 +6,17 @@ import hep.dataforge.names.plus
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.values.Value
|
||||
|
||||
class MetaListener(
|
||||
internal data class MetaListener(
|
||||
val owner: Any? = null,
|
||||
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>>
|
||||
operator fun set(name: Name, item: MetaItem<M>?)
|
||||
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.
|
||||
*/
|
||||
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>()
|
||||
|
||||
/**
|
||||
@ -39,7 +37,7 @@ abstract class MutableMetaNode<M : MutableMetaNode<M>> : MetaNode<M>(), MutableM
|
||||
/**
|
||||
* Remove all listeners belonging to given owner
|
||||
*/
|
||||
override fun removeListener(owner: Any) {
|
||||
override fun removeListener(owner: Any?) {
|
||||
listeners.removeAll { it.owner === owner }
|
||||
}
|
||||
|
||||
@ -49,7 +47,7 @@ abstract class MutableMetaNode<M : MutableMetaNode<M>> : MetaNode<M>(), MutableM
|
||||
get() = _items
|
||||
|
||||
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>?) {
|
||||
@ -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 meta the node itself
|
||||
*/
|
||||
abstract fun wrap(name: Name, meta: Meta): M
|
||||
internal abstract fun wrap(name: Name, meta: Meta): M
|
||||
|
||||
/**
|
||||
* Create empty node
|
||||
*/
|
||||
abstract fun empty(): M
|
||||
internal abstract fun empty(): M
|
||||
|
||||
override operator fun set(name: Name, item: MetaItem<M>?) {
|
||||
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>> M.remove(name: String) = remove(name.toName())
|
||||
fun <M : MutableMeta<M>> MutableMeta<M>.remove(name: Name) = set(name, null)
|
||||
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>> 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>> M.setItem(token: NameToken, item: MetaItem<M>?) = set(token.toName(), item)
|
||||
fun <M : MutableMeta<M>> MutableMeta<M>.setValue(name: Name, value: Value) = set(name, MetaItem.ValueItem(value))
|
||||
fun <M : MutableMeta<M>> MutableMeta<M>.setItem(name: String, item: MetaItem<M>) = set(name.toName(), item)
|
||||
fun <M : MutableMeta<M>> MutableMeta<M>.setValue(name: String, value: Value) =
|
||||
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 : MutableMetaNode<M>> M.setNode(name: String, node: Meta) = setNode(name.toName(), node)
|
||||
fun <M : MutableMeta<M>> MutableMeta<M>.setItem(token: NameToken, item: MetaItem<M>?) = set(token.toName(), item)
|
||||
|
||||
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
|
||||
@ -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?) {
|
||||
when (value) {
|
||||
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)
|
||||
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) }
|
||||
|
||||
|
||||
fun <C : Specification> Specification.spec(spec: SpecificationCompanion<C>, key: String? = null) =
|
||||
ChildConfigDelegate<C>(key) { spec.wrap(config) }
|
||||
fun <M : MutableMetaNode<M>, C : Specification> Specification.spec(
|
||||
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 {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
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"
|
||||
include(
|
||||
@ -15,5 +26,8 @@ include(
|
||||
":dataforge-data",
|
||||
":dataforge-io",
|
||||
":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