From cb4206ea3a9e2dcd2264fb93bf5da355a91ce80b Mon Sep 17 00:00:00 2001 From: Laurent Date: Thu, 11 Jun 2020 11:47:24 +0200 Subject: [PATCH] Change replayer drawing algo to draw only what is necessary --- .../android/model/handhistory/Street.kt | 9 +- .../handhistory/HandHistoryFragment.kt | 3 +- .../modules/handhistory/model/ActionList.kt | 18 +++ .../handhistory/model/ComputedAction.kt | 6 +- .../handhistory/model/HandHistoryViewModel.kt | 4 - .../modules/handhistory/replayer/HandStep.kt | 2 +- .../replayer/ReplayerConfiguration.kt | 62 +++++---- .../handhistory/replayer/ReplayerView.kt | 32 +---- .../handhistory/replayer/TableDrawer.kt | 131 +++++++++++++----- 9 files changed, 170 insertions(+), 97 deletions(-) diff --git a/app/src/main/java/net/pokeranalytics/android/model/handhistory/Street.kt b/app/src/main/java/net/pokeranalytics/android/model/handhistory/Street.kt index 8bec29db..90df7fff 100644 --- a/app/src/main/java/net/pokeranalytics/android/model/handhistory/Street.kt +++ b/app/src/main/java/net/pokeranalytics/android/model/handhistory/Street.kt @@ -5,7 +5,6 @@ import android.graphics.Canvas import net.pokeranalytics.android.R import net.pokeranalytics.android.ui.modules.handhistory.replayer.HandStep import net.pokeranalytics.android.ui.modules.handhistory.replayer.ReplayerConfiguration -import net.pokeranalytics.android.ui.modules.handhistory.replayer.TableDrawer enum class Street : HandStep { PREFLOP, @@ -40,9 +39,9 @@ enum class Street : HandStep { return values()[this.ordinal + 1] } - override fun draw(configuration: ReplayerConfiguration, canvas: Canvas, context: Context) { - TableDrawer.drawStreet(this, configuration, canvas, context) - } +// override fun draw(configuration: ReplayerConfiguration, canvas: Canvas, context: Context) { +// TableDrawer.drawStreet(this, configuration, canvas, context) +// } override fun frames( configuration: ReplayerConfiguration, @@ -50,7 +49,7 @@ enum class Street : HandStep { context: Context, update: () -> Unit ) { - TableDrawer.drawStreet(this, configuration, canvas, context) +// TableDrawer.drawStreet(this, configuration, canvas, context) } } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryFragment.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryFragment.kt index 8fcd2d30..d8a9888b 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryFragment.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/HandHistoryFragment.kt @@ -728,7 +728,8 @@ class HandHistoryFragment : RealmFragment(), RowRepresentableDelegate, KeyboardL val tc = TableDrawer(bitmap) // draw initial table - TableDrawer.initializeTable(config, tc, requireContext()) +// TableDrawer.initializeTable(config, tc, requireContext()) + // TODO val muxer = MMediaMuxer() muxer.Init(requireActivity(), bitmap.width, bitmap.height, "hhVideo", "YES!") diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/ActionList.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/ActionList.kt index 3f07d99a..051bb819 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/ActionList.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/ActionList.kt @@ -711,6 +711,9 @@ class ActionList(var listener: ActionListListener? = null) : ArrayList 0) { @@ -720,5 +723,20 @@ class ActionList(var listener: ActionListListener? = null) : ArrayList (Unit)) - fun draw(configuration: ReplayerConfiguration, canvas: Canvas, context: Context) +// fun draw(configuration: ReplayerConfiguration, canvas: Canvas, context: Context) companion object { diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerConfiguration.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerConfiguration.kt index 75d6ba54..25203126 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerConfiguration.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerConfiguration.kt @@ -18,29 +18,20 @@ class ReplayerConfiguration(var handHistory: HandHistory) { private var lastBlindIndex: Int = 0 - private var currentStep: Int = 0 + private var stepIndex: Int = 0 init { this.actionList.load(this.handHistory) this.lastBlindIndex = max(this.actionList.indexOfLast { it.action.type?.isBlind == true }, 0) - this.currentStep = this.lastBlindIndex + 1 // initialize at big blind + this.stepIndex = this.lastBlindIndex + 1 // initialize at big blind this.steps = HandStep.createSteps(this.handHistory) } data class Size(var width: Float, var height: Float) - data class Circle(var x: Float, var y: Float, var radius: Float) { - fun toRect(): RectF { - return RectF(x - radius, y - radius, x + radius, y + radius) - } - } - data class TextPoint(var x: Float, var y: Float, var fontSize: Float) { - fun toRect(): RectF { - val wRatio = 1.5f - return RectF(x - wRatio * fontSize, y - fontSize, x + wRatio * fontSize, y + fontSize * 0.1f) - } - } + data class Circle(var x: Float, var y: Float, var radius: Float) + data class TextPoint(var x: Float, var y: Float, var fontSize: Float) private val maxCards = 5 @@ -309,41 +300,64 @@ class ReplayerConfiguration(var handHistory: HandHistory) { } fun next() { - if (this.steps.size > this.currentStep + 1) { - this.currentStep += 1 + if (this.steps.size > this.stepIndex + 1) { + this.stepIndex += 1 } } fun previous() { - if (this.currentStep > this.lastBlindIndex + 1) { - this.currentStep -= 1 + if (this.stepIndex > this.lastBlindIndex + 1) { + this.stepIndex -= 1 } } - val stepsToDraw: List + val currentStep: HandStep get() { - return this.steps.take(this.currentStep + 1) + return this.steps[this.stepIndex] } - val activePositions: List +// val stepsToDraw: List +// get() { +// return this.steps.take(this.stepIndex + 1) +// } + + private val lastActionAtStep: ComputedAction? get() { - val action = when (val step = this.steps[currentStep]) { + return when (val step = this.steps[stepIndex]) { is ComputedAction -> { step } is Street -> { - if (currentStep > 0) { - this.steps[currentStep - 1] as ComputedAction? + if (stepIndex > 0) { + this.steps[stepIndex - 1] as ComputedAction? } else { null } } else -> throw PAIllegalStateException("unmanaged step: $step") } - val index = action?.action?.index ?: 0 + } + + val activePositions: List + get() { + val index = this.lastActionAtStep?.action?.index ?: 0 return this.actionList.activePositionIndexes(index) } + fun playerRemainingStack(i: Int): Double? { + this.lastActionAtStep?.action?.index?.let { index -> + return this.actionList.playerRemainingStack(i, index) + } + return null + } + + fun lastSignificantActionOfPlayer(i: Int): ComputedAction? { + this.lastActionAtStep?.action?.index?.let { index -> + return this.actionList.lastChipCommittingActionOfPlayer(i, index) + } + return null + } + } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerView.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerView.kt index 94a19f0d..8c7ce512 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerView.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerView.kt @@ -4,10 +4,11 @@ import android.content.Context import android.graphics.Canvas import android.util.AttributeSet import android.view.View +import net.pokeranalytics.android.exceptions.PAIllegalStateException +import net.pokeranalytics.android.model.handhistory.Street +import net.pokeranalytics.android.ui.modules.handhistory.model.ComputedAction import timber.log.Timber -private data class ReplayerAction(val step: HandStep, val draw: Boolean) - class ReplayerView(context: Context, attrs: AttributeSet) : View(context, attrs) { lateinit var configuration: ReplayerConfiguration @@ -24,21 +25,6 @@ class ReplayerView(context: Context, attrs: AttributeSet) : View(context, attrs) this.invalidate() } -// fun previous(handStep: HandStep) { -// val action = ReplayerAction(handStep, false) -// this.addAction(action) -// } -// -// fun next(handStep: HandStep) { -// val action = ReplayerAction(handStep, true) -// this.addAction(action) -// } -// -// private fun addAction(action: ReplayerAction) { -// this.actionsToDraw.add(action) -// this.invalidate() -// } - override fun onDraw(canvas: Canvas?) { super.onDraw(canvas) @@ -46,17 +32,7 @@ class ReplayerView(context: Context, attrs: AttributeSet) : View(context, attrs) canvas?.let { - TableDrawer.initializeTable(configuration, canvas, context) - - // show cards - configuration.activePositions.forEach { - TableDrawer.drawCards(it, configuration, canvas, context) - } - - // action - this.configuration.stepsToDraw.forEach { step -> - step.draw(this.configuration, canvas, context) - } + TableDrawer.drawTable(configuration, canvas, context) } diff --git a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TableDrawer.kt b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TableDrawer.kt index 427edf92..bb276f5f 100644 --- a/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TableDrawer.kt +++ b/app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TableDrawer.kt @@ -5,6 +5,7 @@ import android.graphics.* import androidx.core.content.res.ResourcesCompat import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory import net.pokeranalytics.android.R +import net.pokeranalytics.android.exceptions.PAIllegalStateException import net.pokeranalytics.android.model.handhistory.Position import net.pokeranalytics.android.model.handhistory.Street import net.pokeranalytics.android.model.realm.handhistory.Action @@ -66,10 +67,78 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) { cardTextPaint.isAntiAlias = true } + fun drawTable(config: ReplayerConfiguration, canvas: Canvas, context: Context) { + + // base + initializeTable(config, canvas, context) + + val step = config.currentStep + val street: Street + var computedAction: ComputedAction? = null + when (step) { + is Street -> { + street = step + config.lastActionBeforeStreet(street)?.let { + drawPot(it, config, canvas, context) + } + } + is ComputedAction -> { + street = step.street + computedAction = step + drawPot(step, config, canvas, context) + } + else -> throw PAIllegalStateException("Step unmanaged: $step") + } + drawBoardCards(street, config, canvas, context) + + val hh = config.handHistory + for (i in 0 until hh.numberOfPlayers) { + Timber.d("Getting player $i setup ") + + // draw player rectangles with action or name + stack + val actionType = computedAction?.action?.type + if (computedAction?.positionIndex == i && actionType != null) { + drawPlayerRectangle(i, true, config, canvas, context) + drawAction(i, actionType, config, canvas, context) + } else { + val remainingStack = config.playerRemainingStack(i) + drawPlayerRectangle(i, false, config, canvas, context) + drawPositionAndStack(i, remainingStack, config, canvas, context) + } + + // draw chips + // when does a chip appears ? + // when the player has put some money during the current street + config.lastSignificantActionOfPlayer(i)?.let { action -> + + when { + action.action.type?.isSignificant == true -> { + action.action.amount?.let { amount -> + drawChip(amount, action.positionIndex, config, canvas, context) + } + } + action.action.type?.isCall == true -> { + action.getStreetLastSignificantAction()?.action?.amount?.let { amount -> + drawChip(amount, action.positionIndex, config, canvas, context) + } + } + else -> {} + } + } + + } + + // show player cards + config.activePositions.forEach { + drawCards(it, config, canvas, context) + } + + } + /*** * WARNING: Avoid instancing objects here, as it's called from onDraw method */ - fun initializeTable(config: ReplayerConfiguration, canvas: Canvas, context: Context) { + private fun initializeTable(config: ReplayerConfiguration, canvas: Canvas, context: Context) { canvas.drawColor(context.getColor(backgroundColor)) @@ -83,7 +152,7 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) { // drawCards(i, config, canvas, context) drawPlayerRectangle(i,false, config, canvas, context) - drawPositionAndStack(i, playerSetup?.stack, config, canvas, context) +// drawPositionAndStack(i, playerSetup?.stack, config, canvas, context) drawPlayerCircle(i, config, canvas, context) @@ -121,8 +190,8 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) { private fun drawChip(amount: Double, chipText: ReplayerConfiguration.TextPoint, chipCircle: ReplayerConfiguration.Circle, canvas: Canvas, context: Context) { - clearText(chipText, canvas) - clearCircle(chipCircle, canvas) +// clearText(chipText, canvas) +// clearCircle(chipCircle, canvas) this.fillPaint.color = context.getColor(R.color.green) canvas.drawCircle(chipCircle.x, chipCircle.y, chipCircle.radius, this.fillPaint) @@ -139,19 +208,19 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) { } - private fun clearText(textPoint: ReplayerConfiguration.TextPoint, canvas: Canvas) { - this.clearRect(textPoint.toRect(), canvas) - } - - private fun clearCircle(circle: ReplayerConfiguration.Circle, canvas: Canvas) { - this.clearRect(circle.toRect(), canvas) - } - - private fun clearRect(rect: RectF, canvas: Canvas) { - canvas.drawRect(rect, this.backgroundPaint) - } +// private fun clearText(textPoint: ReplayerConfiguration.TextPoint, canvas: Canvas) { +// this.clearRect(textPoint.toRect(), canvas) +// } +// +// private fun clearCircle(circle: ReplayerConfiguration.Circle, canvas: Canvas) { +// this.clearRect(circle.toRect(), canvas) +// } +// +// private fun clearRect(rect: RectF, canvas: Canvas) { +// canvas.drawRect(rect, this.backgroundPaint) +// } - fun drawCards(playerIndex: Int, config: ReplayerConfiguration, canvas: Canvas, context: Context) { + private fun drawCards(playerIndex: Int, config: ReplayerConfiguration, canvas: Canvas, context: Context) { val playerSetup = config.handHistory.playerSetupForPosition(playerIndex) val cardRects = config.cardRects(playerIndex) @@ -195,12 +264,12 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) { } - fun drawPlayerPositionAndStack(action: ComputedAction, config: ReplayerConfiguration, canvas: Canvas, context: Context) { + private fun drawPlayerPositionAndStack(action: ComputedAction, config: ReplayerConfiguration, canvas: Canvas, context: Context) { drawPlayerRectangle(action.positionIndex,false, config, canvas, context) drawPositionAndStack(action.positionIndex, action.stackAfterActing, config, canvas, context) } - fun drawAction(action: ComputedAction, highlighted: Boolean = true, config: ReplayerConfiguration, canvas: Canvas, context: Context) { + private fun drawAction(action: ComputedAction, highlighted: Boolean = true, config: ReplayerConfiguration, canvas: Canvas, context: Context) { // show that action is on the player by highlighting drawPlayerRectangle(action.positionIndex, highlighted, config, canvas, context) @@ -265,7 +334,7 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) { /*** * [i] is the player position in the hand */ - private fun drawPlayerRectangle(i: Int, highlighted: Boolean, config: ReplayerConfiguration, canvas: Canvas, context: Context) { + private fun drawPlayerRectangle(i: Int, highlighted: Boolean, config: ReplayerConfiguration, canvas: Canvas, context: Context) { val rect = config.stackRectForPlayer(i) val rectRadius = (rect.bottom - rect.top) / 4 @@ -306,7 +375,7 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) { canvas.drawText(actionName, pnPoint.x, pnPoint.y, this.textPaint) } - fun drawStreet(street: Street, config: ReplayerConfiguration, canvas: Canvas, context: Context) { + private fun drawBoardCards(street: Street, config: ReplayerConfiguration, canvas: Canvas, context: Context) { val cards = config.handHistory.cardsForStreet(street) config.boardCardRects.take(street.totalBoardCards).forEachIndexed { index, rectF -> @@ -314,18 +383,18 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) { } // Clear all chips - val hh = config.handHistory - for (i in 0 until hh.numberOfPlayers) { - val pc = config.chipCircle(i) - clearCircle(pc, canvas) - val pct = config.chipText(i) - clearText(pct, canvas) - } +// val hh = config.handHistory +// for (i in 0 until hh.numberOfPlayers) { +// val pc = config.chipCircle(i) +// clearCircle(pc, canvas) +// val pct = config.chipText(i) +// clearText(pct, canvas) +// } // Clear last action before street - config.lastActionBeforeStreet(street)?.let { action -> - drawPlayerPositionAndStack(action, config, canvas, context) - } +// config.lastActionBeforeStreet(street)?.let { action -> +// drawPlayerPositionAndStack(action, config, canvas, context) +// } } @@ -339,7 +408,7 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) { this.textPaint.textSize = tpTextPoint.fontSize this.textPaint.color = context.getColor(R.color.white) - clearText(config.totalPotTextPoint, canvas) +// clearText(config.totalPotTextPoint, canvas) canvas.drawText(totalPot.formatted, config.totalPotTextPoint.x, config.totalPotTextPoint.y, this.textPaint) }