diff --git a/gamecontext.go b/gamecontext.go index 7cbdac365..6adaf701b 100644 --- a/gamecontext.go +++ b/gamecontext.go @@ -23,24 +23,24 @@ import ( // IsKeyPressed returns a boolean indicating whether key is pressed. func IsKeyPressed(key Key) bool { - return ui.Current().Input().IsKeyPressed(ui.Key(key)) + return ui.IsKeyPressed(ui.Key(key)) } // CursorPosition returns a position of a mouse cursor. func CursorPosition() (x, y int) { - return ui.Current().Input().CursorPosition() + return ui.CursorPosition() } // IsMouseButtonPressed returns a boolean indicating whether mouseButton is pressed. func IsMouseButtonPressed(mouseButton MouseButton) bool { - return ui.Current().Input().IsMouseButtonPressed(ui.MouseButton(mouseButton)) + return ui.IsMouseButtonPressed(ui.MouseButton(mouseButton)) } // NewImage returns an empty image. func NewImage(width, height int, filter Filter) (*Image, error) { var innerImage *innerImage var err error - ui.Current().Use(func(c *opengl.Context) { + ui.Use(func(c *opengl.Context) { var texture *graphics.Texture texture, err = graphics.NewTexture(c, width, height, glFilter(c, filter)) if err != nil { @@ -52,14 +52,14 @@ func NewImage(width, height int, filter Filter) (*Image, error) { if err != nil { return nil, err } - return &Image{ui: ui.Current(), inner: innerImage}, nil + return &Image{inner: innerImage}, nil } // NewImageFromImage creates a new image with the given image (img). func NewImageFromImage(img image.Image, filter Filter) (*Image, error) { var innerImage *innerImage var err error - ui.Current().Use(func(c *opengl.Context) { + ui.Use(func(c *opengl.Context) { var texture *graphics.Texture texture, err = graphics.NewTextureFromImage(c, img, glFilter(c, filter)) if err != nil { @@ -70,5 +70,5 @@ func NewImageFromImage(img image.Image, filter Filter) (*Image, error) { if err != nil { return nil, err } - return &Image{ui: ui.Current(), inner: innerImage}, nil + return &Image{inner: innerImage}, nil } diff --git a/image.go b/image.go index ba520fc35..ac6086b35 100644 --- a/image.go +++ b/image.go @@ -103,7 +103,6 @@ func (t *textureQuads) Texture(i int) (u0, v0, u1, v1 float32) { // The pixel format is alpha-premultiplied. // Image implements image.Image. type Image struct { - ui *ui.UI inner *innerImage pixels []uint8 } @@ -116,7 +115,7 @@ 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.ui.Use(func(c *opengl.Context) { + ui.Use(func(c *opengl.Context) { err = i.inner.Clear(c) }) return @@ -125,7 +124,7 @@ 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.ui.Use(func(c *opengl.Context) { + ui.Use(func(c *opengl.Context) { err = i.inner.Fill(c, clr) }) return @@ -148,7 +147,7 @@ func (i *Image) DrawImage(image *Image, options *DrawImageOptions) (err error) { func (i *Image) drawImage(image *innerImage, option *DrawImageOptions) (err error) { i.pixels = nil - i.ui.Use(func(c *opengl.Context) { + ui.Use(func(c *opengl.Context) { err = i.inner.drawImage(c, image, option) }) return @@ -170,7 +169,7 @@ 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.ui.Use(func(c *opengl.Context) { + ui.Use(func(c *opengl.Context) { var err error i.pixels, err = i.inner.texture.Pixels(c) if err != nil { diff --git a/internal/ui/input.go b/internal/ui/input.go index ac6a8f7d8..d6bed1550 100644 --- a/internal/ui/input.go +++ b/internal/ui/input.go @@ -39,22 +39,34 @@ const ( MouseButtonMax ) -type Input struct { +func IsKeyPressed(key Key) bool { + return current.input.isKeyPressed(key) +} + +func IsMouseButtonPressed(button MouseButton) bool { + return current.input.isMouseButtonPressed(button) +} + +func CursorPosition() (x, y int) { + return current.input.cursorPosition() +} + +type input struct { keyPressed [KeyMax]bool mouseButtonPressed [MouseButtonMax]bool cursorX int cursorY int } -func (i *Input) IsKeyPressed(key Key) bool { +func (i *input) isKeyPressed(key Key) bool { return i.keyPressed[key] } -func (i *Input) IsMouseButtonPressed(button MouseButton) bool { +func (i *input) isMouseButtonPressed(button MouseButton) bool { return i.mouseButtonPressed[button] } -func (i *Input) CursorPosition() (x, y int) { +func (i *input) cursorPosition() (x, y int) { return i.cursorX, i.cursorY } @@ -66,7 +78,7 @@ var glfwKeyCodeToKey = map[glfw.Key]Key{ glfw.KeyDown: KeyDown, } -func (i *Input) update(window *glfw.Window, scale int) { +func (i *input) update(window *glfw.Window, scale int) { for g, u := range glfwKeyCodeToKey { i.keyPressed[u] = window.GetKey(g) == glfw.Press } diff --git a/internal/ui/ui.go b/internal/ui/ui.go index a497a2a8d..02c84b797 100644 --- a/internal/ui/ui.go +++ b/internal/ui/ui.go @@ -21,10 +21,35 @@ import ( "runtime" ) -var current *UI +var current *ui -func Current() *UI { - return current +func Use(f func(*opengl.Context)) { + ch := make(chan struct{}) + current.funcs <- func() { + defer close(ch) + f(current.glContext) + } + <-ch +} + +func ActualScale() int { + return current.actualScale +} + +func DoEvents() { + current.doEvents() +} + +func Terminate() { + current.terminate() +} + +func IsClosed() bool { + return current.isClosed() +} + +func SwapBuffers() { + current.swapBuffers() } func init() { @@ -44,7 +69,7 @@ func init() { panic(err) } - u := &UI{ + u := &ui{ window: window, funcs: make(chan func()), } @@ -60,23 +85,23 @@ func init() { current = u } -type UI struct { +type ui struct { window *glfw.Window scale int actualScale int glContext *opengl.Context - input Input + input input funcs chan func() } -func New(width, height, scale int, title string) (*UI, error) { +func Start(width, height, scale int, title string) error { monitor, err := glfw.GetPrimaryMonitor() if err != nil { - return nil, err + return err } videoMode, err := monitor.GetVideoMode() if err != nil { - return nil, err + return err } x := (videoMode.Width - width*scale) / 2 y := (videoMode.Height - height*scale) / 3 @@ -111,39 +136,22 @@ func New(width, height, scale int, title string) (*UI, error) { windowWidth, _ := window.GetFramebufferSize() ui.actualScale = windowWidth / width - return ui, err + return err } -func (u *UI) ActualScale() int { - return u.actualScale -} - -func (u *UI) DoEvents() { +func (u *ui) doEvents() { glfw.PollEvents() u.input.update(u.window, u.scale) } -func (u *UI) Terminate() { +func (u *ui) terminate() { glfw.Terminate() } -func (u *UI) IsClosed() bool { +func (u *ui) isClosed() bool { return u.window.ShouldClose() } -func (u *UI) SwapBuffers() { +func (u *ui) swapBuffers() { u.window.SwapBuffers() } - -func (u *UI) Input() *Input { - return &u.input -} - -func (u *UI) Use(f func(*opengl.Context)) { - ch := make(chan struct{}) - u.funcs <- func() { - defer close(ch) - f(u.glContext) - } - <-ch -} diff --git a/run.go b/run.go index 424158f29..f9fceaead 100644 --- a/run.go +++ b/run.go @@ -30,13 +30,13 @@ 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 { - ui, err := ui.New(width, height, scale, title) - if err != nil { + if err := ui.Start(width, height, scale, title); err != nil { return err } defer ui.Terminate() var graphicsContext *graphicsContext + var err error ui.Use(func(c *opengl.Context) { graphicsContext, err = newGraphicsContext(c, width, height, ui.ActualScale()) }) @@ -57,7 +57,7 @@ func Run(f func(*Image) error, width, height, scale int, title string) error { if err != nil { return err } - if err := f(&Image{ui: ui, inner: graphicsContext.screen}); err != nil { + if err := f(&Image{inner: graphicsContext.screen}); err != nil { return err } ui.Use(func(*opengl.Context) {