Jojodmo
Jojodmo

Reputation: 23616

Dispatch from GLFW's main thread using LWJGL

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

Answers (1)

A Sammich
A Sammich

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

Related Questions