From 6644e71cc5c21deda0bf00e36d65e34ac709c32f Mon Sep 17 00:00:00 2001 From: Laurent Date: Mon, 23 Oct 2023 10:30:16 +0200 Subject: [PATCH] commit stuff --- .../android/PokerAnalyticsApplication.kt | 20 ++--- .../android/calculus/DataManager.kt | 56 +++++++------- .../android/calculus/ReportWhistleBlower.kt | 7 +- .../android/model/migrations/Patcher.kt | 6 +- .../android/model/realm/Session.kt | 74 +++++++++---------- .../android/model/realm/SessionSet.kt | 6 +- .../ui/modules/calendar/CalendarFragment.kt | 2 +- .../ui/modules/session/SessionFragment.kt | 26 +++++-- .../android/util/FakeDataManager.kt | 19 +++-- .../util/extensions/RealmExtensions.kt | 14 +++- 10 files changed, 129 insertions(+), 101 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt b/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt index 887e2fd6..0dca2917 100644 --- a/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt +++ b/app/src/main/java/net/pokeranalytics/android/PokerAnalyticsApplication.kt @@ -6,16 +6,14 @@ import android.os.Build import com.google.firebase.FirebaseApp import io.realm.Realm import io.realm.RealmConfiguration -import io.realm.kotlin.where import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import net.pokeranalytics.android.calculus.DataManager import net.pokeranalytics.android.model.migrations.Patcher import net.pokeranalytics.android.model.migrations.PokerAnalyticsMigration -import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.model.realm.UserConfigObserver import net.pokeranalytics.android.model.utils.Seed -import net.pokeranalytics.android.calculus.DataManager import net.pokeranalytics.android.util.* import net.pokeranalytics.android.util.billing.AppGuard import timber.log.Timber @@ -99,6 +97,8 @@ class PokerAnalyticsApplication : Application() { // it.delete(Performance::class.java) // } +// createFakeSessions() + } /** @@ -106,15 +106,15 @@ class PokerAnalyticsApplication : Application() { */ private fun createFakeSessions() { - val realm = Realm.getDefaultInstance() - val sessionsCount = realm.where().count() - realm.close() +// val realm = Realm.getDefaultInstance() +// val sessionsCount = realm.where().count() +// realm.close() - if (sessionsCount < 10) { - CoroutineScope(context = Dispatchers.IO).launch { - FakeDataManager.createFakeSessions(500) +// if (sessionsCount < 10) { + CoroutineScope(context = Dispatchers.Default).launch { + FakeDataManager.createFakeSessions(8000) } - } +// } } diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/DataManager.kt b/app/src/main/java/net/pokeranalytics/android/calculus/DataManager.kt index d75cb40f..ee61a222 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/DataManager.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/DataManager.kt @@ -4,7 +4,6 @@ import android.content.Context import io.realm.Realm import io.realm.RealmQuery import io.realm.RealmResults -import io.realm.kotlin.where import net.pokeranalytics.android.exceptions.ModelException import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.realm.Currency @@ -37,18 +36,21 @@ object DataManager { val realm = Realm.getDefaultInstance() sessions = realm.where(Session::class.java).findAllAsync() - sessions?.addChangeListener { results -> - results.realm.writeAsync { asyncRealm -> - computeStatsIfNecessary(asyncRealm) - computeDatesIfNecessary(asyncRealm) - reportWhistleBlower?.requestReportLaunch() - } + sessions?.addChangeListener { sessions -> + +// if (this.dateModifiedSessionIds.isNotEmpty() || this.statsToComputeSessionIds.isNotEmpty()) { + sessions.realm.writeAsync { asyncRealm -> + computeStatsIfNecessary(asyncRealm) + computeDatesIfNecessary(asyncRealm) + reportWhistleBlower?.requestReportLaunch() + } +// } } this.currencies = realm.where(Currency::class.java).findAll() - this.currencies?.addChangeListener { _, _ -> + this.currencies?.addChangeListener { currencies, _ -> if (changedCurrencies.isNotEmpty()) { - realm.writeAsync { asyncRealm -> + currencies.realm.writeAsync { asyncRealm -> for (currencyId in this.changedCurrencies) { asyncRealm.findById(currencyId)?.let { currency -> Timber.d("Compute currency ${currency.code} ") @@ -68,25 +70,25 @@ object DataManager { } fun sessionToCompute(session: Session) { - Timber.d("sessionToCompute") +// Timber.d("sessionToCompute, date = ${session.startDate} / ${session.endDate}") statsToComputeSessionIds.add(session.id) } fun sessionDateChanged(session: Session) { - Timber.d("sessionDateChanged") +// Timber.d("sessionDateChanged") dateModifiedSessionIds.add(session.id) } fun currencyToCompute(currency: Currency) { - Timber.d("sessionToCompute") +// Timber.d("currencyToCompute") changedCurrencies.add(currency.id) } private fun computeStatsIfNecessary(realm: Realm) { if (statsToComputeSessionIds.isNotEmpty()) { for (sessionId in statsToComputeSessionIds) { - Timber.d("Session Manager > compute stats") realm.findById(sessionId)?.let { session -> +// Timber.d("Session Manager > compute stats, set = ${session.sessionSet}") session.computeStats() session.sessionSet?.computeStats() } @@ -98,8 +100,8 @@ object DataManager { private fun computeDatesIfNecessary(realm: Realm) { if (dateModifiedSessionIds.isNotEmpty()) { for (sessionId in dateModifiedSessionIds) { - Timber.d("Session Manager > manage dates") realm.findById(sessionId)?.let { session -> +// Timber.d("Session Manager > manage dates, set = ${session.sessionSet}") if (session.endDate != null) { updateTimeline(session) } else if (session.sessionSet != null) { @@ -116,7 +118,7 @@ object DataManager { */ fun updateTimeline(session: Session) { - Timber.d("updateTimeline...") +// Timber.d("updateTimeline...") if (!session.realm.isInTransaction) { throw PAIllegalStateException("realm should be in transaction at this point") @@ -160,7 +162,7 @@ object DataManager { * Does that by deleting then recreating */ private fun cleanupSessionSets(session: Session, sessionSets: RealmResults) { - Timber.d("cleanupSessionSets...") +// Timber.d("cleanupSessionSets...") // get all endedSessions from sets val allImpactedSessions = mutableSetOf() @@ -183,7 +185,7 @@ object DataManager { * Update the global timeline using the impacted [sessionSets] and the updated [session] */ private fun updateTimeFrames(sessionSets: RealmResults, session: Session) { - Timber.d("updateTimeFrames...") +// Timber.d("updateTimeFrames...") when (sessionSets.size) { 0 -> createOrUpdateSessionSet(session) @@ -196,7 +198,7 @@ object DataManager { * Creates or update the session set for the [session] */ private fun createOrUpdateSessionSet(session: Session) { - Timber.d("createOrUpdateSessionSet...") +// Timber.d("createOrUpdateSessionSet...") val set = session.sessionSet if (set != null) { @@ -212,7 +214,7 @@ object DataManager { * Create a set and affect it to the [session] */ private fun createSessionSet(session: Session) { - Timber.d("createSessionSet...") +// Timber.d("createSessionSet...") val realm = session.realm val set = SessionSet.newInstance(realm) @@ -222,11 +224,11 @@ object DataManager { session.sessionSet = set set.computeStats() - Timber.d("SET SESSION count = ${set.sessions?.size}") - - val t = 0 - val f = realm.where().equalTo("sessions.type", t).findAll() - Timber.d("CASH SET COUNT = ${f.size}") +// Timber.d("SET SESSION count = ${set.sessions?.size}") +// +// val t = 0 +// val f = realm.where().equalTo("sessions.type", t).findAll() +// Timber.d("CASH SET COUNT = ${f.size}") } @@ -236,7 +238,7 @@ object DataManager { */ private fun mergeSessionGroups(session: Session, sessionSets: RealmResults) { - Timber.d("mergeSessionGroups") +// Timber.d("mergeSessionGroups") var startDate = session.startDate!! var endDate = session.endDate!! @@ -291,7 +293,7 @@ object DataManager { */ fun removeFromTimeline(session: Session) { - Timber.d("removeFromTimeline") +// Timber.d("removeFromTimeline") if (!session.realm.isInTransaction) { throw PAIllegalStateException("realm should be in transaction at this point") @@ -304,7 +306,7 @@ object DataManager { sessionSet.sessions?.asIterable()?.let { sessions.addAll(it) } sessions.remove(session) - Timber.d(">>> sessionSet.deleteFromRealm") +// Timber.d(">>> sessionSet.deleteFromRealm") sessionSet.deleteFromRealm() sessions.forEach { diff --git a/app/src/main/java/net/pokeranalytics/android/calculus/ReportWhistleBlower.kt b/app/src/main/java/net/pokeranalytics/android/calculus/ReportWhistleBlower.kt index c2c5fb09..a392c776 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/ReportWhistleBlower.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/ReportWhistleBlower.kt @@ -11,6 +11,7 @@ import net.pokeranalytics.android.model.realm.PerformanceKey import net.pokeranalytics.android.ui.view.rows.StaticReport import net.pokeranalytics.android.util.extensions.findById import net.pokeranalytics.android.util.extensions.formattedHourlyDuration +import net.pokeranalytics.android.util.extensions.writeAsync interface NewPerformanceListener { @@ -104,7 +105,11 @@ class ReportWhistleBlower(var context: Context) { fun resume() { this.paused = false - this.requestReportLaunch() + val realm = Realm.getDefaultInstance() + realm.writeAsync { + this.requestReportLaunch() + } + realm.close() } fun has(performanceId: String): Boolean { diff --git a/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt b/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt index 5f59d3d9..eff2323a 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/migrations/Patcher.kt @@ -4,12 +4,12 @@ import android.content.Context import io.realm.Realm import io.realm.kotlin.where import net.pokeranalytics.android.PokerAnalyticsApplication +import net.pokeranalytics.android.calculus.DataManager import net.pokeranalytics.android.model.filter.Query import net.pokeranalytics.android.model.filter.QueryCondition import net.pokeranalytics.android.model.realm.* import net.pokeranalytics.android.model.realm.handhistory.HandHistory import net.pokeranalytics.android.model.utils.Seed -import net.pokeranalytics.android.calculus.DataManager import net.pokeranalytics.android.util.BLIND_SEPARATOR import net.pokeranalytics.android.util.Preferences import net.pokeranalytics.android.util.extensions.writeAsync @@ -202,7 +202,9 @@ class Patcher { val performanceCount = realm.where().findAll().size if (sessionCount > 1 && performanceCount == 0) { - DataManager.reportWhistleBlower?.requestReportLaunch() + realm.writeAsync { + DataManager.reportWhistleBlower?.requestReportLaunch() + } } realm.close() } diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt index 7157c31e..34045e4a 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt @@ -983,16 +983,16 @@ open class Session : RealmObject(), Savable, RowRepresentable, Timed, } - private fun customFieldEntries(realm: Realm, customField: CustomField): List { - -// val cfEntries = customField.entries -// val sessionEntries = this.customFieldEntries +// private fun customFieldEntries(realm: Realm, customField: CustomField): List { // -// val entries = realm.where() -// .`in`() - - return listOf() - } +//// val cfEntries = customField.entries +//// val sessionEntries = this.customFieldEntries +//// +//// val entries = realm.where() +//// .`in`() +// +// return listOf() +// } // private fun getOrCreateResult(): Result { // return this.result @@ -1016,39 +1016,35 @@ open class Session : RealmObject(), Savable, RowRepresentable, Timed, override fun formattedValue(stat: Stat): TextFormat { -// this.result?.let { result -> - - val value: Double? = when (stat) { - Stat.NET_RESULT, Stat.AVERAGE, Stat.STANDARD_DEVIATION -> this.net - Stat.NUMBER_OF_GAMES, Stat.NUMBER_OF_SETS -> 1.0 - Stat.AVERAGE_BUYIN -> this.buyin - Stat.ROI -> { - this.buyin?.let { - Stat.returnOnInvestment(this.net, it) - } ?: run { - null - } + val value: Double? = when (stat) { + Stat.NET_RESULT, Stat.AVERAGE, Stat.STANDARD_DEVIATION -> this.net + Stat.NUMBER_OF_GAMES, Stat.NUMBER_OF_SETS -> 1.0 + Stat.AVERAGE_BUYIN -> this.buyin + Stat.ROI -> { + this.buyin?.let { + Stat.returnOnInvestment(this.net, it) + } ?: run { + null } - Stat.HOURLY_RATE_BB -> this.bbHourlyRate - Stat.NET_BB_PER_100_HANDS, Stat.STANDARD_DEVIATION_BB_PER_100_HANDS -> Stat.netBBPer100Hands( - this.bbNet, - this.estimatedHands - ) - Stat.AVERAGE_NET_BB, Stat.BB_NET_RESULT -> this.bbNet - Stat.HOURLY_DURATION, Stat.AVERAGE_HOURLY_DURATION -> this.netDuration.toDouble() - Stat.HOURLY_RATE, Stat.STANDARD_DEVIATION_HOURLY -> this.hourlyRate - Stat.HANDS_PLAYED -> this.estimatedHands - Stat.WIN_RATIO -> null - else -> throw StatFormattingException("format undefined for stat ${stat.name}") - } - - value?.let { - return stat.textFormat(it, currency = currency) - } ?: run { - return TextFormat(NULL_TEXT) } + Stat.HOURLY_RATE_BB -> this.bbHourlyRate + Stat.NET_BB_PER_100_HANDS, Stat.STANDARD_DEVIATION_BB_PER_100_HANDS -> Stat.netBBPer100Hands( + this.bbNet, + this.estimatedHands + ) + Stat.AVERAGE_NET_BB, Stat.BB_NET_RESULT -> this.bbNet + Stat.HOURLY_DURATION, Stat.AVERAGE_HOURLY_DURATION -> this.netDuration.toDouble() + Stat.HOURLY_RATE, Stat.STANDARD_DEVIATION_HOURLY -> this.hourlyRate + Stat.HANDS_PLAYED -> this.estimatedHands + Stat.WIN_RATIO -> null + else -> throw StatFormattingException("format undefined for stat ${stat.name}") + } -// } + value?.let { + return stat.textFormat(it, currency = currency) + } ?: run { + return TextFormat(NULL_TEXT) + } } diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/SessionSet.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/SessionSet.kt index c4e6ccb6..75546982 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/SessionSet.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/SessionSet.kt @@ -15,7 +15,6 @@ import net.pokeranalytics.android.model.interfaces.Identifiable import net.pokeranalytics.android.model.interfaces.Timed import net.pokeranalytics.android.util.NULL_TEXT import net.pokeranalytics.android.util.TextFormat -import timber.log.Timber import java.text.DateFormat import java.util.* @@ -62,7 +61,7 @@ open class SessionSet : RealmObject(), Timed, Filterable { override var netDuration: Long = 0L fun computeStats() { - Timber.d("compute > session count = ${this.sessions?.size}") +// Timber.d("compute > session count = ${this.sessions?.size}") this.ratedNet = this.sessions?.sumOf { it.computableResult?.ratedNet ?: 0.0 } ?: 0.0 this.estimatedHands = this.sessions?.sumOf { it.estimatedHands } ?: 0.0 this.bbNet = this.sessions?.sumOf { it.bbNet } ?: 0.0 @@ -103,8 +102,7 @@ open class SessionSet : RealmObject(), Timed, Filterable { companion object { fun newInstance(realm: Realm): SessionSet { - val sessionSet = SessionSet() - return realm.copyToRealm(sessionSet) + return realm.copyToRealm(SessionSet()) } fun fieldNameForQueryType(queryCondition: Class ): String? { diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/calendar/CalendarFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/calendar/CalendarFragment.kt index c546b44a..c9c2427d 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/calendar/CalendarFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/calendar/CalendarFragment.kt @@ -349,7 +349,7 @@ class CalendarFragment : RealmFragment(), CoroutineScope, StaticRowRepresentable CoroutineScope(context = Dispatchers.IO).launch { val realm = Realm.getDefaultInstance() - realm.refresh() +// realm.refresh() launchStatComputation(realm) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/session/SessionFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/session/SessionFragment.kt index 6486365d..f219c22e 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/session/SessionFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/session/SessionFragment.kt @@ -287,9 +287,22 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr } private fun writeChanges() { - getRealm().writeAsync { asyncRealm -> + + Timber.d("write changes") + + getRealm().writeAsync ({ asyncRealm -> + Timber.d("start transaction") asyncRealm.copyToRealmOrUpdate(this.currentSession) - } + Timber.d("yupyup") + }, { // onSuccess we retrieved the object because it might have been changed (i.e. session set added). Not retrieving it can for example copy it without its sessionset, writing null in db whereas it should have it + Timber.d("onSuccess") + val id = this.currentSession.id + getRealm().refresh() + getRealm().findById(id)?.let { session -> + this.currentSession = getRealm().copyFromRealm(session) + Timber.d("Session retrieved, set = ${this.currentSession.sessionSet}, br = ${session.bankroll}") + } ?: throw PAIllegalStateException("session not found") + }) } /** @@ -500,12 +513,15 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr val bankrollId = this.currentSession.bankroll?.id val id = currentSession.id - getRealm().writeAsync { asyncRealm -> + getRealm().writeAsync ({ asyncRealm -> asyncRealm.findById(id)?.let { session -> session.cleanup() session.deleteFromRealm() - } - } + } ?: throw PAIllegalStateException("session not found") + }, { + Timber.d("delete successful") +// getRealm().refresh() + }) bankrollId?.let { BankrollReportManager.notifyBankrollReportImpact(bankrollId) diff --git a/app/src/main/java/net/pokeranalytics/android/util/FakeDataManager.kt b/app/src/main/java/net/pokeranalytics/android/util/FakeDataManager.kt index cd6685fd..a92bd827 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/FakeDataManager.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/FakeDataManager.kt @@ -8,7 +8,6 @@ import net.pokeranalytics.android.model.realm.Game import net.pokeranalytics.android.model.realm.Location import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.util.extensions.getOrCreate -import net.pokeranalytics.android.util.extensions.writeAsync import timber.log.Timber import java.util.* @@ -35,14 +34,6 @@ class FakeDataManager { val bankroll = realm.where().findAll().firstOrNull() val locations = realm.where().findAll() - if (locations.size == 0) { - realm.writeAsync { asyncRealm -> - listOf("Bellagio", "Aria", "Borgata").map { - asyncRealm.getOrCreate(it) - } - } - } - // Test endedSessions Timber.d("*** Start creating ${numberOfSessions} fake computables...") @@ -51,10 +42,16 @@ class FakeDataManager { realm.beginTransaction() + if (locations.size == 0) { + listOf("Bellagio", "Aria", "Borgata").map { + realm.getOrCreate(it) + } + } + for (index in 1..numberOfSessions) { if (index % commitFrequency == 0) { - Timber.d("****** committing at ${index} computables...") + Timber.d("****** committing at ${index} sessions...") realm.commitTransaction() realm.beginTransaction() } @@ -98,6 +95,8 @@ class FakeDataManager { // session.cgSmallBlind = bigBlind / 2.0 } + realm.copyToRealmOrUpdate(session) + } realm.commitTransaction() diff --git a/app/src/main/java/net/pokeranalytics/android/util/extensions/RealmExtensions.kt b/app/src/main/java/net/pokeranalytics/android/util/extensions/RealmExtensions.kt index e5327fe1..c92fe26a 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/extensions/RealmExtensions.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/extensions/RealmExtensions.kt @@ -8,6 +8,7 @@ import net.pokeranalytics.android.model.interfaces.NameManageable import net.pokeranalytics.android.model.interfaces.UsageCountable import net.pokeranalytics.android.model.realm.* import timber.log.Timber +import java.util.* fun Realm.count(clazz: Class) : Long { return this.where(clazz).count() @@ -110,14 +111,23 @@ fun Realm.writeAsync(handler: (Realm) -> (Unit)) { fun Realm.writeAsync(handler: (Realm) -> (Unit), success: () -> (Unit)) { - Timber.d("Start write...") + Timber.d("Start write with success/error...") + + val s = Date() this.executeTransactionAsync({ asyncRealm -> handler(asyncRealm) + Timber.d("REALM execution ended") }, { // success + + val e = Date() + val duration = e.time - s.time + Timber.d("//// transaction duration = $duration") + + Timber.d("SUCCESS!") success() }, { error -> // error - Timber.w("Realm write error: $error") + Timber.d("Realm write error: $error") }) }