Comment puis-je transférer la saisie au clavier de GLFW vers un autre objet?

9

J'ai du mal à essayer d'exécuter des événements de clavier dans une autre classe avec GLFW3. Le problème que j'ai est que GLFW3 utilise une fonction statique pour l'entrée comme indiqué:

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

uest également statique et contrôle détient l'entrée pour les clés WSAD (la seule façon d'obtenir des événements de clé). À partir de là, appuyer sur une touche permet d'afficher quelle touche est enfoncée dans la fenêtre de la console. Le problème que j'ai est d'essayer d'utiliser la touche enfoncée pour manipuler une variable dans une autre classe.

J'ai une autre classe appelée MainMenu qui a la fonction update().Existe-t-il un moyen d'utiliser ma classe d'interface utilisateur dans cette fonction?

ChocoMan
la source

Réponses:

16

Vous adoptez la mauvaise approche avec une classe d'interface utilisateur statique. La façon habituelle de "rebondir" d'un rappel statique vers une fonction d'instance est de stocker quelque chose capable de faire le saut dans un endroit accessible à partir du rappel statique.

La plupart des API, comme GLFW et Win32 natif, qui nécessitent ces types de rappels statiques fournissent un moyen de faire l'association ci-dessus. Les fenêtres GLFW ont un bloc de stockage de la taille d'un pointeur que vous pouvez affecter à: le pointeur utilisateur . Vous pouvez obtenir ou définir ce pointeur utilisateur selon vos besoins.

Un modèle très courant consiste à avoir une sorte de Gameclasse qui a des méthodes comme "HandleKeyPress (Key key)" ou autre chose. Lorsque vous programmez démarre, vous créez l' Gameobjet et faites toute votre initialisation GLFW, puis placez le Gamepointeur dans le stockage de données utilisateur:

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

  glfwSetWindowUserPointer(window, &game);

  ... main game loop ...
}

Ensuite, votre rappel clavier (et tous les autres rappels statiques) peuvent décompresser le Game *stockage du pointeur utilisateur et le transmettre:

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

La HandleKeyDownméthode sur l' Gameinstance peut être transmise à votre objet d'interface utilisateur si nécessaire (ou, si vous n'avez vraiment besoin que d' une entrée au clavier pour l'objet d'interface utilisateur, vous pouvez simplement remplir un pointeur vers votre objet d'interface utilisateur dans le stockage utilisateur, cependant, en remplissant quelque chose comme le jeu ou quelque chose de niveau supérieur est généralement meilleur car vous n'avez qu'un seul pointeur par fenêtre à utiliser).


la source
0

La façon dont je me suis débrouillé pour l'instant était d'utiliser un objet singleton, lorsque j'avais besoin d'accéder à la classe, je pouvais simplement récupérer le pointeur sur le 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)
}

Quelque chose comme ça.

user1777995
la source