습관만들기 Pawbit TIL 4
배치 버튼이 연출이 끝날 때까지 잠겨 있었다
꿈 조각을 퍼즐에 놓으면 조각이 날아가서(fly) 터지고(burst) 그 칸이 열린다(reveal). 그런데 버튼을 한 번 누르면 이 연출이 다 끝날 때까지 버튼이 잠겨서, 조각을 여러 개 놓으려면 매번 기다려야 했다. 답답해서 연타로 눌러도 바로바로 놓이게 해 달라고 했다.
처음엔 앞 조각이 사라졌다
첫 방식은 누를 때마다 새 조각을 출발시키면서 날아가던 앞 조각은 취소하는 것이었다. 연타는 되는데, 취소된 조각이 칸에 닿지 못하고 사라졌다.
줄을 세우니 한 개씩만 돌았다
다음은 큐(queue, 먼저 들어온 것부터 차례로 처리하는 줄)였다. 누른 만큼 조각이 줄을 서고 fly → burst → reveal 순서도 지켜진다. 조각이 사라지지는 않는데, 앞 조각이 다 끝나야 다음 조각이 출발했다. 여전히 한 개씩이었다.
조각마다 자기 컨트롤러를 주니 동시에 날았다
원인은 움직임을 재는 시계가 하나뿐이었다는 데 있었다. Flutter의 애니메이션은 티커(Ticker, 화면이 새로 그려질 때마다 신호를 주는 시계)에 맞춰 돈다. 화면에 SingleTickerProviderStateMixin을 붙이면 티커를 하나만 받고, 그러면 애니메이션을 굴리는 AnimationController도 하나뿐이라 조각들이 그 하나를 차례로 나눠 쓴다.
TickerProviderStateMixin으로 바꿔 조각마다 자기 컨트롤러를 만들게 하자 서로를 기다리지 않고 동시에 날았다. 조각 안의 순서는 흐름을 막지 않는(non-blocking) 방식으로 이었다. 끝날 때까지 기다리는 await로 쓰면 다음 조각도 못 떠나고, 끝나면 이어서 하라는 연결(.then())만 걸어 두면 조각마다 순서를 지키면서 여러 조각이 따로 움직인다.
대신 각자 만든 컨트롤러는 끝나면 각자 정리해야 한다. 안 치우면 화면을 드나들 때마다 쌓인다.
- 판단: 동시에 움직여야 하는 것은 각자 시계를 가져야 한다. 순서는 필요한 범위 안에서만 지키고, 그 밖은 풀어 둔다.
처음부터 그 이름을 알았다면
세 번을 거쳐서야 원하는 동작에 닿았다. 조각마다 자체 컨트롤러를 갖는 방식으로 해 달라고 처음부터 말했으면 금방 끝났을 일이다. 원하는 동작을 설명하는 것과, 그 동작을 가리키는 이름을 아는 것은 다르다.
- 판단: 원하는 걸 결과로만 설명하면 방법은 상대가 고르고, 맞을 때까지 왕복한다. 구조의 이름을 알아 두면 다음에는 한 번에 말할 수 있다.