From 946ebd7d9c4040e2da47de6a52505ba54d8ce740 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Thu, 8 Aug 2019 22:44:19 -0400 Subject: [PATCH] Start manager block & programming UI --- src/main/kotlin/net/shadowfacts/asmr/ASMR.kt | 19 ++++++ .../shadowfacts/asmr/manager/ManagerBlock.kt | 46 ++++++++++++++ .../asmr/manager/ManagerBlockEntity.kt | 45 +++++++++++++ .../asmr/program/ExecutableBlock.kt | 4 +- .../net/shadowfacts/asmr/program/Program.kt | 11 +++- .../shadowfacts/asmr/program/ProgramBlock.kt | 10 ++- .../shadowfacts/asmr/program/ProgramType.kt | 6 +- .../asmr/program/blocks/ConstantBlock.kt | 2 +- .../asmr/program/blocks/PrintBlock.kt | 1 + .../asmr/program/blocks/StartBlock.kt | 2 +- .../blocks/math/BinaryOperatorBlock.kt | 24 +++---- .../asmr/ui/ManagerViewController.kt | 63 +++++++++++++++++++ .../net/shadowfacts/asmr/util/registry.kt | 11 ++++ .../shadowfacts/asmr/program/ProgramTests.kt | 14 ++--- 14 files changed, 228 insertions(+), 30 deletions(-) create mode 100644 src/main/kotlin/net/shadowfacts/asmr/manager/ManagerBlock.kt create mode 100644 src/main/kotlin/net/shadowfacts/asmr/manager/ManagerBlockEntity.kt create mode 100644 src/main/kotlin/net/shadowfacts/asmr/ui/ManagerViewController.kt create mode 100644 src/main/kotlin/net/shadowfacts/asmr/util/registry.kt diff --git a/src/main/kotlin/net/shadowfacts/asmr/ASMR.kt b/src/main/kotlin/net/shadowfacts/asmr/ASMR.kt index 0e37be4..491b420 100644 --- a/src/main/kotlin/net/shadowfacts/asmr/ASMR.kt +++ b/src/main/kotlin/net/shadowfacts/asmr/ASMR.kt @@ -2,17 +2,36 @@ package net.shadowfacts.asmr import net.fabricmc.api.ModInitializer import net.fabricmc.fabric.api.registry.CommandRegistry +import net.minecraft.block.entity.BlockEntityType import net.minecraft.client.MinecraftClient +import net.minecraft.item.BlockItem +import net.minecraft.item.Item import net.minecraft.server.command.CommandManager +import net.minecraft.util.Identifier +import net.minecraft.util.registry.Registry +import net.shadowfacts.asmr.manager.ManagerBlock +import net.shadowfacts.asmr.manager.ManagerBlockEntity +import net.shadowfacts.asmr.util.register +import java.util.function.Supplier /** * @author shadowfacts */ object ASMR: ModInitializer { + const val modid = "asmr" + + val managerBlock = ManagerBlock() + val managerBlockItem = BlockItem(managerBlock, Item.Settings()) + val managerEntityType = BlockEntityType.Builder.create(Supplier { ManagerBlockEntity() }, managerBlock).build(null) + override fun onInitialize() { println("hello fabric") + Registry.BLOCK.register(managerBlock, Identifier(modid, "manager")) + Registry.ITEM.register(managerBlockItem, Identifier(modid, "manager")) + Registry.BLOCK_ENTITY.register(managerEntityType, Identifier(modid, "manager")) + CommandRegistry.INSTANCE.register(false) { dispatcher -> val command = CommandManager.literal("uitest").executes { try { diff --git a/src/main/kotlin/net/shadowfacts/asmr/manager/ManagerBlock.kt b/src/main/kotlin/net/shadowfacts/asmr/manager/ManagerBlock.kt new file mode 100644 index 0000000..9bf33c7 --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/asmr/manager/ManagerBlock.kt @@ -0,0 +1,46 @@ +package net.shadowfacts.asmr.manager + +import net.fabricmc.api.EnvType +import net.fabricmc.api.Environment +import net.minecraft.block.Block +import net.minecraft.block.BlockEntityProvider +import net.minecraft.block.BlockState +import net.minecraft.block.Material +import net.minecraft.block.entity.BlockEntity +import net.minecraft.client.MinecraftClient +import net.minecraft.entity.player.PlayerEntity +import net.minecraft.util.Hand +import net.minecraft.util.hit.BlockHitResult +import net.minecraft.util.math.BlockPos +import net.minecraft.world.BlockView +import net.minecraft.world.World +import net.shadowfacts.asmr.ui.ManagerViewController +import net.shadowfacts.cacao.CacaoScreen +import net.shadowfacts.cacao.Window + +/** + * @author shadowfacts + */ +class ManagerBlock: Block(Settings.of(Material.METAL)), BlockEntityProvider { + + @Deprecated("") + override fun activate(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, hitResult: BlockHitResult?): Boolean { + if (world.isClient) { + openManagerUI(world.getBlockEntity(pos) as ManagerBlockEntity) + } + return true + } + + @Environment(EnvType.CLIENT) + private fun openManagerUI(managerBlockEntity: ManagerBlockEntity) { + val vc = ManagerViewController(managerBlockEntity) + val screen = CacaoScreen() + val window = screen.addWindow(Window(vc)) + MinecraftClient.getInstance().openScreen(screen) + } + + override fun createBlockEntity(world: BlockView): BlockEntity { + return ManagerBlockEntity() + } + +} \ No newline at end of file diff --git a/src/main/kotlin/net/shadowfacts/asmr/manager/ManagerBlockEntity.kt b/src/main/kotlin/net/shadowfacts/asmr/manager/ManagerBlockEntity.kt new file mode 100644 index 0000000..eb0dfab --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/asmr/manager/ManagerBlockEntity.kt @@ -0,0 +1,45 @@ +package net.shadowfacts.asmr.manager + +import net.minecraft.block.entity.BlockEntity +import net.shadowfacts.asmr.ASMR +import net.shadowfacts.asmr.program.Program +import net.shadowfacts.asmr.program.ProgramType.Companion.INT +import net.shadowfacts.asmr.program.blocks.ConstantBlock +import net.shadowfacts.asmr.program.blocks.PrintBlock +import net.shadowfacts.asmr.program.blocks.math.BinaryOperatorBlock +import net.shadowfacts.asmr.program.blocks.math.BinaryOperatorBlock.Operation.DIVIDE +import net.shadowfacts.cacao.geometry.Point + +/** + * @author shadowfacts + */ +class ManagerBlockEntity: BlockEntity(ASMR.managerEntityType) { + + val program = Program() + + init { + val left = program.addBlock(ConstantBlock(INT, 36)) { + it.position = Point(0.0, 60.0) + } + val right = program.addBlock(ConstantBlock(INT, 9)) { + it.position = Point(0.0, 120.0) + } + val divide = program.addBlock(BinaryOperatorBlock(INT, DIVIDE)) { + it.left.source = left.output + it.right.source = right.output + it.position = Point(120.0, 0.0) + } + val print = program.addBlock(PrintBlock(INT)) { + it.input.source = divide.output + it.position = Point(240.0, 0.0) + } + + program.startBlock.nextExecutableBlock = divide + divide.nextExecutableBlock = print + } + + fun activate() { + program.execute() + } + +} \ No newline at end of file diff --git a/src/main/kotlin/net/shadowfacts/asmr/program/ExecutableBlock.kt b/src/main/kotlin/net/shadowfacts/asmr/program/ExecutableBlock.kt index a937c70..c2a5298 100644 --- a/src/main/kotlin/net/shadowfacts/asmr/program/ExecutableBlock.kt +++ b/src/main/kotlin/net/shadowfacts/asmr/program/ExecutableBlock.kt @@ -1,9 +1,11 @@ package net.shadowfacts.asmr.program +import net.shadowfacts.cacao.geometry.Point + /** * @author shadowfacts */ -abstract class ExecutableBlock: ProgramBlock { +abstract class ExecutableBlock: ProgramBlock() { var nextExecutableBlock: ExecutableBlock? = null diff --git a/src/main/kotlin/net/shadowfacts/asmr/program/Program.kt b/src/main/kotlin/net/shadowfacts/asmr/program/Program.kt index 2ebfd59..93d3c9c 100644 --- a/src/main/kotlin/net/shadowfacts/asmr/program/Program.kt +++ b/src/main/kotlin/net/shadowfacts/asmr/program/Program.kt @@ -1,13 +1,16 @@ package net.shadowfacts.asmr.program import net.shadowfacts.asmr.program.blocks.StartBlock +import net.shadowfacts.cacao.geometry.Point /** * @author shadowfacts */ class Program { - var startBlock = StartBlock() + var startBlock = StartBlock().apply { + position = Point.ORIGIN + } val blocks = mutableListOf() fun execute() { @@ -19,4 +22,10 @@ class Program { } } + fun addBlock(block: Block, init: (Block) -> Unit = {}): Block { + init(block) + blocks.add(block) + return block + } + } \ No newline at end of file diff --git a/src/main/kotlin/net/shadowfacts/asmr/program/ProgramBlock.kt b/src/main/kotlin/net/shadowfacts/asmr/program/ProgramBlock.kt index 466f191..a9c0e72 100644 --- a/src/main/kotlin/net/shadowfacts/asmr/program/ProgramBlock.kt +++ b/src/main/kotlin/net/shadowfacts/asmr/program/ProgramBlock.kt @@ -1,11 +1,15 @@ package net.shadowfacts.asmr.program +import net.shadowfacts.cacao.geometry.Point + /** * @author shadowfacts */ -interface ProgramBlock { +abstract class ProgramBlock { - val inputs: Array> - val outputs: Array> + var position: Point = Point.ORIGIN + + abstract val inputs: Array> + abstract val outputs: Array> } \ No newline at end of file diff --git a/src/main/kotlin/net/shadowfacts/asmr/program/ProgramType.kt b/src/main/kotlin/net/shadowfacts/asmr/program/ProgramType.kt index 9a8075b..9dfd151 100644 --- a/src/main/kotlin/net/shadowfacts/asmr/program/ProgramType.kt +++ b/src/main/kotlin/net/shadowfacts/asmr/program/ProgramType.kt @@ -5,8 +5,8 @@ package net.shadowfacts.asmr.program */ class ProgramType { companion object { - val int = ProgramType() - val float = ProgramType() - val string = ProgramType() + val INT = ProgramType() + val FLOAT = ProgramType() + val STRING = ProgramType() } } \ No newline at end of file diff --git a/src/main/kotlin/net/shadowfacts/asmr/program/blocks/ConstantBlock.kt b/src/main/kotlin/net/shadowfacts/asmr/program/blocks/ConstantBlock.kt index a6b633c..83eee8b 100644 --- a/src/main/kotlin/net/shadowfacts/asmr/program/blocks/ConstantBlock.kt +++ b/src/main/kotlin/net/shadowfacts/asmr/program/blocks/ConstantBlock.kt @@ -11,7 +11,7 @@ import net.shadowfacts.asmr.program.ProgramType class ConstantBlock( val type: ProgramType, val value: Type -): ProgramBlock { +): ProgramBlock() { val output = ProgramBlockOutput(type).apply { value = this@ConstantBlock.value diff --git a/src/main/kotlin/net/shadowfacts/asmr/program/blocks/PrintBlock.kt b/src/main/kotlin/net/shadowfacts/asmr/program/blocks/PrintBlock.kt index 190dc4e..5baa272 100644 --- a/src/main/kotlin/net/shadowfacts/asmr/program/blocks/PrintBlock.kt +++ b/src/main/kotlin/net/shadowfacts/asmr/program/blocks/PrintBlock.kt @@ -4,6 +4,7 @@ import net.shadowfacts.asmr.program.ExecutableBlock import net.shadowfacts.asmr.program.ProgramBlockInput import net.shadowfacts.asmr.program.ProgramBlockOutput import net.shadowfacts.asmr.program.ProgramType +import net.shadowfacts.cacao.geometry.Point /** * @author shadowfacts diff --git a/src/main/kotlin/net/shadowfacts/asmr/program/blocks/StartBlock.kt b/src/main/kotlin/net/shadowfacts/asmr/program/blocks/StartBlock.kt index 076f768..7df2e60 100644 --- a/src/main/kotlin/net/shadowfacts/asmr/program/blocks/StartBlock.kt +++ b/src/main/kotlin/net/shadowfacts/asmr/program/blocks/StartBlock.kt @@ -8,7 +8,7 @@ import net.shadowfacts.asmr.program.ProgramBlockOutput /** * @author shadowfacts */ -class StartBlock: ProgramBlock { +class StartBlock: ProgramBlock() { override val inputs: Array> = arrayOf() override val outputs: Array> = arrayOf() diff --git a/src/main/kotlin/net/shadowfacts/asmr/program/blocks/math/BinaryOperatorBlock.kt b/src/main/kotlin/net/shadowfacts/asmr/program/blocks/math/BinaryOperatorBlock.kt index 84c8d24..f12ccf9 100644 --- a/src/main/kotlin/net/shadowfacts/asmr/program/blocks/math/BinaryOperatorBlock.kt +++ b/src/main/kotlin/net/shadowfacts/asmr/program/blocks/math/BinaryOperatorBlock.kt @@ -15,7 +15,7 @@ class BinaryOperatorBlock( ): ExecutableBlock() { init { - if (type != ProgramType.int && type != ProgramType.float) { + if (type != ProgramType.INT && type != ProgramType.FLOAT) { throw RuntimeException("BinaryOperatorBlock type must be int or float") } } @@ -29,29 +29,29 @@ class BinaryOperatorBlock( override val outputs: Array> = arrayOf(output) override fun execute() { - if (type == ProgramType.int) { + if (type == ProgramType.INT) { val left = left.value as Int val right = right.value as Int output.value = when (operation) { - Operation.add -> left + right - Operation.subtract -> left - right - Operation.multiply -> left * right - Operation.divide -> left / right + Operation.ADD -> left + right + Operation.SUBTRACT -> left - right + Operation.MULTIPLY -> left * right + Operation.DIVIDE -> left / right } as Type - } else if (type == ProgramType.float) { + } else if (type == ProgramType.FLOAT) { val left = left.value as Float val right = right.value as Float output.value = when (operation) { - Operation.add -> left + right - Operation.subtract -> left - right - Operation.multiply -> left * right - Operation.divide -> left / right + Operation.ADD -> left + right + Operation.SUBTRACT -> left - right + Operation.MULTIPLY -> left * right + Operation.DIVIDE -> left / right } as Type } } enum class Operation { - add, subtract, multiply, divide + ADD, SUBTRACT, MULTIPLY, DIVIDE } } \ No newline at end of file diff --git a/src/main/kotlin/net/shadowfacts/asmr/ui/ManagerViewController.kt b/src/main/kotlin/net/shadowfacts/asmr/ui/ManagerViewController.kt new file mode 100644 index 0000000..13260d6 --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/asmr/ui/ManagerViewController.kt @@ -0,0 +1,63 @@ +package net.shadowfacts.asmr.ui + +import net.shadowfacts.asmr.manager.ManagerBlockEntity +import net.shadowfacts.cacao.geometry.Rect +import net.shadowfacts.cacao.geometry.Size +import net.shadowfacts.cacao.util.Color +import net.shadowfacts.cacao.util.texture.NinePatchTexture +import net.shadowfacts.cacao.view.Label +import net.shadowfacts.cacao.view.NinePatchView +import net.shadowfacts.cacao.view.View +import net.shadowfacts.cacao.viewcontroller.ViewController + +/** + * @author shadowfacts + */ +class ManagerViewController(val managerBlockEntity: ManagerBlockEntity): ViewController() { + + lateinit var panel: View + + override fun viewDidLoad() { + panel = view.addSubview(View()) + val background = panel.addSubview(NinePatchView(NinePatchTexture.PANEL_BG)) + val label = panel.addSubview(Label("test label")) + + createConstraints { + panel.widthAnchor equalTo (view.widthAnchor - 40) + panel.heightAnchor equalTo (view.heightAnchor - 40) + panel.centerXAnchor equalTo view.centerXAnchor + panel.centerYAnchor equalTo view.centerYAnchor + + background.leftAnchor equalTo panel.leftAnchor + background.rightAnchor equalTo panel.rightAnchor + background.topAnchor equalTo panel.topAnchor + background.bottomAnchor equalTo panel.bottomAnchor + + label.centerXAnchor equalTo view.centerXAnchor + label.centerYAnchor equalTo view.centerYAnchor + } + + createProgramView() + } + + private fun createProgramView() { + val program = managerBlockEntity.program + + program.blocks.forEach { + val blockView = panel.addSubview(View()) + blockView.backgroundColor = Color.BLACK + val title = blockView.addSubview(Label(it.javaClass.simpleName)) + + createConstraints { + blockView.widthAnchor equalTo (title.widthAnchor + 8) + blockView.heightAnchor equalTo (title.heightAnchor + 8) + blockView.leftAnchor equalTo (panel.leftAnchor + 4 + it.position.x) + blockView.topAnchor equalTo (panel.topAnchor + 4 + it.position.y) + + title.leftAnchor equalTo (blockView.leftAnchor + 4) + title.topAnchor equalTo (blockView.topAnchor + 4) + } + } + } + +} \ No newline at end of file diff --git a/src/main/kotlin/net/shadowfacts/asmr/util/registry.kt b/src/main/kotlin/net/shadowfacts/asmr/util/registry.kt new file mode 100644 index 0000000..6f24658 --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/asmr/util/registry.kt @@ -0,0 +1,11 @@ +package net.shadowfacts.asmr.util + +import net.minecraft.util.Identifier +import net.minecraft.util.registry.Registry + +/** + * @author shadowfacts + */ +fun Registry.register(obj: T, identifier: Identifier) { + Registry.register(this, identifier, obj) +} \ No newline at end of file diff --git a/src/test/kotlin/net/shadowfacts/asmr/program/ProgramTests.kt b/src/test/kotlin/net/shadowfacts/asmr/program/ProgramTests.kt index cdfd993..e8df0e0 100644 --- a/src/test/kotlin/net/shadowfacts/asmr/program/ProgramTests.kt +++ b/src/test/kotlin/net/shadowfacts/asmr/program/ProgramTests.kt @@ -13,14 +13,12 @@ class ProgramTests { @Test fun testExecutionFlow() { val program = Program() - val one = ConstantBlock(ProgramType.int, 3) - program.blocks.add(one) - val two = ConstantBlock(ProgramType.int, 7) - program.blocks.add(two) - val multiply = BinaryOperatorBlock(ProgramType.int, BinaryOperatorBlock.Operation.multiply) - multiply.left.source = one.output - multiply.right.source = two.output - program.blocks.add(multiply) + val one = program.addBlock(ConstantBlock(ProgramType.INT, 3)) + val two = program.addBlock(ConstantBlock(ProgramType.INT, 7)) + val multiply = program.addBlock(BinaryOperatorBlock(ProgramType.INT, BinaryOperatorBlock.Operation.MULTIPLY)) { + it.left.source = one.output + it.right.source = two.output + } program.startBlock.nextExecutableBlock = multiply