is it possible to put cbfun's into a class?

Using GLFW
q66680
2014-03-13
2014-03-31
  • q66680
    q66680
    2014-03-13

    hi.i want to put my cbfuns into my class.something like that:

    class scene{

    public:
    virtual void mouse_callback(GLFWwindow*, int, int, int);
    };

    i tried a few case.But no lucky.i always get func signature error something like:

    error: cannot convert ‘void (scene::)(GLFWwindow, int, int, int)’ to ‘GLFWmousebuttonfun {aka void ()(GLFWwindow, int, int, int)}’ for argument ‘2’ to ‘void ( glfwSetMouseButtonCallback(GLFWwindow, GLFWmousebuttonfun))(GLFWwindow*, int, int, int)’

    So i wonder whether it is possible.if so how?

    it might be better to add this signature to all cbfuns. for above e.g:

    void mouse_callback(GLFWwindow, int, int, int,void userdata);

    i think @userdata signature above have many use case and many help to developer.

    Doing so developer can share his data along cbfuns.
    i noticed wayland/weston use this approach for its cbfuns.

    What about you? performance may be affected.

     
    Last edit: q66680 2014-03-13
  • Doug Binks
    Doug Binks
    2014-03-13

    Pointers to C++ member functions can't be used in this way (try searching C++ pointer to member function for more information).

    A typical approach to get around this is a static function and data member, something like:

    class scene{
    public:
    static scene m_Scene;
    static void mouse_callback_static(GLFWwindow* window, int button, int action, int mods)
    {
        m_Scene.mouse_callback(window,button,action,mods);
    }
    virtual void mouse_callback(GLFWwindow* window, int button, int action, int mods);
    };
    

    You can then use mouse_callback_static as the callback function. To have different scene instances for different windows would require some form of mapping between window and scene, for example using std::map or similar.

     
  • Doug Binks
    Doug Binks
    2014-03-31

    To use virtual members, you need to do this by setting a point to the base class with an instance of a derived class. You can do this as follows:

    class scene{
    public:
    static scene* m_pScene;
    static void mouse_callback_static(GLFWwindow* window, int button, int action, int mods)
    {
        m_pScene->mouse_callback(window,button,action,mods);
    }
    virtual void mouse_callback(GLFWwindow* window, int button, int action, int mods);
    };
    
    class myDerivedscene : public scene
    {
        myDerivedscene()
        {
            m_pScene = this;
        }
    };