Skip to content

Commit 047dac5

Browse files
committed
Use MappingSession migrations.
1 parent 51604fe commit 047dac5

File tree

11 files changed

+76
-67
lines changed

11 files changed

+76
-67
lines changed

src/commonMain/kotlin/baaahs/api/ws/WebSocketClient.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package baaahs.api.ws
22

3+
import baaahs.client.document.mappingSessionStore
34
import baaahs.imaging.Bitmap
45
import baaahs.mapper.MappingSession
56
import baaahs.mapper.MappingStore
@@ -22,6 +23,7 @@ class WebSocketClient(
2223
link: Network.Link,
2324
address: Network.Address
2425
) : Network.WebSocketListener {
26+
private val mappingSessionStore = plugins.mappingSessionStore
2527
private val json = plugins.json
2628
private lateinit var tcpConnection: Network.TcpConnection
2729
private var connected = false
@@ -69,7 +71,7 @@ class WebSocketClient(
6971
suspend fun saveSession(mappingSession: MappingSession): String {
7072
return sendCommand(
7173
"saveSession",
72-
json.encodeToJsonElement(MappingSession.serializer(), mappingSession)
74+
mappingSessionStore.encodeToJsonElement(mappingSession)
7375
).jsonPrimitive.contentOrNull ?: error("Failed to save session!")
7476
}
7577

@@ -78,7 +80,7 @@ class WebSocketClient(
7880
"loadSession",
7981
json.encodeToJsonElement(String.serializer(), name)
8082
)
81-
return json.decodeFromJsonElement(MappingSession.serializer(), response)
83+
return mappingSessionStore.decode(response)
8284
}
8385

8486
private suspend fun sendCommand(command: String, vararg args: JsonElement): JsonElement {
Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,39 @@
11
package baaahs.client.document
22

33
import baaahs.io.Fs
4+
import baaahs.mapper.migration.MappingSessionMigrator
45
import baaahs.migrator.DataMigrator
56
import baaahs.plugin.Plugins
67
import baaahs.scene.migration.SceneMigrator
78
import baaahs.show.migration.ShowMigrator
9+
import kotlinx.serialization.json.JsonElement
810

11+
val Plugins.mappingSessionStore get() = DataStore(this, MappingSessionMigrator)
912
val Plugins.showStore get() = DataStore(this, ShowMigrator)
1013
val Plugins.sceneStore get() = DataStore(this, SceneMigrator)
1114

1215
class DataStore<T : Any>(
1316
private val plugins: Plugins,
1417
private val migrator: DataMigrator<T>
1518
) {
19+
fun decode(content: String) =
20+
plugins.json.decodeFromString(migrator, content)
21+
22+
fun decode(content: JsonElement) =
23+
plugins.json.decodeFromJsonElement(migrator, content)
24+
1625
suspend fun load(file: Fs.File): T? =
17-
file.read()?.let {
18-
plugins.json.decodeFromString(migrator, it)
19-
}
26+
file.read()?.let { decode(it) }
27+
28+
fun encode(content: T) =
29+
plugins.json.encodeToString(migrator, content)
30+
31+
fun encodeToJsonElement(content: T) =
32+
plugins.json.encodeToJsonElement(migrator, content)
2033

2134
suspend fun save(file: Fs.File, content: T, allowOverwrite: Boolean = false) =
2235
file.write(
23-
plugins.json.encodeToString(migrator, content),
36+
encode(content),
2437
allowOverwrite
2538
)
2639
}

src/commonMain/kotlin/baaahs/client/document/SceneManager.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import baaahs.io.RemoteFsSerializer
1010
import baaahs.io.resourcesFs
1111
import baaahs.plugin.Plugins
1212
import baaahs.scene.*
13-
import baaahs.scene.migration.SceneMigrator
1413
import baaahs.show.mutable.MutableDocument
1514
import baaahs.ui.DialogHolder
1615
import baaahs.ui.DialogMenuItem
@@ -90,7 +89,7 @@ class SceneManager(
9089
}
9190

9291
override suspend fun onUpload(name: String, content: String) {
93-
val scene = plugins.json.decodeFromString(SceneMigrator, content)
92+
val scene = plugins.sceneStore.decode(content)
9493
onNew(scene)
9594
}
9695

src/commonMain/kotlin/baaahs/client/document/ShowManager.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import baaahs.show.Show
1414
import baaahs.show.ShowMonitor
1515
import baaahs.show.ShowState
1616
import baaahs.show.live.OpenShow
17-
import baaahs.show.migration.ShowMigrator
1817
import baaahs.show.mutable.MutableDocument
1918
import baaahs.sm.webapi.Problem
2019
import baaahs.sm.webapi.Topics
@@ -89,7 +88,7 @@ class ShowManager(
8988
}
9089

9190
override suspend fun onUpload(name: String, content: String) {
92-
val show = toolchain.plugins.json.decodeFromString(ShowMigrator, content)
91+
val show = toolchain.plugins.showStore.decode(content)
9392
onNew(show)
9493
}
9594

src/commonMain/kotlin/baaahs/mapper/MappingStore.kt

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package baaahs.mapper
22

3+
import baaahs.client.document.mappingSessionStore
34
import baaahs.io.Fs
45
import baaahs.plugin.Plugins
56
import baaahs.scene.OpenScene
@@ -9,15 +10,13 @@ import kotlinx.datetime.Instant
910
import kotlinx.datetime.TimeZone
1011
import kotlinx.datetime.toLocalDateTime
1112
import kotlinx.serialization.json.Json
12-
import kotlinx.serialization.json.JsonObject
13-
import kotlinx.serialization.json.buildJsonObject
14-
import kotlinx.serialization.json.jsonObject
1513

1614
class MappingStore(
1715
private val dataDir: Fs.File,
1816
private val plugins: Plugins,
1917
private val clock: Clock
2018
) {
19+
private val mappingSessionStore = plugins.mappingSessionStore
2120
val json = Json(plugins.json) { isLenient = true }
2221
val mappingSessionsDir = dataDir.resolve("mapping-sessions")
2322
val imagesDir = mappingSessionsDir.resolve("images")
@@ -49,9 +48,9 @@ class MappingStore(
4948

5049
suspend fun saveSession(mappingSession: MappingSession): Fs.File {
5150
val name = "${formatDateTime(mappingSession.startedAt, clock.tz())}-v${mappingSession.version}.json"
52-
val file = mappingSessionsDir.resolve(name)
53-
file.write(json.encodeToString(MappingSession.serializer(), mappingSession))
54-
return file
51+
return mappingSessionsDir.resolve(name).also {
52+
mappingSessionStore.save(it, mappingSession)
53+
}
5554
}
5655

5756
suspend fun listImages(sessionName: String?): List<Fs.File> {
@@ -95,25 +94,8 @@ class MappingStore(
9594
}
9695

9796
suspend fun loadMappingSession(f: Fs.File): MappingSession {
98-
val mappingJson = f.read()
97+
val mappingSession = mappingSessionStore.load(f)
9998
?: error("No such file \"${f.fullPath}\".")
100-
val mappingSession = try {
101-
val json = plugins.json.parseToJsonElement(mappingJson).jsonObject.let {
102-
// Janky data migration.
103-
buildJsonObject {
104-
it.entries.forEach { (k, v) ->
105-
put(k, if (k == "cameraMatrix") {
106-
if (v is JsonObject) {
107-
v["elements"]!!
108-
} else v
109-
} else v)
110-
}
111-
}
112-
}
113-
plugins.json.decodeFromJsonElement(MappingSession.serializer(), json)
114-
} catch (e: Exception) {
115-
throw Exception("Error loading \"${f.fullPath}\": ${e.message}.", e)
116-
}
11799
mappingSession.surfaces.forEach { surface ->
118100
logger.debug { "Found pixel mapping for ${surface.entityName} (${surface.controllerId.name()})" }
119101
}

src/commonMain/kotlin/baaahs/mapper/migration/MappingSessionMigrator.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ import baaahs.migrator.DataMigrator
66
object MappingSessionMigrator : DataMigrator<MappingSession>(MappingSession.serializer(), AllMappingSessionMigrations)
77

88
val AllMappingSessionMigrations = listOf<DataMigrator.Migration>(
9-
V1_EpochToIso8601
9+
V1_EpochToIso8601AndFixCameraMatrix
1010
)

src/commonMain/kotlin/baaahs/mapper/migration/V1_EpochToIso8601.kt

Lines changed: 0 additions & 20 deletions
This file was deleted.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package baaahs.mapper.migration
2+
3+
import baaahs.migrator.DataMigrator
4+
import kotlinx.datetime.Instant
5+
import kotlinx.serialization.json.*
6+
7+
object V1_EpochToIso8601AndFixCameraMatrix : DataMigrator.Migration(1) {
8+
override fun migrate(from: JsonObject): JsonObject =
9+
from.toMutableMap().apply {
10+
replace("startedAt") { it.fromMillisToIso8601() }
11+
replace("savedAt") { it.fromMillisToIso8601() }
12+
13+
replace("cameraMatrix") {
14+
if (it is JsonObject) it["elements"]!! else it
15+
}
16+
}.let { JsonObject(it) }
17+
18+
private fun MutableMap<String, JsonElement>.replace(
19+
key: String,
20+
block: (JsonElement) -> JsonElement
21+
) {
22+
this[key]?.let { this[key] = block(it) }
23+
}
24+
25+
private fun JsonElement.fromMillisToIso8601() =
26+
JsonPrimitive(
27+
Instant.fromEpochMilliseconds(
28+
jsonPrimitive.double.toLong()
29+
).toString()
30+
)
31+
}

src/commonTest/kotlin/baaahs/mapper/MappingSessionSpec.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class MappingSessionSpec : Spek({
2121
/**language=json*/
2222
"""
2323
{
24-
"startedAt": "${Instant.fromEpochMilliseconds(12345600)}",
24+
"startedAt": 12345600000,
2525
"surfaces": [
2626
{
2727
"brainId": "brain1234",
@@ -32,7 +32,7 @@ class MappingSessionSpec : Spek({
3232
"cameraMatrix": {
3333
"elements": [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]
3434
},
35-
"savedAt": "${Instant.fromEpochMilliseconds(12345600)}"
35+
"savedAt": 12345600000
3636
}
3737
""".trimIndent()
3838
}
@@ -47,7 +47,7 @@ class MappingSessionSpec : Spek({
4747

4848
it("deserializes equally") {
4949
expect(decoded)
50-
.its({ startedAt }) { toEqual(Instant.fromEpochMilliseconds(12345600)) }
50+
.its({ startedAt }) { toEqual(Instant.fromEpochMilliseconds(12345600_000)) }
5151

5252
val surfaces = decoded.surfaces.only("surface")
5353
expect(surfaces)

src/commonTest/kotlin/baaahs/mapper/migration/V1_EpochToIso8601Spec.kt renamed to src/commonTest/kotlin/baaahs/mapper/migration/V1_EpochToIso8601AndFixCameraMatrixSpec.kt

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,38 @@
11
package baaahs.mapper.migration
22

33
import baaahs.describe
4+
import baaahs.geom.Matrix4F
5+
import baaahs.geom.identity
46
import baaahs.toEqual
57
import ch.tutteli.atrium.api.verbs.expect
6-
import kotlinx.serialization.json.Json
7-
import kotlinx.serialization.json.JsonPrimitive
8-
import kotlinx.serialization.json.buildJsonObject
9-
import kotlinx.serialization.json.jsonObject
8+
import kotlinx.serialization.json.*
109
import org.spekframework.spek2.Spek
1110

1211
@Suppress("unused", "ClassName")
13-
object V1_EpochToIso8601Spec : Spek({
14-
describe<V1_EpochToIso8601> {
12+
object V1_EpochToIso8601AndFixCameraMatrixSpec : Spek({
13+
describe<V1_EpochToIso8601AndFixCameraMatrix> {
1514
val fromJson by value {
1615
/**language=json*/
1716
"""
1817
{
1918
"startedAt": 1.566620051322E12,
2019
"savedAt": 1.566620263433E12,
20+
"cameraMatrix": {
21+
"elements": [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]
22+
},
2123
"other": "pass through"
2224
}
2325
""".trimIndent()
2426
}
2527
val fromJsonEl by value { Json.Default.parseToJsonElement(fromJson).jsonObject }
26-
fun subject() = V1_EpochToIso8601.migrate(fromJsonEl)
28+
fun subject() = V1_EpochToIso8601AndFixCameraMatrix.migrate(fromJsonEl)
2729

2830
it("converts epoch doubles to iso 8601 strings") {
2931
expect(subject()).toEqual(
3032
buildJsonObject {
3133
put("startedAt", JsonPrimitive("2019-08-24T04:14:11.322Z"))
3234
put("savedAt", JsonPrimitive("2019-08-24T04:17:43.433Z"))
35+
put("cameraMatrix", JsonArray(Matrix4F.identity.elements.map { JsonPrimitive(it.toInt()) }))
3336
put("other", JsonPrimitive("pass through"))
3437
}
3538
)

0 commit comments

Comments
 (0)