diff --git a/befunge/src/main/kotlin/befide/befunge/b93/state/Funge93.kt b/befunge/src/main/kotlin/befide/befunge/b93/state/Funge93.kt index 7ae26f1..f44cc73 100644 --- a/befunge/src/main/kotlin/befide/befunge/b93/state/Funge93.kt +++ b/befunge/src/main/kotlin/befide/befunge/b93/state/Funge93.kt @@ -12,45 +12,55 @@ class Funge93 override fun next(pos: Vec2, delta: Vec2): Vec2 = (pos + delta) mod size - val contents = Array(size.y) { Array(size.x) { LongData.SPACE } } + override fun defaultData(): LongData = LongData.SPACE + override fun defaultChar(): Char = '\u2022' // bullet - override fun get(pos: Vec2): LongData = contents[pos.y][pos.x] + val contents = hashMapOf() + + override fun get(pos: Vec2): LongData = contents[pos] ?: defaultData() override fun set(pos: Vec2, data: LongData) { + if (pos.x !in 0 until size.x || pos.y !in 0 until size.y) + return + val from = this[pos] - contents[pos.y][pos.x] = data + contents[pos] = data onChange(FungeChange(this, pos, from, data)) } - override var data: List> + override var data: Map get() { - return contents.map(Array::toList) + return contents.toMap() } set(data) { - for (y in 0 until size.y) for (x in 0 until size.x) { - val pos = Vec2(x, y) - val new = data.getOrNull(y)?.getOrNull(x) ?: this[pos] - this[pos] = new - } + clear() + for ((v, d) in data.entries) + this[v] = d } override var src: String get() { - return contents.map { row -> - row.dropLastWhile { ch -> - ch.char?.isISOControl() ?: false - }.map { ch -> - ch.char ?: '\u2022' // bullet - }.joinToString("") - }.dropLastWhile { line -> - line.isEmpty() - }.joinToString("\n") - } - set(data) { - val lines = data.lines() - for (y in 0 until size.y) for (x in 0 until size.x) { - val pos = Vec2(x, y) - val new = lines.getOrNull(y)?.getOrNull(x)?.let(::LongData) ?: this[pos] - this[pos] = new + val lines = mutableListOf() + for ((y, row) in contents.entries.groupBy { it.key.y }.toSortedMap()) { + lines += List(y - lines.size) { "" } + + val chars = mutableListOf() + for ((v, ch) in row.sortedBy { it.key.x }) { + chars += List(v.x - chars.size) { ' ' } + chars += ch.char ?: defaultChar() + } + lines += chars.joinToString("") } + return lines.joinToString("\n") } + set(src) { + data = src.lines().mapIndexed { y, line -> + line.mapIndexed { x, ch -> + Pair(Vec2(x, y), LongData(ch)) + } + }.flatten().toMap() + } + + override fun clear() { + contents.clear() + } } \ No newline at end of file diff --git a/befunge/src/main/kotlin/befide/befunge/core/state/Funge.kt b/befunge/src/main/kotlin/befide/befunge/core/state/Funge.kt index ca55a47..84c6358 100644 --- a/befunge/src/main/kotlin/befide/befunge/core/state/Funge.kt +++ b/befunge/src/main/kotlin/befide/befunge/core/state/Funge.kt @@ -6,9 +6,12 @@ import befide.befunge.core.util.Event interface Funge { val size: V - val data: List> + val data: Map val src: String + fun defaultData(): D + fun defaultChar(): Char + fun next(pos: V, delta: V): V operator fun get(pos: V): D diff --git a/befunge/src/main/kotlin/befide/befunge/core/state/MutableFunge.kt b/befunge/src/main/kotlin/befide/befunge/core/state/MutableFunge.kt index 63e66d6..aa93dda 100644 --- a/befunge/src/main/kotlin/befide/befunge/core/state/MutableFunge.kt +++ b/befunge/src/main/kotlin/befide/befunge/core/state/MutableFunge.kt @@ -3,8 +3,10 @@ package befide.befunge.core.state interface MutableFunge : Funge { - override var data: List> + override var data: Map override var src: String operator fun set(pos: V, data: D) + + fun clear() } \ No newline at end of file