Frame and animation refactoring

hh
Laurent 5 years ago
parent 1e9d726f23
commit c3f930e339
  1. 8
      app/src/main/java/net/pokeranalytics/android/model/handhistory/Street.kt
  2. 14
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/model/ActionList.kt
  3. 59
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/FrameManager.kt
  4. 101
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/ReplayerAnimator.kt
  5. 8
      app/src/main/java/net/pokeranalytics/android/ui/modules/handhistory/replayer/TableDrawer.kt

@ -41,6 +41,14 @@ enum class Street : HandStep {
return values()[this.ordinal + 1]
}
val previous: Street?
get() {
return when (this) {
PREFLOP -> null
else -> values()[this.ordinal - 1]
}
}
// override fun draw(configuration: ReplayerConfiguration, canvas: Canvas, context: Context) {
// TableDrawer.drawStreet(this, configuration, canvas, context)
// }

@ -309,13 +309,6 @@ class ActionList(var listener: ActionListListener? = null) : ArrayList<ComputedA
return this.last { it.street == street }.action.index
}
/***
* Returns the last action index of the [street]
*/
fun lastActionIndexBeforeStreet(street: Street): Int {
return this.last { it.street == street }.action.index
}
/***
* Returns the list of empty actions before the action at the given [index]
*/
@ -332,6 +325,13 @@ class ActionList(var listener: ActionListListener? = null) : ArrayList<ComputedA
return previousActions.lastOrNull { it.action.isActionSignificant }
}
/***
* Returns true if the [street] contains a significant action
*/
fun streetHasSignificantAction(street: Street): Boolean {
return this.filter { it.street == street }.any { it.action.isActionSignificant }
}
/***
* Check if some positions are still required to play,
* and adds new actions if none exists after [index]

@ -0,0 +1,59 @@
package net.pokeranalytics.android.ui.modules.handhistory.replayer
import net.pokeranalytics.android.exceptions.PAIllegalStateException
import timber.log.Timber
enum class FrameType(val visualOccurences: Int) {
STATE(150),
GATHER_ANIMATION(4),
DISTRIBUTION_ANIMATION(4)
}
class FrameManager {
data class FrameDescriptor(val type: FrameType, val count: Int, private val frameStart: Int) {
var range: IntRange = frameStart until frameStart + count
}
/***
* The list of frame descriptors
*/
private val descriptors = mutableListOf<FrameDescriptor>()
/***
* The total number of added frames in the descriptors
*/
private var totalAddedFrames: Int = 0
val totalFrames: Int
get() { return this.totalAddedFrames }
/***
* Adds a frame descriptor with a frame [type] and a frame [count]
*/
fun add(type: FrameType, count: Int) {
val fd = FrameDescriptor(type, count, this.totalAddedFrames)
this.descriptors.add(fd)
this.totalAddedFrames += count
}
/***
*
*/
fun frameType(frame: Int): FrameType {
this.descriptors.forEach { descriptor ->
if (frame in descriptor.range) {
return descriptor.type
}
}
throw PAIllegalStateException("frame $frame asked out of $totalAddedFrames defined frames, descriptor count = ${this.descriptors.size}")
}
fun reset() {
this.descriptors.clear()
this.totalAddedFrames = 0
}
}

@ -12,18 +12,11 @@ import net.pokeranalytics.android.ui.modules.handhistory.model.ComputedAction
import net.pokeranalytics.android.util.MathUtils
import timber.log.Timber
import kotlin.math.max
import kotlin.math.min
class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) {
// Steps & Frames
enum class FrameType(val visualOccurences: Int) {
STATE(150),
GATHER_ANIMATION(4),
DISTRIBUTION_ANIMATION(4)
}
/***
* The number of frames per second
*/
@ -42,17 +35,55 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) {
private val framesForChipsAnimation: Int
get() { return (chipAnimationDuration / animationRate).toInt() }
private var frameManager = FrameManager()
private fun defineFramesForCurrentStep() {
this.frameManager.reset()
when (val step = this.currentStep) {
is ComputedAction -> this.frameManager.add(FrameType.STATE, 1)
is Street -> {
// gather animation if chips have been committed in the street
if (this.actionList.streetHasSignificantAction(step)) {
this.frameManager.add(FrameType.GATHER_ANIMATION, framesForChipsAnimation)
}
// Chip distribution animation on the Summary
if (step == Street.SUMMARY) {
this.frameManager.add(FrameType.DISTRIBUTION_ANIMATION, framesForChipsAnimation)
}
this.frameManager.add(FrameType.STATE, 1)
}
else -> throw PAIllegalStateException("unmanaged step: $step")
}
}
/***
* The total number of frames for each kind of step
*/
private val numberOfFramesForCurrentStep: Int
get() {
return when (val step = this.currentStep) {
is ComputedAction -> 1
Street.SUMMARY -> 1 + 2 * framesForChipsAnimation // 2 animations
is Street -> 1 + framesForChipsAnimation
else -> throw PAIllegalStateException("unmanaged step: $step")
}
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")
// }
}
/***
@ -65,29 +96,36 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) {
*/
val frameType: FrameType
get() {
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")
}
return this.frameManager.frameType(this.currentFrame)
// 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")
// }
}
/***
* Returns the number of visual occurrences for the current frame
* This function returns a longer value for the last frame of the last step
* because some player auto-replay videos because we want the viewer to have a pause.
*/
private val visualOccurences: Int
get() {
return if (this.currentStepIndex == this.steps.size - 1 && this.currentFrame == this.numberOfFramesForCurrentStep - 1) {
FrameType.STATE.visualOccurences * 4
FrameType.STATE.visualOccurences * 5
} else {
this.frameType.visualOccurences
}
@ -122,6 +160,7 @@ class ReplayerAnimator(var handHistory: HandHistory, var export: Boolean) {
val backwards = value < field
field = value
defineFramesForCurrentStep()
// if we go backwards we don't want to perform an animation, otherwise we want
this.currentFrame = if (backwards) this.numberOfFramesForCurrentStep - 1 else 0
}

@ -159,7 +159,7 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) {
when (animator.currentStep) {
is Street -> {
when (animator.frameType) {
ReplayerAnimator.FrameType.STATE -> {
FrameType.STATE -> {
if (animator.currentStep == Street.SUMMARY) {
val winnerPots = animator.handHistory.winnerPots.firstOrNull { it.position == i }
@ -172,14 +172,14 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) {
}
}
ReplayerAnimator.FrameType.GATHER_ANIMATION -> {
FrameType.GATHER_ANIMATION -> {
lastCommittedAmount(i, animator)?.let { amount ->
val color = colorForAmount(amount)
val circle = animator.animatedChipCircleToPot(i)
drawChipCircle(circle, color, canvas, context)
}
}
ReplayerAnimator.FrameType.DISTRIBUTION_ANIMATION -> {
FrameType.DISTRIBUTION_ANIMATION -> {
val winnerPots = animator.handHistory.winnerPots.firstOrNull { it.position == i }
winnerPots?.let { pot ->
@ -454,7 +454,7 @@ class TableDrawer(bitmap: Bitmap) : Canvas(bitmap) {
private fun drawPot(street: Street, computedAction: ComputedAction?, animator: ReplayerAnimator, canvas: Canvas, context: Context) {
if (street == Street.SUMMARY && animator.frameType != ReplayerAnimator.FrameType.GATHER_ANIMATION) {
if (street == Street.SUMMARY && animator.frameType != FrameType.GATHER_ANIMATION) {
return
}

Loading…
Cancel
Save