diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesViewModel.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesViewModel.kt index 684b32c2..ae19fe10 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesViewModel.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesViewModel.kt @@ -41,9 +41,16 @@ class PassesViewModel @Inject constructor( init { viewModelScope.launch { - predictor.passes.collect { passes -> + predictor.calculatedPasses.collect { passes -> passesProcessing?.cancelAndJoin() - passesProcessing = viewModelScope.launch { tickPasses(passes) } + passesProcessing = viewModelScope.launch { + while (isActive) { + val time = System.currentTimeMillis() + val newPasses = predictor.processPasses(passes, time) + _passes.postValue(DataState.Success(newPasses)) + delay(1000) + } + } } } } @@ -70,25 +77,4 @@ class PassesViewModel @Inject constructor( settings.setHoursAhead(hoursAhead) settings.setMinElevation(minElevation) } - - private suspend fun tickPasses(passes: List) = withContext(Dispatchers.Default) { - var currentPasses = passes - while (isActive) { - val timeNow = System.currentTimeMillis() - currentPasses.forEach { pass -> - if (!pass.isDeepSpace) { - val timeStart = pass.aosTime - if (timeNow > timeStart) { - val deltaNow = timeNow.minus(timeStart).toFloat() - val deltaTotal = pass.losTime.minus(timeStart).toFloat() - pass.progress = ((deltaNow / deltaTotal) * 100).toInt() - } - } - } - currentPasses = currentPasses.filter { it.progress < 100 } - val passesCopy = currentPasses.map { it.copy() } - _passes.postValue(DataState.Success(passesCopy)) - delay(1000) - } - } } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/radarScreen/RadarViewModel.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/radarScreen/RadarViewModel.kt index 8c2bc8bc..558aee65 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/radarScreen/RadarViewModel.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/radarScreen/RadarViewModel.kt @@ -54,7 +54,7 @@ class RadarViewModel @Inject constructor( val orientation: LiveData> = _orientation fun getPass(catNum: Int, aosTime: Long) = liveData { - predictor.passes.collect { passes -> + predictor.calculatedPasses.collect { passes -> val pass = passes.find { it.catNum == catNum && it.aosTime == aosTime } pass?.let { satPass -> emit(satPass) @@ -105,21 +105,13 @@ class RadarViewModel @Inject constructor( } } - private fun processTransmitters(satPass: SatPass) { + private fun processTransmitters(pass: SatPass) { viewModelScope.launch { - val transmitters = dataRepository.getTransmitters(satPass.catNum) + val transmitters = dataRepository.getTransmitters(pass.catNum) while (isActive) { - val satPos = predictor.getSatPos(satPass.satellite, stationPos, Date().time) - val copiedList = transmitters.map { it.copy() } - copiedList.forEach { transmitter -> - transmitter.downlink?.let { - transmitter.downlink = satPos.getDownlinkFreq(it) - } - transmitter.uplink?.let { - transmitter.uplink = satPos.getUplinkFreq(it) - } - } - _transmitters.postValue(copiedList.map { it.copy() }) + val time = System.currentTimeMillis() + val list = predictor.processRadios(pass.satellite, stationPos, transmitters, time) + _transmitters.postValue(list) delay(1000) } } diff --git a/core/src/main/java/com/rtbishop/look4sat/domain/predict/Predictor.kt b/core/src/main/java/com/rtbishop/look4sat/domain/predict/Predictor.kt index 582d3a8d..5f61d544 100644 --- a/core/src/main/java/com/rtbishop/look4sat/domain/predict/Predictor.kt +++ b/core/src/main/java/com/rtbishop/look4sat/domain/predict/Predictor.kt @@ -17,6 +17,7 @@ */ package com.rtbishop.look4sat.domain.predict +import com.rtbishop.look4sat.domain.model.Transmitter import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.SharedFlow @@ -24,9 +25,8 @@ import kotlinx.coroutines.withContext class Predictor(private val predictorDispatcher: CoroutineDispatcher) { - private val _passes = MutableSharedFlow>(replay = 1) - private var selectedSatIds = emptyList() - val passes: SharedFlow> = _passes + private val _calculatedPasses = MutableSharedFlow>(replay = 1) + val calculatedPasses: SharedFlow> = _calculatedPasses suspend fun getSatPos(sat: Satellite, pos: GeoPos, time: Long): SatPos { return withContext(predictorDispatcher) { sat.getPosition(pos, time) } @@ -44,40 +44,55 @@ class Predictor(private val predictorDispatcher: CoroutineDispatcher) { } } - suspend fun triggerCalculation( - satellites: List, - pos: GeoPos, - time: Long, - hoursAhead: Int = 8, - minElevation: Double = 16.0 - ) { - if (satellites.isEmpty()) { - _passes.emit(emptyList()) - } else { - val newCatNums = satellites.map { it.params.catnum } - if (selectedSatIds != newCatNums) { - forceCalculation(satellites, pos, time, hoursAhead, minElevation) + suspend fun processRadios(sat: Satellite, pos: GeoPos, radios: List, time: Long): List { + return withContext(predictorDispatcher) { + val satPos = sat.getPosition(pos, time) + val copiedList = radios.map { it.copy() } + copiedList.forEach { transmitter -> + transmitter.downlink?.let { + transmitter.downlink = satPos.getDownlinkFreq(it) + } + transmitter.uplink?.let { + transmitter.uplink = satPos.getUplinkFreq(it) + } } + copiedList.map { it.copy() } + } + } + + suspend fun processPasses(passList: List, time: Long): List { + return withContext(predictorDispatcher) { + val copiedList = passList.map { it.copy() } + copiedList.forEach { pass -> + if (!pass.isDeepSpace) { + val timeStart = pass.aosTime + if (time > timeStart) { + val deltaNow = time.minus(timeStart).toFloat() + val deltaTotal = pass.losTime.minus(timeStart).toFloat() + pass.progress = ((deltaNow / deltaTotal) * 100).toInt() + } + } + } + copiedList.filter { it.progress < 100 }.map { it.copy() } } } suspend fun forceCalculation( - satellites: List, + satList: List, pos: GeoPos, time: Long, hoursAhead: Int = 8, minElevation: Double = 16.0 ) { - if (satellites.isEmpty()) { - _passes.emit(emptyList()) + if (satList.isEmpty()) { + _calculatedPasses.emit(emptyList()) } else { withContext(predictorDispatcher) { val allPasses = mutableListOf() - selectedSatIds = satellites.map { it.params.catnum } - satellites.forEach { satellite -> + satList.forEach { satellite -> allPasses.addAll(satellite.getPasses(pos, time, hoursAhead)) } - _passes.emit(allPasses.filter(time, hoursAhead, minElevation)) + _calculatedPasses.emit(allPasses.filter(time, hoursAhead, minElevation)) } } }