Refactor MTMCConsole, enhance RegisterView with dynamic flag indicators, update ConsoleView for better output handling, add JavaExec task in Gradle, and update dependencies, styles, and Gradle wrapper version.

This commit is contained in:
2025-08-18 16:41:02 +02:00
parent d7e331728f
commit 11b069ddc5
9 changed files with 95 additions and 18 deletions

13
LICENSE.txt Normal file
View File

@@ -0,0 +1,13 @@
Zero-Clause BSD
=============
Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE
FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

View File

@@ -1,5 +1,6 @@
@file:OptIn(ExperimentalDistributionDsl::class) @file:OptIn(ExperimentalDistributionDsl::class)
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalDistributionDsl import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalDistributionDsl
plugins { plugins {
@@ -21,7 +22,15 @@ repositories {
kotlin { kotlin {
jvmToolchain(21) jvmToolchain(21)
jvm() jvm {
@OptIn(ExperimentalKotlinGradlePluginApi::class)
binaries {
// Configures a JavaExec task named "runJvm" and a Gradle distribution for the "main" compilation in this target
executable {
mainClass.set("mtmc.MainKt")
}
}
}
js { js {
binaries.executable() binaries.executable()
browser { browser {
@@ -40,9 +49,6 @@ kotlin {
val commonMain by getting { val commonMain by getting {
dependencies { dependencies {
api("nl.astraeus:kotlin-simple-logging:1.1.1") api("nl.astraeus:kotlin-simple-logging:1.1.1")
api("nl.astraeus:kotlin-css-generator:1.0.10")
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.0")
} }
} }
val commonTest by getting val commonTest by getting

View File

@@ -1,6 +1,6 @@
#Sun Apr 28 09:54:33 CEST 2024 #Sun Apr 28 09:54:33 CEST 2024
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@@ -10,7 +10,7 @@ class MTMCConsole(private val computer: MonTanaMiniComputer) {
var sysConsole: Console? = null var sysConsole: Console? = null
// non-interactive data // non-interactive data
private val output = StringBuilder() private var output = StringBuilder()
private var shortValueSet = false private var shortValueSet = false
private var shortValue: Short = 0 private var shortValue: Short = 0
private var stringValue: String? = null private var stringValue: String? = null
@@ -83,7 +83,9 @@ class MTMCConsole(private val computer: MonTanaMiniComputer) {
val text = if (index >= 0) output.substring(0, index + 1) else "" val text = if (index >= 0) output.substring(0, index + 1) else ""
if (index >= 0) { if (index >= 0) {
output.removeRange(0, index + 1) val updated = StringBuilder()
updated.append(output.removeRange(0, index + 1))
output = updated
} }
return text return text
@@ -116,7 +118,7 @@ class MTMCConsole(private val computer: MonTanaMiniComputer) {
} }
fun resetOutput() { fun resetOutput() {
output.removeRange(0, output.length) output.clear()
} }
enum class Mode { enum class Mode {

View File

@@ -19,10 +19,14 @@ import org.w3c.dom.events.KeyboardEvent
class ConsoleView( class ConsoleView(
val computer: MonTanaMiniComputer val computer: MonTanaMiniComputer
) : Komponent() { ) : Komponent() {
val history: MutableList<String> = mutableListOf()
var input: String = "" var input: String = ""
var output = StringBuilder()
private var inputElement: HTMLInputElement? = null private var inputElement: HTMLInputElement? = null
init {
output.append(computer.console.consumeLines())
}
override fun HtmlBuilder.render() { override fun HtmlBuilder.render() {
div("console") { div("console") {
onClickFunction = { onClickFunction = {
@@ -30,7 +34,7 @@ class ConsoleView(
} }
div("console-history") { div("console-history") {
div { div {
+computer.console.getOutput() +output.toString()
} }
} }
div("console-input") { div("console-input") {
@@ -41,6 +45,7 @@ class ConsoleView(
value = input value = input
autoFocus = true autoFocus = true
inputElement = currentElement() as? HTMLInputElement inputElement = currentElement() as? HTMLInputElement
currentElement().scrollIntoView()
window.setTimeout({ window.setTimeout({
inputElement?.focus() inputElement?.focus()
}, 0) }, 0)
@@ -61,11 +66,17 @@ class ConsoleView(
} }
private fun handleCommand() { private fun handleCommand() {
//history.add(input) computer.console.print("mtmc$ ")
computer.console.println(input)
Shell.execCommand(input, computer) Shell.execCommand(input, computer)
input = "" input = ""
output.append(computer.console.consumeLines())
if (output.length > 1000 && output.contains("\n")) {
output = output.deleteRange(0, output.indexOf("\n"))
}
mainView.registerView.requestUpdate() mainView.registerView.requestUpdate()
mainView.memoryView.requestUpdate() mainView.memoryView.requestUpdate()
display.requestUpdate() display.requestUpdate()

View File

@@ -123,11 +123,12 @@ class ControlView(
} }
} }
button { button {
disabled = true
+"reset" +"reset"
onClickFunction = { onClickFunction = {
//computer.reset() computer.initMemory()
mainView.requestUpdate()
display.requestUpdate()
} }
} }
} }

View File

@@ -8,6 +8,7 @@ import kotlinx.html.classes
import kotlinx.html.div import kotlinx.html.div
import kotlinx.html.hr import kotlinx.html.hr
import kotlinx.html.id import kotlinx.html.id
import kotlinx.html.span
import kotlinx.html.table import kotlinx.html.table
import kotlinx.html.td import kotlinx.html.td
import kotlinx.html.tr import kotlinx.html.tr
@@ -36,9 +37,34 @@ class RegisterView(
showRegister(16) showRegister(16)
showRegister(17) showRegister(17)
tr { tr {
td { td("flags") {
colSpan = "3" colSpan = "3"
+"Flags" span {
+"flags t:"
div("blinken") {
id = "flags-t"
if (!computer.isFlagTestBitSet) {
classes += "off"
}
}
}
span {
+"o:"
div("blinken") {
id = "flags-o"
classes += "off"
}
}
span {
+"e:"
div("blinken") {
id = "flags-e"
if (computer.getStatus() != MonTanaMiniComputer.ComputerStatus.PERMANENT_ERROR) {
classes += "off"
}
}
}
} }
} }
} }

View File

@@ -128,6 +128,20 @@ table.register-table tr td.register-lights {
padding-left: 20px; padding-left: 20px;
} }
table.register-table tr td.flags {
text-align: center;
}
table.register-table tr td.flags span {
margin-left: 8px;
}
table.register-table tr td.flags span .blinken {
margin-left: 4px;
top: 2px;
position: relative;
}
.blinken { .blinken {
display: inline-block; display: inline-block;
margin-right: 2px; margin-right: 2px;
@@ -214,10 +228,11 @@ table.register-table tr td.register-lights {
font-family: monospace; font-family: monospace;
font-weight: bold; font-weight: bold;
padding: 5px; padding: 5px;
overflow: auto;
} }
.console-prompt { .console-prompt {
margin-right: 10px; margin-right: 6px;
} }
input.console-input { input.console-input {
@@ -225,6 +240,8 @@ input.console-input {
background-color: #35291c; background-color: #35291c;
border: none; border: none;
outline: none; outline: none;
font-weight: bold;
font-family: monospace;
} }
.small-button { .small-button {

View File

@@ -5,12 +5,13 @@ import io.undertow.server.HttpServerExchange
import io.undertow.server.handlers.PathHandler import io.undertow.server.handlers.PathHandler
import io.undertow.server.handlers.resource.PathResourceManager import io.undertow.server.handlers.resource.PathResourceManager
import io.undertow.server.handlers.resource.ResourceHandler import io.undertow.server.handlers.resource.ResourceHandler
import io.undertow.util.Headers
import mtmc.itemUrl import mtmc.itemUrl
import java.nio.file.Paths import java.nio.file.Paths
import kotlin.text.startsWith
object IndexHandler : HttpHandler { object IndexHandler : HttpHandler {
override fun handleRequest(exchange: HttpServerExchange) { override fun handleRequest(exchange: HttpServerExchange) {
exchange.responseHeaders.put(Headers.CONTENT_TYPE, "text/html")
if (exchange.requestPath.startsWith("/$itemUrl/")) { if (exchange.requestPath.startsWith("/$itemUrl/")) {
exchange.responseSender.send(generateIndex(null)) exchange.responseSender.send(generateIndex(null))
} else { } else {