diff --git a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/StatsInstrumentedUnitTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/StatsInstrumentedUnitTest.kt index c98eb4b4..ac31a69d 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/unitTests/StatsInstrumentedUnitTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/unitTests/StatsInstrumentedUnitTest.kt @@ -186,13 +186,13 @@ class StatsInstrumentedUnitTest : SessionInstrumentedUnitTest() { Assert.fail("No std100 stat") } - results.computedStat(Stat.MAXIMUM_NETRESULT)?.let { + results.computedStat(Stat.MAXIMUM_NET_RESULT)?.let { assertEquals(300.0, it.value, delta) } ?: run { Assert.fail("No MAXIMUM_NETRESULT") } - results.computedStat(Stat.MINIMUM_NETRESULT)?.let { + results.computedStat(Stat.MINIMUM_NET_RESULT)?.let { assertEquals(-100.0, it.value, delta) } ?: run { Assert.fail("No MINIMUM_NETRESULT") 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 7e181fa3..1108e621 100644 --- a/app/src/main/java/net/pokeranalytics/android/calculus/ReportWhistleBlower.kt +++ b/app/src/main/java/net/pokeranalytics/android/calculus/ReportWhistleBlower.kt @@ -200,7 +200,7 @@ class ReportTask(private var whistleBlower: ReportWhistleBlower, var context: Co for (stat in result.options.stats) { - Timber.d("analyse stat: $stat for report: $staticReport") +// Timber.d("analyse stat: $stat for report: $staticReport") // Get current performance var query = performancesQuery(realm, staticReport, stat) @@ -219,7 +219,7 @@ class ReportTask(private var whistleBlower: ReportWhistleBlower, var context: Co val performanceQuery = computedResults.group.query val performanceName = performanceQuery.getName(this.context, nameSeparator) - Timber.d("Best computed = $performanceName, ${computedResults.computedStat(Stat.NET_RESULT)?.value}") +// Timber.d("Best computed = $performanceName, ${computedResults.computedStat(Stat.NET_RESULT)?.value}") var storePerf = true currentPerf?.let { 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 fc154bae..93d664bb 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 @@ -70,7 +70,7 @@ class Patcher { val transactionTypes = TransactionType.Value.values() - realm.executeTransaction { + realm.executeTransactionAsync { Seed.createDefaultTransactionTypes(transactionTypes, context, realm) } @@ -84,7 +84,7 @@ class Patcher { val sessions = Filter.queryOn(realm, Query(QueryCondition.IsCash)) val results = realm.where(Result::class.java).findAll() - realm.executeTransaction { + realm.executeTransactionAsync { sets.forEach { it.computeStats() } @@ -103,7 +103,7 @@ class Patcher { private fun patchDefaultTransactionTypes(context: Context) { val realm = Realm.getDefaultInstance() - realm.executeTransaction { + realm.executeTransactionAsync { val tts = realm.where(TransactionType::class.java).findAll() tts.forEach { tt -> tt.kind?.let { kind -> @@ -117,7 +117,7 @@ class Patcher { private fun patchStakes() { val realm = Realm.getDefaultInstance() - realm.executeTransaction { + realm.executeTransactionAsync { val sessions = realm.where(Session::class.java).findAll() sessions.forEach { session -> val blinds = arrayListOf(session.cgOldSmallBlind, session.cgOldBigBlind).filterNotNull() @@ -143,7 +143,7 @@ class Patcher { private fun patchNegativeLimits() { val realm = Realm.getDefaultInstance() - realm.executeTransaction { + realm.executeTransactionAsync { val sessions = realm.where(Session::class.java).lessThan("limit", 0).findAll() sessions.forEach { session -> session.limit = null @@ -154,7 +154,7 @@ class Patcher { private fun cleanBlindsFilters() { val realm = Realm.getDefaultInstance() - realm.executeTransaction { + realm.executeTransactionAsync { val blindFilterConditions = realm.where(FilterCondition::class.java).equalTo("filterName", "AnyBlind").findAll() val filterIds = blindFilterConditions.mapNotNull { it.filters?.firstOrNull() }.map { it.id } val filters = realm.where(Filter::class.java).`in`("id", filterIds.toTypedArray()).findAll() @@ -170,7 +170,7 @@ class Patcher { private fun patchSessionSet() { val realm = Realm.getDefaultInstance() - realm.executeTransaction { + realm.executeTransactionAsync { realm.where(SessionSet::class.java).findAll().deleteAllFromRealm() val sessions = realm.where(Session::class.java).isNotNull("startDate").isNotNull("endDate").findAll() sessions.forEach { session -> @@ -187,7 +187,7 @@ class Patcher { */ private fun patchComputableResults() { val realm = Realm.getDefaultInstance() - realm.executeTransaction { + realm.executeTransactionAsync { val crs = realm.where(ComputableResult::class.java).findAll() crs.forEach { cr -> cr.session?.let { cr.updateWith(it) } @@ -211,7 +211,7 @@ class Patcher { val realm = Realm.getDefaultInstance() val zero = 0 val sessions = realm.where().equalTo("numberOfTables", zero).findAll() - realm.executeTransaction { + realm.executeTransactionAsync { sessions.forEach { s -> s.numberOfTables = 1 } @@ -222,7 +222,7 @@ class Patcher { private fun patchRatedAmounts() { val realm = Realm.getDefaultInstance() val transactions = realm.where().findAll() - realm.executeTransaction { + realm.executeTransactionAsync { transactions.forEach { t -> t.computeRatedAmount() } diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt index 15b55812..3fd6dc22 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/CustomField.kt @@ -250,7 +250,7 @@ open class CustomField : RealmObject(), RowRepresentable, RowUpdatable, NameMana fun cleanupEntries() { // called when saving the custom field val realm = Realm.getDefaultInstance() - realm.executeTransaction { + realm.executeTransactionAsync { this.entriesToDelete.forEach { // entries are out of realm realm.where().equalTo("id", it.id).findFirst()?.deleteFromRealm() } @@ -272,26 +272,6 @@ open class CustomField : RealmObject(), RowRepresentable, RowUpdatable, NameMana } } - /** - * Clean the entries if the type is not a list & remove the deleted entries from realm - */ -// fun cleanEntries(realm: Realm) { -// realm.executeTransaction { -// -// if (!isListType) { -// entriesToDelete.addAll(entries) -// entries.clear() -// } -// -// // @TODO -// entriesToDelete.forEach { -// Timber.d("Delete entry: V=${it.value} N=${it.numericValue} / ID=${it.id}") -// realm.where().equalTo("id", it.id).findFirst()?.deleteFromRealm() -// } -// entriesToDelete.clear() -// } -// } - /** * Returns a comparison criteria based on this custom field */ diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Player.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Player.kt index ce3f537f..f9270c34 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Player.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Player.kt @@ -174,7 +174,7 @@ open class Player : RealmObject(), NameManageable, Savable, Deletable, StaticRow */ fun cleanupComments() { // called when saving the custom field val realm = Realm.getDefaultInstance() - realm.executeTransaction { + realm.executeTransactionAsync { this.commentsToDelete.forEach { // entries are out of realm realm.where().equalTo("id", it.id).findFirst()?.deleteFromRealm() } diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/Result.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/Result.kt index 7298726d..efc5f99a 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/Result.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/Result.kt @@ -14,7 +14,7 @@ open class Result : RealmObject(), Filterable { companion object { - fun fieldNameForQueryType(queryCondition: Class < out QueryCondition>): String? { + fun fieldNameForQueryType(queryCondition: Class ): String? { Session.fieldNameForQueryType(queryCondition)?.let { return "sessions.$it" } 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 5174d4d2..b0261475 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 @@ -80,11 +80,12 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim session.limit = Limit.NO.ordinal session.game = realm.where(Game::class.java).equalTo("shortName", "HE").findFirst() - return if (managed) { - realm.copyToRealm(session) - } else { - session - } + return session +// return if (managed) { +// realm.copyToRealm(session) +// } else { +// session +// } } fun fieldNameForQueryType(queryCondition: Class < out QueryCondition >): String? { @@ -208,7 +209,7 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim if (value != null && this.endDate != null && value.after(this.endDate)) { this.endDate = null } - this.dateChanged() +// this.dateChanged() this.computeStats() } @@ -228,7 +229,7 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim } this.computeNetDuration() - this.dateChanged() +// this.dateChanged() this.defineDefaultTournamentBuyinIfNecessary() this.computeStats() } @@ -386,18 +387,19 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim this.generateStakes() } - /** - * Manages impacts on SessionSets - * Should be called when the start / end date are changed - */ - private fun dateChanged() { - if (this.endDate != null) { - SessionSetManager.updateTimeline(this) - } else if (this.sessionSet != null) { - SessionSetManager.removeFromTimeline(this) - } -// this.updateRowRepresentation() - } +// /** +// * Manages impacts on SessionSets +// * Should be called when the start / end date are changed +// */ +// private fun dateChanged() { +// SessionSetManager.updatedSession(this) +//// if (this.endDate != null) { +//// SessionSetManager.updateTimeline(this) +//// } else if (this.sessionSet != null) { +//// SessionSetManager.removeFromTimeline(this) +//// } +//// this.updateRowRepresentation() +// } /** * Returns a non-null date for the session @@ -501,8 +503,14 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim val numberOfHandsPerHour: Double get() { val tableSize = this.tableSize ?: 9 // 9 is the default table size if null - val config = UserConfig.getConfiguration(this.realm) - val playerHandsPerHour = if (this.isLive) config.liveDealtHandsPerHour else config.onlineDealtHandsPerHour + + var playerHandsPerHour = 0 + UserConfig.getConfiguration(this.realm) { config -> + playerHandsPerHour = if (this.isLive) config.liveDealtHandsPerHour else config.onlineDealtHandsPerHour + } + +// val config = UserConfig.getConfiguration(this.realm) +// val playerHandsPerHour = if (this.isLive) config.liveDealtHandsPerHour else config.onlineDealtHandsPerHour return this.numberOfTables * playerHandsPerHour / tableSize.toDouble() } @@ -557,7 +565,7 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim * Start or continue a session */ fun startOrContinue() { - realm.executeTransaction { +// realm.executeTransaction { when (val state = getState()) { SessionState.PENDING, SessionState.PLANNED -> { this.startDate = Date() @@ -576,7 +584,7 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim throw PAIllegalStateException("unmanaged session state: $state") } } - } +// } } private fun defineDefaultTournamentBuyinIfNecessary() { @@ -589,28 +597,28 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim * Pause a session */ fun pause() { - realm.executeTransaction { +// realm.executeTransaction { when (val state = getState()) { SessionState.STARTED -> { this.pauseDate = Date() } else -> throw PAIllegalStateException("Pausing a session in an unmanaged state: $state") } - } +// } } /** * Stop a session */ fun stop(context: Context) { - realm.executeTransaction { +// realm.executeTransaction { when (val state = getState()) { SessionState.STARTED, SessionState.PAUSED -> { this.end() } else -> throw Exception("Stopping session in unmanaged state: $state") } - } +// } cancelStopNotification(context) } @@ -618,12 +626,12 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim * Restart a session */ fun restart() { - realm.executeTransaction { +// realm.executeTransaction { this.pauseDate = null this.startDate = Date() this.endDate = null this.breakDuration = 0L - } +// } } /** @@ -721,10 +729,10 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim CrashLogging.log("Deletes session. Id = ${this.id}") if (isValid) { - realm.executeTransaction { +// realm.executeTransaction { cleanup() deleteFromRealm() - } +// } } else { CrashLogging.log("Attempt to delete an invalid session") } 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 20025072..1ef5e45f 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 @@ -100,10 +100,10 @@ open class SessionSet() : RealmObject(), Timed, Filterable { companion object { - fun newInstance(realm: Realm) : SessionSet { - val sessionSet = SessionSet() - return realm.copyToRealm(sessionSet) - } +// fun newInstance(realm: Realm) : SessionSet { +// val sessionSet = SessionSet() +// return realm.copyToRealm(sessionSet) +// } fun fieldNameForQueryType(queryCondition: Class < out QueryCondition >): String? { Session.fieldNameForQueryType(queryCondition)?.let { diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/UserConfig.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/UserConfig.kt index 96094c1f..f72ab107 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/UserConfig.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/UserConfig.kt @@ -11,7 +11,19 @@ open class UserConfig : RealmObject() { companion object { - fun getConfiguration(realm: Realm): UserConfig { + fun getConfiguration(realm: Realm?, handler: (UserConfig) -> (Unit)) { + + if (realm != null) { + handler(userConfiguration(realm)) + } else { + val r = Realm.getDefaultInstance() + handler(userConfiguration(r)) + r.close() + } + + } + + private fun userConfiguration(realm: Realm): UserConfig { realm.where(UserConfig::class.java).findFirst()?.let { config -> return config } diff --git a/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/HandHistory.kt b/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/HandHistory.kt index c8db6f7c..197551a1 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/HandHistory.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/realm/handhistory/HandHistory.kt @@ -313,13 +313,7 @@ open class HandHistory : RealmObject(), Deletable, RowRepresentable, Filterable, * Creates and affect a PlayerSetup at the given [positionIndex] */ fun createPlayerSetup(positionIndex: Int): PlayerSetup { - - val playerSetup = if (this.realm != null) { - this.realm.createObject(PlayerSetup::class.java) } - else { - PlayerSetup() - } - + val playerSetup = PlayerSetup() playerSetup.position = positionIndex this.playerSetups.add(playerSetup) return playerSetup @@ -562,7 +556,7 @@ open class HandHistory : RealmObject(), Deletable, RowRepresentable, Filterable, this.winnerPots.clear() this.winnerPots.addAll(wonPots) - Timber.d("Pot won: ${this.winnerPots.size} for positions: ${this.winnerPots.map {it.position}} ") + Timber.d("Pot won: ${this.winnerPots.size} for positions: ${this.winnerPots.map { it.position }} ") } /*** diff --git a/app/src/main/java/net/pokeranalytics/android/model/utils/FavoriteSessionFinder.kt b/app/src/main/java/net/pokeranalytics/android/model/utils/FavoriteSessionFinder.kt index fe40b2bb..97c5f7ad 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/utils/FavoriteSessionFinder.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/utils/FavoriteSessionFinder.kt @@ -73,15 +73,21 @@ class FavoriteSessionFinder { /** * Copies the favorite session parameters on the [session] */ - fun copyParametersFromFavoriteSession(session: Session, location: Location?, context: Context) { + fun copyParametersFromFavoriteSession(realm: Realm, session: Session, location: Location?, context: Context) { - val favoriteSession = favoriteSession(session.type, location, session.realm, context) + val favoriteSession = favoriteSession(session.type, location, realm, context) favoriteSession?.let { fav -> session.limit = fav.limit - session.game = fav.game - session.bankroll = fav.bankroll + + fav.game?.let { + session.game = realm.copyFromRealm(it) + } + fav.bankroll?.let { + session.bankroll = realm.copyFromRealm(it) + } + session.tableSize = fav.tableSize when (session.type) { diff --git a/app/src/main/java/net/pokeranalytics/android/model/utils/SessionSetManager.kt b/app/src/main/java/net/pokeranalytics/android/model/utils/SessionSetManager.kt index 598cba3b..bfdc9a2b 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/utils/SessionSetManager.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/utils/SessionSetManager.kt @@ -1,9 +1,9 @@ package net.pokeranalytics.android.model.utils +import io.realm.Realm import io.realm.RealmQuery import io.realm.RealmResults import net.pokeranalytics.android.exceptions.ModelException -import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.model.realm.SessionSet import kotlin.math.max @@ -14,196 +14,228 @@ class CorruptSessionSetException(message: String) : Exception(message) * The manager is in charge of updating the abstract concept of timeline, * representing the sequenced time frames where the user plays. */ -class SessionSetManager { - - companion object { - - /** - * Updates the global timeline using the updated [session] - */ - fun updateTimeline(session: Session) { - - if (!session.realm.isInTransaction) { - throw PAIllegalStateException("realm should be in transaction at this point") - } - - if (session.startDate == null) { - throw ModelException("Start date should never be null here") - } - if (session.endDate == null) { - throw ModelException("End date should never be null here") - } - - val sessionSets = this.matchingSets(session) - cleanupSessionSets(session, sessionSets) - - - } - - private fun matchingSets(session: Session) : RealmResults { - val realm = session.realm - val endDate = session.endDate!! // tested above - val startDate = session.startDate!! - - val query: RealmQuery = realm.where(SessionSet::class.java) - - query - .lessThanOrEqualTo("startDate", startDate) - .greaterThanOrEqualTo("endDate", startDate) - .or() - .lessThanOrEqualTo("startDate", endDate) - .greaterThanOrEqualTo("endDate", endDate) - .or() - .greaterThanOrEqualTo("startDate", startDate) - .lessThanOrEqualTo("endDate", endDate) - - return query.findAll() - } - - /** - * Multiple session sets update: - * Merges or splits session sets - * Does that by deleting then recreating - */ - private fun cleanupSessionSets(session: Session, sessionSets: RealmResults) { - - // get all endedSessions from sets - val allImpactedSessions = mutableSetOf() - sessionSets.forEach { set -> - set.sessions?.asIterable()?.let { allImpactedSessions.addAll(it) } - } - allImpactedSessions.add(session) - - // delete all sets - sessionSets.deleteAllFromRealm() - - allImpactedSessions.forEach { impactedSession -> - val sets = matchingSets(impactedSession) - this.updateTimeFrames(sets, impactedSession) - } +object SessionSetManager { + + var sessions: RealmResults + + private val sessionsToProcess = mutableSetOf() + + init { + + val realm = Realm.getDefaultInstance() + + this.sessions = realm.where(Session::class.java).findAll() + this.sessions.addChangeListener { sessions, changeSet -> + changeSet.insertions.forEach { index -> + sessions[index]?.let { this.sessionsToProcess.add(it) } + } + changeSet.changes.forEach { index -> + sessions[index]?.let { this.sessionsToProcess.add(it) } + } + + processSessions() + } + + realm.close() + } + +// fun updatedSession(session: Session) { +// this.sessionsToProcess.add(session) +// } + + private fun processSessions() { + for (session in this.sessionsToProcess) { + if (session.startDate != null && session.endDate != null) { + this.updateTimeline(session) + } else if (session.sessionSet != null) { + removeFromTimeline(session) + } + } + this.sessionsToProcess.clear() + } + + /** + * Updates the global timeline using the updated [session] + */ + fun updateTimeline(session: Session) { + +// if (!session.realm.isInTransaction) { +// throw PAIllegalStateException("realm should be in transaction at this point") +// } + + if (session.startDate == null) { + throw ModelException("Start date should never be null here") + } + if (session.endDate == null) { + throw ModelException("End date should never be null here") + } + + val sessionSets = this.matchingSets(session) + cleanupSessionSets(session, sessionSets) + + } + + private fun matchingSets(session: Session): RealmResults { + val realm = session.realm + val endDate = session.endDate!! // tested above + val startDate = session.startDate!! + + val query: RealmQuery = realm.where(SessionSet::class.java) + + query + .lessThanOrEqualTo("startDate", startDate) + .greaterThanOrEqualTo("endDate", startDate) + .or() + .lessThanOrEqualTo("startDate", endDate) + .greaterThanOrEqualTo("endDate", endDate) + .or() + .greaterThanOrEqualTo("startDate", startDate) + .lessThanOrEqualTo("endDate", endDate) + + return query.findAll() + } + + /** + * Multiple session sets update: + * Merges or splits session sets + * Does that by deleting then recreating + */ + private fun cleanupSessionSets(session: Session, sessionSets: RealmResults) { + + // get all endedSessions from sets + val allImpactedSessions = mutableSetOf() + sessionSets.forEach { set -> + set.sessions?.asIterable()?.let { allImpactedSessions.addAll(it) } + } + allImpactedSessions.add(session) + + // delete all sets + sessionSets.deleteAllFromRealm() + + allImpactedSessions.forEach { impactedSession -> + val sets = matchingSets(impactedSession) + this.updateTimeFrames(sets, impactedSession) + } // Timber.d("netDuration 3 = : ${set.timeFrame?.netDuration}") - } - - - /** - * Update the global timeline using the impacted [sessionSets] and the updated [session] - */ - private fun updateTimeFrames(sessionSets: RealmResults, session: Session) { - - when (sessionSets.size) { - 0 -> this.createOrUpdateSessionSet(session) - else -> this.mergeSessionGroups(session, sessionSets) - } - - } - - /** - * Creates or update the session set for the [session] - */ - private fun createOrUpdateSessionSet(session: Session) { - - val set = session.sessionSet - if (set != null) { - set.startDate = session.startDate!! // tested above - set.endDate = session.endDate!! - } else { - this.createSessionSet(session) - } - - } - - /** - * Create a set and affect it to the [session] - */ - private fun createSessionSet(session: Session) { - val set: SessionSet = SessionSet.newInstance(session.realm) - set.startDate = session.startDate!! - set.endDate = session.endDate!! - set.breakDuration = session.breakDuration - session.sessionSet = set - set.computeStats() - } - - /** - * Multiple session sets update: - * Merges all sets into one (delete all then create a new one) - */ - private fun mergeSessionGroups(session: Session, sessionSets: RealmResults) { - - var startDate = session.startDate!! - var endDate = session.endDate!! - - // get all endedSessions from sets - val sessions = mutableSetOf() - sessionSets.forEach { set -> - set.sessions?.asIterable()?.let { sessions.addAll(it) } - } - - // find earlier and later dates from all sets - sessions.forEach { s -> - - if (s.startDate != null && s.endDate != null) { - val start = s.startDate!! - val end = s.endDate!! - if (start.before(startDate)) { - startDate = start - } - if (end.after(endDate)) { - endDate = end - } - } else { - throw CorruptSessionSetException("Set contains unfinished sessions!") - } - } - - // delete all sets - sessionSets.deleteAllFromRealm() - - // Create a new set - val set: SessionSet = SessionSet.newInstance(session.realm) - set.startDate = startDate - set.endDate = endDate - - // Add the session linked to this timeframe to the new sessionGroup - session.sessionSet = set - - // Add all orphan endedSessions - sessions.forEach { s -> - s.sessionSet = set - set.breakDuration = max(set.breakDuration, s.breakDuration) - } - set.computeStats() + } + + /** + * Update the global timeline using the impacted [sessionSets] and the updated [session] + */ + private fun updateTimeFrames(sessionSets: RealmResults, session: Session) { + + when (sessionSets.size) { + 0 -> this.createOrUpdateSessionSet(session) + else -> this.mergeSessionGroups(session, sessionSets) + } + + } + + /** + * Creates or update the session set for the [session] + */ + private fun createOrUpdateSessionSet(session: Session) { + + val set = session.sessionSet + if (set != null) { + set.startDate = session.startDate!! // tested above + set.endDate = session.endDate!! + } else { + this.createSessionSet(session) + } + + } + + /** + * Create a set and affect it to the [session] + */ + private fun createSessionSet(session: Session) { + val set = SessionSet() //.newInstance(session.realm) + set.startDate = session.startDate!! + set.endDate = session.endDate!! + set.breakDuration = session.breakDuration + session.sessionSet = set + set.computeStats() + } + + /** + * Multiple session sets update: + * Merges all sets into one (delete all then create a new one) + */ + private fun mergeSessionGroups(session: Session, sessionSets: RealmResults) { + + var startDate = session.startDate!! + var endDate = session.endDate!! + + // get all endedSessions from sets + val sessions = mutableSetOf() + sessionSets.forEach { set -> + set.sessions?.asIterable()?.let { sessions.addAll(it) } + } + + // find earlier and later dates from all sets + sessions.forEach { s -> + + if (s.startDate != null && s.endDate != null) { + val start = s.startDate!! + val end = s.endDate!! + if (start.before(startDate)) { + startDate = start + } + if (end.after(endDate)) { + endDate = end + } + } else { + throw CorruptSessionSetException("Set contains unfinished sessions!") + } + } + + // delete all sets + sessionSets.deleteAllFromRealm() + + // Create a new set + val set = SessionSet() //.newInstance(session.realm) + set.startDate = startDate + set.endDate = endDate + + // Add the session linked to this timeframe to the new sessionGroup + session.sessionSet = set + + // Add all orphan endedSessions + sessions.forEach { s -> + s.sessionSet = set + set.breakDuration = max(set.breakDuration, s.breakDuration) + } + set.computeStats() // Timber.d("netDuration 3 = : ${set.timeFrame?.netDuration}") - } + } - /** - * Removes the [session] from the timeline - */ - fun removeFromTimeline(session: Session) { + /** + * Removes the [session] from the timeline + */ + fun removeFromTimeline(session: Session) { - if (!session.realm.isInTransaction) { - throw PAIllegalStateException("realm should be in transaction at this point") - } +// if (!session.realm.isInTransaction) { +// throw PAIllegalStateException("realm should be in transaction at this point") +// } - val sessionSet = session.sessionSet - if (sessionSet != null) { + val sessionSet = session.sessionSet + if (sessionSet != null) { - val sessions = mutableSetOf() - sessionSet.sessions?.asIterable()?.let { sessions.addAll(it) } - sessions.remove(session) + val sessions = mutableSetOf() + sessionSet.sessions?.asIterable()?.let { sessions.addAll(it) } + sessions.remove(session) - sessionSet.deleteFromRealm() + sessionSet.deleteFromRealm() - sessions.forEach { - updateTimeline(it) - } - } - } - - } + sessions.forEach { + updateTimeline(it) + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt b/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt index 59fe47b9..34598134 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/activity/HomeActivity.kt @@ -115,7 +115,7 @@ class HomeActivity : BaseActivity(), NewPerformanceListener { // observe currency changes this.currencies = realm.where(Currency::class.java).findAll() this.currencies.addChangeListener { currencies, _ -> - realm.executeTransaction { + realm.executeTransactionAsync { currencies.forEach { it.refreshRelatedRatedValues() } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SettingsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SettingsFragment.kt index 2875020c..fa0a4c9e 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SettingsFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SettingsFragment.kt @@ -185,12 +185,12 @@ class SettingsFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRep Preferences.setCurrencyCode(currencyCode, requireContext()) val realm = Realm.getDefaultInstance() - realm.executeTransaction { - realm.where(Currency::class.java).findAll().forEach { currency -> + realm.executeTransactionAsync { execRealm-> + execRealm.where(Currency::class.java).findAll().forEach { currency -> currency.rate = (currency.rate ?: 1.0) * rate } - realm.where(Session::class.java).findAll().forEach { session -> + execRealm.where(Session::class.java).findAll().forEach { session -> session.bankrollHasBeenUpdated() } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticsFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticsFragment.kt index 2190009d..7cfeb891 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticsFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/StatisticsFragment.kt @@ -96,10 +96,11 @@ class StatisticsFragment : FilterableFragment(), RealmAsyncListener { private fun setTransactionFilterItemColor() { context?.let { - val userConfig = UserConfig.getConfiguration(getRealm()) - val color = if (userConfig.transactionTypeIds.isNotEmpty()) R.color.red else R.color.white - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - this.transactionFilterMenuItem?.iconTintList = ColorStateList.valueOf(it.getColor(color)) + UserConfig.getConfiguration(getRealm()) { userConfig -> + val color = if (userConfig.transactionTypeIds.isNotEmpty()) R.color.red else R.color.white + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + this.transactionFilterMenuItem?.iconTintList = ColorStateList.valueOf(it.getColor(color)) + } } } } @@ -246,7 +247,9 @@ class StatisticsFragment : FilterableFragment(), RealmAsyncListener { computedStats.addAll(tStats) options.stats = computedStats - options.includedTransactions = UserConfig.getConfiguration(realm).transactionTypes(realm) + UserConfig.getConfiguration(realm) { userConfig -> + options.includedTransactions = userConfig.transactionTypes(realm) + } return Calculator.computeGroups(realm, listOf(allSessionGroup, cgSessionGroup, tSessionGroup), options) } 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 17ebb25b..cf1200f5 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 @@ -11,7 +11,6 @@ import io.realm.Realm import io.realm.RealmModel import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import net.pokeranalytics.android.R import net.pokeranalytics.android.calculus.Calculator @@ -25,6 +24,7 @@ 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.Transaction +import net.pokeranalytics.android.model.realm.TransactionType import net.pokeranalytics.android.model.realm.UserConfig import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate @@ -133,11 +133,10 @@ class CalendarFragment : RealmFragment(), StaticRowRepresentableDataSource, private fun setTransactionFilterItemColor() { context?.let { - val userConfig = UserConfig.getConfiguration(getRealm()) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - this.transactionFilterMenuItem?.let { item -> - val color = if (userConfig.transactionTypeIds.isNotEmpty()) R.color.red else R.color.white - item.iconTintList = ColorStateList.valueOf(it.getColor(color)) + UserConfig.getConfiguration(getRealm()) { userConfig -> + val color = if (userConfig.transactionTypeIds.isNotEmpty()) R.color.red else R.color.white + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + this.transactionFilterMenuItem?.iconTintList = ColorStateList.valueOf(it.getColor(color)) } } } @@ -378,7 +377,12 @@ class CalendarFragment : RealmFragment(), StaticRowRepresentableDataSource, Stat.STANDARD_DEVIATION_HOURLY ) - val transactionTypes = UserConfig.getConfiguration(realm).transactionTypes(realm) + var transactionTypes = listOf() + UserConfig.getConfiguration(realm) { userConfig -> + transactionTypes = userConfig.transactionTypes(realm) + } + +// val transactionTypes = UserConfig.getConfiguration(realm).transactionTypes(realm) // All val allOptions = Calculator.Options( diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FilterHandler.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FilterHandler.kt index dadb2a24..f8e5ad07 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FilterHandler.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/filter/FilterHandler.kt @@ -45,9 +45,8 @@ interface FilterHandler { fun saveFilter(context: Context, filterId: String) { Preferences.setActiveFilterId(filterId, context) - val realm = Realm.getDefaultInstance() - realm.executeTransaction { executeRealm -> + realm.executeTransactionAsync { executeRealm -> currentFilter(context, executeRealm)?.let { it.useCount++ } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/editor/EditorFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/editor/EditorFragment.kt index 89330e71..5dc0f294 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/editor/EditorFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/editor/EditorFragment.kt @@ -202,12 +202,15 @@ class EditorFragment : RealmFragment(), RowRepresentableDelegate, KeyboardListen if (resultCode == Activity.RESULT_OK) { val playerId = data?.getStringExtra(BaseFragment.BundleKey.PRIMARY_KEY.value) ?: throw PAIllegalStateException("Primary key not set where as activity has finished") - getRealm().findById(playerId)?.let { player -> - this.model.playerSelected(player) + + val realm = getRealm() + + realm.findById(playerId)?.let { player -> + val p = realm.copyFromRealm(player) + this.model.playerSelected(p) } ?: throw PAIllegalStateException("Player (id=$playerId) not found") this.editorAdapter.notifyDataSetChanged() } - } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/EditorViewModel.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/EditorViewModel.kt index 3024c702..1d103031 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/EditorViewModel.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/EditorViewModel.kt @@ -635,14 +635,12 @@ class EditorViewModel : ViewModel(), RowRepresentableDataSource, CardCentralizer * Saves the current hand state in the database */ fun save(realm: Realm) { - realm.executeTransaction { - this.handHistory.actions.clear() - val actions = this.sortedActions.map { it.action } - this.handHistory.actions.addAll(actions) + this.handHistory.actions.clear() + val actions = this.sortedActions.map { it.action } + this.handHistory.actions.addAll(actions) - if (!this.handHistory.isManaged) { - realm.copyToRealmOrUpdate(this.handHistory) - } + realm.executeTransactionAsync { execRealm -> + execRealm.copyToRealmOrUpdate(this.handHistory) } this.defineWinnerPositions() } @@ -652,8 +650,10 @@ class EditorViewModel : ViewModel(), RowRepresentableDataSource, CardCentralizer val hhId = this.handHistory.id CoroutineScope(Dispatchers.Default).launch { val realm = Realm.getDefaultInstance() - realm.executeTransaction { - realm.findById(hhId)?.defineWinnerPositions() + + realm.findById(hhId)?.defineWinnerPositions() + realm.executeTransactionAsync { execRealm -> + execRealm.copyToRealmOrUpdate(handHistory) } realm.close() } @@ -1004,16 +1004,16 @@ class EditorViewModel : ViewModel(), RowRepresentableDataSource, CardCentralizer fun playerSelected(player: Player) { // Remove all use of the selected player - this.handHistory.playerSetups.filter { it.player == player }.forEach { + this.handHistory.playerSetups.filter { it.player?.id == player.id }.forEach { it.player = null } // Affects the player to the selected position this.tappedPlayerPositionIndex?.let { positionIndex -> - player.realm.executeTransaction { +// player.realm.executeTransaction { val ps = this.handHistory.playerSetupForPosition(positionIndex) ?: this.handHistory.createPlayerSetup(positionIndex) ps.player = player - } +// } } ?: throw PAIllegalStateException("Click position not set for player selection") } 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 edd16ba8..4642e796 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 @@ -176,40 +176,59 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr if (sessionId != null) { val sessionRealm = realm.findById(sessionId) - if (sessionRealm != null) { + sessionRealm?.let { + val copy = realm.copyFromRealm(it) if (this.model.duplicate) { // duplicate session - realm.executeTransaction { - val session = sessionRealm.duplicate() +// realm.executeTransaction { + val session = copy.duplicate() currentSession = session - } +// } sessionHasBeenUserCustomized = false } else { // show existing session - currentSession = sessionRealm + currentSession = copy sessionHasBeenUserCustomized = true } - } else { - throw PAIllegalStateException("Session cannot be null here, session id = $sessionId") - } + + } ?: throw PAIllegalStateException("Session cannot be null here, session id = $sessionId") + +// if (sessionRealm != null) { +// +// if (this.model.duplicate) { // duplicate session +// realm.executeTransaction { +// val session = sessionRealm.duplicate() +// currentSession = session +// } +// sessionHasBeenUserCustomized = false +// } else { // show existing session +// currentSession = sessionRealm +// sessionHasBeenUserCustomized = true +// } +// } else { +// throw PAIllegalStateException("Session cannot be null here, session id = $sessionId") +// } } else { // create new session - realm.executeTransaction { executeRealm -> - currentSession = Session.newInstance(executeRealm, this.model.isTournament) - FavoriteSessionFinder.copyParametersFromFavoriteSession(currentSession, null, requireContext()) - } + + currentSession = Session.newInstance(realm, this.model.isTournament) + FavoriteSessionFinder.copyParametersFromFavoriteSession(realm, currentSession, null, requireContext()) + +// realm.executeTransaction { executeRealm -> +// currentSession = Session.newInstance(executeRealm, this.model.isTournament) +// FavoriteSessionFinder.copyParametersFromFavoriteSession(currentSession, null, requireContext()) +// } // Find the nearest location around the user parentActivity?.findNearestLocation { it?.let { location -> - realm.executeTransaction { executeRealm -> - val realmLocation = executeRealm.findById(location.id) - FavoriteSessionFinder.copyParametersFromFavoriteSession(currentSession, realmLocation, requireContext()) - - currentSession.location = realmLocation - } +// realm.executeTransaction { executeRealm -> + val realmLocation = realm.findById(location.id) + FavoriteSessionFinder.copyParametersFromFavoriteSession(realm, currentSession, realmLocation, requireContext()) + currentSession.location = realmLocation +// } this.updateSessionUI(true) } } - sessionHasBeenUserCustomized = false + this.sessionHasBeenUserCustomized = false } } @@ -251,15 +270,23 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr } override fun onRowValueChanged(value: Any?, row: RowRepresentable) { + + Timber.d("value changed: $value, row: $row") this.sessionHasBeenUserCustomized = true - try { - getRealm().executeTransaction { - this.currentSession.updateValue(value, row) - } - } catch (e: PAIllegalStateException) { - Toast.makeText(context, e.message, Toast.LENGTH_LONG).show() - return + + updateSessionThenSaveAsynchronously { session -> + session.updateValue(value, row) } + +// try { +// this.currentSession.updateValue(value, row) +// getRealm().executeTransactionAsync { realm -> +// realm.copyToRealmOrUpdate(this.currentSession) +// } +// } catch (e: PAIllegalStateException) { +// Toast.makeText(context, e.message, Toast.LENGTH_LONG).show() +// return +// } this.sessionAdapter.refreshRow(row) when (row) { SessionPropertiesRow.CASHED_OUT, SessionPropertiesRow.PRIZE, SessionPropertiesRow.NET_RESULT, @@ -273,6 +300,18 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr } + private fun updateSessionThenSaveAsynchronously(handler: (Session) -> (Unit)) { + try { + handler(this.currentSession) + } catch (e: PAIllegalStateException) { + Toast.makeText(context, e.message, Toast.LENGTH_LONG).show() + return + } + getRealm().executeTransactionAsync { realm -> + realm.copyToRealmOrUpdate(this.currentSession) + } + } + /** * Update the UI with the session data * Should be called after the initialization of the session @@ -386,12 +425,20 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr } } - currentSession.startOrContinue() + updateSessionThenSaveAsynchronously { session -> + session.startOrContinue() + } + +// currentSession.startOrContinue() binding.recyclerView.smoothScrollToPosition(0) } SessionState.STARTED -> { - currentSession.pause() + updateSessionThenSaveAsynchronously { session -> + session.pause() + } + +// currentSession.pause() } else -> { } @@ -435,7 +482,9 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr * Stop the current session */ private fun stopSession() { - this.currentSession.stop(requireContext()) + updateSessionThenSaveAsynchronously { session -> + session.stop(requireContext()) + } updateSessionUI() } @@ -454,7 +503,9 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr * Restart timer */ private fun restartTimer() { - currentSession.restart() + updateSessionThenSaveAsynchronously { session -> + session.restart() + } updateSessionUI() } @@ -478,7 +529,14 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr val bankrollId = this.currentSession.bankroll?.id - this.currentSession.delete() + val sessionId = this.currentSession.id + getRealm().executeTransactionAsync { realm -> + realm.findById(sessionId)?.let { session -> + session.delete() + } + } + +// this.currentSession.delete() bankrollId?.let { BankrollReportManager.notifyBankrollReportImpact(bankrollId) } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/settings/DealtHandsPerHourFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/settings/DealtHandsPerHourFragment.kt index 060bef31..7c91f981 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/settings/DealtHandsPerHourFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/settings/DealtHandsPerHourFragment.kt @@ -49,9 +49,10 @@ class DealtHandsPerHourFragment : RealmFragment() { setDisplayHomeAsUpEnabled(true) - val userConfig = UserConfig.getConfiguration(this.getRealm()) - this.liveValue.hint = "${userConfig.liveDealtHandsPerHour}" - this.onlineValue.hint = "${userConfig.onlineDealtHandsPerHour}" + UserConfig.getConfiguration(this.getRealm()) { userConfig -> + this.liveValue.hint = "${userConfig.liveDealtHandsPerHour}" + this.onlineValue.hint = "${userConfig.onlineDealtHandsPerHour}" + } } @@ -59,14 +60,17 @@ class DealtHandsPerHourFragment : RealmFragment() { getRealm().executeTransaction { realm -> - val userConfig = UserConfig.getConfiguration(realm) - this.liveValue.text.toString().toIntOrNull()?.let { liveDealtHandsPerHour -> - userConfig.liveDealtHandsPerHour = liveDealtHandsPerHour - } - this.onlineValue.text.toString().toIntOrNull()?.let { onlineDealtHandsPerHour -> - userConfig.onlineDealtHandsPerHour = onlineDealtHandsPerHour + UserConfig.getConfiguration(realm) { userConfig -> + this.liveValue.text.toString().toIntOrNull()?.let { liveDealtHandsPerHour -> + userConfig.liveDealtHandsPerHour = liveDealtHandsPerHour + } + this.onlineValue.text.toString().toIntOrNull()?.let { onlineDealtHandsPerHour -> + userConfig.onlineDealtHandsPerHour = onlineDealtHandsPerHour + } + realm.copyToRealmOrUpdate(userConfig) } - realm.copyToRealmOrUpdate(userConfig) + +// val userConfig = UserConfig.getConfiguration(realm) // update all precomputed hand counts realm.where(ComputableResult::class.java).findAll().forEach { cr -> diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/settings/TransactionFilterFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/settings/TransactionFilterFragment.kt index 85f82ac2..c2561ebe 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/settings/TransactionFilterFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/settings/TransactionFilterFragment.kt @@ -90,16 +90,18 @@ class TransactionFilterFragment : RealmFragment(), StaticRowRepresentableDataSou .findAll() this.model.transactionTypes = transactionTypes - val userConfig = UserConfig.getConfiguration(this.getRealm()) - this.model.selectedTransactionTypes = userConfig.transactionTypes(getRealm()).toMutableSet() + UserConfig.getConfiguration(this.getRealm()) { userConfig -> + this.model.selectedTransactionTypes = userConfig.transactionTypes(getRealm()).toMutableSet() + } } private fun save() { getRealm().executeTransaction { realm -> - val userConfig = UserConfig.getConfiguration(realm) - userConfig.setTransactionTypeIds(this.model.selectedTransactionTypes) - realm.copyToRealmOrUpdate(userConfig) + UserConfig.getConfiguration(this.getRealm()) { userConfig -> + userConfig.setTransactionTypeIds(this.model.selectedTransactionTypes) + realm.copyToRealmOrUpdate(userConfig) + } } this.activity?.finish() } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/viewmodel/BottomSheetViewModel.kt b/app/src/main/java/net/pokeranalytics/android/ui/viewmodel/BottomSheetViewModel.kt index c98b5ed3..71bd8a71 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/viewmodel/BottomSheetViewModel.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/viewmodel/BottomSheetViewModel.kt @@ -3,6 +3,7 @@ package net.pokeranalytics.android.ui.viewmodel import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import io.realm.RealmList +import io.realm.RealmModel import io.realm.RealmResults import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.exceptions.RowRepresentableEditDescriptorException @@ -242,9 +243,15 @@ class BottomSheetViewModel(var row: RowRepresentable) : ViewModel() { } } - fun rowSelected(position: Int): RowRepresentable? { + fun rowSelected(position: Int): RowRepresentable { return when(this.row.bottomSheetType) { - BottomSheetType.LIST -> this.realmData?.get(position) + BottomSheetType.LIST -> { + realmData?.realm?.let { realm -> + this.realmData?.get(position)?.let { + realm.copyFromRealm(it as RealmModel) as? RowRepresentable + } ?: throw PAIllegalStateException("item not found at $position") + } ?: throw PAIllegalStateException("realm not found") + } BottomSheetType.LIST_STATIC -> this.staticRows[position] else -> throw PAIllegalStateException("row selected for unmanaged bottom sheet type") } diff --git a/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt b/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt index 774cc807..0b8698c2 100644 --- a/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt +++ b/app/src/main/java/net/pokeranalytics/android/util/csv/CSVDescriptor.kt @@ -61,7 +61,7 @@ abstract class DataCSVDescriptor(source: DataSource, vararg el if (realm.isInTransaction) { this.deleteInsertedFromRealm(realm) } else { - realm.executeTransaction { + realm.executeTransactionAsync { this.deleteInsertedFromRealm(realm) } }