|
|
|
@ -11,7 +11,6 @@ import net.pokeranalytics.android.ui.modules.handhistory.model.ActionList |
|
|
|
import net.pokeranalytics.android.ui.modules.handhistory.model.ComputedAction |
|
|
|
import net.pokeranalytics.android.ui.modules.handhistory.model.ComputedAction |
|
|
|
import net.pokeranalytics.android.util.MathUtils |
|
|
|
import net.pokeranalytics.android.util.MathUtils |
|
|
|
import timber.log.Timber |
|
|
|
import timber.log.Timber |
|
|
|
import kotlin.math.max |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) { |
|
|
|
class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) { |
|
|
|
|
|
|
|
|
|
|
|
@ -44,7 +43,8 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) { |
|
|
|
is ComputedAction -> this.frameManager.add(FrameType.STATE, 1) |
|
|
|
is ComputedAction -> this.frameManager.add(FrameType.STATE, 1) |
|
|
|
is Street -> { |
|
|
|
is Street -> { |
|
|
|
// gather animation if chips have been committed in the street |
|
|
|
// gather animation if chips have been committed in the street |
|
|
|
if (this.actionList.streetHasSignificantAction(step)) { |
|
|
|
val previousStreet = step.previous |
|
|
|
|
|
|
|
if (previousStreet != null && this.actionList.streetHasSignificantAction(previousStreet)) { |
|
|
|
this.frameManager.add(FrameType.GATHER_ANIMATION, framesForChipsAnimation) |
|
|
|
this.frameManager.add(FrameType.GATHER_ANIMATION, framesForChipsAnimation) |
|
|
|
} |
|
|
|
} |
|
|
|
// Chip distribution animation on the Summary |
|
|
|
// Chip distribution animation on the Summary |
|
|
|
@ -64,57 +64,23 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) { |
|
|
|
private val numberOfFramesForCurrentStep: Int |
|
|
|
private val numberOfFramesForCurrentStep: Int |
|
|
|
get() { |
|
|
|
get() { |
|
|
|
return this.frameManager.totalFrames |
|
|
|
return this.frameManager.totalFrames |
|
|
|
// return when (val step = this.currentStep) { |
|
|
|
|
|
|
|
// is ComputedAction -> 1 |
|
|
|
|
|
|
|
// is Street -> { |
|
|
|
|
|
|
|
// var frames = 1 |
|
|
|
|
|
|
|
// // gather animation if chips have been committed in the street |
|
|
|
|
|
|
|
// if (this.actionList.streetHasSignificantAction(step)) { |
|
|
|
|
|
|
|
// frames += framesForChipsAnimation |
|
|
|
|
|
|
|
// } |
|
|
|
|
|
|
|
// // Chip distribution animation on the Summary |
|
|
|
|
|
|
|
// if (step == Street.SUMMARY) { |
|
|
|
|
|
|
|
// frames += framesForChipsAnimation |
|
|
|
|
|
|
|
// } |
|
|
|
|
|
|
|
// frames |
|
|
|
|
|
|
|
// } |
|
|
|
|
|
|
|
// |
|
|
|
|
|
|
|
// |
|
|
|
|
|
|
|
//// Street.SUMMARY -> 1 + 2 * framesForChipsAnimation // 2 animations |
|
|
|
|
|
|
|
//// is Street -> 1 + framesForChipsAnimation |
|
|
|
|
|
|
|
// else -> throw PAIllegalStateException("unmanaged step: $step") |
|
|
|
|
|
|
|
// } |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*** |
|
|
|
/*** |
|
|
|
* The index of the current frame |
|
|
|
* The index of the current frame |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private var currentFrame = 0 |
|
|
|
private var currentFrameIndex = 0 |
|
|
|
|
|
|
|
set(value) { |
|
|
|
|
|
|
|
field = value |
|
|
|
|
|
|
|
this.frameManager.defineFrameDescriptor(value) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*** |
|
|
|
/*** |
|
|
|
* The frame type for the current combination of step + frame index |
|
|
|
* The frame type for the current combination of step + frame index |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
val frameType: FrameType |
|
|
|
val frameType: FrameType |
|
|
|
get() { |
|
|
|
get() { |
|
|
|
return this.frameManager.frameType(this.currentFrame) |
|
|
|
return this.frameManager.currentFrameType |
|
|
|
|
|
|
|
|
|
|
|
// return when (val step = this.currentStep) { |
|
|
|
|
|
|
|
// is ComputedAction -> FrameType.STATE |
|
|
|
|
|
|
|
// Street.SUMMARY -> { |
|
|
|
|
|
|
|
// when (this.currentFrame) { |
|
|
|
|
|
|
|
// in (0 until framesForChipsAnimation) -> FrameType.GATHER_ANIMATION |
|
|
|
|
|
|
|
// in (framesForChipsAnimation until 2 * framesForChipsAnimation) -> FrameType.DISTRIBUTION_ANIMATION |
|
|
|
|
|
|
|
// else -> FrameType.STATE |
|
|
|
|
|
|
|
// } |
|
|
|
|
|
|
|
// } |
|
|
|
|
|
|
|
// is Street -> { |
|
|
|
|
|
|
|
// when (this.currentFrame) { |
|
|
|
|
|
|
|
// in (0 until framesForChipsAnimation) -> FrameType.GATHER_ANIMATION |
|
|
|
|
|
|
|
// else -> FrameType.STATE |
|
|
|
|
|
|
|
// } |
|
|
|
|
|
|
|
// } |
|
|
|
|
|
|
|
// else -> throw PAIllegalStateException("unmanaged step: $step") |
|
|
|
|
|
|
|
// } |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*** |
|
|
|
/*** |
|
|
|
@ -124,8 +90,8 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private val visualOccurences: Int |
|
|
|
private val visualOccurences: Int |
|
|
|
get() { |
|
|
|
get() { |
|
|
|
return if (this.currentStepIndex == this.steps.size - 1 && this.currentFrame == this.numberOfFramesForCurrentStep - 1) { |
|
|
|
return if (this.currentStepIndex == this.steps.size - 1 && this.currentFrameIndex == this.numberOfFramesForCurrentStep - 1) { |
|
|
|
FrameType.STATE.visualOccurences * 5 |
|
|
|
FrameType.STATE.visualOccurences * 3 |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
this.frameType.visualOccurences |
|
|
|
this.frameType.visualOccurences |
|
|
|
} |
|
|
|
} |
|
|
|
@ -144,13 +110,13 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
val shouldShowAdditionalFrame: Boolean |
|
|
|
val shouldShowAdditionalFrame: Boolean |
|
|
|
get() { |
|
|
|
get() { |
|
|
|
return this.currentFrame < this.numberOfFramesForCurrentStep - 1 |
|
|
|
return this.currentFrameIndex < this.numberOfFramesForCurrentStep |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*** |
|
|
|
/*** |
|
|
|
* The list of actions associated with the hand history |
|
|
|
* The list of actions associated with the hand history |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
var actionList: ActionList = ActionList(null) |
|
|
|
var actionList: ActionList = ActionList() |
|
|
|
private set |
|
|
|
private set |
|
|
|
|
|
|
|
|
|
|
|
/*** |
|
|
|
/*** |
|
|
|
@ -161,7 +127,7 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) { |
|
|
|
/*** |
|
|
|
/*** |
|
|
|
* The index of the last blind in the action list |
|
|
|
* The index of the last blind in the action list |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private var lastBlindIndex: Int = 0 |
|
|
|
// private var lastBlindIndex: Int = 0 |
|
|
|
|
|
|
|
|
|
|
|
private var currentStepIndex: Int = 0 |
|
|
|
private var currentStepIndex: Int = 0 |
|
|
|
set(value) { |
|
|
|
set(value) { |
|
|
|
@ -169,8 +135,8 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) { |
|
|
|
field = value |
|
|
|
field = value |
|
|
|
|
|
|
|
|
|
|
|
defineFramesForCurrentStep() |
|
|
|
defineFramesForCurrentStep() |
|
|
|
// if we go backwards we don't want to perform an animation, otherwise we want |
|
|
|
// if we go backwards we don't want to perform an animation, otherwise we do want it |
|
|
|
this.currentFrame = if (backwards) this.numberOfFramesForCurrentStep - 1 else 0 |
|
|
|
this.currentFrameIndex = if (backwards) this.numberOfFramesForCurrentStep - 1 else 0 |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
val currentStep: HandStep |
|
|
|
val currentStep: HandStep |
|
|
|
@ -182,31 +148,31 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) { |
|
|
|
loadHandHistory(this.handHistory) |
|
|
|
loadHandHistory(this.handHistory) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fun loadHandHistory(handHistory: HandHistory) { |
|
|
|
private fun loadHandHistory(handHistory: HandHistory) { |
|
|
|
|
|
|
|
|
|
|
|
this.actionList.load(handHistory) |
|
|
|
this.actionList.load(handHistory) |
|
|
|
this.steps = HandStep.createSteps(handHistory) |
|
|
|
this.steps = HandStep.createSteps(handHistory) |
|
|
|
|
|
|
|
defineFramesForCurrentStep() |
|
|
|
val bi = this.steps.indexOfLast { it is ComputedAction && it.action.type?.isBlind == true } |
|
|
|
|
|
|
|
this.lastBlindIndex = max(bi, 0) // in case indexOfLast returns -1 |
|
|
|
|
|
|
|
this.currentStepIndex = this.lastBlindIndex // initialize at big blind |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*** |
|
|
|
/*** |
|
|
|
* Let the animator know when a frame has been drawn |
|
|
|
* Let the animator know when a frame has been drawn |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
fun frameDrawn() { |
|
|
|
fun frameDrawn() { |
|
|
|
if (this.currentFrame < this.numberOfFramesForCurrentStep - 1) { |
|
|
|
// Timber.d("a>frameDrawn: ${this.currentFrameIndex}, total: ${this.numberOfFramesForCurrentStep}") |
|
|
|
this.currentFrame += 1 |
|
|
|
if (this.currentFrameIndex < this.numberOfFramesForCurrentStep - 1) { |
|
|
|
|
|
|
|
this.currentFrameIndex += 1 |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Timber.d("b>frameDrawn: ${this.currentFrameIndex}") |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*** |
|
|
|
/*** |
|
|
|
* Reset the step and the frame to the start of the hand |
|
|
|
* Reset the step and the frame to the start of the hand |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
fun restart() { |
|
|
|
fun restart() { |
|
|
|
this.currentStepIndex = this.lastBlindIndex |
|
|
|
this.currentStepIndex = 0 |
|
|
|
this.currentFrame = 0 |
|
|
|
this.currentFrameIndex = 0 |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Dimensions |
|
|
|
// Dimensions |
|
|
|
@ -355,7 +321,7 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) { |
|
|
|
val prp = line.intersects(pRect) ?: throw PAIllegalStateException("should not happen") |
|
|
|
val prp = line.intersects(pRect) ?: throw PAIllegalStateException("should not happen") |
|
|
|
|
|
|
|
|
|
|
|
val boxToCenterLine = MathUtils.Line(prp.x, prp.y, tableRect.centerX(), tableRect.centerY()) |
|
|
|
val boxToCenterLine = MathUtils.Line(prp.x, prp.y, tableRect.centerX(), tableRect.centerY()) |
|
|
|
val boxToChipDistance = if (bottomOriented) 3 * chipRadius else 2 * chipRadius // because the chip text needs space |
|
|
|
val boxToChipDistance = if (bottomOriented) 3.3f * chipRadius else 2 * chipRadius // because the chip text needs space |
|
|
|
val chipPoint = boxToCenterLine.pointForDistance(boxToChipDistance) |
|
|
|
val chipPoint = boxToCenterLine.pointForDistance(boxToChipDistance) |
|
|
|
|
|
|
|
|
|
|
|
this.chipCircles.add(Circle(chipPoint.x, chipPoint.y, chipRadius)) |
|
|
|
this.chipCircles.add(Circle(chipPoint.x, chipPoint.y, chipRadius)) |
|
|
|
@ -584,7 +550,7 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fun previousStep() { |
|
|
|
fun previousStep() { |
|
|
|
if (this.currentStepIndex > this.lastBlindIndex + 1) { |
|
|
|
if (this.currentStepIndex > 1) { |
|
|
|
this.currentStepIndex -= 1 |
|
|
|
this.currentStepIndex -= 1 |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -636,7 +602,9 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private fun animatedChipCircle(origin: Circle, destination: Circle): Circle { |
|
|
|
private fun animatedChipCircle(origin: Circle, destination: Circle): Circle { |
|
|
|
val completion = (this.currentFrame + 1).toFloat() / this.numberOfFramesForCurrentStep.toFloat() |
|
|
|
val fd = this.frameManager.currentDescriptor |
|
|
|
|
|
|
|
val currentAnimationFrameIndex = this.currentFrameIndex - fd.frameStart + 1 |
|
|
|
|
|
|
|
val completion = currentAnimationFrameIndex.toFloat() / fd.count.toFloat() |
|
|
|
|
|
|
|
|
|
|
|
val x = origin.x + (destination.x - origin.x) * completion |
|
|
|
val x = origin.x + (destination.x - origin.x) * completion |
|
|
|
val y = origin.y + (destination.y - origin.y) * completion |
|
|
|
val y = origin.y + (destination.y - origin.y) * completion |
|
|
|
@ -659,23 +627,45 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
fun frames(context: Context, frameHandler: (Bitmap, Int) -> Unit) { |
|
|
|
fun frames(context: Context, frameHandler: (Bitmap, Int) -> Unit) { |
|
|
|
|
|
|
|
|
|
|
|
while (this.hasMoreSteps) { |
|
|
|
Timber.d("Step count = ${this.steps.size}") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// The first steps are blinds and we don't animate them |
|
|
|
|
|
|
|
(this.currentStepIndex until this.steps.size).forEach { |
|
|
|
|
|
|
|
|
|
|
|
while (this.shouldShowAdditionalFrame) { |
|
|
|
// Timber.d("STEP [$index] >> ($handStep): Frame count = ${this.frameManager.totalFrames}") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(0 until this.frameManager.totalFrames).forEach { f -> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Timber.d("FRAME [$f] >> step: $currentStepIndex, frame: $currentFrameIndex") |
|
|
|
val bitmap = Bitmap.createBitmap(this.width.toInt(), this.height.toInt(), Bitmap.Config.ARGB_8888) |
|
|
|
val bitmap = Bitmap.createBitmap(this.width.toInt(), this.height.toInt(), Bitmap.Config.ARGB_8888) |
|
|
|
val canvas = Canvas(bitmap) |
|
|
|
val canvas = Canvas(bitmap) |
|
|
|
TableDrawer.drawTable(this, canvas, context) |
|
|
|
TableDrawer.drawTable(this, canvas, context) |
|
|
|
|
|
|
|
|
|
|
|
Timber.d("frame drawn at step: $currentStepIndex, frame: $currentFrame") |
|
|
|
|
|
|
|
frameHandler(bitmap, this.visualOccurences) |
|
|
|
frameHandler(bitmap, this.visualOccurences) |
|
|
|
|
|
|
|
|
|
|
|
// frameDrawn() |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
nextStep() |
|
|
|
nextStep() |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// do { |
|
|
|
|
|
|
|
// |
|
|
|
|
|
|
|
// do { |
|
|
|
|
|
|
|
// |
|
|
|
|
|
|
|
// val bitmap = Bitmap.createBitmap(this.width.toInt(), this.height.toInt(), Bitmap.Config.ARGB_8888) |
|
|
|
|
|
|
|
// val canvas = Canvas(bitmap) |
|
|
|
|
|
|
|
// TableDrawer.drawTable(this, canvas, context) |
|
|
|
|
|
|
|
// |
|
|
|
|
|
|
|
// Timber.d("frame drawn at step: $currentStepIndex, frame: $currentFrame") |
|
|
|
|
|
|
|
// frameHandler(bitmap, this.visualOccurences) |
|
|
|
|
|
|
|
// |
|
|
|
|
|
|
|
// } while (this.shouldShowAdditionalFrame) |
|
|
|
|
|
|
|
// |
|
|
|
|
|
|
|
// nextStep() |
|
|
|
|
|
|
|
// |
|
|
|
|
|
|
|
// } while (this.hasMoreSteps) |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/*** |
|
|
|
/*** |
|
|
|
@ -683,7 +673,7 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
val isReplayFinished: Boolean |
|
|
|
val isReplayFinished: Boolean |
|
|
|
get() { |
|
|
|
get() { |
|
|
|
return this.currentStepIndex >= this.steps.size - 1 && this.currentFrame >= this.numberOfFramesForCurrentStep - 1 |
|
|
|
return this.currentStepIndex >= this.steps.size - 1 && this.currentFrameIndex >= this.numberOfFramesForCurrentStep - 1 |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|