I have a sketch that produces different results when I move the cursor (in void draw). It also has a function (in void keyPressed) to save the current result as a gigantic image whenever I press a key. This leads to the sketch freezing for a few good seconds. This is fine and expected, but instead of having to wait and occasionally wiggle the cursor to verify if it’s unstuck, I’d rather have some sort of signal in the sketch itself (say add a border to it all or put a circle in the middle that’ll get drawn over on the next loop).
But I’m unsure of how to do so in an elegant way. I’ve tried including a rect or ellipse call inside the key pressing function, right before the save, but that doesn’t work as it waits for the entire operation (including the save) to end before drawing, doing so when it’s no longer needed.
What do you usually do for these cases? I’m looking for something short you usually include in your sketches (a few lines). Something overly complex or that requires moving code around won’t be worth it.
Maybe you can work something like this into your code, a white flash fading to black (a rectangle the size of your sketch with reduced alpha as its fill color):
This is because the screen updates when draw() returns. If you start a long operation that takes a while to return in the middle of a frame, the screen freezes.
You could use a thread – but if you want something really simple, just flag the long operation for the next frame. Then you can update the screen, and on the next frame your operation will start. When it is over, clear the flag.
So your problem is this:
boolean longOperation;
void draw(){
background(0);
// long event
if(keyPressed){
// show a long operation in progress
ellipse(width/2, height/2, 50, 50);
// problem -- screen updates only after draw frame ends
// so the ellipse won't display until the delay is over
delay(3000);
}
}
And one simple solution is this:
boolean longOperation;
void draw(){
background(0);
// long event
if(longOperation){
delay(3000);
longOperation = false;
}
// flag long event for next frame and update screen
if(keyPressed){
longOperation = true;
// show a long operation in progress
ellipse(width/2, height/2, 50, 50);
}
}
Your solution works, but also requires I have my lengthy operation inside draw, which I don’t want (should have made that clear). I have it inside void keyPressed (separation of concerns).
I also should have clarified that when I say “what do you usually do for these cases?” I’m really asking for that — suggestions people use. I can devise a workaround, but I was looking for some elegant solution someone already tends to use in their sketches.
Well, the Processing draw() loop is like a for loop that runs the whole sketch (unless you are in static mode or in the noLoop state and calling redraw manually). So no matter whether it is in a function call or class method or input event, almost everything is normally still happening inside a draw loop frame iteration. This is why I gave you a simple single-threaded solution that is commonly used. If you put the keypressed code in keyPressed() the problem and the solution both function in the same, single-threaded way – try them!
As I already mentioned, if you want to initiate a thread instead, use thread():
Processing sketches follow a specific sequence of steps: setup() first, followed by draw() over and over and over again in a loop. A thread is also a series of steps with a beginning, a middle, and an end. A Processing sketch is a single thread, often referred to as the “Animation” thread. Other threads’ sequences, however, can run independently of the main animation loop. In fact, you can launch any number of threads at one time, and they will all run concurrently. You cannot draw to the screen from a function called by thread().
…or if you need something more industrial-strength, use a Java Thread.