diff --git a/befunge/src/main/kotlin/befide/befunge/b93/B93Funge.kt b/befunge/src/main/kotlin/befide/befunge/b93/B93Funge.kt index 7cfa20e..e591d8b 100644 --- a/befunge/src/main/kotlin/befide/befunge/b93/B93Funge.kt +++ b/befunge/src/main/kotlin/befide/befunge/b93/B93Funge.kt @@ -3,64 +3,48 @@ package befide.befunge.b93 import befide.befunge.core.* import befide.befunge.state.* +fun List.padEnd(size: Int, factory: (Int) -> (T)): List = 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() + } + } } } diff --git a/befunge/src/main/kotlin/befide/befunge/state/Vec.kt b/befunge/src/main/kotlin/befide/befunge/state/Vec.kt index da82c1a..0866d1f 100644 --- a/befunge/src/main/kotlin/befide/befunge/state/Vec.kt +++ b/befunge/src/main/kotlin/befide/befunge/state/Vec.kt @@ -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) } \ No newline at end of file diff --git a/ide/src/main/kotlin/befide/ide/ActionView.kt b/ide/src/main/kotlin/befide/ide/ActionView.kt new file mode 100644 index 0000000..fd0f203 --- /dev/null +++ b/ide/src/main/kotlin/befide/ide/ActionView.kt @@ -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() + } + } + } +} \ No newline at end of file diff --git a/ide/src/main/kotlin/befide/ide/CodeView.kt b/ide/src/main/kotlin/befide/ide/CodeView.kt new file mode 100644 index 0000000..8dfa299 --- /dev/null +++ b/ide/src/main/kotlin/befide/ide/CodeView.kt @@ -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) { + + } +} \ No newline at end of file diff --git a/ide/src/main/kotlin/befide/ide/EditorView.kt b/ide/src/main/kotlin/befide/ide/EditorView.kt new file mode 100644 index 0000000..df0a76d --- /dev/null +++ b/ide/src/main/kotlin/befide/ide/EditorView.kt @@ -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">:#,_@""" + } +} \ No newline at end of file diff --git a/ide/src/main/kotlin/befide/ide/IOView.kt b/ide/src/main/kotlin/befide/ide/IOView.kt new file mode 100644 index 0000000..612ba3f --- /dev/null +++ b/ide/src/main/kotlin/befide/ide/IOView.kt @@ -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 { + + } + } +} \ No newline at end of file diff --git a/ide/src/main/kotlin/befide/ide/Main.kt b/ide/src/main/kotlin/befide/ide/Main.kt index 2193b30..bb1bf07 100644 --- a/ide/src/main/kotlin/befide/ide/Main.kt +++ b/ide/src/main/kotlin/befide/ide/Main.kt @@ -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 { diff --git a/ide/src/main/kotlin/befide/ide/Sample.kt b/ide/src/main/kotlin/befide/ide/Sample.kt deleted file mode 100644 index a482529..0000000 --- a/ide/src/main/kotlin/befide/ide/Sample.kt +++ /dev/null @@ -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) { - launch(args) -} \ No newline at end of file diff --git a/ide/src/main/kotlin/befide/ide/StackView.kt b/ide/src/main/kotlin/befide/ide/StackView.kt new file mode 100644 index 0000000..6b2bcbf --- /dev/null +++ b/ide/src/main/kotlin/befide/ide/StackView.kt @@ -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 + } +} \ No newline at end of file diff --git a/ide/src/main/resources/befide/ide/SampleView.fxml b/ide/src/main/resources/befide/ide/SampleView.fxml deleted file mode 100644 index 2aed0d7..0000000 --- a/ide/src/main/resources/befide/ide/SampleView.fxml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - diff --git a/ide/src/main/resources/befide/ide/style.css b/ide/src/main/resources/befide/ide/style.css index 1e918b4..042bbc0 100644 --- a/ide/src/main/resources/befide/ide/style.css +++ b/ide/src/main/resources/befide/ide/style.css @@ -7,3 +7,7 @@ -fx-font-family: monospace; } +.editor-root { + -fx-padding: 4px; + -fx-border-insets: 4px; +} \ No newline at end of file