Compare commits
3 Commits
37835b578d
...
6045800d11
Author | SHA1 | Date |
---|---|---|
Shadowfacts | 6045800d11 | |
Shadowfacts | a61a67cbf3 | |
Shadowfacts | 56bc870ac5 |
|
@ -25,17 +25,17 @@ class ManagerBlockEntity: BlockEntity(ASMR.managerEntityType) {
|
||||||
it.position = Point(0.0, 120.0)
|
it.position = Point(0.0, 120.0)
|
||||||
}
|
}
|
||||||
val divide = program.addBlock(BinaryOperatorBlock(INT, DIVIDE)) {
|
val divide = program.addBlock(BinaryOperatorBlock(INT, DIVIDE)) {
|
||||||
it.left.source = left.output
|
it.left.link(from = left.output)
|
||||||
it.right.source = right.output
|
it.right.link(from = right.output)
|
||||||
it.position = Point(120.0, 0.0)
|
it.position = Point(120.0, 0.0)
|
||||||
}
|
}
|
||||||
val print = program.addBlock(PrintBlock(INT)) {
|
val print = program.addBlock(PrintBlock(INT)) {
|
||||||
it.input.source = divide.output
|
it.input.link(from = divide.output)
|
||||||
it.position = Point(240.0, 0.0)
|
it.position = Point(240.0, 0.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
program.startBlock.nextExecutableBlock = divide
|
program.startBlock.executionFlow.link(divide)
|
||||||
divide.nextExecutableBlock = print
|
divide.executionFlow.link(print)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun activate() {
|
fun activate() {
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
package net.shadowfacts.asmr.program
|
package net.shadowfacts.asmr.program
|
||||||
|
|
||||||
import net.shadowfacts.cacao.geometry.Point
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author shadowfacts
|
* @author shadowfacts
|
||||||
*/
|
*/
|
||||||
abstract class ExecutableBlock: ProgramBlock() {
|
abstract class ExecutableBlock: ProgramBlock() {
|
||||||
|
|
||||||
var nextExecutableBlock: ExecutableBlock? = null
|
open val executionFlow = ExecutionFlow(this)
|
||||||
|
|
||||||
abstract fun execute()
|
abstract fun execute()
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
package net.shadowfacts.asmr.program
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author shadowfacts
|
||||||
|
*/
|
||||||
|
open class ExecutionFlow(val block: ExecutableBlock) {
|
||||||
|
|
||||||
|
open var next: ExecutableBlock? = null
|
||||||
|
open var prev: ExecutableBlock? = null
|
||||||
|
|
||||||
|
fun link(next: ExecutableBlock) {
|
||||||
|
this.next = next
|
||||||
|
next.executionFlow.prev = block
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -11,14 +11,14 @@ class Program {
|
||||||
var startBlock = StartBlock().apply {
|
var startBlock = StartBlock().apply {
|
||||||
position = Point.ORIGIN
|
position = Point.ORIGIN
|
||||||
}
|
}
|
||||||
val blocks = mutableListOf<ProgramBlock>()
|
val blocks = mutableListOf<ProgramBlock>(startBlock)
|
||||||
|
|
||||||
fun execute() {
|
fun execute() {
|
||||||
var currentBlock: ExecutableBlock? = startBlock.nextExecutableBlock
|
var currentBlock: ExecutableBlock? = startBlock.executionFlow.next
|
||||||
while (currentBlock != null) {
|
while (currentBlock != null) {
|
||||||
currentBlock.execute()
|
currentBlock.execute()
|
||||||
|
|
||||||
currentBlock = currentBlock.nextExecutableBlock
|
currentBlock = currentBlock.executionFlow.next
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,29 @@
|
||||||
package net.shadowfacts.asmr.program
|
package net.shadowfacts.asmr.program
|
||||||
|
|
||||||
|
import net.minecraft.util.Identifier
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author shadowfacts
|
* @author shadowfacts
|
||||||
*/
|
*/
|
||||||
class ProgramBlockInput<Type: Any>(
|
class ProgramBlockInput<Type: Any>(
|
||||||
|
val identifier: Identifier,
|
||||||
val type: ProgramType<Type>,
|
val type: ProgramType<Type>,
|
||||||
val block: ProgramBlock,
|
val block: ProgramBlock,
|
||||||
var source: ProgramBlockOutput<Type>? = null
|
source: ProgramBlockOutput<Type>? = null
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
var source: ProgramBlockOutput<Type>? = source
|
||||||
|
internal set
|
||||||
|
|
||||||
val value: Type?
|
val value: Type?
|
||||||
get() = source?.value
|
get() = source?.value
|
||||||
|
|
||||||
|
fun link(from: ProgramBlockOutput<Type>) {
|
||||||
|
from.link(to = this)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unlink() {
|
||||||
|
source?.unlink(to = this)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,29 @@
|
||||||
package net.shadowfacts.asmr.program
|
package net.shadowfacts.asmr.program
|
||||||
|
|
||||||
|
import net.minecraft.util.Identifier
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author shadowfacts
|
* @author shadowfacts
|
||||||
*/
|
*/
|
||||||
class ProgramBlockOutput<Type: Any>(
|
class ProgramBlockOutput<Type: Any>(
|
||||||
|
val identifier: Identifier,
|
||||||
val type: ProgramType<Type>,
|
val type: ProgramType<Type>,
|
||||||
val block: ProgramBlock
|
val block: ProgramBlock
|
||||||
) {
|
) {
|
||||||
|
|
||||||
lateinit var value: Type
|
lateinit var value: Type
|
||||||
|
|
||||||
|
private val _destinations = mutableListOf<ProgramBlockInput<Type>>()
|
||||||
|
val destinations: List<ProgramBlockInput<Type>> = _destinations
|
||||||
|
|
||||||
|
fun link(to: ProgramBlockInput<Type>) {
|
||||||
|
to.source = this
|
||||||
|
_destinations.add(to)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unlink(to: ProgramBlockInput<Type>) {
|
||||||
|
to.source = null
|
||||||
|
_destinations.remove(to)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
package net.shadowfacts.asmr.program.blocks
|
package net.shadowfacts.asmr.program.blocks
|
||||||
|
|
||||||
|
import net.minecraft.util.Identifier
|
||||||
|
import net.shadowfacts.asmr.ASMR
|
||||||
import net.shadowfacts.asmr.program.ProgramBlock
|
import net.shadowfacts.asmr.program.ProgramBlock
|
||||||
import net.shadowfacts.asmr.program.ProgramBlockInput
|
import net.shadowfacts.asmr.program.ProgramBlockInput
|
||||||
import net.shadowfacts.asmr.program.ProgramBlockOutput
|
import net.shadowfacts.asmr.program.ProgramBlockOutput
|
||||||
|
@ -13,7 +15,7 @@ class ConstantBlock<Type: Any>(
|
||||||
val value: Type
|
val value: Type
|
||||||
): ProgramBlock() {
|
): ProgramBlock() {
|
||||||
|
|
||||||
val output = ProgramBlockOutput(type, this).apply {
|
val output = ProgramBlockOutput(Identifier(ASMR.modid, "constant_output"), type, this).apply {
|
||||||
value = this@ConstantBlock.value
|
value = this@ConstantBlock.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
package net.shadowfacts.asmr.program.blocks
|
package net.shadowfacts.asmr.program.blocks
|
||||||
|
|
||||||
import net.shadowfacts.asmr.program.ExecutableBlock
|
import net.minecraft.util.Identifier
|
||||||
import net.shadowfacts.asmr.program.ProgramBlockInput
|
import net.shadowfacts.asmr.ASMR
|
||||||
import net.shadowfacts.asmr.program.ProgramBlockOutput
|
import net.shadowfacts.asmr.program.*
|
||||||
import net.shadowfacts.asmr.program.ProgramType
|
|
||||||
import net.shadowfacts.cacao.geometry.Point
|
import net.shadowfacts.cacao.geometry.Point
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -13,7 +12,7 @@ class PrintBlock<Type: Any>(
|
||||||
val type: ProgramType<Type>
|
val type: ProgramType<Type>
|
||||||
): ExecutableBlock() {
|
): ExecutableBlock() {
|
||||||
|
|
||||||
val input = ProgramBlockInput(type, this)
|
val input = ProgramBlockInput(Identifier(ASMR.modid, "print_input"), type, this)
|
||||||
|
|
||||||
override val inputs: Array<ProgramBlockInput<*>> = arrayOf(input)
|
override val inputs: Array<ProgramBlockInput<*>> = arrayOf(input)
|
||||||
override val outputs: Array<ProgramBlockOutput<*>> = arrayOf()
|
override val outputs: Array<ProgramBlockOutput<*>> = arrayOf()
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
package net.shadowfacts.asmr.program.blocks
|
package net.shadowfacts.asmr.program.blocks
|
||||||
|
|
||||||
import net.shadowfacts.asmr.program.ExecutableBlock
|
import net.shadowfacts.asmr.program.ExecutableBlock
|
||||||
import net.shadowfacts.asmr.program.ProgramBlock
|
|
||||||
import net.shadowfacts.asmr.program.ProgramBlockInput
|
import net.shadowfacts.asmr.program.ProgramBlockInput
|
||||||
import net.shadowfacts.asmr.program.ProgramBlockOutput
|
import net.shadowfacts.asmr.program.ProgramBlockOutput
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author shadowfacts
|
* @author shadowfacts
|
||||||
*/
|
*/
|
||||||
class StartBlock: ProgramBlock() {
|
class StartBlock: ExecutableBlock() {
|
||||||
|
|
||||||
override val inputs: Array<ProgramBlockInput<*>> = arrayOf()
|
override val inputs: Array<ProgramBlockInput<*>> = arrayOf()
|
||||||
override val outputs: Array<ProgramBlockOutput<*>> = arrayOf()
|
override val outputs: Array<ProgramBlockOutput<*>> = arrayOf()
|
||||||
|
|
||||||
var nextExecutableBlock: ExecutableBlock? = null
|
override fun execute() {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
package net.shadowfacts.asmr.program.blocks.math
|
package net.shadowfacts.asmr.program.blocks.math
|
||||||
|
|
||||||
|
import net.minecraft.util.Identifier
|
||||||
|
import net.shadowfacts.asmr.ASMR
|
||||||
import net.shadowfacts.asmr.program.ExecutableBlock
|
import net.shadowfacts.asmr.program.ExecutableBlock
|
||||||
import net.shadowfacts.asmr.program.ProgramBlockInput
|
import net.shadowfacts.asmr.program.ProgramBlockInput
|
||||||
import net.shadowfacts.asmr.program.ProgramBlockOutput
|
import net.shadowfacts.asmr.program.ProgramBlockOutput
|
||||||
|
@ -20,10 +22,10 @@ class BinaryOperatorBlock<Type: Any>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val left = ProgramBlockInput(type, this)
|
val left = ProgramBlockInput(Identifier(ASMR.modid, "left_operand"), type, this)
|
||||||
val right = ProgramBlockInput(type, this)
|
val right = ProgramBlockInput(Identifier(ASMR.modid, "right_operand"), type, this)
|
||||||
|
|
||||||
val output = ProgramBlockOutput(type, this)
|
val output = ProgramBlockOutput(Identifier(ASMR.modid, "result"), type, this)
|
||||||
|
|
||||||
override val inputs: Array<ProgramBlockInput<*>> = arrayOf(left, right)
|
override val inputs: Array<ProgramBlockInput<*>> = arrayOf(left, right)
|
||||||
override val outputs: Array<ProgramBlockOutput<*>> = arrayOf(output)
|
override val outputs: Array<ProgramBlockOutput<*>> = arrayOf(output)
|
||||||
|
|
|
@ -1,18 +1,40 @@
|
||||||
package net.shadowfacts.asmr.ui
|
package net.shadowfacts.asmr.ui
|
||||||
|
|
||||||
|
import net.minecraft.util.Identifier
|
||||||
|
import net.shadowfacts.asmr.ASMR
|
||||||
|
import net.shadowfacts.asmr.program.ExecutableBlock
|
||||||
import net.shadowfacts.asmr.program.ProgramBlock
|
import net.shadowfacts.asmr.program.ProgramBlock
|
||||||
|
import net.shadowfacts.asmr.program.ProgramBlockInput
|
||||||
|
import net.shadowfacts.asmr.program.ProgramBlockOutput
|
||||||
|
import net.shadowfacts.cacao.geometry.Axis
|
||||||
import net.shadowfacts.cacao.geometry.Point
|
import net.shadowfacts.cacao.geometry.Point
|
||||||
import net.shadowfacts.cacao.util.Color
|
import net.shadowfacts.cacao.util.Color
|
||||||
import net.shadowfacts.cacao.util.MouseButton
|
import net.shadowfacts.cacao.util.MouseButton
|
||||||
|
import net.shadowfacts.cacao.util.texture.Texture
|
||||||
import net.shadowfacts.cacao.view.Label
|
import net.shadowfacts.cacao.view.Label
|
||||||
|
import net.shadowfacts.cacao.view.StackView
|
||||||
|
import net.shadowfacts.cacao.view.TextureView
|
||||||
import net.shadowfacts.cacao.view.View
|
import net.shadowfacts.cacao.view.View
|
||||||
import net.shadowfacts.kiwidsl.dsl
|
import net.shadowfacts.kiwidsl.dsl
|
||||||
import no.birkett.kiwi.Constraint
|
import no.birkett.kiwi.Constraint
|
||||||
|
import kotlin.math.max
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author shadowfacts
|
* @author shadowfacts
|
||||||
*/
|
*/
|
||||||
class ProgramBlockView(val block: ProgramBlock): View() {
|
class ProgramBlockView(val block: ProgramBlock): StackView(Axis.VERTICAL, Distribution.CENTER, spacing = 4.0) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val emptyConnection = Texture(Identifier(ASMR.modid, "textures/gui/programmer/program_connections.png"), u = 0, v = 0)
|
||||||
|
val executionConnection = Texture(Identifier(ASMR.modid, "textures/gui/programmer/program_connections.png"), u = 7, v = 0)
|
||||||
|
val parameterConnection = Texture(Identifier(ASMR.modid, "textures/gui/programmer/program_connections.png"), u = 14, v = 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
var incomingExecution: View? = null
|
||||||
|
var outgoingExeuction: View? = null
|
||||||
|
|
||||||
|
val inputViews = mutableMapOf<ProgramBlockInput<*>, View>()
|
||||||
|
val outputViews = mutableMapOf<ProgramBlockOutput<*>, View>()
|
||||||
|
|
||||||
var xConstraint: Constraint? = null
|
var xConstraint: Constraint? = null
|
||||||
var yConstraint: Constraint? = null
|
var yConstraint: Constraint? = null
|
||||||
|
@ -25,15 +47,103 @@ class ProgramBlockView(val block: ProgramBlock): View() {
|
||||||
backgroundColor = Color.BLACK
|
backgroundColor = Color.BLACK
|
||||||
zIndex = 10.0
|
zIndex = 10.0
|
||||||
|
|
||||||
val title = addSubview(Label(block.javaClass.simpleName))
|
val titleStack = addArrangedSubview(StackView(Axis.HORIZONTAL, Distribution.CENTER))
|
||||||
|
val title = titleStack.addArrangedSubview(Label(block.javaClass.simpleName))
|
||||||
|
if (block is ExecutableBlock) {
|
||||||
|
val incomingTexture = if (block.executionFlow.prev == null) emptyConnection else executionConnection
|
||||||
|
incomingExecution = titleStack.addArrangedSubview(TextureView(incomingTexture), index = 0)
|
||||||
|
val outgoingTexture = if (block.executionFlow.next == null) emptyConnection else executionConnection
|
||||||
|
outgoingExeuction = titleStack.addArrangedSubview(TextureView(outgoingTexture))
|
||||||
|
}
|
||||||
|
|
||||||
solver.dsl {
|
solver.dsl {
|
||||||
widthAnchor equalTo (title.widthAnchor + 8)
|
// we have to constrain the titleStack height, because it's distribution is set to CENTER, so it doesn't do it itself
|
||||||
heightAnchor equalTo (title.heightAnchor + 8)
|
titleStack.heightAnchor equalTo title.heightAnchor
|
||||||
title.centerXAnchor equalTo centerXAnchor
|
widthAnchor greaterThanOrEqualTo titleStack.widthAnchor
|
||||||
title.centerYAnchor equalTo centerYAnchor
|
|
||||||
|
if (block is ExecutableBlock) {
|
||||||
|
incomingExecution!!.widthAnchor equalTo incomingExecution!!.heightAnchor
|
||||||
|
incomingExecution!!.widthAnchor equalTo 7
|
||||||
|
outgoingExeuction!!.widthAnchor equalTo outgoingExeuction!!.heightAnchor
|
||||||
|
outgoingExeuction!!.widthAnchor equalTo 7
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// for (paramView in inputViews.values) {
|
||||||
|
// paramView.widthAnchor equalTo paramView.heightAnchor
|
||||||
|
// paramView.widthAnchor equalTo 7
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i in 0 until max(block.inputs.size, block.outputs.size)) {
|
||||||
|
val hStack = addArrangedSubview(StackView(Axis.HORIZONTAL, Distribution.CENTER))
|
||||||
|
|
||||||
|
block.inputs.getOrNull(i)?.let { input ->
|
||||||
|
val inputView = hStack.addArrangedSubview(TextureView(if (input.source == null) emptyConnection else parameterConnection))
|
||||||
|
inputViews[input] = inputView
|
||||||
|
val inputLabel = hStack.addArrangedSubview(Label(input.identifier.toString()))
|
||||||
|
solver.dsl {
|
||||||
|
hStack.heightAnchor equalTo inputLabel.heightAnchor
|
||||||
|
|
||||||
|
inputView.widthAnchor equalTo inputView.heightAnchor
|
||||||
|
inputView.widthAnchor equalTo 7
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val spacingView = hStack.addArrangedSubview(View())
|
||||||
|
solver.dsl {
|
||||||
|
spacingView.widthAnchor equalTo 8
|
||||||
|
}
|
||||||
|
|
||||||
|
block.outputs.getOrNull(i)?.let { output ->
|
||||||
|
val outputLabel = hStack.addArrangedSubview(Label(output.identifier.toString(), textAlignment = Label.TextAlignment.RIGHT))
|
||||||
|
val outputView = hStack.addArrangedSubview(TextureView(if (output.destinations.isEmpty()) emptyConnection else parameterConnection))
|
||||||
|
outputViews[output] = outputView
|
||||||
|
solver.dsl {
|
||||||
|
hStack.heightAnchor equalTo outputLabel.heightAnchor
|
||||||
|
|
||||||
|
outputView.widthAnchor equalTo outputView.heightAnchor
|
||||||
|
outputView.widthAnchor equalTo 7
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// val pairs = block.inputs.zip(block.outputs)
|
||||||
|
// val remainingInputs = if (block.inputs.size > block.outputs.size) block.inputs.drop(block.outputs.size) else listOf()
|
||||||
|
// val remainingOutputs = if (block.outputs.size > block.inputs.size) block.outputs.drop(block.inputs.size) else listOf()
|
||||||
|
// for ((input, output) in pairs) {
|
||||||
|
// val hStack = addArrangedSubview(StackView(Axis.HORIZONTAL, Distribution.CENTER))
|
||||||
|
// val inputView = hStack.addArrangedSubview(TextureView(if (input.source == null) emptyConnection else parameterConnection))
|
||||||
|
// inputViews[input] = inputView
|
||||||
|
// val inputLabel = hStack.addArrangedSubview(Label(input.identifier.toString()))
|
||||||
|
// val spacingView = hStack.addArrangedSubview(View())
|
||||||
|
// hStack.addArrangedSubview(Label(output.identifier.toString()))
|
||||||
|
//// outputViews[output] = hStack.addArrangedSubview(TextureView(if (output.destinations.isEmpty) emptyConnection else parameterConnection))
|
||||||
|
//
|
||||||
|
// solver.dsl {
|
||||||
|
// hStack.heightAnchor equalTo inputLabel.heightAnchor
|
||||||
|
//
|
||||||
|
// inputView.widthAnchor equalTo inputView.heightAnchor
|
||||||
|
// inputView.widthAnchor equalTo 7
|
||||||
|
//
|
||||||
|
// spacingView.widthAnchor equalTo 8
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// for (input in remainingInputs) {
|
||||||
|
// addArrangedSubview(Label(input.identifier.toString()))
|
||||||
|
// }
|
||||||
|
// for (output in remainingOutputs) {
|
||||||
|
// addArrangedSubview(Label(output.identifier.toString(), textAlignment = Label.TextAlignment.RIGHT))
|
||||||
|
// }
|
||||||
|
|
||||||
|
solver.dsl {
|
||||||
|
for (view in arrangedSubviews.drop(1)) {
|
||||||
|
widthAnchor.equalTo(view.widthAnchor, strength = STRONG)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
updateDraggingConstraints()
|
updateDraggingConstraints()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,4 +163,8 @@ class ProgramBlockView(val block: ProgramBlock): View() {
|
||||||
window!!.layout()
|
window!!.layout()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun drawContent(mouse: Point, delta: Float) {
|
||||||
|
super.drawContent(mouse, delta)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
package net.shadowfacts.asmr.ui
|
package net.shadowfacts.asmr.ui
|
||||||
|
|
||||||
|
import net.shadowfacts.asmr.program.ExecutableBlock
|
||||||
import net.shadowfacts.asmr.program.Program
|
import net.shadowfacts.asmr.program.Program
|
||||||
import net.shadowfacts.asmr.program.ProgramBlock
|
import net.shadowfacts.asmr.program.ProgramBlock
|
||||||
import net.shadowfacts.cacao.geometry.Point
|
import net.shadowfacts.cacao.geometry.Point
|
||||||
|
@ -28,16 +29,43 @@ class ProgramCanvasView(val program: Program): View() {
|
||||||
override fun drawContent(mouse: Point, delta: Float) {
|
override fun drawContent(mouse: Point, delta: Float) {
|
||||||
super.drawContent(mouse, delta)
|
super.drawContent(mouse, delta)
|
||||||
|
|
||||||
blocks.keys.forEach { block ->
|
|
||||||
block.inputs
|
|
||||||
.filter { it.source != null }
|
|
||||||
.forEach { input ->
|
|
||||||
val start = block.position
|
|
||||||
val source = input.source!!
|
|
||||||
val sourcePosition = source.block.position
|
|
||||||
val end = Point(sourcePosition.x + blocks[source.block]!!.bounds.width, sourcePosition.y)
|
|
||||||
|
|
||||||
RenderHelper.drawLine(start, end, zIndex, 5f, Color.WHITE)
|
for ((block, view) in blocks) {
|
||||||
|
(block as? ExecutableBlock)?.executionFlow?.next?.let { next ->
|
||||||
|
blocks[next]?.let { nextView ->
|
||||||
|
val outgoing = view.outgoingExeuction!!
|
||||||
|
val incoming = nextView.incomingExecution!!
|
||||||
|
|
||||||
|
val start = outgoing.convert(outgoing.bounds.center, to = this)
|
||||||
|
val end = incoming.convert(outgoing.bounds.center, to = this)
|
||||||
|
|
||||||
|
RenderHelper.drawLine(start, end, zIndex, 5f, Color.GREEN)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (input in block.inputs) {
|
||||||
|
if (input.source == null) continue
|
||||||
|
val source = input.source!!
|
||||||
|
|
||||||
|
blocks[source.block]?.let { sourceView ->
|
||||||
|
view.inputViews[input]?.let { inputView ->
|
||||||
|
sourceView.outputViews[source]?.let { outputView ->
|
||||||
|
val start = inputView.convert(inputView.bounds.center, to = this)
|
||||||
|
val end = outputView.convert(outputView.bounds.center, to = this)
|
||||||
|
|
||||||
|
RenderHelper.drawLine(start, end, zIndex, 5f, Color.RED)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// val start = block.position
|
||||||
|
// val sourcePosition = source.block.position
|
||||||
|
// val end = Point(sourcePosition.x + blocks[source.block]!!.bounds.width, sourcePosition.y)
|
||||||
|
|
||||||
|
// val inputView = view.inputViews[input]
|
||||||
|
// val outputView =
|
||||||
|
//
|
||||||
|
// RenderHelper.drawLine(start, end, zIndex, 5f, Color.RED)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,14 +186,13 @@ class Window(
|
||||||
return currentlyDraggedView.mouseDragged(startPoint, delta, mouseButton)
|
return currentlyDraggedView.mouseDragged(startPoint, delta, mouseButton)
|
||||||
} else if (startPoint in viewController.view.frame) {
|
} else if (startPoint in viewController.view.frame) {
|
||||||
val startInView = Point(startPoint.x - viewController.view.frame.left, startPoint.y - viewController.view.frame.top)
|
val startInView = Point(startPoint.x - viewController.view.frame.left, startPoint.y - viewController.view.frame.top)
|
||||||
lateinit var prevView: View
|
var prevView: View? = null
|
||||||
var view = viewController.view.subviewsAtPoint(startInView).maxBy(View::zIndex)
|
var view = viewController.view.subviewsAtPoint(startInView).maxBy(View::zIndex)
|
||||||
while (view != null && !view.respondsToDragging) {
|
while (view != null && !view.respondsToDragging) {
|
||||||
prevView = view
|
prevView = view
|
||||||
val pointInView = viewController.view.convert(startInView, to = view)
|
val pointInView = viewController.view.convert(startInView, to = view)
|
||||||
view = view.subviewsAtPoint(pointInView).maxBy(View::zIndex)
|
view = view.subviewsAtPoint(pointInView).maxBy(View::zIndex)
|
||||||
}
|
}
|
||||||
// this.currentlyDraggedView = viewController.view.subviewsAtPoint(startInView).maxBy(View::zIndex)
|
|
||||||
this.currentDragReceiver = view ?: prevView
|
this.currentDragReceiver = view ?: prevView
|
||||||
return this.currentDragReceiver?.mouseDragged(startPoint, delta, mouseButton) ?: false
|
return this.currentDragReceiver?.mouseDragged(startPoint, delta, mouseButton) ?: false
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,9 @@ data class Color(val red: Int, val green: Int, val blue: Int, val alpha: Int = 2
|
||||||
val CLEAR = Color(0, alpha = 0)
|
val CLEAR = Color(0, alpha = 0)
|
||||||
val WHITE = Color(0xffffff)
|
val WHITE = Color(0xffffff)
|
||||||
val BLACK = Color(0)
|
val BLACK = Color(0)
|
||||||
|
val RED = Color(0xff0000)
|
||||||
|
val GREEN = Color(0x00ff00)
|
||||||
|
val BLUE = Color(0x0000ff)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -117,7 +117,7 @@ object RenderHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun BufferBuilder.color(color: Color): BufferBuilder {
|
private fun BufferBuilder.color(color: Color): BufferBuilder {
|
||||||
color(color.alpha, color.red, color.green, color.blue)
|
color(color.red, color.green, color.blue, color.alpha)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ import java.util.*
|
||||||
* @param distribution The mode by which this stack lays out its children along the axis perpendicular to the
|
* @param distribution The mode by which this stack lays out its children along the axis perpendicular to the
|
||||||
* primary [axis].
|
* primary [axis].
|
||||||
*/
|
*/
|
||||||
class StackView(
|
open class StackView(
|
||||||
val axis: Axis,
|
val axis: Axis,
|
||||||
val distribution: Distribution = Distribution.FILL,
|
val distribution: Distribution = Distribution.FILL,
|
||||||
val spacing: Double = 0.0
|
val spacing: Double = 0.0
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 923 B |
|
@ -16,11 +16,11 @@ class ProgramTests {
|
||||||
val one = program.addBlock(ConstantBlock(ProgramType.INT, 3))
|
val one = program.addBlock(ConstantBlock(ProgramType.INT, 3))
|
||||||
val two = program.addBlock(ConstantBlock(ProgramType.INT, 7))
|
val two = program.addBlock(ConstantBlock(ProgramType.INT, 7))
|
||||||
val multiply = program.addBlock(BinaryOperatorBlock(ProgramType.INT, BinaryOperatorBlock.Operation.MULTIPLY)) {
|
val multiply = program.addBlock(BinaryOperatorBlock(ProgramType.INT, BinaryOperatorBlock.Operation.MULTIPLY)) {
|
||||||
it.left.source = one.output
|
it.left.link(from = one.output)
|
||||||
it.right.source = two.output
|
it.right.link(from = two.output)
|
||||||
}
|
}
|
||||||
|
|
||||||
program.startBlock.nextExecutableBlock = multiply
|
program.startBlock.executionFlow.link(multiply)
|
||||||
|
|
||||||
program.execute()
|
program.execute()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue