Ви приймаєте неправильний підхід зі статичним класом інтерфейсу користувача. Звичайний спосіб "відскочити" від статичного зворотного виклику до функції екземпляра - зберігати щось, здатне здійснити стрибок у місці, доступному зі статичного зворотного виклику.
Більшість 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 можна просто засунути покажчик на об'єкт призначеного для користувача інтерфейсу в сховище користувача, однак, набивати що - щось на зразок гри або щось вищого рівня, як правило, краще, оскільки у вас є лише один покажчик на вікно).