Skip to content

Commit abf752a

Browse files
committed
Refactor Task tick listener logic and improve TimerMachine behavior handling #146
1 parent 0db9683 commit abf752a

4 files changed

Lines changed: 67 additions & 71 deletions

File tree

presentation/src/main/java/xyz/aprildown/timer/presentation/stream/TimerMachine.kt

Lines changed: 55 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -126,58 +126,50 @@ internal class TimerMachine(
126126

127127
private fun StepEntity.Step.toTask(useTtsNextStep: Boolean = false): Task {
128128
val behaviour = behaviour
129-
return if (behaviour.find { it.type == BehaviourType.HALT } != null) {
130-
StopwatchTask(this@TimerMachine).apply {
131-
behaviour.forEach {
132-
when (it.type) {
133-
BehaviourType.BEEP -> {
134-
addTickListener(BeepTickListener(beep = listener::beep))
135-
}
136-
else -> Unit
137-
}
129+
val countUp = behaviour.find { it.type == BehaviourType.HALT } != null
130+
return if (countUp) {
131+
StopwatchTask(master = this@TimerMachine)
132+
} else {
133+
CountDownTimerTask(master = this@TimerMachine, countDownTime = length).apply {
134+
if (useTtsNextStep) {
135+
addTickListener(WarmUpTtsListener(warmUp = { listener.countRead("") }))
138136
}
139137
}
140-
} else {
141-
CountDownTimerTask(
142-
this@TimerMachine,
143-
length
144-
).apply {
145-
behaviour.forEach { behaviour ->
146-
when (behaviour.type) {
147-
BehaviourType.BEEP -> {
148-
addTickListener(BeepTickListener(beep = listener::beep))
149-
}
150-
BehaviourType.HALF -> {
151-
addTickListener(
152-
HalfTickListener(
153-
total = length,
154-
half = { listener.notifyHalf(behaviour.toHalfAction().option) },
155-
)
138+
}.apply {
139+
behaviour.forEach { item ->
140+
when (item.type) {
141+
BehaviourType.BEEP -> {
142+
addTickListener(BeepTickListener(beep = listener::beep))
143+
}
144+
BehaviourType.HALF -> {
145+
addTickListener(
146+
HalfTickListener(
147+
total = length,
148+
countUp = countUp,
149+
half = { listener.notifyHalf(item.toHalfAction().option) },
156150
)
157-
}
158-
BehaviourType.COUNT -> {
159-
val action = behaviour.toCountAction()
160-
addTickListener(
161-
CountTickListener(
162-
times = action.times,
163-
count = if (action.beep) {
164-
{
165-
if (it.isNotBlank()) {
166-
listener.beep()
167-
}
151+
)
152+
}
153+
BehaviourType.COUNT -> {
154+
val action = item.toCountAction()
155+
addTickListener(
156+
CountTickListener(
157+
times = action.times,
158+
total = length,
159+
countUp = countUp,
160+
count = if (action.beep) {
161+
{
162+
if (it.isNotBlank()) {
163+
listener.beep()
168164
}
169-
} else {
170-
{ listener.countRead(it) }
171-
},
172-
)
165+
}
166+
} else {
167+
{ listener.countRead(it) }
168+
},
173169
)
174-
}
175-
else -> Unit
170+
)
176171
}
177-
}
178-
179-
if (useTtsNextStep) {
180-
addTickListener(WarmUpTtsListener(warmUp = { listener.countRead("") }))
172+
else -> Unit
181173
}
182174
}
183175
}
@@ -190,19 +182,21 @@ internal class TimerMachine(
190182
}
191183

192184
private class HalfTickListener(
193-
total: Long,
185+
private val total: Long,
186+
private val countUp: Boolean = false,
194187
private val half: () -> Unit,
195188
) : TickListener {
196189

197-
/**
198-
* Plus one second to make some warm up time.
199-
*/
200-
private val notifyTime: Long = total / 2 + 1000
201-
202190
private var isNotified = false
203191

204192
override fun onNewTime(newTime: Long) {
205-
if (!isNotified && newTime < notifyTime) {
193+
if (isNotified) return
194+
val isPassed = if (countUp) {
195+
newTime > total / 2 - 1000
196+
} else {
197+
newTime < total / 2 + 1000
198+
}
199+
if (isPassed) {
206200
isNotified = true
207201
half()
208202
}
@@ -211,21 +205,27 @@ internal class TimerMachine(
211205

212206
private class CountTickListener(
213207
private var times: Int,
208+
private val total: Long = 0L,
209+
private val countUp: Boolean = false,
214210
private val count: (String) -> Unit,
215211
) : TickListener {
216212

217213
private val warmUpTime = times + 1
218214
private var isWarmedUp = false
219215

220216
override fun onNewTime(newTime: Long) {
221-
val remainingSeconds = newTime / 1000
217+
val remainingSeconds = if (countUp) {
218+
(total - newTime) / 1000
219+
} else {
220+
newTime / 1000
221+
}
222222
if (!isWarmedUp && remainingSeconds <= warmUpTime) {
223223
isWarmedUp = true
224224
count("")
225225
}
226226
if (remainingSeconds <= times && times > 0) {
227227
times--
228-
count(remainingSeconds.toInt().toString())
228+
count((newTime / 1000).toString())
229229
}
230230
}
231231
}

presentation/src/main/java/xyz/aprildown/timer/presentation/stream/task/CountDownTimerTask.kt

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,11 @@ import com.github.deweyreed.tools.helper.HandlerHelper
55
import xyz.aprildown.timer.presentation.stream.StreamState
66

77
internal class CountDownTimerTask(master: TaskMaster, countDownTime: Long) : Task(master) {
8-
9-
// We place tickListeners before timer because MyTimer will onTick in the init
10-
private val tickListeners = mutableListOf<TickListener>()
11-
128
private var timer = MyTimer(countDownTime)
139
private var millisLeft = countDownTime
1410

1511
override val currentTime: Long get() = millisLeft
1612

17-
fun addTickListener(listener: TickListener) {
18-
tickListeners.add(listener)
19-
}
20-
2113
override fun start() {
2214
super.start()
2315
timer.start()
@@ -51,7 +43,7 @@ internal class CountDownTimerTask(master: TaskMaster, countDownTime: Long) : Tas
5143
private fun onTick(millisUntilFinished: Long) {
5244
millisLeft = millisUntilFinished
5345
master.onTick(this, currentTime)
54-
tickListeners.forEach { it.onNewTime(currentTime) }
46+
tick()
5547
}
5648

5749
private inner class MyTimer(

presentation/src/main/java/xyz/aprildown/timer/presentation/stream/task/StopwatchTask.kt

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,12 @@ import xyz.aprildown.timer.presentation.stream.StreamState
99
*/
1010
internal class StopwatchTask(master: TaskMaster) : Task(master) {
1111

12-
private val tickListeners = mutableListOf<TickListener>()
13-
1412
private var timer = MyTimer()
1513
private var millisPassedBase = 0L
1614
private var millisPassedCurrent = 0L
1715

1816
override val currentTime: Long get() = millisPassedBase + millisPassedCurrent
1917

20-
fun addTickListener(listener: TickListener) {
21-
tickListeners.add(listener)
22-
}
23-
2418
override fun start() {
2519
super.start()
2620
timer.start()
@@ -57,7 +51,7 @@ internal class StopwatchTask(master: TaskMaster) : Task(master) {
5751
private fun onTick(millisPassed: Long) {
5852
millisPassedCurrent = millisPassed
5953
master.onTick(this, currentTime)
60-
tickListeners.forEach { it.onNewTime(currentTime) }
54+
tick()
6155
}
6256

6357
private inner class MyTimer : AccurateCountDownTimer(DURATION, 1_000L) {

presentation/src/main/java/xyz/aprildown/timer/presentation/stream/task/Task.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,21 @@ import kotlin.math.roundToLong
66

77
internal abstract class Task(protected val master: TaskMaster) {
88

9+
private val tickListeners = mutableListOf<TickListener>()
10+
911
var taskState: StreamState =
1012
StreamState.RESET
1113
internal set
1214
open val currentTime: Long = 0L
1315

16+
fun addTickListener(listener: TickListener) {
17+
tickListeners.add(listener)
18+
}
19+
20+
protected fun tick() {
21+
tickListeners.forEach { it.onNewTime(currentTime) }
22+
}
23+
1424
@CallSuper
1525
open fun start() {
1626
taskState = StreamState.RUNNING

0 commit comments

Comments
 (0)