-
Notifications
You must be signed in to change notification settings - Fork 0
/
progvm.ts
71 lines (62 loc) · 1.83 KB
/
progvm.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import { StateSetter, butterfly } from 'butterfloat'
import { firstValueFrom, Observable, map, shareReplay } from 'rxjs'
import { tag } from 'rxjs-spy/operators'
export const BaseSpeed = 0.005
export const SpeedMultiplier = 2
export class ProgVm {
readonly #name: Observable<string>
readonly #setName: (name: StateSetter<string>) => void
get name() {
return this.#name
}
readonly #percent: Observable<number>
readonly #setPercent: (percent: StateSetter<number>) => void
get percent() {
return this.#percent
}
readonly #roundPercent: Observable<string>
get roundPercent() {
return this.#roundPercent
}
readonly #paused: Observable<boolean>
readonly #setPaused: (paused: StateSetter<boolean>) => void
get paused() {
return this.#paused
}
readonly #perTick: Observable<number>
readonly #setPerTick: (perTick: StateSetter<number>) => void
get perTick() {
return this.#perTick
}
constructor() {
;[this.#name, this.#setName] = butterfly('Item')
;[this.#percent, this.#setPercent] = butterfly(0)
;[this.#paused, this.#setPaused] = butterfly(false)
;[this.#perTick, this.#setPerTick] = butterfly(BaseSpeed)
this.#roundPercent = this.percent.pipe(
map((percent) => percent.toLocaleString(undefined, { style: 'percent' })),
tag('progvm-round-percent'),
shareReplay(1),
)
}
pause() {
this.#setPaused(true)
}
unpause() {
this.#setPaused(false)
}
speedUp() {
this.#setPerTick((perTick) => perTick * SpeedMultiplier)
}
slowDown() {
this.#setPerTick((perTick) => perTick / SpeedMultiplier)
}
async tick() {
const paused = await firstValueFrom(this.paused)
const perTick = paused ? 0 : await firstValueFrom(this.perTick)
this.#setPercent((percent) => Math.min(percent + perTick, 1))
}
finish() {
this.#setPercent(1)
}
}