Refactor VisionForge global

This commit is contained in:
Alexander Nozik 2021-02-26 13:03:40 +03:00
parent a5bfa0f147
commit bc15d9241b
26 changed files with 136 additions and 138 deletions

View File

@ -12,7 +12,6 @@ val fxVersion by extra("14")
allprojects {
repositories {
mavenLocal()
mavenCentral()
jcenter()
maven("https://kotlin.bintray.com/kotlin-js-wrappers")

View File

@ -3,15 +3,14 @@ package hep.dataforge.playground
import hep.dataforge.misc.DFExperimental
import hep.dataforge.vision.Vision
import hep.dataforge.vision.VisionForge
import hep.dataforge.vision.VisionManager
import hep.dataforge.vision.gdml.toVision
import hep.dataforge.vision.html.HtmlVisionFragment
import hep.dataforge.vision.html.Page
import hep.dataforge.vision.html.embedVisionFragment
import hep.dataforge.vision.html.fragment
import hep.dataforge.vision.plotly.toVision
import hep.dataforge.vision.plotly.withPlotly
import hep.dataforge.vision.solid.withSolids
import hep.dataforge.vision.plotly.usePlotly
import hep.dataforge.vision.solid.useSolids
import hep.dataforge.vision.visionManager
import kotlinx.html.div
import kotlinx.html.id
@ -44,7 +43,7 @@ internal class VisionForgePlayGroundForJupyter : JupyterIntegration() {
}
script {
type = "text/javascript"
unsafe { +"renderVisionsAt(\"$id\");" }
unsafe { +"VisionForge.renderVisionsAt(\"$id\");" }
}
}
@ -52,7 +51,8 @@ internal class VisionForgePlayGroundForJupyter : JupyterIntegration() {
resource(jsResource)
onLoaded {
VisionForge.withPlotly().withSolids()
VisionForge.useSolids()
VisionForge.usePlotly()
}
import(
@ -66,14 +66,14 @@ internal class VisionForgePlayGroundForJupyter : JupyterIntegration() {
import("hep.dataforge.vision.VisionForge")
render<Gdml> { gdmlModel ->
val fragment = VisionManager.fragment {
val fragment = VisionForge.fragment {
vision(gdmlModel.toVision())
}
HTML(produceHtmlVisionString(fragment))
}
render<Vision> { vision ->
val fragment = VisionManager.fragment {
val fragment = VisionForge.fragment {
vision(vision)
}
@ -81,7 +81,7 @@ internal class VisionForgePlayGroundForJupyter : JupyterIntegration() {
}
render<Plot> { plot ->
val fragment = VisionManager.fragment {
val fragment = VisionForge.fragment {
vision(plot.toVision())
}

View File

@ -1,9 +1,8 @@
//import hep.dataforge.vision.plotly.withPlotly
import hep.dataforge.vision.VisionForge
import hep.dataforge.vision.plotly.usePlotly
import hep.dataforge.vision.renderVisionsInWindow
import hep.dataforge.vision.solid.three.useThreeJs
fun main() {
fun main(): Unit = VisionForge.run{
usePlotly()
useThreeJs()
renderVisionsInWindow()

View File

@ -2,11 +2,11 @@ package hep.dataforge.vision.examples
import hep.dataforge.misc.DFExperimental
import hep.dataforge.vision.VisionForge
import hep.dataforge.vision.VisionManager
import hep.dataforge.vision.gdml.toVision
import hep.dataforge.vision.html.ResourceLocation
import hep.dataforge.vision.html.fragment
import hep.dataforge.vision.solid.withSolids
import hep.dataforge.vision.invoke
import hep.dataforge.vision.solid.useSolids
import space.kscience.gdml.*
internal val cubes = Gdml {
@ -60,12 +60,12 @@ internal val cubes = Gdml {
}
@DFExperimental
fun main() {
val content = VisionManager.fragment {
fun main() = VisionForge {
val content = VisionForge.fragment {
vision("canvas") {
cubes.toVision()
}
}
VisionForge.withSolids().makeVisionFile(content, resourceLocation = ResourceLocation.SYSTEM)
useSolids()
makeVisionFile(content, resourceLocation = ResourceLocation.SYSTEM)
}

View File

@ -2,25 +2,25 @@ package hep.dataforge.vision.examples
import hep.dataforge.misc.DFExperimental
import hep.dataforge.vision.VisionForge
import hep.dataforge.vision.VisionManager
import hep.dataforge.vision.html.ResourceLocation
import hep.dataforge.vision.html.fragment
import hep.dataforge.vision.invoke
import hep.dataforge.vision.plotly.plotly
import hep.dataforge.vision.plotly.withPlotly
import hep.dataforge.vision.plotly.usePlotly
import kscience.plotly.scatter
@DFExperimental
fun main() {
val fragment = VisionManager.fragment {
fun main() = VisionForge {
val fragment = fragment {
vision {
plotly {
scatter {
x(1,2,3)
y(5,8,7)
x(1, 2, 3)
y(5, 8, 7)
}
}
}
}
VisionForge.withPlotly().makeVisionFile(fragment, resourceLocation = ResourceLocation.SYSTEM)
usePlotly()
makeVisionFile(fragment, resourceLocation = ResourceLocation.SYSTEM)
}

View File

@ -2,19 +2,19 @@ package hep.dataforge.vision.examples
import hep.dataforge.misc.DFExperimental
import hep.dataforge.vision.VisionForge
import hep.dataforge.vision.VisionManager
import hep.dataforge.vision.html.ResourceLocation
import hep.dataforge.vision.html.fragment
import hep.dataforge.vision.invoke
import hep.dataforge.vision.solid.*
import kotlinx.html.h1
import java.nio.file.Paths
import kotlin.random.Random
@OptIn(DFExperimental::class)
fun main() {
fun main() = VisionForge.invoke {
val random = Random(112233)
val fragment = VisionManager.fragment {
val fragment = fragment {
h1 { +"Happy new year!" }
vision {
solid {
@ -33,8 +33,8 @@ fun main() {
}
}
}
VisionForge.withSolids().makeVisionFile(
useSolids()
makeVisionFile(
fragment,
Paths.get("randomSpheres.html"),
resourceLocation = ResourceLocation.EMBED

View File

@ -1,8 +1,8 @@
package hep.dataforge.vision.examples
import hep.dataforge.context.Context
import hep.dataforge.misc.DFExperimental
import hep.dataforge.vision.Vision
import hep.dataforge.vision.VisionForge
import hep.dataforge.vision.html.HtmlVisionFragment
import hep.dataforge.vision.html.ResourceLocation
import hep.dataforge.vision.html.page
@ -19,7 +19,7 @@ public fun VisionServer.usePlayground(): Unit {
}
@DFExperimental
public fun Context.makeVisionFile(
public fun VisionForge.makeVisionFile(
content: HtmlVisionFragment,
path: Path? = null,
title: String = "VisionForge page",
@ -33,7 +33,7 @@ public fun Context.makeVisionFile(
}
@DFExperimental
public fun Context.makeVisionFile(
public fun VisionForge.makeVisionFile(
vision: Vision,
path: Path? = null,
title: String = "VisionForge page",

View File

@ -2,22 +2,22 @@ package hep.dataforge.vision.examples
import hep.dataforge.misc.DFExperimental
import hep.dataforge.vision.VisionForge
import hep.dataforge.vision.VisionManager
import hep.dataforge.vision.html.ResourceLocation
import hep.dataforge.vision.html.fragment
import hep.dataforge.vision.invoke
import hep.dataforge.vision.solid.box
import hep.dataforge.vision.solid.solid
import hep.dataforge.vision.solid.withSolids
import hep.dataforge.vision.solid.useSolids
@DFExperimental
fun main() {
val content = VisionManager.fragment {
fun main() = VisionForge.invoke {
val content = fragment {
vision("canvas") {
solid {
box(100, 100, 100)
}
}
}
VisionForge.withSolids().makeVisionFile(content, resourceLocation = ResourceLocation.SYSTEM)
useSolids()
makeVisionFile(content, resourceLocation = ResourceLocation.SYSTEM)
}

View File

@ -3,10 +3,8 @@ pluginManagement {
val toolsVersion = "0.8.3"
repositories {
mavenLocal()
maven("https://repo.kotlin.link")
mavenCentral()
jcenter()
gradlePluginPortal()
}

View File

@ -1,8 +1,12 @@
package hep.dataforge.vision
import hep.dataforge.context.Context
import hep.dataforge.context.PluginManager
/**
* A drop-in replacement for [Global] for VisionForge activities
*/
public expect val VisionForge: Context
public expect object VisionForge
public expect val VisionForge.context: Context
public val VisionForge.plugins: PluginManager get() = context.plugins
public val VisionForge.visionManager: VisionManager get() = plugins.fetch(VisionManager)

View File

@ -26,8 +26,9 @@ public open class VisionGroupBase(
override val children: Map<NameToken, Vision> get() = childrenInternal
init {
childrenInternal.values.forEach {
it.parent = this
childrenInternal.forEach { (token, child) ->
if (child.parent != null && child.parent != this) error("Can't reassign existing parent for child $token")
child.parent = this
}
}
@ -78,7 +79,7 @@ public open class VisionGroupBase(
childrenInternal[token] = child
}
child.parent !== this -> {
error("Can't reassign existing parent for $child")
error("Can't reassign existing parent for child $token")
}
}
if (before != child) {

View File

@ -1,7 +1,7 @@
package hep.dataforge.vision.html
import hep.dataforge.misc.DFExperimental
import hep.dataforge.vision.VisionManager
import hep.dataforge.vision.VisionForge
import kotlinx.html.FlowContent
import kotlinx.html.TagConsumer
@ -18,4 +18,4 @@ public fun FlowContent.fragment(fragment: HtmlFragment) {
public typealias HtmlVisionFragment = VisionTagConsumer<*>.() -> Unit
@DFExperimental
public fun VisionManager.Companion.fragment(content: HtmlVisionFragment): VisionTagConsumer<*>.() -> Unit = content
public fun VisionForge.fragment(content: HtmlVisionFragment): VisionTagConsumer<*>.() -> Unit = content

View File

@ -2,9 +2,10 @@ package hep.dataforge.vision.html
import hep.dataforge.context.Context
import hep.dataforge.misc.DFExperimental
import hep.dataforge.vision.VisionForge
import hep.dataforge.vision.context
import hep.dataforge.vision.visionManager
import kotlinx.html.*
import kotlinx.html.stream.createHTML
public data class Page(
public val context: Context,
@ -30,8 +31,8 @@ public data class Page(
@DFExperimental
public fun Context.page(
public fun VisionForge.page(
title: String,
content: HtmlVisionFragment,
vararg headers: Pair<String, HtmlFragment>,
): Page = Page(this, title, mapOf(*headers), content)
): Page = Page(context, title, mapOf(*headers), content)

View File

@ -1,11 +1,8 @@
package hep.dataforge.vision.client
package hep.dataforge.vision
import hep.dataforge.context.*
import hep.dataforge.meta.Meta
import hep.dataforge.meta.MetaSerializer
import hep.dataforge.vision.Vision
import hep.dataforge.vision.VisionChange
import hep.dataforge.vision.VisionManager
import hep.dataforge.vision.html.VisionTagConsumer
import hep.dataforge.vision.html.VisionTagConsumer.Companion.OUTPUT_CONNECT_ATTRIBUTE
import hep.dataforge.vision.html.VisionTagConsumer.Companion.OUTPUT_ENDPOINT_ATTRIBUTE

View File

@ -1,38 +0,0 @@
package hep.dataforge.vision
import hep.dataforge.context.Context
import hep.dataforge.context.Global
import hep.dataforge.vision.client.VisionClient
import hep.dataforge.vision.client.renderAllVisions
import hep.dataforge.vision.client.renderAllVisionsAt
import kotlinx.browser.document
import kotlinx.browser.window
public actual val VisionForge: Context = Global.context("VisionForge").apply {
plugins.fetch(VisionManager)
plugins.fetch(VisionClient)
}
/**
* Render all visions in this [window] using current global state of [VisionForge]
*/
@JsExport
public fun renderVisionsInWindow() {
window.onload = {
VisionForge.plugins[VisionClient]?.renderAllVisions()
}
}
/**
* Render all visions in an element with a given [id]
*/
@JsExport
public fun renderVisionsAt(id: String) {
val element = document.getElementById(id)
if (element != null) {
VisionForge.plugins[VisionClient]?.renderAllVisionsAt(element)
} else {
console.warn("Element with id $id not found")
}
}

View File

@ -1,8 +1,7 @@
package hep.dataforge.vision.client
package hep.dataforge.vision
import hep.dataforge.meta.Meta
import hep.dataforge.misc.Type
import hep.dataforge.vision.Vision
import org.w3c.dom.Element
@Type(ElementVisionRenderer.TYPE)

View File

@ -0,0 +1,37 @@
package hep.dataforge.vision
import hep.dataforge.context.Context
import kotlinx.browser.document
import kotlinx.browser.window
@JsExport
public actual object VisionForge{
/**
* Render all visions in this [window] using current global state of [VisionForge]
*/
public fun renderVisionsInWindow() {
window.onload = {
visionClient.renderAllVisions()
}
}
/**
* Render all visions in an element with a given [id]
*/
public fun renderVisionsAt(id: String) {
val element = document.getElementById(id)
if (element != null) {
visionClient.renderAllVisionsAt(element)
} else {
console.warn("Element with id $id not found")
}
}
}
private val visionForgeContext = Context("VisionForge"){
plugin(VisionClient)
}
public actual val VisionForge.context: Context get() = visionForgeContext
public val VisionForge.visionClient: VisionClient get() = plugins.fetch(VisionClient)

View File

@ -1,8 +0,0 @@
package hep.dataforge.vision
import hep.dataforge.context.Context
import hep.dataforge.context.Global
public actual val VisionForge: Context = Global.context("VisionForge").apply{
plugins.fetch(VisionManager)
}

View File

@ -0,0 +1,13 @@
package hep.dataforge.vision
import hep.dataforge.context.Context
import hep.dataforge.misc.DFExperimental
public actual object VisionForge
private val visionForgeContext = Context("VisionForge")
public actual val VisionForge.context: Context get() = visionForgeContext
@DFExperimental
public operator fun VisionForge.invoke(block: VisionForge.() -> Unit): Unit = run(block)

View File

@ -1,15 +1,27 @@
package hep.dataforge.vision.plotly
import hep.dataforge.context.PluginFactory
import hep.dataforge.vision.Vision
import hep.dataforge.vision.VisionForge
import hep.dataforge.vision.VisionPlugin
import hep.dataforge.vision.plugins
import kotlinx.serialization.modules.SerializersModule
import kotlinx.serialization.modules.polymorphic
import kotlinx.serialization.modules.subclass
public expect class PlotlyPlugin : VisionPlugin
public expect class PlotlyPlugin : VisionPlugin{
public companion object: PluginFactory<PlotlyPlugin>
}
internal val plotlySerializersModule = SerializersModule {
polymorphic(Vision::class) {
subclass(VisionOfPlotly.serializer())
}
}
/**
* Ensure that [PlotlyPlugin] is loaded in the global [VisionForge] context
*/
public fun VisionForge.usePlotly() {
plugins.fetch(PlotlyPlugin)
}

View File

@ -6,11 +6,10 @@ import hep.dataforge.context.PluginTag
import hep.dataforge.meta.Meta
import hep.dataforge.names.Name
import hep.dataforge.names.asName
import hep.dataforge.vision.ElementVisionRenderer
import hep.dataforge.vision.Vision
import hep.dataforge.vision.VisionForge
import hep.dataforge.vision.VisionClient
import hep.dataforge.vision.VisionPlugin
import hep.dataforge.vision.client.ElementVisionRenderer
import hep.dataforge.vision.client.VisionClient
import kotlinx.serialization.modules.SerializersModule
import kscience.plotly.PlotlyConfig
import kscience.plotly.plot
@ -42,17 +41,9 @@ public actual class PlotlyPlugin : VisionPlugin(), ElementVisionRenderer {
}
}
public companion object : PluginFactory<PlotlyPlugin> {
public actual companion object : PluginFactory<PlotlyPlugin> {
override val tag: PluginTag = PluginTag("vision.plotly", PluginTag.DATAFORGE_GROUP)
override val type: KClass<PlotlyPlugin> = PlotlyPlugin::class
override fun invoke(meta: Meta, context: Context): PlotlyPlugin = PlotlyPlugin()
}
}
/**
* Ensure that [PlotlyPlugin] is loaded in the global [VisionForge] context
*/
@JsExport
public fun usePlotly() {
VisionForge.plugins.fetch(PlotlyPlugin)
}

View File

@ -15,13 +15,9 @@ public actual class PlotlyPlugin : VisionPlugin(), Plugin {
override val visionSerializersModule: SerializersModule get() = plotlySerializersModule
public companion object : PluginFactory<PlotlyPlugin> {
public actual companion object : PluginFactory<PlotlyPlugin> {
override val tag: PluginTag = PluginTag("vision.plotly", PluginTag.DATAFORGE_GROUP)
override val type: KClass<PlotlyPlugin> = PlotlyPlugin::class
override fun invoke(meta: Meta, context: Context): PlotlyPlugin = PlotlyPlugin()
}
}
public fun Context.withPlotly(): Context = apply {
plugins.fetch(PlotlyPlugin)
}

View File

@ -70,6 +70,7 @@ public class SolidManager(meta: Meta) : VisionPlugin(meta) {
@DFExperimental
public inline fun VisionOutput.solid(block: SolidGroup.() -> Unit): SolidGroup = SolidGroup().apply(block)
public fun Context.withSolids(): Context = apply {
@DFExperimental
public fun VisionForge.useSolids(): Unit{
plugins.fetch(SolidManager)
}
}

View File

@ -3,13 +3,10 @@ package hep.dataforge.vision.solid.three
import hep.dataforge.context.*
import hep.dataforge.meta.Meta
import hep.dataforge.names.*
import hep.dataforge.vision.Vision
import hep.dataforge.vision.VisionForge
import hep.dataforge.vision.client.ElementVisionRenderer
import hep.dataforge.vision.onPropertyChange
import hep.dataforge.vision.*
import hep.dataforge.vision.solid.*
import hep.dataforge.vision.solid.specifications.Canvas3DOptions
import hep.dataforge.vision.visible
import hep.dataforge.vision.solid.three.set
import info.laht.threekt.core.Object3D
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.launchIn
@ -155,9 +152,8 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer {
/**
* Ensure that [ThreePlugin] is loaded in the global [VisionForge] context
*/
@JsExport
public fun useThreeJs() {
VisionForge.plugins.fetch(ThreePlugin)
public fun VisionForge.useThreeJs() {
plugins.fetch(ThreePlugin)
}
public fun ThreePlugin.render(

View File

@ -1,9 +1,9 @@
package hep.dataforge.vision.three.server
import hep.dataforge.vision.renderVisionsInWindow
import hep.dataforge.vision.VisionForge
import hep.dataforge.vision.solid.three.useThreeJs
public fun main() {
public fun main(): Unit = VisionForge.run {
useThreeJs()
renderVisionsInWindow()
}

View File

@ -1,7 +1,7 @@
package hep.dataforge.vision.three.server
import hep.dataforge.context.Context
import hep.dataforge.misc.DFExperimental
import hep.dataforge.vision.VisionForge
import hep.dataforge.vision.html.HtmlVisionFragment
import hep.dataforge.vision.html.ResourceLocation
import hep.dataforge.vision.html.page
@ -16,7 +16,7 @@ public fun VisionServer.useThreeJs(): Unit {
}
@DFExperimental
public fun Context.makeThreeJsFile(
public fun VisionForge.makeThreeJsFile(
content: HtmlVisionFragment,
path: Path? = null,
title: String = "VisionForge page",