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. 6package event // import "golang.org/x/exp/shiny/driver/internal/event" 7 8import ( 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. 14type 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 21func (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. 29func (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. 53func (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. 62func (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} 69