event.go (1498B)
1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package event provides an infinitely buffered double-ended queue of events. 6 package event // import "golang.org/x/exp/shiny/driver/internal/event" 7 8 import ( 9 "sync" 10 ) 11 12 // Deque is an infinitely buffered double-ended queue of events. The zero value 13 // is usable, but a Deque value must not be copied. 14 type Deque struct { 15 mu sync.Mutex 16 cond sync.Cond // cond.L is lazily initialized to &Deque.mu. 17 back []interface{} // FIFO. 18 front []interface{} // LIFO. 19 } 20 21 func (q *Deque) lockAndInit() { 22 q.mu.Lock() 23 if q.cond.L == nil { 24 q.cond.L = &q.mu 25 } 26 } 27 28 // NextEvent implements the screen.EventDeque interface. 29 func (q *Deque) NextEvent() interface{} { 30 q.lockAndInit() 31 defer q.mu.Unlock() 32 33 for { 34 if n := len(q.front); n > 0 { 35 e := q.front[n-1] 36 q.front[n-1] = nil 37 q.front = q.front[:n-1] 38 return e 39 } 40 41 if n := len(q.back); n > 0 { 42 e := q.back[0] 43 q.back[0] = nil 44 q.back = q.back[1:] 45 return e 46 } 47 48 q.cond.Wait() 49 } 50 } 51 52 // Send implements the screen.EventDeque interface. 53 func (q *Deque) Send(event interface{}) { 54 q.lockAndInit() 55 defer q.mu.Unlock() 56 57 q.back = append(q.back, event) 58 q.cond.Signal() 59 } 60 61 // SendFirst implements the screen.EventDeque interface. 62 func (q *Deque) SendFirst(event interface{}) { 63 q.lockAndInit() 64 defer q.mu.Unlock() 65 66 q.front = append(q.front, event) 67 q.cond.Signal() 68 }