PApplet call order (multi-threading thread safety)

what is the call order for the following methods:

  • setup()
  • draw()
  • mousePressed()
  • mouseDragged()
  • mouseReleased()
  • // related keyboard methods

in particular:

am i correct to assume that draw() will pause during the run on any non-draw() method

for example:

if i want to implement a graphics save/restore feature in mouseReleased()

that must assume that no draw() calls will be made during the save and restore

will this be possible and if so how would i implement it if draw() is still being called for the duration of other main functions

for example

upon state restore, the current graphics does not have unexpected values in it related to graphical calculations

for example

  • timer is 3 on save
  • draw() gets called and increases timer to 4
  • restore is called
  • draw is called
  • draw expects time to be 4 and increase to 5 but is instead 3
1 Like

All of those callbacks are run synchronously by the same “Animation” Thread.

It’s not that draw() “pauses” for the resolution of the input callbacks, but rather that draw() has already finished for that frame iteration.

2 Likes

so… if all the callbacks are called synchronously, then all methods would block one another correct? eg something like this

Thread animation() {
    applet.setup();
    while(true) {
        applet.draw();
        if (mousePressed()) applet.mousePressed();
        if (mouseDragged()) applet.mouseDragged();
        if (mouseReleased()) applet.mouseReleased();
        if (!applet.ShouldLoop) break;
    }
}

True. That is why we don’t execute time consuming blocks of code inside an event handler.

In the code you provide there appears to be two applet instances. If that is correct then each applet has its own event-handling thread and you shouldn’t be calling the draw method or event handlers of one applet instance from another instance.

i dont know how the internals work but im assuming the thread and the Applet are seperate classes and as such it as a reference to the current running Applet, eg

thisAppletInstance.setup()

To get a reference to the running PApplet we use the Java keyword this. If you run the following code you will see the output PApplet PApplet which demonstrates this.

void setup(){
  size(400,400);
  String thisname = this.getClass().getSuperclass().getSimpleName();
  String name = this.getClass().getSuperclass().getSimpleName();
  println(thisname, name);
}

Are you trying to have multiple PApplets running? What are you hoping to achieve?

1 Like

like… all i want to know is what functions will block the draw() call if any

The following answer applies to Java mode.

First we distinguish between event capture and event handlers. When the mouse moves or a mouse button clicked or a key typed … then this is captured by the OS which creates an event-data-object that is forwarded to the currently active application, our sketch perhaps.

Now our sketch will have several threads running one of which will add the event-data-object to a fifo queue (fifo = first in first out) to be processed later.

So now we come to the interesting bit - the main event-handling-thread (EHT). This thread handles both rendering and event handling so when the thread is not rendering it will look remove the first event from the queue and depending on its type call the appropriate event handler to process the event. the EHT might process several events between each frame render so you get

draw : event : event : draw : event : event : event : event : draw : event : draw : event

Events are processed in the order they were captured but there is no way to predict how many event will be handled between frames.

Now you have your answer - all event handlers will block the draw method so it is important that large time consuming tasks are not performed inside the event handlers. If we do, not only will it block draw but it will prevent other events being processed, making the sketch unresponsive.

int eventCount = 0, maxEventCount = 0;
;

void setup() {
  size(320, 200);
  textSize(30);
}

void draw() {
  background(0);
  fill(255);
  text("" + eventCount, 20, 100);
  fill(255, 0, 0);
  maxEventCount = max(maxEventCount, eventCount);
  text("" + maxEventCount, 220, 100);
  eventCount = 0;
}

void mouseMoved() {
  eventCount++;
}
2 Likes
1 Like

If you are interested in finding out what threads are running with your sketch then try the code in this discussion.

1 Like