고랭 라이브러리 Lorca 를 이용하여 타이머 페이지를 만들어보자.
예제 깃헙 페이지에서 Lorca 를 이용하는 방법에 대해 확인할 수 있다.
먼저 Lorca 를 통해 GUI 를 띄우기 위한 코드를 작성한다.
ui, err := lorca.New("", "", 480, 320)
if err != nil {
log.Fatal(err)
}
defer ui.Close()
GUI 의 너비와 높이를 지정하여 생성하고 defer
을 통해 연기된 Close()
를 실행한다.
// 타이머 숫자
ticks := uint32(0)
// 백그라운드에의 타이머 고루틴과 UI 이벤트를 연결할 채널 생성
togglec := make(chan bool)
// JS 함수와 GO 를 바인드
ui.Bind("toggle", func() { togglec <- true })
ui.Bind("reset", func() {
atomic.StoreUint32(&ticks, 0)
ui.Eval(`document.querySelector('.timer').innerText = '0'`)
})
타이머에 사용할 숫자 tick
를 설정하고 타이머를 멈췄다 재시작을 할 수 있는 토글 채널 togglec
을 만든다.
그리고 채널을 활용하여 만든 토글을 toggle
에, 타이머를 0 으로 초기화를 시켜줄 함수를 reset
에 바인드 한다.
저수준의 작은 메모리를 활용하여 동기화를 사용하기 위해 atomic
을 활용한다.
// JS 함수와 GO 함수를 바인드한 후 HTML 을 로드
ui.Load("data:text/html," + url.PathEscape(`
<html>
<style>
div {
color: #323232;
font-size: 2em;
}
div:hover {
cursor: pointer;
}
</style>
<body>
<!-- 토글, 리셋 함수 사용 -->
<div class="timer" onclick="toggle()"></div>
<button onclick="reset()">Reset</button>
</body>
</html>
`))
ui.load
를 통해 html 을 로드하며, url.PathExcape
로 html 코드를 이스케이프한다.
// 타이머 고루틴을 시작
go func() {
t := time.NewTicker(time.Second)
defer t.Stop()
for {
select {
case <-t.C: // 타이머 숫자는 1초마다 증가하고 UI 를 업데이트
ui.Eval(fmt.Sprintf(`document.querySelector('.timer').innerText = 1 * %d`,
atomic.AddUint32(&ticks, 1)))
case <-togglec: // 정지했다면 정지 해제를 위한 다른 토글 이벤트를 기다림
<-togglec
}
}
}()
<-ui.Done()
NewTicker
를 통해 case
에서 지정된 시간 만큼 간격을 두면서 포함된 채널을 통해 신호를 보낸다.
타이머로 채널을 받으면 timer
클래스의 div 텍스트를 ticks
로 지정한다.
그리고 다른 case
에서 togglec
토글 함수를 통해 채널로 오는 신호를 받았다면 다시한번 <-togglec
를 통해 다시 토글 이벤트가 생길때 까지 기다리도록 한다.