Як я можу переслати вкладку клавіатури 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().Чи є спосіб я використовувати свій клас інтерфейсу в межах цієї функції?

Відповіді:


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

Те, як я зараз обійшов це у використанні об'єкта 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)
}

Щось таке.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.