11package xyz.aprildown.timer.presentation.stream.task
22
3- import android.os.Handler
4- import android.os.Looper
5- import android.os.SystemClock
3+ import com.github.cardinalby.accuratecountdowntimer.AccurateCountDownTimer
4+ import com.github.deweyreed.tools.helper.HandlerHelper
5+ import xyz.aprildown.timer.presentation.stream.StreamState
66
77/* *
88 * You must call [TaskManager.interfere] to move on.
@@ -11,68 +11,75 @@ internal class StopwatchTask(master: TaskMaster) : Task(master) {
1111
1212 private val tickListeners = mutableListOf<TickListener >()
1313
14- private val handler = Handler (Looper .getMainLooper())
15- private var currentStartTime = 0L
16- private var baseElapsedTime = 0L
17- private var currentElapsedTime = 0L
14+ private var timer = MyTimer ()
15+ private var millisPassedBase = 0L
16+ private var millisPassedCurrent = 0L
1817
19- override val currentTime: Long get() = currentElapsedTime + baseElapsedTime
18+ override val currentTime: Long get() = millisPassedBase + millisPassedCurrent
19+
20+ fun addTickListener (listener : TickListener ) {
21+ tickListeners.add(listener)
22+ }
2023
2124 override fun start () {
2225 super .start()
23- currentStartTime = SystemClock .elapsedRealtime()
24- currentElapsedTime = 0
25- handler.post(TickRunnable ())
26+ timer.start()
2627 }
2728
2829 override fun pause () {
2930 super .pause()
30- handler.removeCallbacksAndMessages(null )
31- baseElapsedTime + = currentElapsedTime
32- currentElapsedTime = 0
31+ timer.cancel()
32+ millisPassedBase + = millisPassedCurrent
33+ millisPassedCurrent = 0L
34+ timer = MyTimer ()
3335 }
3436
3537 override fun forceStop () {
3638 super .forceStop()
37- handler.removeCallbacksAndMessages( null )
39+ timer.cancel( )
3840 }
3941
4042 override fun adjust (amount : Long , add : Boolean ) {
41- handler.removeCallbacksAndMessages(null )
42- baseElapsedTime + = if (add) currentElapsedTime + amount else amount
43- currentElapsedTime = 0
43+ timer.cancel()
44+ millisPassedBase = if (add) millisPassedBase + millisPassedCurrent + amount else amount
45+ millisPassedCurrent = 0L
46+ timer = MyTimer ()
4447 if (taskState.isRunning) {
45- start()
46- } else {
47- master.onTick(this , currentTime)
48+ timer.start()
4849 }
4950 }
5051
51- /* *
52- * newElapsedTime pattern: 26, 1026, 2026, 3026...
53- * So the result is 0, 1, 2, 3
54- */
55- private fun onTick (newElapsedTime : Long ) {
56- currentElapsedTime = newElapsedTime
57- val time = currentTime
58- master.onTick(this , time)
59- tickListeners.forEach { it.onNewTime(time) }
52+ private fun onFinish () {
53+ taskState = StreamState .RESET
54+ master.onTaskDone(this )
6055 }
6156
62- fun addTickListener (listener : TickListener ) {
63- tickListeners.add(listener)
57+ private fun onTick (millisPassed : Long ) {
58+ millisPassedCurrent = millisPassed
59+ master.onTick(this , currentTime)
60+ tickListeners.forEach { it.onNewTime(currentTime) }
6461 }
6562
66- private inner class TickRunnable : Runnable {
67- override fun run () {
68- val tickStartTime = SystemClock .elapsedRealtime()
63+ private inner class MyTimer : AccurateCountDownTimer (DURATION , 1_000L ) {
6964
70- val newElapsedTime = tickStartTime - currentStartTime
71- onTick(newElapsedTime)
65+ init {
66+ HandlerHelper .runOnUiThread {
67+ this @StopwatchTask.onTick(0L )
68+ }
69+ }
7270
73- val tickEndTime = SystemClock .elapsedRealtime()
74- val consume = tickEndTime - tickStartTime
75- handler.postDelayed(this , 1_000L - (consume % 1_000L ))
71+ override fun onFinish () {
72+ HandlerHelper .runOnUiThread {
73+ this @StopwatchTask.onFinish()
74+ }
75+ }
76+
77+ override fun onTick (millisUntilFinished : Long ) {
78+ HandlerHelper .runOnUiThread {
79+ this @StopwatchTask.onTick((DURATION - millisUntilFinished).round())
80+ }
7681 }
7782 }
7883}
84+
85+ private const val DURATION = Long .MAX_VALUE
0 commit comments