Fixes calculation refresh problem

bs
Laurent 5 years ago
parent 50ff357afa
commit b125e94dda
  1. 7
      app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt
  2. 4
      app/src/main/java/net/pokeranalytics/android/ui/fragment/ImportFragment.kt
  3. 1
      app/src/main/java/net/pokeranalytics/android/ui/fragment/ReportsFragment.kt
  4. 43
      app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticsFragment.kt
  5. 50
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/RealmFragment.kt
  6. 4
      app/src/main/java/net/pokeranalytics/android/ui/fragment/report/ComposableTableReportFragment.kt
  7. 5
      app/src/main/java/net/pokeranalytics/android/ui/modules/bankroll/BankrollFragment.kt
  8. 72
      app/src/main/java/net/pokeranalytics/android/ui/modules/calendar/CalendarFragment.kt
  9. 4
      app/src/main/java/net/pokeranalytics/android/ui/modules/session/SessionFragment.kt

@ -18,6 +18,7 @@ import net.pokeranalytics.android.ui.activity.ProgressReportActivity
import net.pokeranalytics.android.ui.activity.TableReportActivity
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.util.extensions.startOfDay
import timber.log.Timber
import java.util.*
import kotlin.math.max
import kotlin.math.min
@ -281,8 +282,11 @@ class Calculator {
val results = ComputedResults(computableGroup, options.shouldManageMultiGroupProgressValues)
val computables = computableGroup.computables(realm, options.shouldSortValues)
// Timber.d(">>>> Start computing group ${computableGroup.name}, ${computables.size} computables")
Timber.d("#### Start computing group, ${computables.size} computables")
results.addStat(NUMBER_OF_GAMES, computables.size.toDouble())
// computables.forEach {
// Timber.d("$$$ buyin = ${it.ratedBuyin} $$$ net result = ${it.ratedNet}")
// }
val sum = computables.sum(ComputableResult.Field.RATED_NET.identifier).toDouble()
results.addStat(NET_RESULT, sum)
@ -301,6 +305,7 @@ class Calculator {
val totalBuyin = computables.sum(ComputableResult.Field.RATED_BUYIN.identifier).toDouble()
results.addStat(TOTAL_BUYIN, totalBuyin)
Timber.d("########## totalBuyin = ${totalBuyin} ### sum = ${sum}")
val maxNetResult = computables.max(ComputableResult.Field.RATED_NET.identifier)?.toDouble()
maxNetResult?.let {

@ -23,8 +23,8 @@ import kotlin.coroutines.CoroutineContext
class ImportFragment : RealmFragment(), ImportDelegate {
val coroutineContext: CoroutineContext
get() = Dispatchers.Main
// val coroutineContext: CoroutineContext
// get() = Dispatchers.Main
private lateinit var filePath: String
private lateinit var inputStream: InputStream

@ -190,6 +190,7 @@ class ReportsFragment : DeletableItemFragment(), StaticRowRepresentableDataSourc
val startDate = Date()
val realm = Realm.getDefaultInstance()
realm.refresh()
val report = Calculator.computeStats(realm, options = options)

@ -7,8 +7,6 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import io.realm.Realm
import io.realm.RealmModel
import io.realm.RealmResults
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
@ -23,19 +21,16 @@ import net.pokeranalytics.android.model.filter.Query
import net.pokeranalytics.android.model.filter.QueryCondition
import net.pokeranalytics.android.model.realm.ComputableResult
import net.pokeranalytics.android.model.realm.Filter
import net.pokeranalytics.android.ui.modules.filter.FiltersActivity
import net.pokeranalytics.android.ui.fragment.components.FilterableFragment
import net.pokeranalytics.android.ui.fragment.components.RealmAsyncListener
import net.pokeranalytics.android.ui.fragment.report.ComposableTableReportFragment
import net.pokeranalytics.android.ui.modules.filter.FilterActivityRequestCode
import net.pokeranalytics.android.ui.modules.filter.FilterableType
import net.pokeranalytics.android.ui.modules.filter.FiltersActivity
import timber.log.Timber
import java.util.*
import kotlin.coroutines.CoroutineContext
class StatisticsFragment : FilterableFragment() {
private val coroutineContext: CoroutineContext
get() = Dispatchers.Main
class StatisticsFragment : FilterableFragment(), RealmAsyncListener {
private lateinit var tableReportFragment: ComposableTableReportFragment
@ -64,21 +59,27 @@ class StatisticsFragment : FilterableFragment() {
initUI()
this.currentFilterable = FilterableType.SESSION
applyFilter()
listenAsynchronously(this, ComputableResult::class.java)
}
private fun initUI() {
val fragmentTransaction = requireFragmentManager().beginTransaction()
val fragmentTransaction = parentFragmentManager.beginTransaction()
val fragment = ComposableTableReportFragment.newInstance(null)
fragmentTransaction.add(R.id.tableContainer, fragment)
fragmentTransaction.commitAllowingStateLoss()
this.tableReportFragment = fragment
}
override val observedEntities: List<Class<out RealmModel>> = listOf(ComputableResult::class.java)
// override val observedEntities: List<Class<out RealmModel>> = listOf(ComputableResult::class.java)
override fun entitiesChanged(clazz: Class<out RealmModel>, results: RealmResults<out RealmModel>) {
this.launchStatComputation()
}
// override fun entitiesChanged(clazz: Class<out RealmModel>, results: RealmResults<out RealmModel>) {
// Timber.d("Entities changes, launch stats computation, size = ${results.size}")
// val cr = results as RealmResults<ComputableResult>
// cr.forEach {
// Timber.d("### buyin = ${it.ratedBuyin} ### net result = ${it.ratedNet}")
// }
// this.launchStatComputation()
// }
// override fun convertReportIntoRepresentables(report: Report): ArrayList<RowRepresentable> {
// val rows: ArrayList<RowRepresentable> = ArrayList()
@ -115,6 +116,17 @@ class StatisticsFragment : FilterableFragment() {
// Business
override fun asyncListenedEntityChange(realm: Realm) {
val report = createSessionGroupsAndStartCompute(realm)
tableReportFragment.report = report
GlobalScope.launch(Dispatchers.Main) {
tableReportFragment.showResults()
}
}
/**
* Launch stat computation
*/
@ -122,11 +134,12 @@ class StatisticsFragment : FilterableFragment() {
GlobalScope.launch(coroutineContext) {
val test = GlobalScope.async {
val async = GlobalScope.async {
val s = Date()
Timber.d(">>> start...")
val realm = Realm.getDefaultInstance()
realm.refresh()
val report = createSessionGroupsAndStartCompute(realm)
tableReportFragment.report = report
@ -138,7 +151,7 @@ class StatisticsFragment : FilterableFragment() {
Timber.d(">>> ended in $duration seconds")
}
test.await()
async.await()
if (!isDetached) {
tableReportFragment.showResults()

@ -1,20 +1,46 @@
package net.pokeranalytics.android.ui.fragment.components
import android.os.Bundle
import android.os.Looper
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import io.realm.Realm
import io.realm.RealmModel
import io.realm.RealmResults
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import timber.log.Timber
import kotlin.coroutines.CoroutineContext
interface RealmAsyncListener {
fun asyncListenedEntityChange(realm: Realm)
}
open class RealmFragment : BaseFragment() {
val coroutineContext: CoroutineContext
get() = Dispatchers.Main
/**
* A realm instance
*/
private lateinit var realm: Realm
/***
* A background realm instance
*/
private var asyncRealm: Realm? = null
/***
* A listener to async updates
*/
private var asyncListener: RealmAsyncListener? = null
private var asyncResults: RealmResults<out RealmModel>? = null
/**
* A List of observed RealmResults
*/
@ -36,6 +62,28 @@ open class RealmFragment : BaseFragment() {
return super.onCreateView(inflater, container, savedInstanceState)
}
fun listenAsynchronously(listener: RealmAsyncListener, clazz: Class<out RealmModel>) {
this.asyncListener = listener
GlobalScope.launch(coroutineContext) {
val async = GlobalScope.async {
Looper.prepare() // a looper is required on the thread to listen to change
val realm = Realm.getDefaultInstance()
asyncResults = realm.where(clazz).findAll()
asyncResults?.addChangeListener { t, _ ->
Timber.d("Realm changes: ${asyncResults?.size}, ${this@RealmFragment}")
asyncListener?.asyncListenedEntityChange(t.realm)
}
Looper.loop()
asyncRealm = realm
}
async.await()
}
}
override fun onDestroyView() {
super.onDestroyView()
@ -44,6 +92,8 @@ open class RealmFragment : BaseFragment() {
}
this.realm.close()
this.asyncResults?.removeAllChangeListeners()
this.asyncRealm?.close()
}
/**

@ -34,8 +34,8 @@ import kotlin.coroutines.CoroutineContext
open class ComposableTableReportFragment : RealmFragment(), StaticRowRepresentableDataSource, CoroutineScope,
RowRepresentableDelegate {
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main
// override val coroutineContext: CoroutineContext
// get() = Dispatchers.Main
private var rowRepresentables: ArrayList<RowRepresentable> = ArrayList()

@ -50,8 +50,7 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour
* Create new instance
*/
fun newInstance(): BankrollFragment {
val fragment =
BankrollFragment()
val fragment = BankrollFragment()
val bundle = Bundle()
fragment.arguments = bundle
return fragment
@ -135,7 +134,7 @@ class BankrollFragment : DeletableItemFragment(), StaticRowRepresentableDataSour
rows.add(CustomizableRowRepresentable(RowViewType.HEADER_TITLE, resId = R.string.bankrolls))
bankrolls.forEach { bankroll ->
Timber.d("Creating row for br : ${bankroll.id}, name= ${bankroll.name}, isManaged = ${bankroll.isManaged()}, isValid = ${bankroll.isValid}")
Timber.d("Creating row for br : ${bankroll.id}, name= ${bankroll.name}, isManaged = ${bankroll.isManaged}, isValid = ${bankroll.isValid}")
val row = BankrollTotalRow(bankroll.id, bankroll.name)
rows.add(row)
bankrollRowRepresentables[bankroll.id] = listOf(row)

@ -7,8 +7,6 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.tabs.TabLayout
import io.realm.Realm
import io.realm.RealmModel
import io.realm.RealmResults
import kotlinx.android.synthetic.main.fragment_calendar.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@ -27,6 +25,7 @@ import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.adapter.StaticRowRepresentableDataSource
import net.pokeranalytics.android.ui.extensions.hideWithAnimation
import net.pokeranalytics.android.ui.extensions.showWithAnimation
import net.pokeranalytics.android.ui.fragment.components.RealmAsyncListener
import net.pokeranalytics.android.ui.fragment.components.RealmFragment
import net.pokeranalytics.android.ui.view.CalendarTabs
import net.pokeranalytics.android.ui.view.RowRepresentable
@ -35,11 +34,10 @@ import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepres
import net.pokeranalytics.android.util.extensions.*
import timber.log.Timber
import java.util.*
import kotlin.coroutines.CoroutineContext
class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentableDataSource,
RowRepresentableDelegate {
RowRepresentableDelegate, RealmAsyncListener {
enum class TimeFilter {
MONTH, YEAR
@ -51,8 +49,7 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
* Create new instance
*/
fun newInstance(): CalendarFragment {
val fragment =
CalendarFragment()
val fragment = CalendarFragment()
val bundle = Bundle()
fragment.arguments = bundle
return fragment
@ -61,8 +58,8 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
private lateinit var calendarAdapter: RowRepresentableAdapter
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main
// override val coroutineContext: CoroutineContext
// get() = Dispatchers.Main
private var rows: ArrayList<CustomizableRowRepresentable> = ArrayList()
@ -86,11 +83,7 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
super.onViewCreated(view, savedInstanceState)
initData()
initUI()
}
override fun onResume() {
super.onResume()
launchStatComputation()
listenAsynchronously(this, ComputableResult::class.java)
}
override fun adapterRows(): List<RowRepresentable>? {
@ -120,11 +113,11 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
}
}
override val observedEntities: List<Class<out RealmModel>> = listOf(ComputableResult::class.java)
// override val observedEntities: List<Class<out RealmModel>> = listOf(ComputableResult::class.java)
override fun entitiesChanged(clazz: Class<out RealmModel>, results: RealmResults<out RealmModel>) {
launchStatComputation()
}
// override fun entitiesChanged(clazz: Class<out RealmModel>, results: RealmResults<out RealmModel>) {
// launchAsyncStatComputation()
// }
// Business
@ -132,6 +125,7 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
* Init data
*/
private fun initData() {
launchAsyncStatComputation()
}
/**
@ -173,7 +167,7 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
sessionTypeCondition = null
filterSessionCash.isChecked = false
filterSessionTournament.isChecked = false
launchStatComputation()
launchAsyncStatComputation()
} else if (sessionTypeCondition == null) {
filterSessionAll.isChecked = true
}
@ -183,7 +177,7 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
sessionTypeCondition = QueryCondition.IsCash
filterSessionAll.isChecked = false
filterSessionTournament.isChecked = false
launchStatComputation()
launchAsyncStatComputation()
} else if (sessionTypeCondition == QueryCondition.IsCash) {
filterSessionCash.isChecked = true
}
@ -193,7 +187,7 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
sessionTypeCondition = QueryCondition.IsTournament
filterSessionAll.isChecked = false
filterSessionCash.isChecked = false
launchStatComputation()
launchAsyncStatComputation()
} else if (sessionTypeCondition == QueryCondition.IsTournament) {
filterSessionTournament.isChecked = true
}
@ -233,22 +227,35 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
}
}
/**
* Launch stat computation
* Asynchronously Launch stat computation
*/
private fun launchStatComputation() {
private fun launchAsyncStatComputation() {
progressBar?.showWithAnimation()
recyclerView?.hideWithAnimation()
GlobalScope.launch {
val realm = Realm.getDefaultInstance()
realm.refresh()
launchStatComputation(realm)
realm.close()
GlobalScope.launch(Dispatchers.Main) {
displayData()
}
}
}
private fun launchStatComputation(realm: Realm) {
val calendar = Calendar.getInstance()
calendar.time = Date().startOfMonth()
val startDate = Date()
val realm = Realm.getDefaultInstance()
val monthlyReports: HashMap<Date, ComputedResults> = HashMap()
val yearlyReports: HashMap<Date, ComputedResults> = HashMap()
@ -337,19 +344,13 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
Timber.d("$it => ${sortedYearlyReports[it]?.computedStat(Stat.NET_RESULT)?.value}")
}
*/
realm.close()
GlobalScope.launch(Dispatchers.Main) {
displayData()
}
}
}
/**
* Display data
*/
private fun displayData() {
Timber.d("displayData")
val startDate = Date()
@ -415,4 +416,13 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable
}
override fun asyncListenedEntityChange(realm: Realm) {
Timber.d("asyncListenedEntityChange")
launchStatComputation(realm)
activity?.runOnUiThread {
displayData()
}
}
}

@ -74,8 +74,8 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate {
}
}
private val coroutineContext: CoroutineContext
get() = Dispatchers.Main
// private val coroutineContext: CoroutineContext
// get() = Dispatchers.Main
override fun onResume() {
super.onResume()

Loading…
Cancel
Save