summaryrefslogtreecommitdiff
path: root/src/jsMain/kotlin/WebOS.kt
blob: f762d3a47e0790b05eca1bf48bfeb7c9396a9101 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import io.FileService
import io.Path
import io.PrimitiveFileService
import io.PrimitiveINode
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: FileService<PrimitiveINode> = PrimitiveFileService()
	fun registerConsole(element: Element) {
		_consoles.add(Console(this, element))
	}
}

data class User(
	val name: String,
	val homeDirectory: Path.Absolute,
	val isRoot: Boolean = false,
)