我正在尝试设置一个“事件接收器”类,以将GLFW回调包装为用户可以继承的类,但是在将基类成员函数传递给GLFW“设置回调”函数时遇到了问题。
#include <GLFW/glfw3.h>
//
//
// Event Receiver Framework
enum EventTypes {
Keyboard = 1,
Mouse = 2
};
struct Event {
EventTypes Action;
// Other Event Related Values
};
class EventReceiver {
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
Event NewEvent;
NewEvent.Action = EventTypes::Keyboard;
OnEvent(NewEvent);
}
public:
virtual void OnEvent(Event& NewEvent) = 0;
};
//
//
// Application Framework
class MyApplication {
GLFWwindow* window;
public:
void SetEventReceiver(EventReceiver* EventHandler) {
glfwSetKeyCallback(window, &EventHandler->key_callback);
}
};
//
//
// User-Defined Event Receiver
class MyEventReceiver : public EventReceiver {
public:
void OnEvent(Event& NewEvent) {
if (NewEvent.Action == EventTypes::Keyboard) {
// Custom Event Actions
}
else if (NewEvent.Action == EventTypes::Mouse) {
// Custom Event Actions
}
}
};
//
//
// Main
int main() {
MyEventReceiver _Events;
MyApplication _App;
_App.SetEventReceiver(&_Events);
//
// Do logic
//
return 0;
}
这从根本上为基类提供了纯虚拟函数,供用户从事件中继承和重写以提供事件发生时自己的逻辑。用户定义的子类旨在传递给更大的“应用程序框架”类,该类进行必要的调用以设置GLFW回调函数。
当然,您不能将成员函数作为期望c-style-function的函数参数传递,因为您必须提供对类实例的访问权限,换句话说,必须提供类实例,以便调用成员函数知道将哪个对象用作“ this指针”。
对于GLFW中的'glfwSet * Callback'函数,我不确定该怎么做。
答案 0 :(得分:0)
在GLFW中只能像这样使用静态成员函数,如果需要,可以使用glfwGetWindowUserPointer和glfwSetWindowUserPointer在这些情况下提供对基础类对象的访问。
#include <GLFW/glfw3.h>
//
//
// Event Receiver Framework
enum EventTypes {
Keyboard = 1,
Mouse = 2
};
struct Event {
EventTypes Action;
// Other Event Related Values
};
class EventReceiver {
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
Event NewEvent;
NewEvent.Action = EventTypes::Keyboard;
static_cast<EventReceiver*>(glfwGetWindowUserPointer(window))->OnEvent(NewEvent);
}
public:
virtual void OnEvent(Event& NewEvent) = 0;
friend class MyApplication;
};
//
//
// Application Framework
class MyApplication {
GLFWwindow* window;
public:
void SetEventReceiver(EventReceiver* EventHandler) {
glfwSetWindowUserPointer(window, EventHandler);
glfwSetKeyCallback(window, &EventReceiver::key_callback);
}
};
//
//
// User-Defined Event Receiver
class MyEventReceiver : public EventReceiver {
public:
void OnEvent(Event& NewEvent) {
if (NewEvent.Action == EventTypes::Keyboard) {
// Custom Event Actions
}
else if (NewEvent.Action == EventTypes::Mouse) {
// Custom Event Actions
}
}
};
//
//
// Main
int main() {
MyEventReceiver _Events;
MyApplication _App;
_App.SetEventReceiver(&_Events);
//
// Do logic
//
return 0;
}