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)
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalDistributionDsl
plugins {
@@ -21,7 +22,15 @@ repositories {
kotlin {
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 {
binaries.executable()
browser {
@@ -40,9 +49,6 @@ kotlin {
val commonMain by getting {
dependencies {
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
@@ -72,4 +78,4 @@ kotlin {
}
val jsTest by getting
}
}
}

View File

@@ -1,6 +1,6 @@
#Sun Apr 28 09:54:33 CEST 2024
distributionBase=GRADLE_USER_HOME
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
zipStorePath=wrapper/dists

View File

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

View File

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

View File

@@ -123,11 +123,12 @@ class ControlView(
}
}
button {
disabled = true
+"reset"
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.hr
import kotlinx.html.id
import kotlinx.html.span
import kotlinx.html.table
import kotlinx.html.td
import kotlinx.html.tr
@@ -36,9 +37,34 @@ class RegisterView(
showRegister(16)
showRegister(17)
tr {
td {
td("flags") {
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;
}
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 {
display: inline-block;
margin-right: 2px;
@@ -214,10 +228,11 @@ table.register-table tr td.register-lights {
font-family: monospace;
font-weight: bold;
padding: 5px;
overflow: auto;
}
.console-prompt {
margin-right: 10px;
margin-right: 6px;
}
input.console-input {
@@ -225,6 +240,8 @@ input.console-input {
background-color: #35291c;
border: none;
outline: none;
font-weight: bold;
font-family: monospace;
}
.small-button {

View File

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