How to glfwSetKeyCallback for different classes?

I use GLFW , and I have different classes representing different states in my application and one state management class. I want to use GLFW to get the key input and pass it to the current state (therefore to another class).

The only way I could think of is to give each class its own keycallback function and use glfwSetKeyCallback (window, keyCallback);

keycallback(GLFWwindow *window, int key, int scancode, int action, int mods)

This did not work.

cannot convert 'IntroState::handleKeyEvent' from type 'void (IntroState::)(GLFWwindow*, int, int, int, int)' to type 'GLFWkeyfun {aka void (*)(GLFWwindow*, int, int, int, int)}'
     glfwSetKeyCallback(m_manager->window, handleKeyEvent);

People recommended something like this:

void GLFWCALL functionname( int key, int action );

But the GLFWCALL macro has been removed from GLFW ( Official Note ).


I read that you can use a static function.

static void keyCallback(GLFWwindow*, int, int, int);

- , .


:

"" - - GLFW?

states.back()->handlekeyEvent(int, int, int);
+3
3

, . , . , , .

, . :

keycallback(GLFWwindow *window, int key, int scancode, int action, int mods);

-, , . void,

void GLFWCALL keycallback(
    GLFWwindow *window,
    int key,
    int scancode,
    int action,
    int mods);

GLFWCALL - , . , , . , ,

class FooState
{
    void GLFWCALL keycallback(
        GLFWwindow *window,
        int key,
        int scancode,
        int action,
        int mods);  
};

? , ,

void GLFWCALL FooState::keycallback(
    GLFWwindow *window,
    int key,
    int scancode,
    int action,
    int mods);  

FooState::. . . ( ), ( ++) . this. , C- ( ), GLFW C,

void GLFWCALL keycallback(
    FooState *this,
    GLFWwindow *window,
    int key,
    int scancode,
    int action,
    int mods);  

, GLFW. - , . ? , , .

. static , , , ( C ).

,

// statebase.h
class StateBase
{
    virtual void keycallback(
        GLFWwindow *window,
        int key,
        int scancode,
        int action,
        int mods) = 0; /* purely abstract function */

    static StateBase *event_handling_instance;
    // technically setEventHandling should be finalized so that it doesn't
    // get overwritten by a descendant class.
    virtual void setEventHandling() { event_handling_instance = this; }

    static void GLFWCALL keycallback_dispatch(
        GLFWwindow *window,
        int key,
        int scancode,
        int action,
        int mods)
    {
        if(event_handling_instance)
            event_handling_instance->keycallback(window,key,scancode,action,mods);
    }    
};

// statebase.cpp
#include "statebase.h"
// funny thing that you have to omit `static` here. Learn about global scope
// type qualifiers to understand why.
StateBase * StateBase::event_handling_instance;

- : , StateBase, event_handling_instance , .

, FooState StateBase ( GLFWCALL)

class FooState : BaseState
{
    virtual void keycallback(
        GLFWwindow *window,
        int key,
        int scancode,
        int action,
        int mods);  
};
void FooState::keycallback(
    GLFWwindow *window,
    int key,
    int scancode,
    int action,
    int mods)
{
    /* ... */
}

GLFW,

glfwSetKeyCallback(window, StateBase::keycallback_dispatcher);

, void StateBase::setEventHandling().

FooState state;
state.setEventHandling();

:

++ , . - , , , ++, .

: , , . structs - ( ), . , , , .

+10

, , closure ( ). C, ++ ( this).

, void *, , . void * , , -, .

, GLFWCALL . , . - ++, , / DLL.

+4

GLFW; , . ( .)

0

All Articles