Splitting up processing into chunks - behaviour of Enqueue

I was just thinking that I have some operations that need doing on the GUI thread - but to avoid framerate stalls I’d like to split them up and do a bit of processing each frame. I may not need this as I can probably speed the relevant code up a lot but it did make me wonder:



The question is whether if I enqueue a new callable from within a callable does it get executed that frame on in the following frame?



If its in the following frame then that would make deferring some processing easy as I just call enqueue again. If not then I’d need to “bounce” off to another thread that then calls enqueue again…which while it would work is considerably less efficient and in fact might skip doing processing entirely in some frames depending on how the thread scheduling kicks in…and that would then lead to unstable frame rates.

they are called next frame i think:



From application.java

[java]

/**

  • Enqueues a task/callable object to execute in the jME3
  • rendering thread.
  • <p>
  • Callables are executed right at the beginning of the main loop.
  • They are executed even if the application is currently paused
  • or out of focus.

    */

    public <V> Future<V> enqueue(Callable<V> callable) {

    AppTask<V> task = new AppTask<V>(callable);

    taskQueue.add(task);

    return task;

    }



    /**
  • Do not call manually.
  • Callback from ContextListener.

    /

    public void update(){

    // Make sure the audio renderer is available to callables

    AudioContext.setAudioRenderer(audioRenderer);



    AppTask<?> task = taskQueue.poll();

    toploop: do {

    if (task == null) break;

    while (task.isCancelled()) {

    task = taskQueue.poll();

    if (task == null) break toploop;

    }

    task.invoke();

    } while (((task = taskQueue.poll()) != null));



    /
    I think the above is really just doing this:

    AppTask<?> task;

    while( (task = taskQueue.poll()) != null ) {

    if (!task.isCancelled()) {

    task.invoke();

    }

    }

    //…but it’s hard to say for sure. It’s so twisted

    //up that I don’t trust my eyes. -pspeed

    */

    [/java]





    note how @pspeed can even ninja when hes not online :slight_smile:

Maybe…



By my reading of the code it would happen in the same frame as the new enqueue would get added to the list - and you would then poll and get it after the current ones have completed but before exiting the loop.



But as pspeed has ninjad in to say it’s so twisted that I don’t trust that :s

I agree with zarch. Callables enqueued by a running Callable will be executed in the same frame.



If you want to split something over several frames then use an app state instead. You will keep getting called until you remove yourself… and you can use whatever strategy you like for breaking up the work on update. Your own Callable queue where you pull one item per frame or something else.

Yeeh, I think the app state is the best way to go should I need to do it (I’m still hoping to avoid it).



In the mean time that loop should be taken out and shot…although I fully understand no-one wanting to touch it so long as it isn’t broken!

Exactly this is why I propose proper threading instead of mindless async queueing for everything.