How to understand the execution order when draw() and mousePressed() are next to each other?

Here is a code example from LearningProcessing book:

void draw() {
  background(255);

  // Update and display all balls
  for (int i = 0; i < balls.length; i ++ ) { // Whatever the length of that array, update and display all of the objects.
    balls[i].gravity();
    balls[i].move();
    balls[i].display();
  }
}

void mousePressed() {
  // A new ball object
  Ball b = new Ball(mouseX,mouseY,24); // Make a new object at the mouse location.
  balls = (Ball[]) append(balls,b);

What I am not clear about is: when the program is running, and then press mouse,

  1. draw function will halt immediately (even it is in the middle line of its code), mousePressed function will run once, then draw function continue to run until mousePressed is triggered again or the program reload or stopped?
  2. draw function will finish its latest run and then halts, then mousePressed function will run once, then draw function continue to run until mousePressed is triggered again or the program reload or stopped?
  3. both draw and mousePressed functions are running at the same time, but mousePressed runs only once, draw will continue until the program is stopped.

which one is correct way of understanding their execution order behind the curtain? or how should I understand it?

Thank you!

Kenny

Answers

  • edited October 2015

    2nd option is closer to what really happens. :-j

    Processing has a Thread called "Animation" which runs all its callbacks like setup(), draw(), mousePressed(), etc.

    However, there's another "hidden" Thread called "Dispatch Event" which enqueues every input Event like keyboard & mouse while draw() is running.

    Once draw() finishes, all accumulated Event are dequeued 1 by 1.

    Then the corresponding Event callback is invoked.
    But they're still run synchronously by the "Animation" Thread.

    Unless noLoop() is active. Then the "Dispatch Event" itself is responsible for the dequeue executions.

  • Answer ✓

    The correct one is #3. The draw() function will just keep going over and over, no matter what. When the mouse is pressed, the code inside the mousePressed() function happens.

    The explanation is that they're running in different threads.

  • edited October 2015 Answer ✓

    Example sketch below proves that Event instances are enqueued asynchronously.
    But their dequeue happens synchronously after draw() finishes.

    Pay attention that the Event's println() statements only happen after each 5 seconds.
    Since draw() callbacks are configured as frameRate(1/5.0);
    https://Processing.org/reference/frameRate_.html

    Just hit some keys or click at the mouse during the 5 seconds between each draw():

    // forum.processing.org/two/discussion/13161/
    // how-to-understand-the-execution-order-
    // when-draw-and-mousepressed-are-next-to-each-other
    
    // by GoToLoop (2015-Oct-21)
    
    int mouseClicks, keyPresses;
    
    void setup() {
      size(400, 400);
      frameRate(1/5.0);
    }
    
    void draw() {
      println("\n\nReset back to", mouseClicks = keyPresses = 0);
      background((color) random(#000000));
    }
    
    void mousePressed() {
      print("Click", ++mouseClicks, '\t');
    }
    
    void keyPressed() {
      print("Press", ++keyPresses, '\t');
    }
    
  • edited October 2015

    @GoToLoop@TfGuy44 Thank you for the detailed answers and they are very helpful, @GoToLoop 's example in particular. I experimented the code (only altered a little bit) for a while in the following ways:

    1. run the code, immediate after the first run of draw (meaning after the first color change), I started to click mouse(at equal speed at my best) normally 15 times in total (usually the last 5 clicks happened after the second run, then I left draw to run for another two times, finally stop the program.
    2. move mousePressed function before draw, and do the same as above.

    Both ways gave me the same result:

    1. the second run's console result put draw println message first, then came mouseClicked's 8 click messages;
    2. the third run's console result also put draw println message first, then came mouseClicked's 4 click messages;

    My findings/hypothesis of this outcome is consistant with the answers given by @GoToLoop:

    1. No matter when mouseClicked is triggered (say triggered 8 times), either during draw is running or draw is waiting for the 5 seconds to pass, mouseClicked will be queued after draw, and after the waiting period (5 seconds) passed, draw runs first and the eight mouseClicked immediately follow, and then another waiting period begins;
    2. Even we put mouseClicked function before draw, the above finding is still true.

    What do you think? Is it what in your mind? or something is still not right?

    Thanks,

    here is the code I experimented upon the code provided by @GoToLoop

        // forum.processing.org/two/discussion/13161/
        // how-to-understand-the-execution-order-
        // when-draw-and-mousepressed-are-next-to-each-other
    
        // by GoToLoop (2015-Oct-21)
    
        int mouseClicks, keyPresses;
    
        void setup() {
          size(400, 400);
          frameRate(1/5.0);
        }
    
    
        void mousePressed() {
          print("\n\n I am in mousePressed to Click", ++mouseClicks, '\t');
        }
    
    
        void draw() {
    
          background((color) random(#000000));
          println("\n\n so far there are ", mouseClicks, "mouseClicks and ", keyPresses, " keyPresses"); 
          println("Reset back to", mouseClicks = keyPresses = 0);
          println("i am in end of draw");
        }
    
    
        void keyPressed() {
          print("Press", ++keyPresses, '\t');
        }
    

    Here is the console messages:

    (this is the first run of draw )
    so far there are 0 mouseClicks and 0 keyPresses
    Reset back to 0
    i am in end of draw

    (second run of draw)
    so far there are 0 mouseClicks and 0 keyPresses
    Reset back to 0
    i am in end of draw

    (1st - 8th clicks run after second run of draw)
    I am in mousePressed to Click 1

    I am in mousePressed to Click 2

    I am in mousePressed to Click 3

    I am in mousePressed to Click 4

    I am in mousePressed to Click 5

    I am in mousePressed to Click 6

    I am in mousePressed to Click 7

    I am in mousePressed to Click 8

    (this is third run of draw)
    so far there are 8 mouseClicks and 0 keyPresses
    Reset back to 0
    i am in end of draw

    (9th - 12th clicks run after third run of draw)
    I am in mousePressed to Click 1

    I am in mousePressed to Click 2

    I am in mousePressed to Click 3

    I am in mousePressed to Click 4

    so far there are 4 mouseClicks and 0 keyPresses
    Reset back to 0
    i am in end of draw

    so far there are 0 mouseClicks and 0 keyPresses
    Reset back to 0
    i am in end of draw

Sign In or Register to comment.