Merge pull request #120 from nightscout/adrian/graph-update

refactor update graph and prevent crash if view is no longer available.
This commit is contained in:
Milos Kozak 2020-12-16 00:06:33 +01:00 committed by GitHub
commit 756c76f591
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -37,11 +37,7 @@ import info.nightscout.androidaps.dialogs.InsulinDialog
import info.nightscout.androidaps.dialogs.TreatmentDialog import info.nightscout.androidaps.dialogs.TreatmentDialog
import info.nightscout.androidaps.dialogs.WizardDialog import info.nightscout.androidaps.dialogs.WizardDialog
import info.nightscout.androidaps.events.* import info.nightscout.androidaps.events.*
import info.nightscout.androidaps.interfaces.ActivePluginProvider import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.aps.loop.events.EventNewOpenLoopNotification import info.nightscout.androidaps.plugins.aps.loop.events.EventNewOpenLoopNotification
@ -76,36 +72,16 @@ import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.overview_buttons_layout.* import kotlinx.android.synthetic.main.overview_buttons_layout.*
import kotlinx.android.synthetic.main.overview_buttons_layout.overview_carbsbutton
import kotlinx.android.synthetic.main.overview_buttons_layout.overview_insulinbutton
import kotlinx.android.synthetic.main.overview_buttons_layout.overview_quickwizardbutton
import kotlinx.android.synthetic.main.overview_buttons_layout.overview_treatmentbutton
import kotlinx.android.synthetic.main.overview_buttons_layout.overview_wizardbutton
import kotlinx.android.synthetic.main.overview_fragment.overview_notifications import kotlinx.android.synthetic.main.overview_fragment.overview_notifications
import kotlinx.android.synthetic.main.overview_fragment_nsclient.* import kotlinx.android.synthetic.main.overview_fragment_nsclient.*
import kotlinx.android.synthetic.main.overview_graphs_layout.overview_bggraph import kotlinx.android.synthetic.main.overview_graphs_layout.*
import kotlinx.android.synthetic.main.overview_graphs_layout.overview_chartMenuButton
import kotlinx.android.synthetic.main.overview_graphs_layout.overview_iobcalculationprogess
import kotlinx.android.synthetic.main.overview_graphs_layout.overview_iobgraph
import kotlinx.android.synthetic.main.overview_info_layout.* import kotlinx.android.synthetic.main.overview_info_layout.*
import kotlinx.android.synthetic.main.overview_info_layout.overview_arrow
import kotlinx.android.synthetic.main.overview_info_layout.overview_basebasal
import kotlinx.android.synthetic.main.overview_info_layout.overview_bg
import kotlinx.android.synthetic.main.overview_info_layout.overview_cob
import kotlinx.android.synthetic.main.overview_info_layout.overview_extendedbolus
import kotlinx.android.synthetic.main.overview_info_layout.overview_iob
import kotlinx.android.synthetic.main.overview_info_layout.overview_sensitivity
import kotlinx.android.synthetic.main.overview_info_layout.overview_time
import kotlinx.android.synthetic.main.overview_info_layout.overview_timeagoshort
import kotlinx.android.synthetic.main.overview_loop_pumpstatus_layout.* import kotlinx.android.synthetic.main.overview_loop_pumpstatus_layout.*
import kotlinx.android.synthetic.main.overview_statuslights_layout.* import kotlinx.android.synthetic.main.overview_statuslights_layout.*
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.util.* import java.util.*
import java.util.concurrent.Executors
import java.util.concurrent.ScheduledFuture
import java.util.concurrent.TimeUnit
import javax.inject.Inject import javax.inject.Inject
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
import kotlin.math.abs import kotlin.math.abs
@ -155,9 +131,6 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
private var loopHandler = Handler() private var loopHandler = Handler()
private var refreshLoop: Runnable? = null private var refreshLoop: Runnable? = null
private val worker = Executors.newSingleThreadScheduledExecutor()
private var scheduledUpdate: ScheduledFuture<*>? = null
private val secondaryGraphs = ArrayList<GraphView>() private val secondaryGraphs = ArrayList<GraphView>()
private val secondaryGraphsLabel = ArrayList<TextView>() private val secondaryGraphsLabel = ArrayList<TextView>()
@ -522,21 +495,19 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
} }
} }
var task: Runnable? = null
private fun scheduleUpdateGUI(from: String) { private fun scheduleUpdateGUI(from: String) {
class UpdateRunnable : Runnable { class UpdateRunnable : Runnable {
override fun run() { override fun run() {
activity?.runOnUiThread {
updateGUI(from) updateGUI(from)
scheduledUpdate = null task = null
} }
} }
} view?.removeCallbacks(task)
// prepare task for execution in 500 milliseconds task = UpdateRunnable()
// cancel waiting task to prevent multiple updates view?.postDelayed(task, 500)
scheduledUpdate?.cancel(false)
val task: Runnable = UpdateRunnable()
scheduledUpdate = worker.schedule(task, 500, TimeUnit.MILLISECONDS)
} }
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
@ -562,6 +533,14 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
val units = profileFunction.getUnits() val units = profileFunction.getUnits()
val lowLine = defaultValueHelper.determineLowLine() val lowLine = defaultValueHelper.determineLowLine()
val highLine = defaultValueHelper.determineHighLine() val highLine = defaultValueHelper.determineHighLine()
val lastRun = loopPlugin.lastRun
val predictionsAvailable = if (config.APS) lastRun?.request?.hasPredictions == true else config.NSCLIENT
try {
updateGraph(lastRun, predictionsAvailable, lowLine, highLine, pump, profile)
} catch (e: IllegalStateException) {
return // view no longer exists
}
//Start with updating the BG as it is unaffected by loop. //Start with updating the BG as it is unaffected by loop.
// **** BG value **** // **** BG value ****
@ -664,8 +643,6 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
overview_apsmode_text?.visibility = View.GONE overview_apsmode_text?.visibility = View.GONE
overview_time_llayout?.visibility = View.VISIBLE overview_time_llayout?.visibility = View.VISIBLE
} }
val lastRun = loopPlugin.lastRun
val predictionsAvailable = if (config.APS) lastRun?.request?.hasPredictions == true else config.NSCLIENT
// temp target // temp target
val tempTarget = treatmentsPlugin.tempTargetFromHistory val tempTarget = treatmentsPlugin.tempTargetFromHistory
@ -803,8 +780,9 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList
iobCobCalculatorPlugin.getLastAutosensData("Overview")?.let { autosensData -> iobCobCalculatorPlugin.getLastAutosensData("Overview")?.let { autosensData ->
String.format(Locale.ENGLISH, "%.0f%%", autosensData.autosensResult.ratio * 100) String.format(Locale.ENGLISH, "%.0f%%", autosensData.autosensResult.ratio * 100)
} ?: "" } ?: ""
}
// ****** GRAPH ******* private fun updateGraph(lastRun: LoopInterface.LastRun?, predictionsAvailable: Boolean, lowLine: Double, highLine: Double, pump: PumpInterface, profile: Profile) {
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) { viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
overview_bggraph ?: return@launch overview_bggraph ?: return@launch
val graphData = GraphData(injector, overview_bggraph, iobCobCalculatorPlugin, treatmentsPlugin) val graphData = GraphData(injector, overview_bggraph, iobCobCalculatorPlugin, treatmentsPlugin)