9
\$\begingroup\$

I'm having trouble trying to execute keyboard events in a another class with GLFW3. The problem I'm having is that GLFW3 uses a static function for input as shown:

static UI u;
...
...
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    u.controls(window, key, action);
}

u is also static and controls holds the the input for WSAD keys (the only way I could get get key events). From here, pressing a key works displaying which key is pressed in the console window. The trouble I'm having is trying to used the key pressed to manipulate a variable in another class.

I have another class called MainMenu that has the function update(). Is there a way I can use my UI class within this function?

\$\endgroup\$

2 Answers 2

17
\$\begingroup\$

You're taking the wrong approach with a static UI class. The usual way to "bounce" from a static callback to an instance function is to store something capable of making the jump in a place that is accessible from the static callback.

Most APIs, like GLFW and native Win32, that require these sorts of static callbacks provide a way to make the association above. GLFW windows have a pointer-sized block of storage that you can assign to: the user pointer. You can get or set this user pointer as needed.

A very common pattern is to have some kind of Game class that has methods like "HandleKeyPress(Key key)" or whatnot. When you program starts, you create the Game object and do all your GLFW initialization, then stuff the Game pointer into the user data storage:

int main () {
  GLFWindow * window = ... create GLFW window ...
  Game game(... game constructor parameters ...);

  glfwSetWindowUserPointer(window, &game);

  ... main game loop ...
}

Then, your keyboard callback (and all other static callbacks) can unpack the Game * from user pointer storage and forward to it:

static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
  Game * game = reinterpret_cast<Game *>(glfwGetWindowUserPointer(window);
  game->HandleKeyDown(...);
}

The HandleKeyDown method on the Game instance can forward along to your UI object if needed (or, if you really only need keyboard input for the UI object you could just stuff a pointer to your UI object in the user storage, however, stuffing something like the game or something higher-level is generally better since you only have one pointer per window to use).

\$\endgroup\$
0
\$\begingroup\$

The way I got around that for now was in using a singleton object, when I needed to access the class I could just retrieve the pointer to the singleton:

void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    InputManager * in_manager = InputManager::get_instance();
    in_manager->handle_key_press( params)
}

Somehting like that.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .