Как я могу переслать ввод с клавиатуры GLFW другому объекту?

9

У меня возникают проблемы при попытке выполнить события клавиатуры в другом классе с GLFW3. У меня проблема в том, что GLFW3 использует статическую функцию для ввода, как показано:

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

uтакже является статическим, и элементы управления содержат входные данные для ключей WSAD (единственный способ получить события ключей). Отсюда нажатие клавиши работает, показывая, какая клавиша нажата в окне консоли. Проблема в том, что я пытаюсь использовать нажатую клавишу для управления переменной в другом классе.

У меня есть другой класс с именем MainMenu, у которого есть функция. update().Есть ли способ, которым я могу использовать свой класс пользовательского интерфейса в этой функции?

ChocoMan
источник

Ответы:

16

Вы используете неправильный подход со статическим классом пользовательского интерфейса. Обычный способ «отскочить» от статического обратного вызова к функции экземпляра - сохранить что-то, способное сделать переход, в месте, доступном из статического обратного вызова.

Большинство API, таких как GLFW и родной Win32, для которых требуются статические обратные вызовы такого рода, предоставляют способ для установления связи выше. В окнах GLFW есть блок памяти размером с указатель, который вы можете назначить: пользовательский указатель . Вы можете получить или установить этот указатель пользователя по мере необходимости.

Очень распространенный шаблон - иметь некоторый Gameкласс, который имеет методы типа «HandleKeyPress (Key key)» или еще много чего. Когда вы запускаете программу, вы создаете Gameобъект и выполняете всю инициализацию GLFW, а затем Gameвставляете указатель в хранилище пользовательских данных:

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

  glfwSetWindowUserPointer(window, &game);

  ... main game loop ...
}

Затем ваш обратный вызов с клавиатуры (и все другие статические обратные вызовы) может распаковать объект Game *из хранилища указателя пользователя и переслать его:

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

HandleKeyDownМетод по Gameпримеру может переслать по вашему объекту пользовательского интерфейса , если это необходимо (или, если вы действительно только нужен ввод с клавиатурой для объекта UI можно просто засунуть указатель на объект пользовательского интерфейса в хранилище пользователя, однако, набивать что - то вроде игры или что-то более высокого уровня, как правило, лучше, так как у вас есть только один указатель на окно для использования).


источник
0

То, как я обошел это сейчас, заключалось в использовании одноэлементного объекта, когда мне нужно было получить доступ к классу, я мог просто получить указатель на одноэлементный объект:

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

Нечто подобное.

user1777995
источник