diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/jsMain/kotlin/WebOS.kt | 82 | ||||
-rw-r--r-- | src/jsMain/kotlin/io/Path.kt | 75 | ||||
-rw-r--r-- | src/jsMain/kotlin/io/files.kt | 90 | ||||
-rw-r--r-- | src/jsMain/kotlin/util/sequence.kt | 5 | ||||
-rw-r--r-- | src/jsMain/resources/index.html | 17 | ||||
-rw-r--r-- | src/jsTest/kotlin/ProjectConfig.kt | 7 | ||||
-rw-r--r-- | src/jsTest/kotlin/io/PathTest.kt | 31 |
7 files changed, 0 insertions, 307 deletions
diff --git a/src/jsMain/kotlin/WebOS.kt b/src/jsMain/kotlin/WebOS.kt deleted file mode 100644 index b7c4cfb..0000000 --- a/src/jsMain/kotlin/WebOS.kt +++ /dev/null @@ -1,82 +0,0 @@ -import io.IOHandler -import io.Path -import kotlinx.browser.document -import kotlinx.browser.window -import org.w3c.dom.Element -import org.w3c.dom.asList - -fun main() { - console.log("Hello from Kotlin") - val webos = WebOS() - document.body?.addEventListener("load", { - document.body?.querySelectorAll(".webosconsole")?.asList()?.forEach { - if (it !is Element) return@forEach - webos.registerConsole(it) - } - }) -} - -data class CharacterRun(val text: String, val color: String) - -abstract class Activity(val console: Console) { - abstract fun render(columns: Int, rows: Int): List<List<CharacterRun>> -} - -class Console(val os: WebOS, val renderElement: Element?) { - val isVirtual get() = renderElement == null - val activityStack = ArrayDeque<Activity>() - - var columns: Int = 80 - var rows: Int = 46 - - var shouldRerender = true - - var currentUser: User? = null - - private var _workingDirectory: Path.Absolute? = null - - var workingDirectory: Path.Absolute - get() = _workingDirectory ?: currentUser?.homeDirectory ?: Path.root - set(value) { - _workingDirectory = value - } - - fun openActivity(activity: Activity) { - activityStack.addLast(activity) - invalidateRender() - } - - fun render() { - if (renderElement == null) return - if (!shouldRerender) return - shouldRerender = false - activityStack.last() - } - - fun invalidateRender() { - shouldRerender = true - window.requestAnimationFrame { render() } - } - - fun resize(newColumns: Int, newRows: Int) { - invalidateRender() - } - - // TODO: Handle resizes of the renderElement - -} - -class WebOS { - private val _consoles = mutableListOf<Console>() - val consoles get() = _consoles.toList() - val files = IOHandler() - fun registerConsole(element: Element) { - _consoles.add(Console(this, element)) - } -} - -data class User( - val name: String, - val homeDirectory: Path.Absolute -) - diff --git a/src/jsMain/kotlin/io/Path.kt b/src/jsMain/kotlin/io/Path.kt deleted file mode 100644 index 8f77203..0000000 --- a/src/jsMain/kotlin/io/Path.kt +++ /dev/null @@ -1,75 +0,0 @@ -package io - -sealed interface Path { - val parts: List<String> - fun toAbsolutePath(relativeTo: Absolute): Absolute { - return relativeTo.resolve(this) - } - - fun resolve(path: Path): Path - - companion object { - val root = Absolute(listOf()) - - fun ofShell(string: String, userHome: Absolute): Path = - ofShell(string.split("/"), userHome) - - fun ofShell(vararg parts: String, userHome: Absolute): Path = - ofShell(parts.toList(), userHome) - - fun of(vararg parts: String): Path = - of(parts.toList()) - - fun of(string: String): Path = - of(string.split("/")) - - fun ofShell(parts: List<String>, userHome: Absolute): Path { - if (parts.firstOrNull() == "~") - return userHome.resolve(Relative(parts.subList(1, parts.size).filter { it.isNotEmpty() })) - return of(parts) - } - - fun of(parts: List<String>): Path { - if (parts.isEmpty()) - return root - if (parts[0] == "") // Starts with a / - return Absolute(parts.subList(1, parts.size).filter { it.isNotEmpty() }) - return Relative(parts.filter { it.isNotEmpty() }) - } - } - - data class Relative internal constructor(override val parts: List<String>) : Path { - override fun resolve(path: Path): Path { - if (path is Absolute) return path - return Relative(this.parts + path.parts) - } - } - - data class Absolute internal constructor(override val parts: List<String>) : Path { - override fun resolve(path: Path): Absolute { - if (path is Absolute) return path - return Absolute(this.parts + path.parts) - } - - fun relativize(path: Path): Relative = when (path) { - is Relative -> path - is Absolute -> { - var commonPrefix = true - val partList = mutableListOf<String>() - var returns = 0 - for ((idx, part) in path.parts.withIndex()) { - if (idx < this.parts.size) { - if (this.parts[idx] == part && commonPrefix) { - continue - } else { - commonPrefix = false - returns++ - } - } - partList.add(part) - } - Relative(List(returns) { "" } + partList) - } - } - } -} diff --git a/src/jsMain/kotlin/io/files.kt b/src/jsMain/kotlin/io/files.kt deleted file mode 100644 index d37035d..0000000 --- a/src/jsMain/kotlin/io/files.kt +++ /dev/null @@ -1,90 +0,0 @@ -package io - -import User - -class IOHandler { - val mounts = mutableListOf<Mount>() - fun mount(absolutePath: Path.Absolute, fileSystem: FileSystem) { - if (mounts.any { it.mountPoint == absolutePath }) - return // TODO sensible error message handling - mounts += Mount(absolutePath, fileSystem) - } - - fun unmount(mountPoint: Path.Absolute) { - mounts.removeAll { it.mountPoint == mountPoint } - } - - fun <T> findMountFor( - workingDirectory: Path.Absolute, - path: Path, - operation: FileSystem.(relativePath: Path) -> T - ): T { - val absolutPath = path.toAbsolutePath(workingDirectory) - val mount = mounts.filter { - it.mountPoint.parts.zip(absolutPath.parts).all { (a, b) -> a == b } - }.maxByOrNull { it.mountPoint.parts.size } ?: throw IllegalStateException("No mount present") - return mount.fileSystem.operation( - Path.Absolute( - absolutPath.parts.subList( - mount.mountPoint.parts.size, - absolutPath.parts.size - ) - ) // TODO: unangenehm - ) - } - - fun findINode(absolutePath: Path.Absolute): INode { - val mount = mounts.filter { - it.mountPoint.parts.zip(absolutePath.parts).all { (a, b) -> a == b } - }.maxByOrNull { it.mountPoint.parts.size } ?: throw IllegalStateException("No mount present") - val iNode = mount.fileSystem.getINode(absolutePath.relativize(mount.mountPoint)) - return when (iNode) { - is INodeResult.File -> iNode.op - is INodeResult.ResolveAgain -> findINode(absolutePath.resolve(iNode.relativeToOriginal)) - } - } - - fun read(workingDirectory: Path.Absolute, path: Path): ReadResult = - findMountFor(workingDirectory, path) { read(it) } - - fun write(workingDirectory: Path.Absolute, path: Path, data: ByteArray): Unit = - findMountFor(workingDirectory, path) { write(it, data) } - - fun stat(workingDirectory: Path.Absolute, path: Path): Unit = - findMountFor(workingDirectory, path) { stat(it) } -} - -interface INode { - val fs: FileSystem -} - -sealed interface INodeResult { - class File(val op: INode) : INodeResult - class ResolveAgain(val relativeToOriginal: Path): INodeResult -} - -interface FileSystem { - fun getINode(relativePath: Path.Relative): INodeResult - fun read(relativePath: Path): ReadResult - fun write(path: Path, data: ByteArray): Unit // Write result - fun stat(path: Path): Unit // TODO io.Stat result -} - -sealed class ReadResult { - class Success(val text: String) : ReadResult() - object NotFound : ReadResult() - object NoAccess : ReadResult() -} - -data class Mount( - val mountPoint: Path.Absolute, - val fileSystem: FileSystem -) - -data class Stat( - val exists: Boolean, - var owner: User, - val created: Long, - val edited: Long, - val size: Long -) diff --git a/src/jsMain/kotlin/util/sequence.kt b/src/jsMain/kotlin/util/sequence.kt deleted file mode 100644 index 72b07dc..0000000 --- a/src/jsMain/kotlin/util/sequence.kt +++ /dev/null @@ -1,5 +0,0 @@ -package util - -fun <T> Iterable<T>.expandWith(t: T): Sequence<T> = - this.asSequence() + generateSequence { t }.asSequence() - diff --git a/src/jsMain/resources/index.html b/src/jsMain/resources/index.html deleted file mode 100644 index 719506b..0000000 --- a/src/jsMain/resources/index.html +++ /dev/null @@ -1,17 +0,0 @@ -<!doctype html> -<html lang="en"> -<head> - <meta charset="UTF-8"> - <meta name="viewport" - content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> - <meta http-equiv="X-UA-Compatible" content="ie=edge"> - <title>WebOs</title> -</head> -<body> -<noscript>tf you don't have js enabled? do you still live in the stone ages or what?</noscript> -<div id="content"> - -</div> -<script src="/webos.js"></script> -</body> -</html> diff --git a/src/jsTest/kotlin/ProjectConfig.kt b/src/jsTest/kotlin/ProjectConfig.kt deleted file mode 100644 index cf0f15d..0000000 --- a/src/jsTest/kotlin/ProjectConfig.kt +++ /dev/null @@ -1,7 +0,0 @@ -import io.kotest.core.config.AbstractProjectConfig - -class ProjectConfig : AbstractProjectConfig() { - override suspend fun beforeProject() { - println("HELLO") - } -} diff --git a/src/jsTest/kotlin/io/PathTest.kt b/src/jsTest/kotlin/io/PathTest.kt deleted file mode 100644 index 73667a6..0000000 --- a/src/jsTest/kotlin/io/PathTest.kt +++ /dev/null @@ -1,31 +0,0 @@ -package io - -import io.kotest.core.spec.style.FunSpec -import io.kotest.matchers.booleans.shouldBeFalse -import io.kotest.matchers.types.shouldBeTypeOf - -class PathTest : FunSpec({ - val homeDir = Path.of("/home") as Path.Absolute - test("recognize relative paths as such") { - listOf( - Path.of("a/b"), - Path.of("."), - Path.of("a", "b"), - Path.ofShell("a/b", userHome = homeDir), - Path.ofShell(".", userHome = homeDir), - Path.ofShell("a", "b", userHome = homeDir), - Path.ofShell(listOf("a", "b"), userHome = homeDir), - ).forEach { - it.shouldBeTypeOf<Path.Relative>() - } - } - test("recognize absolute paths as such") { - listOf( - Path.of("/a/b"), - Path.of("/"), - Path.ofShell("/b/c", userHome = homeDir), - ).forEach { - it.shouldBeTypeOf<Path.Absolute>() - } - } -}) |