mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
refactor: simplify RadioConfigViewModel packet processing
This commit is contained in:
parent
54435fc031
commit
5b43089392
4 changed files with 34 additions and 18 deletions
|
|
@ -18,8 +18,6 @@ import com.geeksville.mesh.Portnums
|
|||
import com.geeksville.mesh.Position
|
||||
import com.geeksville.mesh.android.Logging
|
||||
import com.geeksville.mesh.config
|
||||
import com.geeksville.mesh.database.MeshLogRepository
|
||||
import com.geeksville.mesh.database.entity.MeshLog
|
||||
import com.geeksville.mesh.deviceProfile
|
||||
import com.geeksville.mesh.moduleConfig
|
||||
import com.geeksville.mesh.repository.datastore.RadioConfigRepository
|
||||
|
|
@ -30,7 +28,6 @@ import dagger.hilt.android.lifecycle.HiltViewModel
|
|||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
|
|
@ -58,7 +55,6 @@ data class RadioConfigState(
|
|||
class RadioConfigViewModel @Inject constructor(
|
||||
private val app: Application,
|
||||
private val radioConfigRepository: RadioConfigRepository,
|
||||
meshLogRepository: MeshLogRepository,
|
||||
) : ViewModel(), Logging {
|
||||
|
||||
private var destNum: Int = 0
|
||||
|
|
@ -73,7 +69,7 @@ class RadioConfigViewModel @Inject constructor(
|
|||
val myNodeInfo: StateFlow<MyNodeInfo?> get() = radioConfigRepository.myNodeInfo
|
||||
val ourNodeInfo: StateFlow<NodeInfo?> get() = radioConfigRepository.ourNodeInfo
|
||||
|
||||
private val requestIds = MutableStateFlow<HashMap<Int, Boolean>>(hashMapOf())
|
||||
private val requestIds = MutableStateFlow(hashSetOf<Int>())
|
||||
private val _radioConfigState = MutableStateFlow(RadioConfigState())
|
||||
val radioConfigState: StateFlow<RadioConfigState> = _radioConfigState
|
||||
|
||||
|
|
@ -85,12 +81,9 @@ class RadioConfigViewModel @Inject constructor(
|
|||
_currentDeviceProfile.value = it
|
||||
}.launchIn(viewModelScope)
|
||||
|
||||
viewModelScope.launch {
|
||||
combine(meshLogRepository.getAllLogs(9), requestIds) { list, ids ->
|
||||
val unprocessed = ids.filterValues { !it }.keys.ifEmpty { return@combine emptyList() }
|
||||
list.filter { log -> log.meshPacket?.decoded?.requestId in unprocessed }
|
||||
}.collect { it.forEach(::processPacketResponse) }
|
||||
}
|
||||
radioConfigRepository.meshPacketFlow.onEach(::processPacketResponse)
|
||||
.launchIn(viewModelScope)
|
||||
|
||||
debug("RadioConfigViewModel created")
|
||||
}
|
||||
|
||||
|
|
@ -112,7 +105,7 @@ class RadioConfigViewModel @Inject constructor(
|
|||
val packetId = service.packetId
|
||||
try {
|
||||
requestAction(service, packetId, destNum)
|
||||
requestIds.update { it.apply { put(packetId, false) } }
|
||||
requestIds.update { it.apply { add(packetId) } }
|
||||
_radioConfigState.update { state ->
|
||||
if (state.responseState is ResponseState.Loading) {
|
||||
val total = maxOf(requestIds.value.size, state.responseState.total)
|
||||
|
|
@ -362,7 +355,7 @@ class RadioConfigViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
fun clearPacketResponse() {
|
||||
requestIds.value = hashMapOf()
|
||||
requestIds.value = hashSetOf()
|
||||
_radioConfigState.update { it.copy(responseState = ResponseState.Empty) }
|
||||
}
|
||||
|
||||
|
|
@ -411,9 +404,9 @@ class RadioConfigViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun processPacketResponse(log: MeshLog?) {
|
||||
val packet = log?.meshPacket ?: return
|
||||
private fun processPacketResponse(packet: MeshProtos.MeshPacket) {
|
||||
val data = packet.decoded
|
||||
if (data.requestId !in requestIds.value) return
|
||||
val route = radioConfigState.value.route
|
||||
|
||||
// val destNum = destNode.value?.num ?: return
|
||||
|
|
@ -426,8 +419,8 @@ class RadioConfigViewModel @Inject constructor(
|
|||
if (parsed.errorReason != MeshProtos.Routing.Error.NONE) {
|
||||
setResponseStateError(parsed.errorReason.name)
|
||||
} else if (packet.from == destNum && route.isEmpty()) {
|
||||
requestIds.update { it.apply { put(data.requestId, true) } }
|
||||
if (requestIds.value.filterValues { !it }.isEmpty()) setResponseStateSuccess()
|
||||
requestIds.update { it.apply { remove(data.requestId) } }
|
||||
if (requestIds.value.isEmpty()) setResponseStateSuccess()
|
||||
else incrementCompleted()
|
||||
}
|
||||
}
|
||||
|
|
@ -498,7 +491,7 @@ class RadioConfigViewModel @Inject constructor(
|
|||
|
||||
else -> TODO()
|
||||
}
|
||||
requestIds.update { it.apply { put(data.requestId, true) } }
|
||||
requestIds.update { it.apply { remove(data.requestId) } }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import com.geeksville.mesh.ConfigProtos.Config
|
|||
import com.geeksville.mesh.IMeshService
|
||||
import com.geeksville.mesh.LocalOnlyProtos.LocalConfig
|
||||
import com.geeksville.mesh.LocalOnlyProtos.LocalModuleConfig
|
||||
import com.geeksville.mesh.MeshProtos.MeshPacket
|
||||
import com.geeksville.mesh.ModuleConfigProtos.ModuleConfig
|
||||
import com.geeksville.mesh.MyNodeInfo
|
||||
import com.geeksville.mesh.NodeInfo
|
||||
|
|
@ -16,7 +17,9 @@ import com.geeksville.mesh.model.NodeDB
|
|||
import com.geeksville.mesh.model.getChannelUrl
|
||||
import com.geeksville.mesh.service.MeshService.ConnectionState
|
||||
import com.geeksville.mesh.service.ServiceRepository
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.firstOrNull
|
||||
|
|
@ -167,6 +170,12 @@ class RadioConfigRepository @Inject constructor(
|
|||
serviceRepository.clearErrorMessage()
|
||||
}
|
||||
|
||||
val meshPacketFlow: SharedFlow<MeshPacket> get() = serviceRepository.meshPacketFlow
|
||||
|
||||
suspend fun emitMeshPacket(packet: MeshPacket) = coroutineScope {
|
||||
serviceRepository.emitMeshPacket(packet)
|
||||
}
|
||||
|
||||
val tracerouteResponse: StateFlow<String?> get() = serviceRepository.tracerouteResponse
|
||||
|
||||
fun setTracerouteResponse(value: String?) {
|
||||
|
|
|
|||
|
|
@ -997,6 +997,10 @@ class MeshService : Service(), Logging {
|
|||
)
|
||||
insertMeshLog(packetToSave)
|
||||
|
||||
serviceScope.handledLaunch {
|
||||
radioConfigRepository.emitMeshPacket(packet)
|
||||
}
|
||||
|
||||
// Update last seen for the node that sent the packet, but also for _our node_ because anytime a packet passes
|
||||
// through our node on the way to the phone that means that local node is also alive in the mesh
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
package com.geeksville.mesh.service
|
||||
|
||||
import com.geeksville.mesh.IMeshService
|
||||
import com.geeksville.mesh.MeshProtos.MeshPacket
|
||||
import com.geeksville.mesh.android.Logging
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
|
@ -39,6 +42,13 @@ class ServiceRepository @Inject constructor() : Logging {
|
|||
_errorMessage.value = null
|
||||
}
|
||||
|
||||
private val _meshPacketFlow = MutableSharedFlow<MeshPacket>()
|
||||
val meshPacketFlow: SharedFlow<MeshPacket> get() = _meshPacketFlow
|
||||
|
||||
suspend fun emitMeshPacket(packet: MeshPacket) {
|
||||
_meshPacketFlow.emit(packet)
|
||||
}
|
||||
|
||||
private val _tracerouteResponse = MutableStateFlow<String?>(null)
|
||||
val tracerouteResponse: StateFlow<String?> get() = _tracerouteResponse
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue