Mic*_*ell 4 c++ static-methods global-variables callback glfw
我在我的C++应用程序中使用GLFW作为窗口,我正在尝试使用GLFW的回调来获取输入事件.例如,这是您获取关键事件的方式:
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods){
// Do something with event data.
}
int main(){
// initialize window (I have no problems with this step)
glfwSetKeyCallback(window, key_callback);
// Now when a key is pressed in the window it will call this function.
}
Run Code Online (Sandbox Code Playgroud)
问题:
在我的key_callback我想要使用在key_callback函数外声明的变量,因为我不能改变参数,key_callback我无法传递对变量的引用.
现在,在上面给出的例子中,我可以简单地宣布我的变量外int main()无一不key_callback和int main()将有机会获得该变量的同一个实例.
我想要的用途:
我希望有一个WindowWrapper创建和管理生命周期的类glfwWindow,这将包括设置事件回调.
WindowWrapper.h
// Includes
class WindowWrapper{
private:
Centrum* g_centrum_;
GLFWwindow* window_;
std::thread thread_;
public:
WindowWrapper();
WindowWrapper(Centrum* g_centrum);
~WindowWrapper();
private:
// Callbacks
static void key_callback(
GLFWwindow* window, int key, int scancode, int action, int mods
);
};
Run Code Online (Sandbox Code Playgroud)
WindowWrapper.cpp
WindowWrapper::WindowWrapper(Centrum* g_centrum){
g_centrum_ = g_centrum;
// Initialize window
glfwSetKeyCallback(window_, key_callback); // Problems
// Window loop and OpenGL stuff
}
WindowWrapper::~WindowWrapper(){
thread_.join(); // Don't worry about this, it works but, I will make it safer.
glfwDestroyWindow(window_);
printf("WindowWrapper Completely Destructed!\n"); // For testing purposes
}
void WindowWrapper::key_callback(
GLFWwindow* window, int key, int scancode, int action, int mods
){
// This function is declared static in the class declaration.
// And as a result I cannot use g_centrum_ since it is a non-static variable
// Essentially I want to be able to access g_centrum_ from this function
g_centrum_->input_eventmanager_->key_eventmanager_->
TriggerKeyEvent(key, action, mods);
}
Run Code Online (Sandbox Code Playgroud)
我认为这样做的第一种方法是传递一个引用g_centrum,但GLFW不会对回调的参数产生任何偏差.
我的第二次尝试是在构造函数中声明和定义回调,但你不能这样做.
我的第三个尝试是使g_centrum_静态,但我必须在构造函数之外给它引用,我不认为这是一个优雅的解决方案.
用于glfwSetWindowUserPointer()在注册回调之前将包装器指针关联到窗口.调用回调时,您可以使用glfwGetWindowUserPointer()它来检索它.GLFW文档中描述了这些API .
窗口用户指针
每个窗口具有可与设置用户指针glfwSetWindowUserPointer并取出与glfwGetWindowUserPointer.这可以用于您需要的任何目的,并且在窗口的整个生命周期内不会被GLFW修改.
例如,您可以在WindowWrapper构造函数中执行此操作:
WindowWrapper::WindowWrapper(Centrum* g_centrum){
g_centrum_ = g_centrum;
// Initialize window first
...
// Now, associate the wrapper to the window
glfwSetWindowUserPointer(window_, this);
glfwSetKeyCallback(window_, key_callback); // Problems
// Window loop and OpenGL stuff
}
Run Code Online (Sandbox Code Playgroud)
然后,在你的回调中:
void WindowWrapper::key_callback(
GLFWwindow* window, int key, int scancode, int action, int mods
){
void *data = glfwGetWindowUserPointer(window);
WindowWrapper *w = static_cast<WindowWrapper *>(data);
w->g_centrum_->input_eventmanager_->key_eventmanager_->
TriggerKeyEvent(key, action, mods);
}
Run Code Online (Sandbox Code Playgroud)