Jak mogę przekazać dane wejściowe klawiatury GLFW do innego obiektu?

9

Mam problem z wykonaniem zdarzeń klawiatury w innej klasie za pomocą GLFW3. Problemem jest to, że GLFW3 używa funkcji statycznej do wprowadzania danych, jak pokazano:

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

ujest również statyczny, a formanty przechowują dane wejściowe dla kluczy WSAD (jedyny sposób, w jaki mogłem uzyskać kluczowe zdarzenia). Stąd, naciśnięcie klawisza działa, wyświetlając, który klawisz został naciśnięty w oknie konsoli. Problem, jaki mam, polega na tym, że próbuję użyć wciśniętego klawisza do manipulowania zmienną w innej klasie.

Mam inną klasę o nazwie MainMenu, która ma funkcję update().Czy istnieje sposób, w jaki mogę korzystać z mojej klasy interfejsu użytkownika w ramach tej funkcji?

ChocoMan
źródło

Odpowiedzi:

16

Podchodzisz niewłaściwie do statycznej klasy interfejsu użytkownika. Zwykłym sposobem „odbicia” od statycznego wywołania zwrotnego do funkcji instancji jest przechowanie czegoś zdolnego do wykonania skoku w miejscu, które jest dostępne od statycznego wywołania zwrotnego.

Większość interfejsów API, takich jak GLFW i natywny Win32, które wymagają tego rodzaju statycznych wywołań zwrotnych, umożliwia utworzenie powyższego powiązania. Okna GLFW mają blok pamięci wielkości wskaźnika, do którego można przypisać: wskaźnik użytkownika . Możesz pobrać lub ustawić ten wskaźnik użytkownika w razie potrzeby.

Bardzo częstym wzorcem jest posiadanie jakiejś Gameklasy, która ma metody takie jak „HandleKeyPress (klawisz klucza)” lub coś w tym stylu. Po uruchomieniu programu tworzysz Gameobiekt i wykonujesz całą inicjalizację GLFW, a następnie umieszczasz Gamewskaźnik w pamięci danych użytkownika:

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

  glfwSetWindowUserPointer(window, &game);

  ... main game loop ...
}

Następnie oddzwanianie klawiatury (i wszystkie inne statyczne oddzwaniania) może rozpakować Game *pamięć podręczną użytkownika i przesłać do niej:

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

HandleKeyDownSposób na Gameprzykład można przekazać wzdłuż do obiektu UI w razie potrzeby (lub, jeśli naprawdę tylko potrzebne wprowadzanie danych z klawiatury dla obiektu UI można po prostu rzeczy wskaźnik do obiektu UI w pamięci użytkownika, jednak farsz coś jak gra lub coś wyższego poziomu jest ogólnie lepsze, ponieważ masz tylko jeden wskaźnik na okno do użycia).


źródło
0

Sposób, w jaki na to poradziłem, to używanie obiektu singleton, kiedy potrzebowałem dostępu do klasy, mogłem po prostu pobrać wskaźnik do singletonu:

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)
}

Coś w tym rodzaju.

użytkownik1777995
źródło