Skip to content

Commit

Permalink
solve performance issue in LogsViewModel (?)
Browse files Browse the repository at this point in the history
westnordost committed Feb 12, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent e584a2d commit 314f05f
Showing 3 changed files with 27 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -8,7 +8,6 @@ import androidx.recyclerview.widget.DividerItemDecoration
import de.westnordost.streetcomplete.BuildConfig
import de.westnordost.streetcomplete.R
import de.westnordost.streetcomplete.data.logs.LogMessage
import de.westnordost.streetcomplete.data.logs.format
import de.westnordost.streetcomplete.databinding.FragmentLogsBinding
import de.westnordost.streetcomplete.screens.TwoPaneDetailFragment
import de.westnordost.streetcomplete.util.ktx.now
@@ -62,12 +61,11 @@ class LogsFragment : TwoPaneDetailFragment(R.layout.fragment_logs) {
}

private fun onClickShare() = viewLifecycleScope.launch {
val logText = viewModel.logs.value.format()
val logTimestamp = LocalDateTime.now().toString()
val logTitle = "${BuildConfig.APPLICATION_ID}_${BuildConfig.VERSION_NAME}_$logTimestamp.log"

val shareIntent = Intent(Intent.ACTION_SEND).also {
it.putExtra(Intent.EXTRA_TEXT, logText)
it.putExtra(Intent.EXTRA_TEXT, viewModel.logsText)
it.putExtra(Intent.EXTRA_TITLE, logTitle)
it.type = "text/plain"
}
Original file line number Diff line number Diff line change
@@ -4,9 +4,12 @@ import androidx.lifecycle.ViewModel
import de.westnordost.streetcomplete.data.logs.LogMessage
import de.westnordost.streetcomplete.data.logs.LogsFilters
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow

abstract class LogsViewModel : ViewModel() {
abstract val filters: MutableStateFlow<LogsFilters>
abstract val logs: StateFlow<List<LogMessage>>
abstract val logs: SharedFlow<List<LogMessage>>

abstract val logsText: String
}
Original file line number Diff line number Diff line change
@@ -4,13 +4,13 @@ import androidx.lifecycle.viewModelScope
import de.westnordost.streetcomplete.data.logs.LogMessage
import de.westnordost.streetcomplete.data.logs.LogsController
import de.westnordost.streetcomplete.data.logs.LogsFilters
import de.westnordost.streetcomplete.data.logs.format
import de.westnordost.streetcomplete.util.ktx.systemTimeNow
import de.westnordost.streetcomplete.util.ktx.toEpochMilli
import de.westnordost.streetcomplete.util.ktx.toLocalDate
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.getAndUpdate
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.datetime.LocalDateTime
@@ -23,28 +23,40 @@ class LogsViewModelImpl(
private val logsControllerListener = object : LogsController.Listener {
override fun onAdded(message: LogMessage) {
if (filters.value.matches(message)) {
// TODO this is hugely inefficient (log list is copied every time a single entry is added!!!)
logs.update { it + message }
synchronized(_logs) {
_logs.add(message)
logs.tryEmit(_logs)
}
}
}
}

override val filters: MutableStateFlow<LogsFilters>

override val logs: MutableStateFlow<List<LogMessage>> = MutableStateFlow(emptyList())
override val logs: MutableSharedFlow<List<LogMessage>> = MutableSharedFlow(1)
private val _logs = ArrayList<LogMessage>()

override val logsText: String get() = _logs.format()

init {
val startOfToday = LocalDateTime(systemTimeNow().toLocalDate(), LocalTime(0, 0, 0))
filters = MutableStateFlow(LogsFilters(timestampNewerThan = startOfToday))
viewModelScope.launch {
// get logs initially and subscribe to updates, then
logs.value = withContext(Dispatchers.IO) { logsController.getLogs(filters.value) }
// get logs initially, subscribe to updates and then...
updateLogs(filters.value)
logsController.addListener(logsControllerListener)

// get logs anew whenever filters changed
filters.collect { f ->
logs.update { withContext(Dispatchers.IO) { logsController.getLogs(f) } }
}
filters.collect { f -> updateLogs(f) }
}
}

private suspend fun updateLogs(filters: LogsFilters) {
val newLogs = withContext(Dispatchers.IO) { logsController.getLogs(filters) }
synchronized(_logs) {
_logs.clear()
_logs.addAll(newLogs)
logs.tryEmit(_logs)
}
}

0 comments on commit 314f05f

Please sign in to comment.