Como encaminhar a entrada do teclado do GLFW para outro objeto?

9

Estou tendo problemas para tentar executar eventos de teclado em outra classe com o GLFW3. O problema que estou tendo é que o GLFW3 usa uma função estática para entrada, como mostrado:

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

utambém é estático e controla a entrada das chaves WSAD (a única maneira de obter eventos-chave). A partir daqui, pressionar uma tecla funciona exibindo qual tecla foi pressionada na janela do console. O problema que estou tendo é tentar usar a tecla pressionada para manipular uma variável em outra classe.

Eu tenho outra classe chamada MainMenu que possui a função update().Existe uma maneira de usar minha classe de interface do usuário nessa função?

ChocoMan
fonte

Respostas:

16

Você está adotando a abordagem errada com uma classe de interface do usuário estática. A maneira usual de "devolver" de um retorno de chamada estático para uma função de instância é armazenar algo capaz de saltar em um local acessível a partir do retorno de chamada estático.

A maioria das APIs, como GLFW e Win32 nativo, que exigem esses tipos de retornos de chamada estáticos, fornece uma maneira de fazer a associação acima. As janelas do GLFW possuem um bloco de armazenamento do tamanho de um ponteiro ao qual você pode atribuir: o ponteiro do usuário . Você pode obter ou definir esse ponteiro do usuário, conforme necessário.

Um padrão muito comum é ter algum tipo de Gameclasse que possua métodos como "HandleKeyPress (tecla Key)" ou outros enfeites. Ao iniciar o programa, você cria o Gameobjeto e realiza toda a inicialização do GLFW e, em seguida, coloca o Gameponteiro no armazenamento de dados do usuário:

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

  glfwSetWindowUserPointer(window, &game);

  ... main game loop ...
}

Em seguida, o retorno de chamada do teclado (e todos os outros retornos estáticos) pode descompactar o Game *armazenamento do ponteiro do usuário e encaminhar para ele:

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

O HandleKeyDownmétodo na Gameinstância pode encaminhar para o seu objeto de interface do usuário, se necessário (ou, se você realmente precisar apenas de entrada de teclado para o objeto de interface do usuário, basta inserir um ponteiro para o objeto de interface do usuário no armazenamento do usuário, no entanto, colocar algo como o jogo ou algo de nível superior é geralmente melhor, pois você só tem um ponteiro por janela para usar).


fonte
0

A maneira como eu consegui contornar isso por enquanto estava usando um objeto singleton, quando eu precisava acessar a classe, apenas podia recuperar o ponteiro para o 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)
}

Algo assim.

user1777995
fonte