diff --git a/image.go b/image.go index a13931fa9..6022d507f 100644 --- a/image.go +++ b/image.go @@ -98,15 +98,11 @@ func (t *textureQuads) Texture(i int) (u0, v0, u1, v1 float32) { return u(float64(src.Min.X), w), v(float64(src.Min.Y), h), u(float64(src.Max.X), w), v(float64(src.Max.Y), h) } -type syncer interface { - Sync(func()) -} - // Image represents an image. // The pixel format is alpha-premultiplied. // Image implements image.Image. type Image struct { - syncer syncer + ui *ui inner *innerImage pixels []uint8 } @@ -119,8 +115,8 @@ func (i *Image) Size() (width, height int) { // Clear resets the pixels of the image into 0. func (i *Image) Clear() (err error) { i.pixels = nil - i.syncer.Sync(func() { - err = i.inner.Clear(currentUI.glContext) + i.ui.use(func() { + err = i.inner.Clear(i.ui.glContext) }) return } @@ -128,8 +124,8 @@ func (i *Image) Clear() (err error) { // Fill fills the image with a solid color. func (i *Image) Fill(clr color.Color) (err error) { i.pixels = nil - i.syncer.Sync(func() { - err = i.inner.Fill(currentUI.glContext, clr) + i.ui.use(func() { + err = i.inner.Fill(i.ui.glContext, clr) }) return } @@ -151,8 +147,8 @@ func (i *Image) DrawImage(image *Image, options *DrawImageOptions) (err error) { func (i *Image) drawImage(image *innerImage, option *DrawImageOptions) (err error) { i.pixels = nil - i.syncer.Sync(func() { - err = i.inner.drawImage(currentUI.glContext, image, option) + i.ui.use(func() { + err = i.inner.drawImage(i.ui.glContext, image, option) }) return } @@ -173,9 +169,9 @@ func (i *Image) ColorModel() color.Model { // This method loads pixels from GPU to VRAM if necessary. func (i *Image) At(x, y int) color.Color { if i.pixels == nil { - i.syncer.Sync(func() { + i.ui.use(func() { var err error - i.pixels, err = i.inner.texture.Pixels(currentUI.glContext) + i.pixels, err = i.inner.texture.Pixels(i.ui.glContext) if err != nil { panic(err) } diff --git a/run.go b/run.go index 44fe236a8..c3e20d2a1 100644 --- a/run.go +++ b/run.go @@ -28,18 +28,12 @@ import ( // but this is not strictly guaranteed. // If you need to care about time, you need to check current time every time f is called. func Run(f func(*Image) error, width, height, scale int, title string) error { - err := startUI(width, height, scale, title) + ui, err := startUI(width, height, scale, title) if err != nil { return err } - ui := currentUI defer ui.terminate() - currentUI = ui - defer func() { - currentUI = nil - }() - for { // To avoid busy loop when the window is inactive, wait 1/120 [sec] at least. ch := time.After(1 * time.Second / 120) diff --git a/ui.go b/ui.go index 86974f0ab..472287d61 100644 --- a/ui.go +++ b/ui.go @@ -42,15 +42,16 @@ func init() { panic(err) } - currentUI = &ui{ + u := &ui{ window: window, funcs: make(chan func()), } - currentUI.run() - currentUI.use(func() { - currentUI.glContext = opengl.NewContext() + u.run() + u.use(func() { + u.glContext = opengl.NewContext() glfw.SwapInterval(1) }) + currentUI = u } type ui struct { @@ -62,20 +63,21 @@ type ui struct { funcs chan func() } -func startUI(width, height, scale int, title string) error { +func startUI(width, height, scale int, title string) (*ui, error) { monitor, err := glfw.GetPrimaryMonitor() if err != nil { - return err + return nil, err } videoMode, err := monitor.GetVideoMode() if err != nil { - return err + return nil, err } x := (videoMode.Width - width*scale) / 2 y := (videoMode.Height - height*scale) / 3 ch := make(chan struct{}) - window := currentUI.window + ui := currentUI + window := ui.window window.SetFramebufferSizeCallback(func(w *glfw.Window, width, height int) { close(ch) }) @@ -97,7 +99,6 @@ func startUI(width, height, scale int, title string) error { } } - ui := currentUI ui.scale = scale // For retina displays, recalculate the scale with the framebuffer size. @@ -106,7 +107,7 @@ func startUI(width, height, scale int, title string) error { ui.use(func() { ui.graphicsContext, err = newGraphicsContext(ui.glContext, width, height, realScale) }) - return err + return ui, err } func (u *ui) doEvents() { @@ -122,10 +123,6 @@ func (u *ui) isClosed() bool { return u.window.ShouldClose() } -func (u *ui) Sync(f func()) { - u.use(f) -} - func (u *ui) draw(f func(*Image) error) (err error) { u.use(func() { err = u.graphicsContext.preUpdate() @@ -133,7 +130,7 @@ func (u *ui) draw(f func(*Image) error) (err error) { if err != nil { return } - err = f(&Image{syncer: u, inner: u.graphicsContext.screen}) + err = f(&Image{ui: u, inner: u.graphicsContext.screen}) if err != nil { return } @@ -161,7 +158,7 @@ func (u *ui) newImageFromImage(img image.Image, filter Filter) (*Image, error) { if err != nil { return nil, err } - return &Image{syncer: u, inner: innerImage}, nil + return &Image{ui: u, inner: innerImage}, nil } func (u *ui) newImage(width, height int, filter Filter) (*Image, error) { @@ -179,7 +176,7 @@ func (u *ui) newImage(width, height int, filter Filter) (*Image, error) { if err != nil { return nil, err } - return &Image{syncer: u, inner: innerImage}, nil + return &Image{ui: u, inner: innerImage}, nil } func (u *ui) run() {