Fixes various issues with async writes

perftest
Laurent 3 years ago
parent 99cf2d465a
commit 3d8991baab
  1. 2
      app/src/main/java/net/pokeranalytics/android/calculus/Calculator.kt
  2. 6
      app/src/main/java/net/pokeranalytics/android/model/migrations/PokerAnalyticsMigration.kt
  3. 4
      app/src/main/java/net/pokeranalytics/android/model/realm/ComputableResult.kt
  4. 56
      app/src/main/java/net/pokeranalytics/android/model/realm/Result.kt
  5. 170
      app/src/main/java/net/pokeranalytics/android/model/realm/Session.kt
  6. 2
      app/src/main/java/net/pokeranalytics/android/model/realm/SessionSet.kt
  7. 28
      app/src/main/java/net/pokeranalytics/android/model/utils/SessionSetManager.kt
  8. 4
      app/src/main/java/net/pokeranalytics/android/ui/fragment/Top10Fragment.kt
  9. 3
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/RealmFragment.kt
  10. 12
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetDataListFragment.kt
  11. 21
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetDataMultiSelectionFragment.kt
  12. 11
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetFragment.kt
  13. 2
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetListGameFragment.kt
  14. 2
      app/src/main/java/net/pokeranalytics/android/ui/fragment/components/bottomsheet/BottomSheetStaticListFragment.kt
  15. 2
      app/src/main/java/net/pokeranalytics/android/ui/modules/feed/FeedSessionRowRepresentableAdapter.kt
  16. 43
      app/src/main/java/net/pokeranalytics/android/ui/modules/session/SessionFragment.kt
  17. 23
      app/src/main/java/net/pokeranalytics/android/ui/viewmodel/BottomSheetViewModel.kt
  18. 2
      app/src/main/java/net/pokeranalytics/android/util/csv/PACSVDescriptor.kt
  19. 19
      app/src/main/java/net/pokeranalytics/android/util/extensions/RealmExtensions.kt

@ -618,7 +618,7 @@ class SSStats(sessionSet: SessionSet, query: Query) { // Session Set Stats
if (setSessions.size == filteredSessions.size) {
this.initStatsWithSet(sessionSet)
} else {
ratedNet = filteredSessions.sumOf { it.managedComputableResult?.ratedNet ?: 0.0 }
ratedNet = filteredSessions.sumOf { it.computableResult?.ratedNet ?: 0.0 }
bbSum = filteredSessions.sumOf { it.bbNet }
hourlyDuration = filteredSessions.hourlyDuration
estimatedHands = filteredSessions.sumOf { it.estimatedHands }

@ -337,7 +337,11 @@ class PokerAnalyticsMigration : RealmMigration {
// Migrate to version 15
if (currentVersion == 14) {
schema.get("ComputableResult")?.let { crs ->
// schema.get("ComputableResult")?.let { crs ->
// crs.addField("id", String::class.java).setRequired("id", true)
// crs.addPrimaryKey("id")
// }
schema.get("Result")?.let { crs ->
crs.addField("id", String::class.java).setRequired("id", true)
crs.addPrimaryKey("id")
}

@ -8,8 +8,8 @@ import java.util.*
open class ComputableResult : RealmObject(), Filterable {
@PrimaryKey
var id = UUID.randomUUID().toString()
// @PrimaryKey
// var id = UUID.randomUUID().toString()
var ratedNet: Double = 0.0

@ -3,13 +3,13 @@ package net.pokeranalytics.android.model.realm
import io.realm.RealmList
import io.realm.RealmObject
import io.realm.RealmResults
import io.realm.annotations.Ignore
import io.realm.annotations.LinkingObjects
import io.realm.annotations.PrimaryKey
import io.realm.annotations.RealmClass
import net.pokeranalytics.android.exceptions.PADataModelException
import net.pokeranalytics.android.model.filter.Filterable
import net.pokeranalytics.android.model.filter.QueryCondition
import java.lang.ref.WeakReference
import java.util.*
@RealmClass
open class Result : RealmObject(), Filterable {
@ -24,13 +24,17 @@ open class Result : RealmObject(), Filterable {
}
}
@PrimaryKey
var id = UUID.randomUUID().toString()
/**
* The buyin amount
*/
var buyin: Double? = null
set(value) {
field = value
this.computeNumberOfRebuy()
// this.computeNumberOfRebuy()
this.computeNet(true)
}
@ -41,9 +45,6 @@ open class Result : RealmObject(), Filterable {
set(value) {
field = value
this.computeNet(true)
if (value != null) {
this.session().end()
}
}
/**
@ -53,9 +54,6 @@ open class Result : RealmObject(), Filterable {
set(value) {
field = value
this.computeNet(false)
if (value != null) {
this.session().end()
}
}
/**
@ -68,10 +66,6 @@ open class Result : RealmObject(), Filterable {
* Tips
*/
var tips: Double? = null
set(value) {
field = value
this.session().computeStats()
}
// The transactions associated with the Result, impacting the result
var transactions: RealmList<Transaction> = RealmList()
@ -89,26 +83,26 @@ open class Result : RealmObject(), Filterable {
@LinkingObjects("result")
private val sessions: RealmResults<Session>? = null
// @Ignore
// private fun managedSession(): Session {
// return this.sessions?.firstOrNull() ?: throw PAIllegalStateException("Unmanaged Result")
// }
// Manually set session
@Ignore
var inverseSession: WeakReference<Session>? = null
private val managedSession: Session
get() {
return this.sessions?.firstOrNull() ?: throw PADataModelException("Unmanaged Result")
}
// // Manually set session
// @Ignore
fun session() : Session {
return this.inverseSession?.get() ?: throw PADataModelException("Inverse session not set")
}
// var inverseSession: WeakReference<Session>? = null
//
//// @Ignore
// fun session() : Session {
// return this.inverseSession?.get() ?: throw PADataModelException("Inverse session not set")
// }
/**
* Returns 1 if the session is positive
*/
val isPositive: Int
get() {
return if (session().isTournament()) {
return if (managedSession.isTournament()) {
if ((this.cashout ?: -1.0) >= 0.0) 1 else 0 // if cashout is null we want to count a negative session
} else {
if (this.net >= 0.0) 1 else 0
@ -128,7 +122,7 @@ open class Result : RealmObject(), Filterable {
} else if (buyin != null || cashout != null) {
useBuyin = true
} else {
if (this.session().isCashGame() && !this.session().isLive) {
if (this.managedSession.isCashGame() && !this.managedSession.isLive) {
useBuyin = false
}
}
@ -144,14 +138,14 @@ open class Result : RealmObject(), Filterable {
}
// Precompute results
this.session().computeStats()
this.session().sessionSet?.computeStats()
// this.managedSession.computeStats()
// this.managedSession.sessionSet?.computeStats()
}
// Computes the number of rebuy
fun computeNumberOfRebuy() {
if (this.session().isCashGame()) {
this.session().cgBiggestBet?.let { bb ->
if (this.managedSession.isCashGame()) {
this.managedSession.cgBiggestBet?.let { bb ->
if (bb > 0.0) {
this.numberOfRebuy = (this.buyin ?: 0.0) / (bb * 100.0)
} else {
@ -159,7 +153,7 @@ open class Result : RealmObject(), Filterable {
}
}
} else {
this.session().tournamentEntryFee?.let { entryFee ->
this.managedSession.tournamentEntryFee?.let { entryFee ->
if (entryFee > 0.0) {
this.numberOfRebuy = (this.buyin ?: 0.0) / entryFee
} else {

@ -33,8 +33,11 @@ import net.pokeranalytics.android.ui.graph.Graph
import net.pokeranalytics.android.ui.view.*
import net.pokeranalytics.android.ui.view.rows.SessionPropertiesRow
import net.pokeranalytics.android.util.*
import net.pokeranalytics.android.util.extensions.*
import java.lang.ref.WeakReference
import net.pokeranalytics.android.util.extensions.hourMinute
import net.pokeranalytics.android.util.extensions.shortDateTime
import net.pokeranalytics.android.util.extensions.toCurrency
import net.pokeranalytics.android.util.extensions.toMinutes
import timber.log.Timber
import java.text.DateFormat
import java.text.NumberFormat
import java.text.ParseException
@ -68,7 +71,7 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
fun newInstance(realm: Realm, isTournament: Boolean, bankroll: Bankroll? = null): Session {
val session = Session()
val result = Result()
result.inverseSession = WeakReference(session)
// result.inverseSession = WeakReference(session)
session.result = result
if (bankroll != null) {
@ -160,18 +163,10 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
var result: Result? = null
@LinkingObjects("session")
private val managedComputableResults: RealmResults<ComputableResult>? = null
private val computableResults: RealmResults<ComputableResult>? = null
@Ignore
val managedComputableResult: ComputableResult? = this.managedComputableResults?.firstOrNull()
@Ignore
var inverseComputableResult: WeakReference<ComputableResult>? = null
// @Ignore
fun computableResult() : ComputableResult? {
return this.inverseComputableResult?.get()
}
val computableResult: ComputableResult? = this.computableResults?.firstOrNull()
// Timed interface
@ -225,8 +220,8 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
if (value != null && this.endDate != null && value.after(this.endDate)) {
this.endDate = null
}
// this.dateChanged()
this.computeStats()
this.dateChanged()
// this.computeStats()
}
/**
@ -245,9 +240,9 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
}
this.computeNetDuration()
// this.dateChanged()
this.dateChanged()
this.defineDefaultTournamentBuyinIfNecessary()
this.computeStats()
// this.computeStats()
}
/**
@ -257,7 +252,7 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
set(value) {
field = value
this.computeNetDuration()
this.computeStats()
// this.computeStats()
}
/**
@ -285,7 +280,7 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
set(value) {
field = value
this.generateStakes()
this.computeStats()
// this.computeStats()
// this.updateRowRepresentation()
}
@ -313,7 +308,7 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
set(value) {
if (value > 0) {
field = value
this.computeStats()
// this.computeStats()
}
}
@ -340,7 +335,7 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
set(value) {
field = value
this.computeStats()
this.result?.computeNumberOfRebuy()
// this.result?.computeNumberOfRebuy()
}
// var blinds: String? = null
@ -351,8 +346,8 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
field = value
this.generateStakes()
this.defineHighestBet()
this.computeStats()
this.result?.computeNumberOfRebuy()
// this.computeStats()
// this.result?.computeNumberOfRebuy()
}
var cgBlinds: String? = null
@ -360,8 +355,8 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
field = cleanupBlinds(value)
this.generateStakes()
this.defineHighestBet()
this.computeStats()
this.result?.computeNumberOfRebuy()
// this.computeStats()
// this.result?.computeNumberOfRebuy()
}
var cgBiggestBet: Double? = null
@ -374,7 +369,7 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
var tournamentEntryFee: Double? = null
set(value) {
field = value
this.result?.computeNumberOfRebuy()
// this.result?.computeNumberOfRebuy()
}
// The total number of players who participated in the tournament
@ -396,13 +391,17 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
var handsCount: Int? = null
set(value) {
field = value
this.computeStats()
// this.computeStats()
}
fun bankrollHasBeenUpdated() {
this.generateStakes()
}
private fun dateChanged() {
SessionSetManager.dateChange = true
}
// /**
// * Manages impacts on SessionSets
// * Should be called when the start / end date are changed
@ -489,35 +488,35 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
return this.result?.net ?: 0.0
}
fun preCompute() {
this.computeStats()
this.sessionSet?.computeStats()
this.result?.computeNumberOfRebuy()
}
/**
* Pre-compute various statIds
*/
fun computeStats() {
val realm = Realm.getDefaultInstance()
val currentComputableResult = realm.computableResult(this)
// ComputableResult are created only when a session is over
if (this.startDate != null && this.endDate != null && currentComputableResult == null && this.inverseComputableResult?.get() == null) {
val computableResult = ComputableResult()
if (this.startDate != null && this.endDate != null && this.computableResults?.size == 0) {
val computableResult = realm.createObject(ComputableResult::class.java)
computableResult.session = this
this.inverseComputableResult = WeakReference(computableResult)
} // if a ComputableResult exists and the session is not completed, delete it
else if ((this.startDate == null || this.endDate == null) && currentComputableResult != null && currentComputableResult.isValid) {
currentComputableResult.deleteFromRealm()
else if ((this.startDate == null || this.endDate == null) && this.computableResult != null && this.computableResult.isValid) {
this.computableResult.deleteFromRealm()
}
realm.close()
this.computableResult()?.updateWith(this)
// Update the ComputableResult
// this.computableResult()?.forEachIndexed { index, computableResult ->
// computableResult.updateWith(this)
// if (index > 0) {
// throw PAIllegalStateException("Session cannot have more than one computable result")
// }
// }
this.computableResults?.forEachIndexed { index, computableResult ->
computableResult.updateWith(this)
if (index > 0) {
throw PAIllegalStateException("Session cannot have more than one computable result")
}
}
this.sessionSet?.computeStats()
}
/**
@ -707,42 +706,9 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
}
fun getFormattedStakes(): String {
return this.cgStakes?.let { StakesHolder.readableStakes(it) } ?: run { NULL_TEXT }
//
// val formattedBlinds = StakesHolder.formattedBlinds(this.cgBlinds, this.currency)
// val formattedAntes = StakesHolder.formattedAnte(this.cgAnte, this.currency)
//
// return StakesHolder.formattedStakes(formattedBlinds, formattedAntes)
//
//
// val components = arrayListOf<String>()
// this.formattedBlinds?.let { components.add(it) }
// this.formattedAnte?.let { components.add("($it)") }
//
// return if (components.isNotEmpty()) {
// components.joinToString(" ")
// } else {
// NULL_TEXT
// }
}
// fun formatBlinds() {
// blinds = null
// if (cgBigBlind == null) return
// cgBigBlind?.let { bb ->
// val sb = cgSmallBlind ?: bb / 2.0
// val preFormattedBlinds = "${sb.formatted}/${bb.round()}"
// println("<<<<<< bb.toCurrency(currency) : ${bb.toCurrency(currency)}")
// println("<<<<<< preFormattedBlinds : $preFormattedBlinds")
// val regex = Regex("-?\\d+(\\.\\d+)?")
// blinds = bb.toCurrency(currency).replace(regex, preFormattedBlinds)
// println("<<<<<< blinds = $blinds")
// }
// }
// LifeCycle
/**
@ -772,7 +738,7 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
}
// cleanup unnecessary related objects
this.result?.deleteFromRealm()
this.computableResult()?.deleteFromRealm()
this.computableResult?.deleteFromRealm()
}
@ -807,32 +773,12 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
when (row) {
SessionPropertiesRow.BANKROLL -> bankroll = value as Bankroll?
SessionPropertiesRow.STAKES -> if (value is Stakes) {
if (value.ante != null) {
this.cgAnte = value.ante
}
if (value.blinds != null) {
this.cgBlinds = value.blinds
}
// cgSmallBlind = try {
// (value[0] as String? ?: "0").toDouble()
// } catch (e: Exception) {
// null
// }
//
// cgBigBlind = try {
// (value[1] as String? ?: "0").toDouble()
// } catch (e: Exception) {
// null
// }
//
// cgBigBlind?.let {
// if (cgSmallBlind == null || cgSmallBlind == 0.0) {
// cgSmallBlind = it / 2.0
// }
// }
} else if (value == null) {
this.cgBlinds = null
this.cgAnte = null
@ -843,15 +789,21 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
SessionPropertiesRow.BUY_IN -> {
val localResult = getOrCreateResult()
localResult.buyin = value as Double?
// this.updateRowRepresentation()
}
SessionPropertiesRow.CASHED_OUT, SessionPropertiesRow.PRIZE -> {
val localResult = getOrCreateResult()
localResult.cashout = value as Double?
Timber.d("localResult cashout = ${localResult.cashout}")
if (value != null) {
this.end()
}
}
SessionPropertiesRow.NET_RESULT -> {
val localResult = getOrCreateResult()
localResult.netResult = value as Double?
if (value != null) {
this.end()
}
}
SessionPropertiesRow.COMMENT -> comment = value as String? ?: ""
SessionPropertiesRow.END_DATE -> if (value is Date?) {
@ -907,12 +859,10 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
SessionPropertiesRow.TOURNAMENT_NAME -> tournamentName = value as TournamentName?
SessionPropertiesRow.TOURNAMENT_TYPE -> tournamentType = (value as TournamentType?)?.ordinal
SessionPropertiesRow.TOURNAMENT_FEATURE -> {
this.tournamentFeatures.clear()
value?.let {
tournamentFeatures = RealmList()
tournamentFeatures.addAll((it as ArrayList<TournamentFeature>))
} ?: run {
tournamentFeatures.removeAll(this.tournamentFeatures)
tournamentFeatures.addAll((it as List<TournamentFeature>))
}
}
SessionPropertiesRow.HANDS_COUNT -> handsCount = (value as Double?)?.toInt()
@ -945,11 +895,11 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
private fun getOrCreateResult(): Result {
return this.result
?: run {
val result = realm.createObject(Result::class.java)
result.inverseSession = WeakReference(this)
this.result = result
result
}
val result = Result()
// result.inverseSession = WeakReference(this)
this.result = result
result
}
}
// Stat Entry
@ -1030,7 +980,7 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
var right: TextFormat? = null
if (!hasMainCurrencyCode) {
this.managedComputableResult?.ratedNet?.let { ratedNet ->
this.computableResult?.ratedNet?.let { ratedNet ->
right = Stat.NET_RESULT.textFormat(ratedNet)
}
}
@ -1060,7 +1010,7 @@ open class Session : RealmObject(), Savable, RowUpdatable, RowRepresentable, Tim
SessionPropertiesRow.BUY_IN -> this.result?.buyin?.toCurrency(currency) ?: NULL_TEXT
SessionPropertiesRow.CASHED_OUT, SessionPropertiesRow.PRIZE -> this.result?.cashout?.toCurrency(currency) ?: NULL_TEXT
SessionPropertiesRow.NET_RESULT -> this.result?.netResult?.toCurrency(currency) ?: NULL_TEXT
SessionPropertiesRow.COMMENT -> if (this.comment.isNotEmpty()) this.comment else NULL_TEXT
SessionPropertiesRow.COMMENT -> this.comment.ifEmpty { NULL_TEXT }
SessionPropertiesRow.END_DATE -> this.endDate?.shortDateTime() ?: NULL_TEXT
SessionPropertiesRow.GAME -> getFormattedGame()
SessionPropertiesRow.INITIAL_BUY_IN -> tournamentEntryFee?.toCurrency(currency) ?: NULL_TEXT

@ -61,7 +61,7 @@ open class SessionSet() : RealmObject(), Timed, Filterable {
override var netDuration: Long = 0L
fun computeStats() {
this.ratedNet = this.sessions?.sumOf { it.managedComputableResult?.ratedNet ?: 0.0 } ?: 0.0
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
this.breakDuration = this.sessions?.max("breakDuration")?.toLong() ?: 0L

@ -22,22 +22,30 @@ object SessionSetManager {
private val sessionsToProcess = mutableSetOf<Session>()
var dateChange = false
fun configure() {} // launch init
init {
val realm = Realm.getDefaultInstance()
this.sessions = realm.where(Session::class.java).findAllAsync()
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) }
}
val sessionIds = this.sessionsToProcess.map { it.id }
realm.executeTransactionAsync { asyncRealm ->
processSessions(asyncRealm, sessionIds)
if (this.dateChange) {
this.dateChange = false
changeSet.insertions.forEach { index ->
sessions[index]?.let { this.sessionsToProcess.add(it) }
}
changeSet.changes.forEach { index ->
sessions[index]?.let { this.sessionsToProcess.add(it) }
}
val sessionIds = this.sessionsToProcess.map { it.id }
realm.executeTransactionAsync { asyncRealm ->
processSessions(asyncRealm, sessionIds)
}
}
}
@ -51,6 +59,8 @@ object SessionSetManager {
private fun processSessions(realm: Realm, sessionIds: List<String>) {
Timber.d("PROCESS SESSIONS")
for (sessionId in sessionIds) {
realm.findById<Session>(sessionId)?.let { session ->
if (session.startDate != null && session.endDate != null) {

@ -141,10 +141,10 @@ class Top10Fragment : RealmFragment(), RowRepresentableDataSource, RowRepresenta
// Sort by rated net
val sortedCashGames = cashGames.sortedByDescending {
it.managedComputableResult?.ratedNet
it.computableResult?.ratedNet
}.toMutableList()
val sortedTournaments = tournaments.sortedByDescending {
it.managedComputableResult?.ratedNet
it.computableResult?.ratedNet
}.toMutableList()
// Keep 10 items

@ -36,8 +36,7 @@ open class RealmFragment : BaseFragment() {
realm = Realm.getDefaultInstance()
this.observedEntities.forEach {
val realmResults = realm.where(it).findAll()
val realmResults = realm.where(it).findAllAsync()
realmResults.addChangeListener { t, _ ->
this.entitiesChanged(it, t)
}

@ -13,7 +13,7 @@ import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType
open class BottomSheetListFragment : BottomSheetFragment(), LiveRowRepresentableDataSource, RowRepresentableDelegate {
open class BottomSheetDataListFragment : BottomSheetFragment(), LiveRowRepresentableDataSource, RowRepresentableDelegate {
private var _binding: BottomSheetListBinding? = null
private val binding get() = _binding!!
@ -62,18 +62,8 @@ open class BottomSheetListFragment : BottomSheetFragment(), LiveRowRepresentable
}
override fun onRowSelected(position: Int, row: RowRepresentable, tag: Int) {
this.onRowSelected(position)
dismiss()
// this.viewModel.realmData?.let {
// val selectedData = it[position]
// selectedData?.let {data ->
// this.viewModel.onRowValueChanged(data)
//// this.delegate.onRowValueChanged(data, this.row)
// dismiss()
// }
// }
// super.onRowSelected(position, row, tag)
}
/**

@ -2,22 +2,16 @@ package net.pokeranalytics.android.ui.fragment.components.bottomsheet
import android.app.Activity
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import io.realm.RealmModel
import net.pokeranalytics.android.databinding.BottomSheetDoubleEditTextBinding
import net.pokeranalytics.android.databinding.BottomSheetListBinding
import net.pokeranalytics.android.model.LiveData
import net.pokeranalytics.android.ui.modules.data.EditableDataActivity
import net.pokeranalytics.android.ui.activity.components.BaseActivity
import net.pokeranalytics.android.ui.modules.data.EditableDataActivity
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowViewType
/**
* Manage multiple items selection in a bottom sheet list
*/
open class BottomSheetMultiSelectionFragment : BottomSheetListFragment() {
open class BottomSheetDataMultiSelectionFragment : BottomSheetDataListFragment() {
override fun viewTypeForPosition(position: Int): Int {
return RowViewType.TITLE_CHECK.ordinal
@ -27,11 +21,14 @@ open class BottomSheetMultiSelectionFragment : BottomSheetListFragment() {
if (requestCode == REQUEST_CODE_ADD_NEW_OBJECT && resultCode == Activity.RESULT_OK && data != null) {
val dataType = data.getIntExtra(EditableDataActivity.IntentKey.DATA_TYPE.keyName, 0)
val primaryKey = data.getStringExtra(EditableDataActivity.IntentKey.PRIMARY_KEY.keyName)
val pokerAnalyticsActivity = activity as BaseActivity
val liveDataType = LiveData.values()[dataType]
val proxyItem: RealmModel? = liveDataType.getData(pokerAnalyticsActivity.getRealm(), primaryKey)
this.model.selectedRows.add(proxyItem as RowRepresentable)
this.refreshRow(proxyItem as RowRepresentable)
val realm = (activity as BaseActivity).getRealm()
liveDataType.getData(realm, primaryKey)?.let { proxyItem ->
val copy = realm.copyFromRealm(proxyItem)
this.model.selectedRows.add(copy as RowRepresentable)
this.refreshRow(copy as RowRepresentable)
}
// dataAdapter.refreshRow(proxyItem as RowRepresentable)
}
}

@ -82,11 +82,11 @@ open class BottomSheetFragment : BottomSheetDialogFragment() {
private fun newInstance(bottomSheetType: BottomSheetType): BottomSheetFragment {
return when (bottomSheetType) {
BottomSheetType.NONE -> BottomSheetFragment()
BottomSheetType.LIST -> BottomSheetListFragment()
BottomSheetType.LIST -> BottomSheetDataListFragment()
BottomSheetType.LIST_STATIC -> BottomSheetStaticListFragment()
BottomSheetType.LIST_GAME -> BottomSheetListGameFragment()
BottomSheetType.DOUBLE_LIST -> BottomSheetListGameFragment()
BottomSheetType.MULTI_SELECTION -> BottomSheetMultiSelectionFragment()
BottomSheetType.MULTI_SELECTION -> BottomSheetDataMultiSelectionFragment()
BottomSheetType.GRID -> BottomSheetTableSizeGridFragment()
BottomSheetType.EDIT_TEXT -> BottomSheetEditTextFragment()
BottomSheetType.EDIT_TEXT_MULTI_LINES -> BottomSheetEditTextMultiLinesFragment()
@ -102,6 +102,7 @@ open class BottomSheetFragment : BottomSheetDialogFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
//TODO: When dependency 'com.google.android.material:material:1.1.0' will be available in stable version, upgrade and remove that
activity?.setTheme(R.style.PokerAnalyticsTheme)
_binding = FragmentBottomSheetBinding.inflate(inflater, container, false)
inflateContentView(inflater, binding.root)
return binding.root
@ -277,9 +278,9 @@ open class BottomSheetFragment : BottomSheetDialogFragment() {
return this.model.rowRepresentableEditDescriptors
}
private fun getValue(): Any? {
return this.model.getValue()
}
// private fun getValue(): Any? {
// return this.model.getValue()
// }
private fun onClear() {
this.delegate?.onRowValueChanged(null, this.model.row)

@ -18,7 +18,7 @@ import net.pokeranalytics.android.ui.view.RowRepresentable
* Bottom Sheet List Game Fragment
* Display a list of game + chips to choose the game limit
*/
class BottomSheetListGameFragment : BottomSheetListFragment() {
class BottomSheetListGameFragment : BottomSheetDataListFragment() {
private var _binding: BottomSheetGameListBinding? = null
private val binding get() = _binding!!

@ -45,9 +45,7 @@ class BottomSheetStaticListFragment : BottomSheetFragment(), StaticRowRepresenta
override fun onRowSelected(position: Int, row: RowRepresentable, tag: Int) {
this.model.selectedRows.add(row)
this.onRowValueChanged()
// this.delegate.onRowValueChanged(row, this.row)
dismiss()
// super.onRowSelected(position, row, tag)
}
/**

@ -182,7 +182,7 @@ class FeedSessionRowRepresentableAdapter(
allSessions.clear()
allSessions.addAll(this.pendingSessions)
allSessions.addAll(this.startedSessions)
Timber.d("Update session list, total count = ${allSessions.size}")
// Timber.d("Update session list, total count = ${allSessions.size}")
val headersPositions = HashMap<Int, Date?>()

@ -11,7 +11,10 @@ import androidx.appcompat.content.res.AppCompatResources
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.DiffUtil
import kotlinx.coroutines.*
import io.realm.RealmModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import net.pokeranalytics.android.R
import net.pokeranalytics.android.calculus.bankroll.BankrollReportManager
import net.pokeranalytics.android.calculus.optimalduration.CashGameOptimalDurationCalculator
@ -40,8 +43,8 @@ import net.pokeranalytics.android.util.CrashLogging
import net.pokeranalytics.android.util.Preferences
import net.pokeranalytics.android.util.extensions.*
import timber.log.Timber
import java.lang.Runnable
import java.util.*
import kotlin.collections.ArrayList
class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepresentableDataSource, ResultCaptureTypeDelegate {
@ -190,7 +193,7 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr
val sessionRealm = realm.findById<Session>(sessionId)
sessionRealm?.let {
val copy = realm.copySessionFromRealm(it)
val copy = realm.copyFromRealm(it)
if (this.model.duplicate) { // duplicate session
// realm.executeTransaction {
@ -307,13 +310,10 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr
Toast.makeText(context, e.message, Toast.LENGTH_LONG).show()
return
}
getRealm().executeTransactionAsync { realm ->
realm.copyToRealmOrUpdate(this.currentSession)
this.currentSession.inverseComputableResult?.get()?.let { computableResult ->
realm.copyToRealmOrUpdate(computableResult)
}
getRealm().executeTransactionAsync { realm ->
val session = realm.copyToRealmOrUpdate(this.currentSession)
session.preCompute()
}
}
@ -536,9 +536,7 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr
val sessionId = this.currentSession.id
getRealm().executeTransactionAsync { asyncRealm ->
asyncRealm.findById<Session>(sessionId)?.let { session ->
session.delete()
}
asyncRealm.findById<Session>(sessionId)?.delete()
}
// this.currentSession.delete()
@ -548,15 +546,18 @@ class SessionFragment : RealmFragment(), RowRepresentableDelegate, StaticRowRepr
activity?.finish()
}
/**
* Called when the user pressed back on the parent activity
*/
override fun onBackPressed() {
super.onBackPressed()
if (!sessionHasBeenUserCustomized) {
currentSession.delete()
}
}
// /**
// * Called when the user pressed back on the parent activity
// */
// override fun onBackPressed() {
// super.onBackPressed()
// if (!sessionHasBeenUserCustomized) {
// val sessionId = currentSession.id
// getRealm().executeTransactionAsync { asyncRealm ->
// asyncRealm.findById<Session>(sessionId)?.delete()
// }
// }
// }
//// Static Data Source

@ -8,11 +8,13 @@ import io.realm.RealmResults
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import net.pokeranalytics.android.exceptions.RowRepresentableEditDescriptorException
import net.pokeranalytics.android.model.Stakes
import net.pokeranalytics.android.model.interfaces.Identifiable
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate
import net.pokeranalytics.android.ui.fragment.components.bottomsheet.BottomSheetType
import net.pokeranalytics.android.ui.view.RowRepresentable
import net.pokeranalytics.android.ui.view.RowRepresentableEditDescriptor
import net.pokeranalytics.android.ui.view.rows.SessionPropertiesRow
import net.pokeranalytics.android.util.extensions.findById
import java.util.*
class BottomSheetViewModelFactory(var row: RowRepresentable, var delegate: RowRepresentableDelegate): ViewModelProvider.Factory {
@ -85,7 +87,7 @@ class BottomSheetViewModel(var row: RowRepresentable) : ViewModel() {
var alternativeLabels: Boolean = false
/**
* Multiselection
* Multi-selection
*/
val selectedRows: ArrayList<RowRepresentable> = ArrayList()
@ -225,12 +227,31 @@ class BottomSheetViewModel(var row: RowRepresentable) : ViewModel() {
fun isSelected(row: RowRepresentable): Boolean {
return this.selectedRows.contains(row)
// return when(row.bottomSheetType) {
// BottomSheetType.MULTI_SELECTION -> {
// val identifiables = this.selectedRows as List<Identifiable>
// val ids = identifiables.map { it.id }
// val id = (row as Identifiable).id
// ids.contains(id)
// }
// else -> this.selectedRows.contains(row)
// }
}
fun changedValue(): Any? {
return when(row.bottomSheetType) {
BottomSheetType.DOUBLE_EDIT_TEXT -> arrayListOf(this.stringValue, this.secondStringValue)
BottomSheetType.DOUBLE_LIST, BottomSheetType.LIST_GAME -> arrayListOf(this.someValues[0], this.someValues[1])
BottomSheetType.MULTI_SELECTION -> {
this.realmData?.realm?.let { realm ->
val identifiables = this.selectedRows as List<Identifiable>
identifiables.firstOrNull()?.realmObjectClass?.let { clazz ->
val ids = identifiables.map { it.id }
val objects = ids.mapNotNull { realm.findById(clazz, it) }
objects.map { realm.copyFromRealm(it) }
} ?: kotlin.run { this.selectedRows }
} ?: kotlin.run { this.selectedRows }
}
else -> getValue()
}
}

@ -276,6 +276,8 @@ abstract class PACSVDescriptor<T : Identifiable>(source: DataSource,
this.addAdditionallyCreatedIdentifiable(transaction)
}
managedSession.preCompute()
return managedSession
} else {
Timber.d("Session already exists(count=$count): sd=$startDate, ed=$endDate, net=$net")

@ -9,7 +9,6 @@ import net.pokeranalytics.android.model.interfaces.Identifiable
import net.pokeranalytics.android.model.interfaces.NameManageable
import net.pokeranalytics.android.model.interfaces.UsageCountable
import net.pokeranalytics.android.model.realm.*
import java.lang.ref.WeakReference
fun <T : RealmModel>Realm.count(clazz: Class<T>) : Long {
return this.where(clazz).count()
@ -159,12 +158,12 @@ fun Realm.computableResult(session: Session): ComputableResult? {
return crs.firstOrNull()
}
fun Realm.copySessionFromRealm(session: Session): Session {
val copy = this.copyFromRealm(session)
copy.result?.inverseSession = WeakReference(copy)
this.computableResult(session)?.let {
val computableResult = this.copyFromRealm(it)
copy.inverseComputableResult = WeakReference(computableResult)
}
return copy
}
//fun Realm.copySessionFromRealm(session: Session): Session {
// val copy = this.copyFromRealm(session)
// copy.result?.inverseSession = WeakReference(copy)
//// this.computableResult(session)?.let {
//// val computableResult = this.copyFromRealm(it)
//// copy.inverseComputableResult = WeakReference(computableResult)
//// }
// return copy
//}
Loading…
Cancel
Save