diff options
| author | Sam Anthony <sam@samanthony.xyz> | 2024-08-28 18:55:11 -0400 |
|---|---|---|
| committer | Sam Anthony <sam@samanthony.xyz> | 2024-08-28 18:55:11 -0400 |
| commit | 33713cb2334d8dce3e4ae2f7a7905104efa8519b (patch) | |
| tree | 9077d7b49a96a06c19d3c6d6d15bcf28d0a78969 /win.go | |
| parent | b4b7f20fc66c85673adb65849050314be515f3f3 (diff) | |
| download | gui-33713cb2334d8dce3e4ae2f7a7905104efa8519b.zip | |
synchronize shared win data
Diffstat (limited to 'win.go')
| -rw-r--r-- | win.go | 71 |
1 files changed, 48 insertions, 23 deletions
@@ -4,6 +4,7 @@ import ( "image" "image/draw" "runtime" + "sync" "time" "unsafe" @@ -69,12 +70,15 @@ type Win struct { events share.Queue[Event] draw chan func(draw.Image) image.Rectangle + w *glfw.Window newSize chan image.Rectangle - finish chan struct{} + img share.Val[*image.RGBA] + ratio int - w *glfw.Window - img *image.RGBA - ratio int + kill chan bool + dead chan bool + + threads *sync.WaitGroup } // NewWin creates a new window with all the supplied options. @@ -99,7 +103,10 @@ func NewWin(opts ...WinOption) (*Win, error) { events: events, draw: make(chan func(draw.Image) image.Rectangle), newSize: make(chan image.Rectangle), - finish: make(chan struct{}), + img: share.NewVal[*image.RGBA](), + kill: make(chan bool), + dead: make(chan bool), + threads: new(sync.WaitGroup), } var err error @@ -129,7 +136,7 @@ func NewWin(opts ...WinOption) (*Win, error) { } bounds := image.Rect(0, 0, o.width*w.ratio, o.height*w.ratio) - w.img = image.NewRGBA(bounds) + w.img.Set <- image.NewRGBA(bounds) go func() { runtime.LockOSThread() @@ -257,14 +264,23 @@ func (w *Win) eventThread() { w.events.Enqueue <- WiClose{} }) - r := w.img.Bounds() + r := w.img.Get().Bounds() w.events.Enqueue <- Resize{Rectangle: r} for { select { - case <-w.finish: + case <-w.kill: + close(w.kill) close(w.events.Enqueue) + close(w.draw) + close(w.newSize) w.w.Destroy() + + w.threads.Wait() + + w.dead <- true + close(w.dead) + return default: glfw.WaitEventsTimeout(1.0 / 30) @@ -273,28 +289,34 @@ func (w *Win) eventThread() { } func (w *Win) openGLThread() { + w.threads.Add(1) + defer w.threads.Done() + w.w.MakeContextCurrent() gl.Init() - w.openGLFlush(w.img.Bounds()) + w.openGLFlush(w.img.Get().Bounds()) loop: for { var totalR image.Rectangle select { - case r := <-w.newSize: - img := image.NewRGBA(r) - draw.Draw(img, w.img.Bounds(), w.img, w.img.Bounds().Min, draw.Src) - w.img = img + case r, ok := <-w.newSize: + if !ok { + return + } + newImg := image.NewRGBA(r) + oldImg := w.img.Get() + draw.Draw(newImg, oldImg.Bounds(), oldImg, oldImg.Bounds().Min, draw.Src) + w.img.Set <- newImg totalR = totalR.Union(r) case d, ok := <-w.draw: if !ok { - close(w.finish) return } - r := d(w.img) + r := d(w.img.Get()) totalR = totalR.Union(r) } @@ -305,18 +327,21 @@ loop: totalR = image.ZR continue loop - case r := <-w.newSize: - img := image.NewRGBA(r) - draw.Draw(img, w.img.Bounds(), w.img, w.img.Bounds().Min, draw.Src) - w.img = img + case r, ok := <-w.newSize: + if !ok { + return + } + newImg := image.NewRGBA(r) + oldImg := w.img.Get() + draw.Draw(newImg, oldImg.Bounds(), oldImg, oldImg.Bounds().Min, draw.Src) + w.img.Set <- newImg totalR = totalR.Union(r) case d, ok := <-w.draw: if !ok { - close(w.finish) return } - r := d(w.img) + r := d(w.img.Get()) totalR = totalR.Union(r) } } @@ -324,14 +349,14 @@ loop: } func (w *Win) openGLFlush(r image.Rectangle) { - bounds := w.img.Bounds() + bounds := w.img.Get().Bounds() r = r.Intersect(bounds) if r.Empty() { return } tmp := image.NewRGBA(r) - draw.Draw(tmp, r, w.img, r.Min, draw.Src) + draw.Draw(tmp, r, w.img.Get(), r.Min, draw.Src) gl.DrawBuffer(gl.FRONT) gl.Viewport( |