Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add callback functionality for input events #293

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions pixelgl/input.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,46 @@ func (w *Window) Typed() string {
return w.currInp.typed
}

// Register button callback
func (w *Window) RegisterButtonCallback(cbfun ButtonCallback) {
w.callbacks.buttonCallbacks = append(w.callbacks.buttonCallbacks, cbfun)
}

// Register cursor enter callback
func (w *Window) RegisterCursorEnterCallback(cbfun CursorEnterCallback) {
w.callbacks.cursorEnterCallbacks = append(w.callbacks.cursorEnterCallbacks, cbfun)
}

// Register cursor pos callback
func (w *Window) RegisterCursorPosCallback(cbfun CursorPosCallback) {
w.callbacks.cursorPosCallbacks = append(w.callbacks.cursorPosCallbacks, cbfun)
}

// Register scroll callback
func (w *Window) RegisterScrollCallback(cbfun ScrollCallback) {
w.callbacks.scrollCallbacks = append(w.callbacks.scrollCallbacks, cbfun)
}

// Register char callback
func (w *Window) RegisterCharCallback(cbfun CharCallback) {
w.callbacks.charCallbacks = append(w.callbacks.charCallbacks, cbfun)
}

type ButtonCallback func(key Button, action ButtonAction)
type CursorEnterCallback func()
type CursorPosCallback func(x, y float64)
type ScrollCallback func(xoff, yoff float64)
type CharCallback func(r rune)

type ButtonAction int

// List of all button actions.
const (
Press = ButtonAction(glfw.Press)
Release = ButtonAction(glfw.Release)
Repeat = ButtonAction(glfw.Repeat)
)

// Button is a keyboard or mouse button. Why distinguish?
type Button int

Expand Down Expand Up @@ -368,6 +408,10 @@ func (w *Window) initInput() {
w.tempReleaseEvents[Button(button)] = true
w.tempInp.buttons[Button(button)] = false
}

for _, cbfun := range w.callbacks.buttonCallbacks {
go cbfun(Button(button), ButtonAction(action))
}
})

w.window.SetKeyCallback(func(_ *glfw.Window, key glfw.Key, scancode int, action glfw.Action, mods glfw.ModifierKey) {
Expand All @@ -384,26 +428,45 @@ func (w *Window) initInput() {
case glfw.Repeat:
w.tempInp.repeat[Button(key)] = true
}

for _, cbfun := range w.callbacks.buttonCallbacks {
go cbfun(Button(key), ButtonAction(action))
}
})

w.window.SetCursorEnterCallback(func(_ *glfw.Window, entered bool) {
w.cursorInsideWindow = entered

for _, cbfun := range w.callbacks.cursorEnterCallbacks {
go cbfun()
}
})

w.window.SetCursorPosCallback(func(_ *glfw.Window, x, y float64) {
w.tempInp.mouse = pixel.V(
x+w.bounds.Min.X,
(w.bounds.H()-y)+w.bounds.Min.Y,
)

for _, cbfun := range w.callbacks.cursorPosCallbacks {
go cbfun(x, y)
}
})

w.window.SetScrollCallback(func(_ *glfw.Window, xoff, yoff float64) {
w.tempInp.scroll.X += xoff
w.tempInp.scroll.Y += yoff

for _, cbfun := range w.callbacks.scrollCallbacks {
go cbfun(xoff, yoff)
}
})

w.window.SetCharCallback(func(_ *glfw.Window, r rune) {
w.tempInp.typed += string(r)
for _, cbfun := range w.callbacks.charCallbacks {
go cbfun(r)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a reason you are doing this asynchronously with go instead of calling them sequentially? I feel like this could be an issue if callbacks overlap with each other. Not sure if that's a valid fear or not however. Would like to hearinput from you and @dusk125 on this...

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Say you register multiple callbacks for an event. Calling the callbacks asynchronously was done as to not keep one callback waiting for the previous one to finish. However, I see the reason for calling them sequentially, so that might be something that we could change.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps maybe a waitgroup then?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My preference would be to call them sequentially, and leave it to the handler to do what it needs to async. Especially handling typing, things could get out of order which would be annoying.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe have async as a bool option somehow?

}
})
})
}
Expand Down
8 changes: 8 additions & 0 deletions pixelgl/window.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,14 @@ type Window struct {
xpos, ypos, width, height int
}

callbacks struct {
buttonCallbacks []ButtonCallback
cursorEnterCallbacks []CursorEnterCallback
cursorPosCallbacks []CursorPosCallback
scrollCallbacks []ScrollCallback
charCallbacks []CharCallback
}

prevInp, currInp, tempInp struct {
mouse pixel.Vec
buttons [KeyLast + 1]bool
Expand Down