|
|
|
|
@ -11,10 +11,13 @@ import io.realm.Realm |
|
|
|
|
import io.realm.RealmModel |
|
|
|
|
import kotlinx.coroutines.CoroutineScope |
|
|
|
|
import kotlinx.coroutines.Dispatchers |
|
|
|
|
import kotlinx.coroutines.async |
|
|
|
|
import kotlinx.coroutines.launch |
|
|
|
|
import net.pokeranalytics.android.AppState |
|
|
|
|
import net.pokeranalytics.android.R |
|
|
|
|
import net.pokeranalytics.android.calculus.Calculator |
|
|
|
|
import net.pokeranalytics.android.calculus.ComputedResults |
|
|
|
|
import net.pokeranalytics.android.calculus.Report |
|
|
|
|
import net.pokeranalytics.android.calculus.Stat |
|
|
|
|
import net.pokeranalytics.android.databinding.FragmentCalendarBinding |
|
|
|
|
import net.pokeranalytics.android.exceptions.PAIllegalStateException |
|
|
|
|
@ -35,13 +38,11 @@ import net.pokeranalytics.android.ui.view.CalendarTabs |
|
|
|
|
import net.pokeranalytics.android.ui.view.RowRepresentable |
|
|
|
|
import net.pokeranalytics.android.ui.view.RowViewType |
|
|
|
|
import net.pokeranalytics.android.ui.view.rows.CustomizableRowRepresentable |
|
|
|
|
import net.pokeranalytics.android.util.Global |
|
|
|
|
import net.pokeranalytics.android.util.extensions.* |
|
|
|
|
import timber.log.Timber |
|
|
|
|
import java.util.* |
|
|
|
|
import kotlin.collections.set |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CalendarFragment : RealmFragment(), StaticRowRepresentableDataSource, |
|
|
|
|
RowRepresentableDelegate, RealmAsyncListener { |
|
|
|
|
|
|
|
|
|
@ -85,6 +86,13 @@ class CalendarFragment : RealmFragment(), StaticRowRepresentableDataSource, |
|
|
|
|
private var _binding: FragmentCalendarBinding? = null |
|
|
|
|
private val binding get() = _binding!! |
|
|
|
|
|
|
|
|
|
private val requiredStats: List<Stat > = listOf( |
|
|
|
|
Stat.LOCATIONS_PLAYED, |
|
|
|
|
Stat.LONGEST_STREAKS, |
|
|
|
|
Stat.DAYS_PLAYED, |
|
|
|
|
Stat.STANDARD_DEVIATION_HOURLY |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
// Life Cycle |
|
|
|
|
|
|
|
|
|
override fun onCreateView( |
|
|
|
|
@ -99,15 +107,13 @@ class CalendarFragment : RealmFragment(), StaticRowRepresentableDataSource, |
|
|
|
|
|
|
|
|
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |
|
|
|
|
super.onViewCreated(view, savedInstanceState) |
|
|
|
|
initData() |
|
|
|
|
initUI() |
|
|
|
|
initData() |
|
|
|
|
|
|
|
|
|
if (Global.LAUNCH_ASYNC_LISTENERS) { |
|
|
|
|
addRealmChangeListener(this, UserConfig::class.java) |
|
|
|
|
addRealmChangeListener(this, ComputableResult::class.java) |
|
|
|
|
addRealmChangeListener(this, Transaction::class.java) |
|
|
|
|
addRealmChangeListener(this, SessionSet::class.java) |
|
|
|
|
} |
|
|
|
|
addRealmChangeListener(this, UserConfig::class.java) |
|
|
|
|
addRealmChangeListener(this, ComputableResult::class.java) |
|
|
|
|
addRealmChangeListener(this, Transaction::class.java) |
|
|
|
|
addRealmChangeListener(this, SessionSet::class.java) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private var transactionFilterMenuItem: MenuItem? = null |
|
|
|
|
@ -162,12 +168,44 @@ class CalendarFragment : RealmFragment(), StaticRowRepresentableDataSource, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private fun showDetails(computedResults: ComputedResults, title: String?) { |
|
|
|
|
CalendarDetailsActivity.newInstance( |
|
|
|
|
requireContext(), |
|
|
|
|
computedResults, |
|
|
|
|
sessionTypeCondition, |
|
|
|
|
title |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
// start calculation with progress values |
|
|
|
|
|
|
|
|
|
CoroutineScope(Dispatchers.Default).launch { |
|
|
|
|
|
|
|
|
|
var report: Report? = null |
|
|
|
|
|
|
|
|
|
val coroutine = async { |
|
|
|
|
|
|
|
|
|
val realm = Realm.getDefaultInstance() |
|
|
|
|
|
|
|
|
|
val options = Calculator.Options( |
|
|
|
|
progressValues = Calculator.Options.ProgressValues.STANDARD, |
|
|
|
|
stats = requiredStats, |
|
|
|
|
query = computedResults.group.query, |
|
|
|
|
includedTransactions = transactionTypes(realm) |
|
|
|
|
) |
|
|
|
|
report = Calculator.computeStats(realm, options = options) |
|
|
|
|
|
|
|
|
|
realm.close() |
|
|
|
|
} |
|
|
|
|
coroutine.await() |
|
|
|
|
|
|
|
|
|
launch(Dispatchers.Main) { |
|
|
|
|
|
|
|
|
|
report?.results?.firstOrNull()?.let { cr -> |
|
|
|
|
CalendarDetailsActivity.newInstance( |
|
|
|
|
requireContext(), |
|
|
|
|
cr, |
|
|
|
|
sessionTypeCondition, |
|
|
|
|
title |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun onRowSelected(position: Int, row: RowRepresentable, tag: Int) { |
|
|
|
|
@ -348,17 +386,52 @@ class CalendarFragment : RealmFragment(), StaticRowRepresentableDataSource, |
|
|
|
|
|
|
|
|
|
CoroutineScope(Dispatchers.Default).launch { |
|
|
|
|
|
|
|
|
|
val realm = Realm.getDefaultInstance() |
|
|
|
|
realm.refresh() |
|
|
|
|
val async = async { |
|
|
|
|
val s = Date() |
|
|
|
|
Timber.d(">>> start...") |
|
|
|
|
|
|
|
|
|
val realm = Realm.getDefaultInstance() |
|
|
|
|
realm.refresh() |
|
|
|
|
|
|
|
|
|
launchStatComputation(realm) |
|
|
|
|
launchStatComputation(realm) |
|
|
|
|
|
|
|
|
|
realm.close() |
|
|
|
|
realm.close() |
|
|
|
|
|
|
|
|
|
val e = Date() |
|
|
|
|
val duration = (e.time - s.time) / 1000.0 |
|
|
|
|
Timber.d(">>> computations took $duration seconds") |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
async.await() |
|
|
|
|
|
|
|
|
|
launch(Dispatchers.Main) { |
|
|
|
|
displayData() |
|
|
|
|
if (isAdded && !isDetached) { |
|
|
|
|
displayData() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// CoroutineScope(Dispatchers.Default).launch { |
|
|
|
|
// |
|
|
|
|
// val realm = Realm.getDefaultInstance() |
|
|
|
|
// realm.refresh() |
|
|
|
|
// |
|
|
|
|
// launchStatComputation(realm) |
|
|
|
|
// |
|
|
|
|
// realm.close() |
|
|
|
|
// |
|
|
|
|
// launch(Dispatchers.Main) { |
|
|
|
|
// displayData() |
|
|
|
|
// } |
|
|
|
|
// } |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private fun transactionTypes(realm: Realm): List<TransactionType> { |
|
|
|
|
var transactionTypes = listOf<TransactionType>() |
|
|
|
|
UserConfig.getConfiguration(realm) { userConfig -> |
|
|
|
|
transactionTypes = userConfig.transactionTypes(realm) |
|
|
|
|
} |
|
|
|
|
return transactionTypes |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private fun launchStatComputation(realm: Realm) { |
|
|
|
|
@ -368,26 +441,12 @@ class CalendarFragment : RealmFragment(), StaticRowRepresentableDataSource, |
|
|
|
|
val calendar = Calendar.getInstance() |
|
|
|
|
calendar.time = Date().startOfMonth() |
|
|
|
|
|
|
|
|
|
// val startDate = Date() |
|
|
|
|
|
|
|
|
|
val requiredStats: List<Stat> = |
|
|
|
|
listOf( |
|
|
|
|
Stat.LOCATIONS_PLAYED, |
|
|
|
|
Stat.LONGEST_STREAKS, |
|
|
|
|
Stat.DAYS_PLAYED, |
|
|
|
|
Stat.STANDARD_DEVIATION_HOURLY |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
var transactionTypes = listOf<TransactionType>() |
|
|
|
|
UserConfig.getConfiguration(realm) { userConfig -> |
|
|
|
|
transactionTypes = userConfig.transactionTypes(realm) |
|
|
|
|
} |
|
|
|
|
val startDate = Date() |
|
|
|
|
|
|
|
|
|
// val transactionTypes = UserConfig.getConfiguration(realm).transactionTypes(realm) |
|
|
|
|
val transactionTypes = this.transactionTypes(realm) |
|
|
|
|
|
|
|
|
|
// All |
|
|
|
|
val allOptions = Calculator.Options( |
|
|
|
|
progressValues = Calculator.Options.ProgressValues.STANDARD, |
|
|
|
|
stats = requiredStats, |
|
|
|
|
query = Query(this.sessionTypeCondition), |
|
|
|
|
includedTransactions = transactionTypes |
|
|
|
|
@ -397,7 +456,6 @@ class CalendarFragment : RealmFragment(), StaticRowRepresentableDataSource, |
|
|
|
|
|
|
|
|
|
// Sliding Month [sm] |
|
|
|
|
val smOptions = Calculator.Options( |
|
|
|
|
progressValues = Calculator.Options.ProgressValues.STANDARD, |
|
|
|
|
stats = requiredStats, |
|
|
|
|
query = Query(this.slidingMonthQueryCondition, this.sessionTypeCondition), |
|
|
|
|
includedTransactions = transactionTypes |
|
|
|
|
@ -410,23 +468,24 @@ class CalendarFragment : RealmFragment(), StaticRowRepresentableDataSource, |
|
|
|
|
val monthlyReports: HashMap<Date, ComputedResults> = HashMap() |
|
|
|
|
|
|
|
|
|
val monthlyQueries = when (sessionTypeCondition) { |
|
|
|
|
QueryCondition.IsCash -> listOf(Criteria.AllMonthsUpToNow, Criteria.Cash).combined() |
|
|
|
|
QueryCondition.IsTournament -> listOf(Criteria.AllMonthsUpToNow, Criteria.Tournament).combined() |
|
|
|
|
else -> listOf(Criteria.Years, Criteria.MonthsOfYear).combined() |
|
|
|
|
QueryCondition.IsCash -> listOf(Criteria.AllMonthsUpToNow, Criteria.Cash).combined(realm) |
|
|
|
|
QueryCondition.IsTournament -> listOf(Criteria.AllMonthsUpToNow, Criteria.Tournament).combined(realm) |
|
|
|
|
else -> listOf(Criteria.Years, Criteria.MonthsOfYear).combined(realm) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
monthlyQueries.forEach { query -> |
|
|
|
|
for (monthlyQuery in monthlyQueries) { |
|
|
|
|
val options = Calculator.Options( |
|
|
|
|
progressValues = Calculator.Options.ProgressValues.STANDARD, |
|
|
|
|
stats = requiredStats, |
|
|
|
|
query = query, |
|
|
|
|
query = monthlyQuery, |
|
|
|
|
includedTransactions = transactionTypes |
|
|
|
|
) |
|
|
|
|
val report = Calculator.computeStats(realm, options = options) |
|
|
|
|
report.results.forEach { computedResults -> |
|
|
|
|
|
|
|
|
|
for (computedResults in report.results) { |
|
|
|
|
if (!computedResults.isEmpty) { |
|
|
|
|
// Set date data |
|
|
|
|
query.conditions.forEach { condition -> |
|
|
|
|
|
|
|
|
|
for (condition in monthlyQuery.conditions) { |
|
|
|
|
when (condition) { |
|
|
|
|
is QueryCondition.AnyYear -> calendar.set( |
|
|
|
|
Calendar.YEAR, |
|
|
|
|
@ -443,11 +502,11 @@ class CalendarFragment : RealmFragment(), StaticRowRepresentableDataSource, |
|
|
|
|
monthlyReports[calendar.time] = computedResults |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Sliding Year [sm] |
|
|
|
|
val syOptions = Calculator.Options( |
|
|
|
|
progressValues = Calculator.Options.ProgressValues.STANDARD, |
|
|
|
|
stats = requiredStats, |
|
|
|
|
query = Query(this.slidingYearQueryCondition, this.sessionTypeCondition), |
|
|
|
|
includedTransactions = transactionTypes |
|
|
|
|
@ -462,14 +521,13 @@ class CalendarFragment : RealmFragment(), StaticRowRepresentableDataSource, |
|
|
|
|
val yearlyReports: HashMap<Date, ComputedResults> = HashMap() |
|
|
|
|
|
|
|
|
|
val yearConditions = when (sessionTypeCondition) { |
|
|
|
|
QueryCondition.IsCash -> listOf(Criteria.Years, Criteria.Cash).combined() |
|
|
|
|
QueryCondition.IsTournament -> listOf(Criteria.Years, Criteria.Tournament).combined() |
|
|
|
|
else -> listOf(Criteria.Years).combined() |
|
|
|
|
QueryCondition.IsCash -> listOf(Criteria.Years, Criteria.Cash).combined(realm) |
|
|
|
|
QueryCondition.IsTournament -> listOf(Criteria.Years, Criteria.Tournament).combined(realm) |
|
|
|
|
else -> listOf(Criteria.Years).combined(realm) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
yearConditions.forEach { query -> |
|
|
|
|
val options = Calculator.Options( |
|
|
|
|
progressValues = Calculator.Options.ProgressValues.STANDARD, |
|
|
|
|
stats = requiredStats, |
|
|
|
|
query = query, |
|
|
|
|
includedTransactions = transactionTypes |
|
|
|
|
@ -495,7 +553,7 @@ class CalendarFragment : RealmFragment(), StaticRowRepresentableDataSource, |
|
|
|
|
sortedMonthlyReports = monthlyReports.toSortedMap(compareByDescending { it }) |
|
|
|
|
sortedYearlyReports = yearlyReports.toSortedMap(compareByDescending { it }) |
|
|
|
|
|
|
|
|
|
// Timber.d("Computation: ${System.currentTimeMillis() - startDate.time}ms") |
|
|
|
|
Timber.d("Computation: ${System.currentTimeMillis() - startDate.time}ms") |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -505,9 +563,12 @@ class CalendarFragment : RealmFragment(), StaticRowRepresentableDataSource, |
|
|
|
|
private fun displayData() { |
|
|
|
|
// Timber.d("displayData") |
|
|
|
|
|
|
|
|
|
this.binding.progressBar.hideWithAnimation() |
|
|
|
|
this.binding.recyclerView.showWithAnimation() |
|
|
|
|
|
|
|
|
|
if (context == null) { return } // required because of launchAsyncStatComputation |
|
|
|
|
|
|
|
|
|
// val startDate = Date() |
|
|
|
|
val startDate = Date() |
|
|
|
|
|
|
|
|
|
datesForRows.clear() |
|
|
|
|
rows.clear() |
|
|
|
|
@ -599,14 +660,11 @@ class CalendarFragment : RealmFragment(), StaticRowRepresentableDataSource, |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Timber.d("Display data: ${System.currentTimeMillis() - startDate.time}ms") |
|
|
|
|
// Timber.d("Rows: ${rows.size}") |
|
|
|
|
Timber.d("Display data: ${System.currentTimeMillis() - startDate.time}ms") |
|
|
|
|
Timber.d("Rows: ${rows.size}") |
|
|
|
|
|
|
|
|
|
this.calendarAdapter.notifyDataSetChanged() |
|
|
|
|
|
|
|
|
|
this.binding.progressBar.hideWithAnimation() |
|
|
|
|
this.binding.recyclerView.showWithAnimation() |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun asyncListenedEntityChange(realm: Realm, clazz: Class<out RealmModel>) { |
|
|
|
|
|