From 75dcd54859dedaec52b2f9a48a1d0bd8006182a3 Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 8 Mar 2019 16:36:59 +0100 Subject: [PATCH 1/3] refresh UI when break is changed --- .../net/pokeranalytics/android/ui/fragment/SessionFragment.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt index fade82f1..906cb013 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/fragment/SessionFragment.kt @@ -113,6 +113,7 @@ class SessionFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, Bott when (row) { SessionRow.CASHED_OUT, SessionRow.PRIZE, SessionRow.NET_RESULT, SessionRow.BUY_IN, SessionRow.TIPS, SessionRow.START_DATE, SessionRow.END_DATE, SessionRow.BANKROLL -> updateSessionUI() + SessionRow.BREAK_TIME -> this.sessionAdapter.notifyDataSetChanged() } } @@ -183,8 +184,6 @@ class SessionFragment : PokerAnalyticsFragment(), RowRepresentableDelegate, Bott floatingActionButton.animate().scaleX(0f).scaleY(0f).alpha(0f) .setInterpolator(FastOutSlowInInterpolator()).start() } - else -> { - } } updateMenuUI() From 17b234a428c6aa9440ca1668a8df491ecc532ace Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 8 Mar 2019 17:14:29 +0100 Subject: [PATCH 2/3] Manages pauses and break durations --- .../android/model/interfaces/Timed.kt | 3 +++ .../android/model/realm/Session.kt | 21 ++++++---------- .../android/model/realm/SessionSet.kt | 8 ++++++ .../android/model/utils/SessionSetManager.kt | 25 +++++++++++++++++-- 4 files changed, 42 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/interfaces/Timed.kt b/app/src/main/java/net/pokeranalytics/android/model/interfaces/Timed.kt index 49256174..7803b4f1 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/interfaces/Timed.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/interfaces/Timed.kt @@ -10,8 +10,11 @@ interface Timed { var breakDuration: Long + var pauseDate: Date? + var netDuration: Long + /** * Computes the net netDuration of the session */ 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 92b3b8ba..c872c102 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 @@ -106,7 +106,7 @@ open class Session : RealmObject(), SessionInterface, Savable, StaticRowRepresen /** * The start date of the break */ - var pauseDate: Date? = null + override var pauseDate: Date? = null // The time frame of the Session, i.e. the start & end date // var timeFrame: TimeFrame? = null @@ -288,14 +288,14 @@ open class Session : RealmObject(), SessionInterface, Savable, StaticRowRepresen if (this.tournamentEntryFee != null) { this.result?.buyin = this.tournamentEntryFee } - -// val sessionTimeFrame = this.timeFrame ?: realm.createObject(TimeFrame::class.java) -// sessionTimeFrame.setStart(Date()) -// sessionTimeFrame.setDate(Date(), null) -// this.timeFrame = sessionTimeFrame } SessionState.PAUSED -> { -// this.timeFrame?.paused = false + val pauseDate = this.pauseDate + if (pauseDate != null) { + this.breakDuration += Date().time - pauseDate.time + } else { + throw IllegalStateException("When resuming, the pause date must be set") + } this.pauseDate = null } else -> { @@ -312,10 +312,9 @@ open class Session : RealmObject(), SessionInterface, Savable, StaticRowRepresen realm.executeTransaction { when (getState()) { SessionState.STARTED -> { -// this.?.paused = true this.pauseDate = Date() } - else -> throw IllegalStateException("unmanaged state") + else -> throw IllegalStateException("Pausing a session in an unmanaged state") } } } @@ -328,10 +327,6 @@ open class Session : RealmObject(), SessionInterface, Savable, StaticRowRepresen when (getState()) { SessionState.STARTED, SessionState.PAUSED -> { this.end() -// this.timeFrame?.paused = false -// this.pauseDate = null -// this.endDate = Date() -// this.timeFrame?.setDate(null, Date()) } else -> throw Exception("Stopping session in unmanaged state") } 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 2ef8ca93..b2bed1e7 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 @@ -37,6 +37,14 @@ open class SessionSet : RealmObject(), Timed { this.computeNetDuration() } + /** + * The start date of the break + */ + override var pauseDate: Date? = null + + /** + * the net duration of the set + */ override var netDuration: Long = 0L companion object { 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 c3faaaf1..f68ccccf 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 @@ -4,11 +4,19 @@ import io.realm.RealmQuery import io.realm.RealmResults import net.pokeranalytics.android.model.realm.Session import net.pokeranalytics.android.model.realm.SessionSet +import kotlin.math.max +/** + * 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) { @@ -42,7 +50,7 @@ class SessionSetManager { } /** - * Update Time frames from sets + * Update the global timeline using the impacted [sessionSets] and the updated [session] */ private fun updateTimeFrames(sessionSets: RealmResults, session: Session) { @@ -53,6 +61,9 @@ class SessionSetManager { } + /** + * Creates or update the session set for the [session] + */ private fun createOrUpdateSessionSet(session: Session) { val set = session.sessionSet @@ -65,10 +76,14 @@ class SessionSetManager { } + /** + * 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 } @@ -109,11 +124,17 @@ class SessionSetManager { session.sessionSet = set // Add all orphan endedSessions - sessions.forEach { it.sessionSet = set } + sessions.forEach { session -> + session.sessionSet = set + set.breakDuration = max(set.breakDuration, session.breakDuration) + } // Timber.d("netDuration 3 = : ${set.timeFrame?.netDuration}") } + /** + * Removes the [session] from the timeline + */ fun removeFromTimeline(session: Session) { if (!session.realm.isInTransaction) { From f3351e2e36e26181d47730653fd20aa487cc78ed Mon Sep 17 00:00:00 2001 From: Laurent Date: Fri, 8 Mar 2019 17:41:35 +0100 Subject: [PATCH 3/3] Managing hands estimation per hour + tests --- .../android/StatsInstrumentedUnitTest.kt | 12 ++++--- .../android/model/interfaces/Timed.kt | 3 +- .../android/model/realm/Session.kt | 34 ++++++++++++++++++- .../android/model/realm/SessionSet.kt | 3 +- 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/app/src/androidTest/java/net/pokeranalytics/android/StatsInstrumentedUnitTest.kt b/app/src/androidTest/java/net/pokeranalytics/android/StatsInstrumentedUnitTest.kt index 1a5c7e84..fdd5a18f 100644 --- a/app/src/androidTest/java/net/pokeranalytics/android/StatsInstrumentedUnitTest.kt +++ b/app/src/androidTest/java/net/pokeranalytics/android/StatsInstrumentedUnitTest.kt @@ -51,6 +51,8 @@ class StatsInstrumentedUnitTest : RealmInstrumentedUnitTest() { s1.cgBigBlind = 0.5 // bb net result = -200bb s2.cgBigBlind = 2.0 // bb net result = 150bb + s2.tableSize = 5 + realm.insert(s1) realm.insert(s2) realm.commitTransaction() @@ -58,9 +60,9 @@ class StatsInstrumentedUnitTest : RealmInstrumentedUnitTest() { val sdf = SimpleDateFormat("dd/M/yyyy hh:mm") val sd1 = sdf.parse("01/1/2019 10:00") - val ed1 = sdf.parse("01/1/2019 11:00") + val ed1 = sdf.parse("01/1/2019 11:00") // 1 hour val sd2 = sdf.parse("02/1/2019 08:00") - val ed2 = sdf.parse("02/1/2019 11:00") + val ed2 = sdf.parse("02/1/2019 11:00") // 3 hours realm.beginTransaction() @@ -112,7 +114,7 @@ class StatsInstrumentedUnitTest : RealmInstrumentedUnitTest() { } val handsPlayed = results.computedStat(Stat.HANDS_PLAYED) if (handsPlayed != null) { - assertEquals(100.0, handsPlayed.value, delta) + assertEquals(177.77, handsPlayed.value, delta) } else { Assert.fail("No hands played stat") } @@ -161,7 +163,7 @@ class StatsInstrumentedUnitTest : RealmInstrumentedUnitTest() { } val netbbPer100Hands = results.computedStat(Stat.NET_BB_PER_100_HANDS) if (netbbPer100Hands != null) { - assertEquals(-50.0, netbbPer100Hands.value, delta) + assertEquals(-28.12, netbbPer100Hands.value, delta) } else { Assert.fail("No netbbPer100Hands stat") } @@ -182,7 +184,7 @@ class StatsInstrumentedUnitTest : RealmInstrumentedUnitTest() { val std100 = results.computedStat(Stat.STANDARD_DEVIATION_BB_PER_100_HANDS) if (std100 != null) { - assertEquals(559.01, std100.value, delta) + assertEquals(497.54, std100.value, delta) } else { Assert.fail("No std100 stat") } diff --git a/app/src/main/java/net/pokeranalytics/android/model/interfaces/Timed.kt b/app/src/main/java/net/pokeranalytics/android/model/interfaces/Timed.kt index 7803b4f1..08316cda 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/interfaces/Timed.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/interfaces/Timed.kt @@ -26,8 +26,7 @@ interface Timed { } } - var hourlyDuration: Double + val hourlyDuration: Double get() = this.netDuration / 3600000.0 - set(value) = TODO() } \ No newline at end of file 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 c872c102..6dafe561 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 @@ -221,8 +221,40 @@ open class Session : RealmObject(), SessionInterface, Savable, StaticRowRepresen return this.result?.net ?: 0.0 } +/* + public var numberOfHandsPerHour: Double { + + var playersHandsPerHour: Int = Session.livePlayersHandsPerHour // default is live + if let bankroll = self.bankroll { + playersHandsPerHour = bankroll.isLive() ? Session.livePlayersHandsPerHour : Session.onlinePlayersHandsPerHour + } + var numberOfPlayers: Int = 9 // default is 9 players + if let playersAtTable = self.tableSize?.intValue { + numberOfPlayers = playersAtTable + } + + return Double(playersHandsPerHour) / Double(numberOfPlayers) + } +*/ + + @Ignore + val ONLINE_PLAYER_HANDS_PER_HOUR = 400.0 + @Ignore + val LIVE_PLAYER_HANDS_PER_HOUR = 250.0 + + /** + * Approximates the number of hands played per hour at the table + */ + val numberOfHandsPerHour: Double + get() { + val tableSize = this.tableSize ?: 9 + val isLive = this.bankroll?.live ?: true + val playerHandsPerHour = if (isLive) LIVE_PLAYER_HANDS_PER_HOUR else ONLINE_PLAYER_HANDS_PER_HOUR + return playerHandsPerHour / tableSize.toDouble() + } + @Ignore - override var estimatedHands: Double = 25.0 * this.hourlyDuration + override var estimatedHands: Double = this.numberOfHandsPerHour * this.hourlyDuration @Ignore override var bbNetResult: Double = 0.0 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 b2bed1e7..8b211cdc 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 @@ -51,7 +51,6 @@ open class SessionSet : RealmObject(), Timed { fun newInstance(realm: Realm) : SessionSet { val sessionSet: SessionSet = realm.createObject(SessionSet::class.java) -// sessionSet.timeFrame = realm.createObject(TimeFrame::class.java) return realm.copyToRealm(sessionSet) } @@ -75,7 +74,7 @@ open class SessionSet : RealmObject(), Timed { val hourlyRate: Double = this.ratedNet / this.hourlyDuration @Ignore - val estimatedHands: Double = 25.0 * this.hourlyDuration + val estimatedHands: Double = this.sessions?.sumByDouble { it.estimatedHands } ?: 0.0 @Ignore var bbNetResult: Double = this.sessions?.sumByDouble { it.bbNetResult } ?: 0.0