简体   繁体   中英

Set member function pointer to free function pointer

I am working on a simple engine coded in c++ and wrapped with ctypes. I'm working on window class and I want to give the engine user ability to set draw and update functions. I have the following code:

window.h

#pragma once
#include <GL/glew.h>
#include <GLFW/glfw3.h>
class window
{
public:
    GLFWwindow* wnd;

    window(int width, int height, const char* title);
    void close();

    void update();
    void (window::*draw)();

    void setDrawFunction(void (window::*)());
    void setUpdateFunction(int*);
};

window.cpp

#include <GL/glew.h>
#include <GLFW/glfw3.h>

#include "window.h"

void default_draw() {
    glClear(GL_COLOR_BUFFER_BIT);
}

void default_update() {
    
}

window::window(int width, int height, const char* title)
{
    glfwWindowHint(GLFW_SAMPLES, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_COMPAT_PROFILE, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    wnd = glfwCreateWindow(width, height, title, NULL, NULL);

    if (wnd == NULL) { glfwTerminate(); return; }

    glfwMakeContextCurrent(wnd);

    if (glewInit() != GLEW_OK) {
        glfwTerminate();
        return;
    }

    setDrawFunction((void)(window::*)()default_draw);
}

void window::close() {
    glfwDestroyWindow(this->wnd);
}

void window::update() {
    default_update();
}

void window::setDrawFunction(void (window::*fnptr)()) {
    draw = fnptr;
}

This doesn't work. Am I missing something obvious or it's just impossible to accomplish this way. If so, is there any way I could achieve this? All I need is to be able to overdrive function, so I can do this in python, using ctypes.

Errors i get: 109 expression before calling must have a function (pointer) type 29 expression expected 18 expected ")"

Use of a member function pointer of window as a member variable is not appropriate.

I can think of the following options to address the issue.

Option 1

Make draw a non-member function pointer.

void (*draw)();

void setDrawFunction(void (*func)());

Option 2

Make draw a std::function

std::function<void()> draw;

void setDrawFunction(std::function<void()> func);

Option 3

Use a separater class/interface for drawing.

std::unique_ptr<DrawingAgent> draw;

void setDrawingAgent(std::unique_ptr<DrawingAgent> agent);

where

class DrawingAgent
{
   public:
      virtual void draw(window*); // Draw in given window.
};

Of the above options, I would recommend using Option 3 . It cleanly separates the window aspect of your application from the drawing functionality.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM