fun HomeScreen(engine: AudioEngine, onGoSetting: () -> Unit){
val spl by engine.spl.collectAsState()
val spectrum by engine.spectrum.collectAsState()
...
SoundLevelScreen(
splValue = spl,
splStereo = stereoDbState,
spectrum = spectrum,
stereoSpectrum = stereoSpectrum
)
}
이렇게 있을때 spl 이 변경되면 SoundLevelScreen 부분만 다시 재구성된다.
@Composable
fun SoundLevelScreen(
splValue: Double,
splStereo: Pair<Double, Double>,
spectrum: FloatArray,
stereoSpectrum: Pair<FloatArray, FloatArray>
) {
println("1초 마다 호출")
...
}
즉 이렇게 1초마다 호출이 된다.
val splApprox = monoCalculateDb(n, buf)
val smoothed = if (ema == null) {
ema = splApprox
splApprox
} else {
val v = alpha * splApprox + (1.0 - alpha) * ema!!
ema = v; v
}
_spl.value = splApprox
// 스펙트럼만 따로
println("호출 _spl 계산끝")
//delay(10)
val spec = monoCalculateEqualizer(n, buf, real, imag, spectrumCtx)
_spectrum.value = spec
println("호출 _spectrum 계산끝")
이게 1초마다 호출되니까 println("호출 _spl 계산끝") 끝나고 SoundLevelScreen 가 재구성되고, println("호출 _spectrum 계산끝") 끝나고 SoundLevelScreen 가 재구성되니 총 1초에 2번 println("1초 마다 호출") 이게 호출되는 것이 아닐까?
내부적은로는 _spl.value = splApprox 되면
Compose: “아 이 Composable(scope) 다시 그려야겠네” 하고 recomposition을 예약만 해 둔다.
recompose()가 시작되기 전에
_spectrum.value = ... 도 바로 실행됨
engine.spectrum.collectAsState() 안 state도 변경됨
Compose: “어? 같은 scope 또 변경됐네. 이미 재구성 예약되어 있으니까 또 스케줄 잡을 필요는 없겠다.”
→ 두 번째 변경은 이미 잡혀 있는 그 한 번의 재구성에 같이 포함
실제로 delay(10) 을 추가하면 println("1초 마다 호출") 가 2번 호출된다.