Reputation: 23616
I am trying to call GLFW.glfwPollEvents()
in an asynchronous task that runs every tick (1/30th of a second in this case). This ticking timer effectively controls when every action in the app takes place.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask(){
@Override
public void run(){
//... more code ...
GLFW.glfwPollEvents();
//... more code ...
}
}, 33, 33);
But, this does not work because
This function may only be called from the main thread.
(from the documentation)
How can I call this on the main thread? When it isn't run on the main thread, the application crashes. I'm looking for something like
GLFW.dispatchMainThread(new GLFWRunnable(){
public void run(){
//...
}
});
This is possible to do in swing
and awt
by using
EventQueue.invokeLater(new Runnable(){
public void run(){
//...
}
});
But the same code doesn't work for GLFW
.
How can I run a task on GLFW
's main thread using LWJGL without using a while(true)
loop on the main thread?
Upvotes: 2
Views: 629
Reputation: 386
Since GLFW's main thread must be the same as the application's main thread (a limitation in GLFW; that's where it puts the OS message queue that is handled differently by swing/awt it seems - see my answer here) I would do things the other way around.
My main thread would have the forever loop (probably using glfwWaitEvents so as not to eat CPU time needlessly). I would then post any events that were app-specific to another thread that does the processing. Your message processing is now decoupled from your message receiving.
This way I don't have to wait for 1/30th of a second to get OS messages (it always frustrates me when an app lags opening a menu, registering a click, or arrowing through a list).
Your update thread can even sleep for 1/30th of a second (or less, sleeping again if not enough time has passed or not if a second high-priority queue needs work) and only wake up to check for queued events as an extremely simple scheduling method.
The answer I linked to above has a link to an LWJGL Multithreaded Demo that does something very similar. Their renderLoop would be your updateLoop and would draw from a queue and do processing before going to sleep again instead of updating and presenting graphics.
Upvotes: 2