From c0644b4c7005316e5bec57ff588b1c8146cd2b14 Mon Sep 17 00:00:00 2001 From: 2ndbeam <2ndbeam@disroot.org> Date: Thu, 7 Aug 2025 16:48:06 +0300 Subject: [PATCH] I push my tiles into my database --- .idea/deviceManager.xml | 13 ++++ .../com/mirenkov/ktheightmap/MainActivity.kt | 7 +- .../mirenkov/ktheightmap/SettingsActivity.kt | 75 +++++++++++++------ .../mirenkov/ktheightmap/TileRepository.kt | 16 +++- .../com/mirenkov/ktheightmap/TileViewModel.kt | 2 +- 5 files changed, 81 insertions(+), 32 deletions(-) create mode 100644 .idea/deviceManager.xml diff --git a/.idea/deviceManager.xml b/.idea/deviceManager.xml new file mode 100644 index 0000000..91f9558 --- /dev/null +++ b/.idea/deviceManager.xml @@ -0,0 +1,13 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/mirenkov/ktheightmap/MainActivity.kt b/app/src/main/java/com/mirenkov/ktheightmap/MainActivity.kt index 639fdd8..48b87a0 100644 --- a/app/src/main/java/com/mirenkov/ktheightmap/MainActivity.kt +++ b/app/src/main/java/com/mirenkov/ktheightmap/MainActivity.kt @@ -3,15 +3,11 @@ package com.mirenkov.ktheightmap import android.app.Application import android.content.Intent import android.os.Bundle -import android.util.Log import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.BoxWithConstraints -import androidx.compose.foundation.layout.absoluteOffset -import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding @@ -24,7 +20,6 @@ import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme.colorScheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Slider -import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableFloatStateOf @@ -76,7 +71,7 @@ class MainActivity : ComponentActivity() { @Composable fun Main(vm: TileViewModel = viewModel()) { - var sliderValue = rememberSaveable { mutableFloatStateOf(1F) } + val sliderValue = rememberSaveable { mutableFloatStateOf(1F) } KtHeightMapTheme { Box(modifier = Modifier.background(color = colorScheme.background)) { Scaffold( diff --git a/app/src/main/java/com/mirenkov/ktheightmap/SettingsActivity.kt b/app/src/main/java/com/mirenkov/ktheightmap/SettingsActivity.kt index df37348..8cb2376 100644 --- a/app/src/main/java/com/mirenkov/ktheightmap/SettingsActivity.kt +++ b/app/src/main/java/com/mirenkov/ktheightmap/SettingsActivity.kt @@ -1,22 +1,27 @@ package com.mirenkov.ktheightmap -import android.graphics.BitmapFactory +import android.app.Application import android.os.Bundle import android.util.Log import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge +import androidx.activity.result.ActivityResultLauncher import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.safeDrawingPadding import androidx.compose.material3.Button import androidx.compose.material3.Text +import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner +import androidx.lifecycle.viewmodel.compose.viewModel import com.mirenkov.ktheightmap.ui.theme.KtHeightMapTheme import com.nareshchocha.filepickerlibrary.FilePickerResultContracts +import com.nareshchocha.filepickerlibrary.models.DocumentFilePickerConfig import com.nareshchocha.filepickerlibrary.models.FilePickerResult -import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch import java.io.FileInputStream @@ -25,7 +30,10 @@ import java.util.zip.ZipInputStream class SettingsActivity : ComponentActivity() { - var filePath: String? = null + companion object { + var filePath: String? = null + } + fun filePickerResult(result: FilePickerResult): String? { if (result.errorMessage != null) { Log.e(TAG, result.errorMessage ?: "") @@ -41,47 +49,72 @@ class SettingsActivity : ComponentActivity() { } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - val launcher = registerForActivityResult(FilePickerResultContracts.PickDocumentFile(), + val launcher = registerForActivityResult(FilePickerResultContracts.PickDocumentFile()) { result -> filePath = filePickerResult(result) } - ) enableEdgeToEdge() setContent { - val coroutineScope = rememberCoroutineScope() - - KtHeightMapTheme { - Column(Modifier.fillMaxSize() - .safeDrawingPadding()) { - Button(onClick = { - launcher.launch(null) - }) { Text(text = "Select database") } - Button(onClick = { coroutineScope.launch { processZip(filePath) } }) { - Text(text = "Load database") - } - } + val owner = LocalViewModelStoreOwner.current + owner?.let { + val viewModel: TileViewModel = viewModel( + it, + "TileViewModel2", + TileViewModelFactory(LocalContext.current.applicationContext as Application) + ) + SettingsMain(viewModel, launcher) } } } } -suspend fun processZip(filePath: String?) = coroutineScope { +@Composable +fun SettingsMain(vm: TileViewModel, launcher: ActivityResultLauncher) { + val coroutineScope = rememberCoroutineScope() + KtHeightMapTheme { + Column(Modifier.fillMaxSize() + .safeDrawingPadding()) { + Button(onClick = { + launcher.launch(null) + }) { Text(text = "Select database") } + Button(onClick = { coroutineScope.launch { + processZip(SettingsActivity.filePath).forEach { + with(vm.repository) { + val t = getTile(it.x, it.y, it.level) + if (t == null) { + pushTile(it) + Log.i(TAG, "pushed to db: %d, %d, %d".format(it.level, it.x, it.y)) + } + else + Log.i(TAG, "found in db: %d, %d, %d".format(t.level, t.x, t.y)) + } + } + } }) { Text(text = "Load database") } + } + } +} + +suspend fun processZip(filePath: String?): List = coroutineScope { + val list: MutableList = mutableListOf() filePath?.let { ZipInputStream(FileInputStream(it)).use { zipInputStream -> var entry = zipInputStream.nextEntry while (true) { if (entry.name.endsWith(".jpg")) { Log.i(TAG, entry.name) - processEntry(zipInputStream, entry) + val tile = processEntry(zipInputStream, entry) + list.add(tile) } entry = zipInputStream.nextEntry if (entry == null) break } + Log.i(TAG, "got list") } } + return@coroutineScope list } -fun processEntry(zis: ZipInputStream, entry: ZipEntry) { +fun processEntry(zis: ZipInputStream, entry: ZipEntry): Tile { val ba = ByteArray(entry.size.toInt()) var offset = 0 var size = zis.read(ba, 0, ba.size) @@ -93,5 +126,5 @@ fun processEntry(zis: ZipInputStream, entry: ZipEntry) { val ( level, x, y ) = regex.findAll(entry.name).map { it.value.toInt() }.toList() val base64 = ba.toBase64() - val tile = Tile(x, y, level, base64) + return Tile(x, y, level, base64) } \ No newline at end of file diff --git a/app/src/main/java/com/mirenkov/ktheightmap/TileRepository.kt b/app/src/main/java/com/mirenkov/ktheightmap/TileRepository.kt index ef3e5e5..0626e58 100644 --- a/app/src/main/java/com/mirenkov/ktheightmap/TileRepository.kt +++ b/app/src/main/java/com/mirenkov/ktheightmap/TileRepository.kt @@ -1,20 +1,28 @@ package com.mirenkov.ktheightmap +import android.util.Log import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.async +import kotlinx.coroutines.launch class TileRepository(private val tileDao: TileDao) { private val coroutineScope = CoroutineScope(Dispatchers.Main) fun pushTile(tile: Tile) { - tileDao.pushTile(tile) + coroutineScope.launch(Dispatchers.IO) { tileDao.pushTile(tile) } } - fun getTile(x: Int, y: Int, level: Int): Tile? { - return tileDao.getTile(x, y, level) + @OptIn(ExperimentalCoroutinesApi::class) + suspend fun getTile(x: Int, y: Int, level: Int): Tile? { + val tileDeferred = coroutineScope.async(Dispatchers.IO) { + tileDao.getTile(x, y, level) + } + return tileDeferred.await() } fun clearTiles() { - tileDao.clearTiles() + coroutineScope.launch(Dispatchers.IO) { tileDao.clearTiles() } } } \ No newline at end of file diff --git a/app/src/main/java/com/mirenkov/ktheightmap/TileViewModel.kt b/app/src/main/java/com/mirenkov/ktheightmap/TileViewModel.kt index cbd9a14..bd2d9bf 100644 --- a/app/src/main/java/com/mirenkov/ktheightmap/TileViewModel.kt +++ b/app/src/main/java/com/mirenkov/ktheightmap/TileViewModel.kt @@ -5,7 +5,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.lifecycle.ViewModel class TileViewModel(application: Application): ViewModel() { - private val repository: TileRepository + val repository: TileRepository init { val tileDb = TileDB.getInstance(application)