separate view files; B93Funge stores Value objects

This commit is contained in:
2018-11-19 14:48:18 -05:00
parent a1e6368b2f
commit cdf0dfee28
11 changed files with 175 additions and 232 deletions

View File

@@ -3,64 +3,48 @@ package befide.befunge.b93
import befide.befunge.core.*
import befide.befunge.state.*
fun <T> List<T>.padEnd(size: Int, factory: (Int) -> (T)): List<T> = this + (this.size until size).map { factory(it) }
class B93Funge : Funge {
override val width = 80
override val height = 25
private var cars = Array(height) { Array(width) { ' '.toLong() } }
val bounds = Vec(width, height)
private var cars = Array(height) { Array(width) { Value(' ') } }
override fun get(vec: Vec): Value {
return Value(cars[vec.y][vec.x])
return cars[vec.y][vec.x]
}
override fun set(vec: Vec, value: Value) {
cars[vec.y][vec.x] = value.value
cars[vec.y][vec.x] = value
}
override fun nextVec(vec: Vec, delta: Vec): Vec {
var x = vec.x + delta.x
var y = vec.y + delta.y
if (x >= width || x < 0) {
x %= width
}
if (x < 0) {
x += width
}
if (y >= height || y < 0) {
y %= height
}
if (y < 0) {
y += height
}
return Vec(x, y)
return (vec + delta) mod bounds
}
override fun setString(data: String) {
val strings = data.split('\n')
for (i in strings.size until height) {
cars[i] = Array(width) { ' '.toLong() }
}
strings.map {
it.toList().map { it.toLong() }
}
.forEachIndexed { index, list ->
if (index > height) {
return
}
cars[index] = (
list.toList() + List(
if (list.size <= width) width - list.size else 0
) {
' '.toLong()
}
)
.subList(0, width)
.toTypedArray()
}
cars = data.split("\n").map {
it.map {
Value(it)
}.padEnd(width) {
Value(' ')
}.toTypedArray()
}.padEnd(height) {
Array(width) {
Value(' ')
}
}.toTypedArray()
}
override fun toString(): String {
return cars.map { it.map { Value(it).asChar ?: '?' }.joinToString("") }.joinToString("\n")
return cars.joinToString("\n") { row ->
row.joinToString("") { value ->
(value.asChar ?: '?').toString()
}
}
}
}

View File

@@ -1,6 +1,13 @@
package befide.befunge.state
infix fun Int.mod(other: Int): Int {
val x = this % other
return if (x >= 0) x else (x + other)
}
data class Vec(val x: Int, val y: Int) {
operator fun plus(other: Vec) = Vec(x + other.x, y + other.y)
operator fun times(c: Int) = Vec(x * c, y * c)
infix fun mod(other: Vec) = Vec(x mod other.x, y mod other.y)
}

View File

@@ -0,0 +1,51 @@
package befide.ide
import befide.befunge.core.Interpreter
import javafx.animation.Animation
import javafx.animation.Timeline
import javafx.util.Duration
import tornadofx.*
class ActionView(val interp: Interpreter) : View() {
var runTimeline: Timeline = timeline(false) {
keyframe(Duration.seconds(0.0)) {
setOnFinished {
if (!interp.step())
this@timeline.stop()
}
}
keyframe(Duration.seconds(1.0)) {}
cycleCount = Animation.INDEFINITE
}
override val root = hbox {
button("step") {
setOnAction { interp.step() }
}
button("reset") {
setOnAction { interp.reset() }
}
button("run") {
setOnAction {
runTimeline.rate = 1000.0
runTimeline.playFromStart()
}
}
button("crawl") {
setOnAction {
runTimeline.rate = 2.0
runTimeline.playFromStart()
}
}
button("stop") {
setOnAction {
runTimeline.stop()
}
}
}
}

View File

@@ -0,0 +1,19 @@
package befide.ide
import befide.befunge.core.Interpreter
import javafx.beans.property.SimpleStringProperty
import tornadofx.*
class CodeView(val interp: Interpreter) : View() {
val srcProperty = SimpleStringProperty("")
var src by srcProperty
init {
interp.fungeChanged += { src = interp.funge.toString() }
srcProperty.addListener { _, _, newValue -> interp.funge.setString(newValue) }
}
override val root = textarea(srcProperty) {
}
}

View File

@@ -0,0 +1,34 @@
package befide.ide
import befide.befunge.b93.B93Interpreter
import befide.befunge.core.Interpreter
import tornadofx.*
class EditorView : View("Befide") {
private var interp: Interpreter = B93Interpreter()
private val codeView = CodeView(interp)
private val actionView = ActionView(interp)
private val stackView = StackView(interp)
private val ioView = IOView(interp)
override val root = borderpane {
addClass("editor-root")
top { add(actionView) }
center {
add(codeView)
}
right {
add(stackView)
}
bottom { add(ioView) }
}
init {
codeView.src = """64+"!dlroW ,olleH">:#,_@"""
}
}

View File

@@ -0,0 +1,25 @@
package befide.ide
import befide.befunge.core.Interpreter
import javafx.beans.property.SimpleStringProperty
import tornadofx.*
class IOView(val interp: Interpreter) : View() {
val outputProperty = SimpleStringProperty("")
var output by outputProperty
init {
// add listeners to interp, handle streams, idk
}
override val root = vbox {
addClass("")
textarea(outputProperty) {
// width, height, idk
prefHeight = 200.0
}
textfield {
}
}
}

View File

@@ -1,128 +1,6 @@
package befide.ide
import befide.befunge.b93.B93Interpreter
import befide.befunge.core.Interpreter
import befide.befunge.core.Pointer
import javafx.animation.Animation
import javafx.animation.Timeline
import javafx.beans.property.SimpleObjectProperty
import javafx.beans.property.SimpleStringProperty
import javafx.util.Duration
import tornadofx.*
import tornadofx.getValue
import tornadofx.setValue
class IOView(val interp: Interpreter) : View() {
val textProperty = SimpleStringProperty("")
var text by textProperty
init {
// add listeners to interp, handle streams, idk
}
override val root = vbox {
textarea(textProperty) {
// width, height, idk
prefHeight = 200.0
}
textfield {
}
}
}
class ActionView(val interp: Interpreter) : View() {
var runTimeline: Timeline = timeline(false) {
keyframe(Duration.seconds(0.0)) {
setOnFinished {
if (!interp.step())
this@timeline.stop()
}
}
keyframe(Duration.seconds(1.0)) {}
cycleCount = Animation.INDEFINITE
}
override val root = hbox {
button("step") {
setOnAction { interp.step() }
}
button("reset") {
setOnAction { interp.reset() }
}
button("run") {
setOnAction {
runTimeline.rate = 1000.0
runTimeline.playFromStart()
}
}
button("crawl") {
setOnAction {
runTimeline.rate = 2.0
runTimeline.playFromStart()
}
}
button("stop") {
setOnAction {
runTimeline.stop()
}
}
}
}
class CodeView(val interp: Interpreter) : View() {
val srcProperty = SimpleStringProperty("")
var src by srcProperty
init {
interp.fungeChanged += { src = interp.funge.toString() }
srcProperty.addListener { _, _, newValue -> interp.funge.setString(newValue) }
}
override val root = textarea(srcProperty) {
}
}
class StackView(val interp: Interpreter) : View() {
override val root = textarea {
prefWidth = 100.0
}
}
class EditorView : View("Befide") {
private var interp: Interpreter = B93Interpreter()
private val codeView = CodeView(interp)
private val actionView = ActionView(interp)
private val stackView = StackView(interp)
private val ioView = IOView(interp)
override val root = borderpane {
addClass("editor-root")
top { add(actionView) }
center {
add(codeView)
}
right {
add(stackView)
}
bottom { add(ioView) }
}
init {
codeView.src = """64+"!dlroW ,olleH">:#,_@"""
}
}
class MainApp : App(EditorView::class) {
init {

View File

@@ -1,53 +0,0 @@
package befide.ide
import befide.befunge.b93.B93Interpreter
import befide.befunge.core.Interpreter
import javafx.beans.property.SimpleIntegerProperty
import javafx.scene.Parent
import javafx.scene.control.Label
import tornadofx.*
class SampleView : View() {
private val controller: SampleController by inject()
override val root: Parent by fxml()
private val width: Label by fxid()
private val height: Label by fxid()
init {
importStylesheet(resources["style.css"])
width.bind(controller.width)
height.bind(controller.height)
}
}
class SampleController : Controller() {
private val bf: Interpreter = B93Interpreter()
val width = SimpleIntegerProperty()
val height = SimpleIntegerProperty()
init {
// sample event subscription. this is not necessary, but would update the
// width and height labels every time a value in the funge is changed
bf.fungeChanged += { updateFungeLabels() }
updateFungeLabels()
}
fun updateFungeLabels() {
width.set(bf.funge.width)
height.set(bf.funge.height)
}
}
class SampleApp : App() {
override val primaryView = SampleView::class
}
fun main(args: Array<String>) {
launch<SampleApp>(args)
}

View File

@@ -0,0 +1,10 @@
package befide.ide
import befide.befunge.core.Interpreter
import tornadofx.*
class StackView(val interp: Interpreter) : View() {
override val root = textarea {
prefWidth = 100.0
}
}

View File

@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.*?>
<GridPane alignment="CENTER" minHeight="-Infinity" minWidth="-Infinity" prefHeight="200.0" prefWidth="300.0"
xmlns="http://javafx.com/javafx/8.0.172-ea" xmlns:fx="http://javafx.com/fxml/1">
<Label text="Width: " styleClass="lbl"
fx:id="widthLabel"/>
<Label text="Height: " styleClass="lbl"
fx:id="heightLabel" GridPane.rowIndex="1"/>
<Label text="{width}" styleClass="val"
fx:id="width" GridPane.columnIndex="1"/>
<Label text="{height}" styleClass="val"
fx:id="height" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
</GridPane>

View File

@@ -7,3 +7,7 @@
-fx-font-family: monospace;
}
.editor-root {
-fx-padding: 4px;
-fx-border-insets: 4px;
}