Skip to content

Commit

Permalink
Merge branch 'etch_split'
Browse files Browse the repository at this point in the history
  • Loading branch information
hufman committed Sep 23, 2024
2 parents 5cde9be + b00d5e0 commit 6984020
Show file tree
Hide file tree
Showing 41 changed files with 252 additions and 231 deletions.
2 changes: 1 addition & 1 deletion .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion .idea/gradle.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/kotlinc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 10 additions & 4 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ kotlin {
implementation(libs.compose.material3.android)
implementation(libs.cache4k)
implementation(libs.pngj)

implementation(projects.iDriveConnectKit)
}

commonMain.dependencies {
Expand All @@ -56,6 +54,7 @@ kotlin {
implementation(compose.ui)
@OptIn(ExperimentalComposeLibrary::class)
implementation(compose.components.resources)
implementation(libs.idriveconnectkit)

// api(libs.moko.compose)
implementation(libs.kotlinx.datetime)
Expand All @@ -66,6 +65,13 @@ kotlin {

implementation(compose.components.uiToolingPreview)
}

@Suppress("OPT_IN_USAGE")
wasmJs {
dependencies {
// implementation(libs.idriveconnectkit.wasmJs)
}
}
}
}

Expand Down Expand Up @@ -129,8 +135,8 @@ compose.experimental {
web.application {}
}

tasks.named("preBuild").dependsOn(":IDriveConnectKit:compileEtch")
tasks.named("preBuild").dependsOn(":IDriveConnectKit:extractEtchRuntime")
//tasks.named("preBuild").dependsOn(":IDriveConnectKit:compileEtch")
//tasks.named("preBuild").dependsOn(":IDriveConnectKit:extractEtchRuntime")


//tasks["desugarDebugFileDependencies"].dependsOn("extractEtchRuntime")
Expand Down
17 changes: 4 additions & 13 deletions app/src/androidMain/java/io/bimmergestalt/headunit/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,12 @@ import androidx.compose.animation.animateColorAsState
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Home
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
Expand All @@ -33,12 +25,10 @@ import cafe.adriel.voyager.transitions.SlideTransition
import io.bimmergestalt.headunit.bcl.ServerService
import io.bimmergestalt.headunit.models.RHMIAppsModel
import io.bimmergestalt.headunit.models.ThemeSettings
import io.bimmergestalt.headunit.screens.HeadunitScreen
import io.bimmergestalt.headunit.screens.HomeScreen
import io.bimmergestalt.headunit.ui.screens.HomeScreen
import io.bimmergestalt.headunit.ui.components.Background
import io.bimmergestalt.headunit.ui.components.StaticTopBar
import io.bimmergestalt.headunit.ui.components.TopBar
import io.bimmergestalt.headunit.ui.screens.AppListScreen
import io.bimmergestalt.headunit.ui.screens.RHMIScreen
import io.bimmergestalt.headunit.ui.theme.Appearance
import io.bimmergestalt.headunit.ui.theme.HeadunitktAndroidTheme
Expand Down Expand Up @@ -81,8 +71,9 @@ fun Contents() {
color = background
) {
// Greeting("Android")
val homeScreen = AppListScreen
// val homeScreen = AppListScreen
// val homeScreen = if (Theme.appearance == Appearance.Material) AppListScreen else HomeScreen
val homeScreen = HomeScreen
Navigator(homeScreen) { navigator ->
Background(navigator)
SlideTransition(navigator) { screen ->
Expand All @@ -98,7 +89,7 @@ fun Contents() {
}
StaticTopBar(navigator = navigator)

LaunchedEffectAndCollect(flow = RHMIAppsModel.incomingEvents) { incomingEvent ->
LaunchedEffectAndCollect<io.bimmergestalt.headunit.models.RHMIEvent>(flow = RHMIAppsModel.incomingEvents) { incomingEvent ->
Log.i("MainActivity", "Examining incomingEvent $incomingEvent")
val app = RHMIAppsModel.knownApps[incomingEvent.appId]
val event = app?.resources?.app?.events?.get(incomingEvent.eventId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package io.bimmergestalt.headunit.managers

import android.os.Handler
import android.os.HandlerThread
import android.os.Looper
import android.util.Log
import de.bmw.idrive.BMWRemoting
import de.bmw.idrive.BMWRemoting.RHMIDataTable
Expand All @@ -13,13 +14,16 @@ import io.bimmergestalt.headunit.models.RHMIAppInfo
import io.bimmergestalt.headunit.models.RHMIApps
import io.bimmergestalt.headunit.models.RHMIEvent
import io.bimmergestalt.headunit.rhmi.RHMIResources
import io.bimmergestalt.headunit.rhmi.loadResources
import io.bimmergestalt.headunit.utils.asEtchIntOrAny
import io.bimmergestalt.headunit.utils.decodeImage
import io.bimmergestalt.headunit.utils.isSameSize
import io.bimmergestalt.headunit.utils.merge
import io.bimmergestalt.headunit.utils.overlaps
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.android.asCoroutineDispatcher
import kotlinx.coroutines.runBlocking
import java.util.Collections.max
import java.util.concurrent.ConcurrentHashMap

Expand All @@ -31,6 +35,7 @@ class RHMIManager(val state: RHMIApps) {

private val ioThread = HandlerThread("toEtchClients").apply { start() }
private val ioHandler = Handler(ioThread.looper)
private val uiHandler = Handler(Looper.getMainLooper())

fun registerApp(handle: Int, appId: String, resourceData: Map<RHMIResourceType, List<ByteArray>>) {
val existing = state.knownApps[appId]
Expand Down Expand Up @@ -127,20 +132,28 @@ class RHMIManager(val state: RHMIApps) {
existing.fromRow, existing.numRows, existing.totalRows,
existing.fromColumn, existing.numColumns, existing.totalColumns)
replacement.merge(parsedValue)
app.resources.app.setModel(modelId, replacement)
runBlocking(uiHandler.asCoroutineDispatcher()) {
app.resources.app.setModel(modelId, replacement)
}
return
} catch (e: IllegalArgumentException) {
// unable to merge this table update, just replace like normal
}
}
app.resources.app.setModel(modelId, parsedValue)
runBlocking(uiHandler.asCoroutineDispatcher()) {
app.resources.app.setModel(modelId, parsedValue)
}
} else {
app.resources.app.setModel(modelId, parsedValue?.asEtchIntOrAny())
runBlocking(uiHandler.asCoroutineDispatcher()) {
app.resources.app.setModel(modelId, parsedValue?.asEtchIntOrAny())
}
}

}
fun setProperty(appId: String, componentId: Int, propertyId: Int, value: Any?) {
state.knownApps[appId]?.resources?.app?.setProperty(componentId, propertyId, value)
runBlocking(uiHandler.asCoroutineDispatcher()) {
state.knownApps[appId]?.resources?.app?.setProperty(componentId, propertyId, value)
}
}
fun triggerEvent(appId: String, eventId: Int, args: Map<Int, Any?>) {
Log.i(TAG, "Triggering event $appId $eventId")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package io.bimmergestalt.headunit.rhmi

import android.os.Handler
import android.os.Looper
import android.util.Log
import de.bmw.idrive.BMWRemoting
import io.bimmergestalt.headunit.models.ImageModel
import io.bimmergestalt.headunit.models.ImageTintable
import io.bimmergestalt.headunit.utils.decodeAndCacheImage
import io.bimmergestalt.idriveconnectkit.rhmi.RHMIModel
import io.bimmergestalt.idriveconnectkit.rhmi.deserialization.loadFromXML
import kotlinx.coroutines.android.asCoroutineDispatcher
import kotlinx.coroutines.runBlocking
import java.io.ByteArrayInputStream
import java.util.zip.ZipInputStream

fun RHMIResources.Companion.loadResources(incoming: Map<BMWRemoting.RHMIResourceType, List<ByteArray>>): RHMIResources {
val app = RHMIApplicationState()
app.loadFromXML(incoming[BMWRemoting.RHMIResourceType.DESCRIPTION]!!.first())

// convert any ImageIds and RaImages to a generic Model
app.models.keys.forEach { id ->
if (app.models[id] is RHMIModel.ImageIdModel ||
app.models[id] is RHMIModel.RaImageModel) {
app.models[id] = ImageModel(app, id)
}
}

val textFiles = incoming.getOrDefault(BMWRemoting.RHMIResourceType.TEXTDB, emptyList()).map {
loadZipfile(it)
}.fold(HashMap<String, ByteArray>()) { acc, cur ->
acc.putAll(cur); acc
}.mapKeys { it.key.split('.').first()
}.mapValues {
loadTextDb(it.value.decodeToString())
}
Log.i("Resources", "Loaded textDb $textFiles")

@Suppress("UNCHECKED_CAST")
val iconFiles = incoming.getOrDefault(BMWRemoting.RHMIResourceType.IMAGEDB, emptyList()).map {
loadZipfile(it)
}.fold(HashMap<String, ByteArray>()) { acc, cur ->
acc.putAll(cur); acc
}.mapKeys { it.key.split('.').first().toInt() }.mapValues {
runBlocking { it.value.decodeAndCacheImage(true) }
}.filterValues {
it != null
} as Map<Int, ImageTintable>

// convert any hardcoded ImageIds to their ImageBitmaps
app.modelStates.keys.forEach {
val value = app.modelStates[it]
if (value is BMWRemoting.RHMIResourceIdentifier && value.type == BMWRemoting.RHMIResourceType.IMAGEID) {
app.modelStates[it] = iconFiles[value.id]
}
}

return RHMIResources(app, textFiles, iconFiles)
}

fun loadZipfile(input: ByteArray): Map<String, ByteArray> {
val output = HashMap<String, ByteArray>()
// based on https://stackoverflow.com/a/66683493/169035
val zip = ZipInputStream(ByteArrayInputStream(input))
zip.use {
generateSequence { it.nextEntry }.forEach {
output[it.name] = zip.readBytes()
}
}
return output
}

fun loadTextDb(input: String): Map<Int, String> {
return input.lines()
.map { it.split('=', limit = 2) }
.filter { it.size == 2 && it[0].toIntOrNull() != null }
.associate { it[0].toInt() to it[1] }
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,13 @@ import headunit_kt.app.generated.resources.ic_carinfo
import io.bimmergestalt.headunit.models.AMAppsModel
import io.bimmergestalt.headunit.models.ImageTintable
import io.bimmergestalt.headunit.models.RHMIAppsModel
import io.bimmergestalt.headunit.screens.SettingsScreen
import io.bimmergestalt.headunit.ui.components.AppList
import io.bimmergestalt.headunit.ui.components.AppListEntry
import org.jetbrains.compose.resources.ExperimentalResourceApi
import org.jetbrains.compose.resources.imageResource


object AppListScreen: Screen {
object MainScreen: Screen {
@OptIn(ExperimentalResourceApi::class)
@Composable
override fun Content() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import io.bimmergestalt.headunit.screens.HeadunitScreen
import io.bimmergestalt.headunit.ui.screens.HeadunitScreen
import io.bimmergestalt.headunit.ui.components.CalendarEvent
import io.bimmergestalt.headunit.ui.components.CalendarMonth
import kotlinx.datetime.Clock
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.bimmergestalt.headunit.apps.calendar

import androidx.compose.runtime.Composable
import io.bimmergestalt.headunit.screens.HeadunitScreen
import io.bimmergestalt.headunit.ui.screens.HeadunitScreen
import io.bimmergestalt.headunit.ui.components.CalendarDayView
import io.bimmergestalt.headunit.ui.components.CalendarEvent
import kotlinx.datetime.LocalDate
Expand Down
Loading

0 comments on commit 6984020

Please sign in to comment.