|
|
|
|
@ -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,13 +83,9 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable |
|
|
|
|
super.onViewCreated(view, savedInstanceState) |
|
|
|
|
initData() |
|
|
|
|
initUI() |
|
|
|
|
listenAsynchronously(this, ComputableResult::class.java) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun onResume() { |
|
|
|
|
super.onResume() |
|
|
|
|
launchStatComputation() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun adapterRows(): List<RowRepresentable>? { |
|
|
|
|
return rows |
|
|
|
|
} |
|
|
|
|
@ -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,123 +227,130 @@ 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 calendar = Calendar.getInstance() |
|
|
|
|
calendar.time = Date().startOfMonth() |
|
|
|
|
|
|
|
|
|
val startDate = Date() |
|
|
|
|
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 monthlyReports: HashMap<Date, ComputedResults> = HashMap() |
|
|
|
|
val yearlyReports: HashMap<Date, ComputedResults> = HashMap() |
|
|
|
|
val startDate = Date() |
|
|
|
|
|
|
|
|
|
val monthlyReports: HashMap<Date, ComputedResults> = HashMap() |
|
|
|
|
val yearlyReports: HashMap<Date, ComputedResults> = HashMap() |
|
|
|
|
|
|
|
|
|
val requiredStats: List<Stat> = |
|
|
|
|
listOf(Stat.LOCATIONS_PLAYED, Stat.LONGEST_STREAKS, Stat.DAYS_PLAYED, Stat.STANDARD_DEVIATION_HOURLY) |
|
|
|
|
val requiredStats: List<Stat> = |
|
|
|
|
listOf(Stat.LOCATIONS_PLAYED, Stat.LONGEST_STREAKS, Stat.DAYS_PLAYED, Stat.STANDARD_DEVIATION_HOURLY) |
|
|
|
|
|
|
|
|
|
// Compute data per AnyYear and AnyMonthOfYear |
|
|
|
|
// Compute data per AnyYear and AnyMonthOfYear |
|
|
|
|
|
|
|
|
|
// println(">>>> ${Criteria.MonthsOfYear.queryConditions.map { it.id }}") |
|
|
|
|
|
|
|
|
|
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() |
|
|
|
|
} |
|
|
|
|
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() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
monthlyQueries.forEach { query -> |
|
|
|
|
val options = Calculator.Options( |
|
|
|
|
progressValues = Calculator.Options.ProgressValues.STANDARD, |
|
|
|
|
stats = requiredStats, |
|
|
|
|
query = query |
|
|
|
|
) |
|
|
|
|
val report = Calculator.computeStats(realm, options = options) |
|
|
|
|
report.results.forEach { computedResults -> |
|
|
|
|
if (!computedResults.isEmpty) { |
|
|
|
|
// Set date data |
|
|
|
|
query.conditions.forEach { condition -> |
|
|
|
|
when (condition) { |
|
|
|
|
is QueryCondition.AnyYear -> calendar.set(Calendar.YEAR, condition.listOfValues.first()) |
|
|
|
|
is QueryCondition.AnyMonthOfYear -> calendar.set( |
|
|
|
|
Calendar.MONTH, |
|
|
|
|
condition.listOfValues.first() |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
monthlyQueries.forEach { query -> |
|
|
|
|
val options = Calculator.Options( |
|
|
|
|
progressValues = Calculator.Options.ProgressValues.STANDARD, |
|
|
|
|
stats = requiredStats, |
|
|
|
|
query = query |
|
|
|
|
) |
|
|
|
|
val report = Calculator.computeStats(realm, options = options) |
|
|
|
|
report.results.forEach { computedResults -> |
|
|
|
|
if (!computedResults.isEmpty) { |
|
|
|
|
// Set date data |
|
|
|
|
query.conditions.forEach { condition -> |
|
|
|
|
when (condition) { |
|
|
|
|
is QueryCondition.AnyYear -> calendar.set(Calendar.YEAR, condition.listOfValues.first()) |
|
|
|
|
is QueryCondition.AnyMonthOfYear -> calendar.set( |
|
|
|
|
Calendar.MONTH, |
|
|
|
|
condition.listOfValues.first() |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
monthlyReports[calendar.time] = computedResults |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
monthlyReports[calendar.time] = computedResults |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
calendar.time = Date().startOfYear() |
|
|
|
|
calendar.time = Date().startOfYear() |
|
|
|
|
|
|
|
|
|
// Compute data per AnyYear |
|
|
|
|
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() |
|
|
|
|
} |
|
|
|
|
// Compute data per AnyYear |
|
|
|
|
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() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
yearConditions.forEach { query -> |
|
|
|
|
val options = Calculator.Options( |
|
|
|
|
progressValues = Calculator.Options.ProgressValues.STANDARD, |
|
|
|
|
stats = requiredStats, |
|
|
|
|
query = query |
|
|
|
|
) |
|
|
|
|
val report = Calculator.computeStats(realm, options = options) |
|
|
|
|
report.results.forEach { computedResults -> |
|
|
|
|
if (!computedResults.isEmpty) { |
|
|
|
|
// Set date data |
|
|
|
|
query.conditions.forEach { condition -> |
|
|
|
|
when (condition) { |
|
|
|
|
is QueryCondition.AnyYear -> calendar.set(Calendar.YEAR, condition.listOfValues.first()) |
|
|
|
|
} |
|
|
|
|
yearConditions.forEach { query -> |
|
|
|
|
val options = Calculator.Options( |
|
|
|
|
progressValues = Calculator.Options.ProgressValues.STANDARD, |
|
|
|
|
stats = requiredStats, |
|
|
|
|
query = query |
|
|
|
|
) |
|
|
|
|
val report = Calculator.computeStats(realm, options = options) |
|
|
|
|
report.results.forEach { computedResults -> |
|
|
|
|
if (!computedResults.isEmpty) { |
|
|
|
|
// Set date data |
|
|
|
|
query.conditions.forEach { condition -> |
|
|
|
|
when (condition) { |
|
|
|
|
is QueryCondition.AnyYear -> calendar.set(Calendar.YEAR, condition.listOfValues.first()) |
|
|
|
|
} |
|
|
|
|
yearlyReports[calendar.time] = computedResults |
|
|
|
|
} |
|
|
|
|
yearlyReports[calendar.time] = computedResults |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sortedMonthlyReports = monthlyReports.toSortedMap(compareByDescending { it }) |
|
|
|
|
sortedYearlyReports = yearlyReports.toSortedMap(compareByDescending { it }) |
|
|
|
|
|
|
|
|
|
Timber.d("Computation: ${System.currentTimeMillis() - startDate.time}ms") |
|
|
|
|
sortedMonthlyReports = monthlyReports.toSortedMap(compareByDescending { it }) |
|
|
|
|
sortedYearlyReports = yearlyReports.toSortedMap(compareByDescending { it }) |
|
|
|
|
|
|
|
|
|
// Logs |
|
|
|
|
/* |
|
|
|
|
Timber.d("========== AnyYear x AnyMonthOfYear") |
|
|
|
|
sortedMonthlyReports.keys.forEach { |
|
|
|
|
Timber.d("$it => ${sortedMonthlyReports[it]?.computedStat(Stat.NET_RESULT)?.value}") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Timber.d("========== YEARLY") |
|
|
|
|
sortedYearlyReports.keys.forEach { |
|
|
|
|
Timber.d("$it => ${sortedYearlyReports[it]?.computedStat(Stat.NET_RESULT)?.value}") |
|
|
|
|
} |
|
|
|
|
*/ |
|
|
|
|
Timber.d("Computation: ${System.currentTimeMillis() - startDate.time}ms") |
|
|
|
|
|
|
|
|
|
realm.close() |
|
|
|
|
// Logs |
|
|
|
|
/* |
|
|
|
|
Timber.d("========== AnyYear x AnyMonthOfYear") |
|
|
|
|
sortedMonthlyReports.keys.forEach { |
|
|
|
|
Timber.d("$it => ${sortedMonthlyReports[it]?.computedStat(Stat.NET_RESULT)?.value}") |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
GlobalScope.launch(Dispatchers.Main) { |
|
|
|
|
displayData() |
|
|
|
|
} |
|
|
|
|
Timber.d("========== YEARLY") |
|
|
|
|
sortedYearlyReports.keys.forEach { |
|
|
|
|
Timber.d("$it => ${sortedYearlyReports[it]?.computedStat(Stat.NET_RESULT)?.value}") |
|
|
|
|
} |
|
|
|
|
*/ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 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() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |