We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpSyntax Questions › Drawing before the end of draw()
Page Index Toggle Pages: 1
Drawing before the end of draw() (Read 1257 times)
Drawing before the end of draw()
Dec 22nd, 2008, 11:35pm
 
I want to display what is in the image buffer before the end of draw() and can't seem to be able to do this simply.

The use case is simple: i want to display "Loading..." before calling a function that takes a few second to execute. More specifically, the user hits the spacebar to load the next image. The next image takes 2 seconds to load, and I'd like to display "Loading..." while this during that time lapse. The image load is called during "void keyPressed()".

Please help!





Re: Drawing before the end of draw()
Reply #1 - Dec 23rd, 2008, 3:56pm
 
I think you can draw something during any event, including keyPressed.
Re: Drawing before the end of draw()
Reply #2 - Dec 24th, 2008, 6:08am
 
You are right, you can draw during an event, but it won't show up on the screen until end of the next draw().

I wrote this simple program to illustrate my point. Notice what happens when you hit a key: the number from println is one higher than the one on the display, even thought it is called before. And notice how "Loading" shows up only for a split second on the display but behaves ok on the prinln() area.

Well that's because the image in the buffer is not displayed until the end of draw and events. The code in keyPressed() shows that it actually runs in between draw() cycles. The buffer is displayed on screen  after keyPressed().
----------------------------
int i=0;
PFont font;
void setup()
{
 size(200,200, P3D);
 font = createFont("Verdana", 40);
}
void draw()
{
 background(0);
 textFont(font);
 text(i, width/2, height/2);
 println(i);
 i++;
}
void keyPressed()
{
 println("Loading...");
 background(0);
 text("Loading", width/2, height/2);
 
 delay(5000);
 
}
----------------------------

So back to the question: can I force the buffer to get displayed on the screen before the end of draw?

Re: Drawing before the end of draw()
Reply #3 - Dec 24th, 2008, 6:43am
 
Maybe you can thread the load routine instead of drawing mid-load out of single thread?  I did that recently to have the client display what's being loaded and it works pretty well - just have to be careful about what point something is accessed, though.  But if it's just for load message, it shouldn't cause much problem.

main routine:
Code:

enum Appmode{LOAD, LOADMESSAGE, MAINLOOP};

Appmode appmode = Appmode.LOAD;

void draw(){
...
switch(appmode){
 case LOAD:
   ThreadedLoad threadjob = new ThreadedLoad();
   new Thread(threadjob).start();

   appmode = Appmode.LOADMESSAGE;
   break;
 case LOADMESSAGE:
   ...
   break;
 case MAINLOOP:
   ...
   break;
...
}


subroutine:
Code:


class ThreadedLoad implements Runnable {
public void run() {
 // TODO: STUB - load something
 appmode = Appmode.MAINLOOP;
}




of course, I made it up as a quick and ugly fix with lots of flags, so if someone has better suggestion, I'd really like to know.

====edit===
fixed a bug. made it less wordy.
Re: Drawing before the end of draw()
Reply #4 - Dec 24th, 2008, 9:31am
 
You are right, I never understood the drawing orders were delayed until the next draw.
I actually tend to centralize all drawing orders in the draw routine, anyway.
Here is a "soft" way to do what you want, without thread, if it is OK to freeze the display while loading: I just delay the costly operation by one frame.
Code:
int i=0;
PFont font;
int flag = 0;

void setup()
{
 size(200,200, P3D);
 font = createFont("Verdana", 40);
}

void draw()
{
 background(0);
 textFont(font);
 text(i, width/2, height/2);
 println(i);
 i++;

 if (flag == 1)
 {
   println("Loading...");
   background(0);
   text("Loading", width/2, height/2);
   flag = 2;
 }
 else if (flag == 2)
 {
   delay(5000);
   flag = 0;
 }
}

void keyPressed()
{
 flag = 1;
}
Re: Drawing before the end of draw()
Reply #5 - Dec 24th, 2008, 10:47am
 
Thanks for the answers guys.

About threading, I need to learn to use my other cpu core so this will help and it opens new doors.

PhiLho, I have been doing similar things with flags, and it's good that this thread now documents these options. I just wish I could call a simple function like something called "render();"  to force display at any moment. I feel like it would make my code cleaner. It would just flow the way I want it to. I mean Processing is got to have to call some Java procedure at some point to display what's in the buffer onto the screen. Either there's some undocumented way to call it (a PGraphics' method?), or maybe this could be added to the Processing core in some future version.

Distancing myself from this request, I can see the simplification dilemma. Processing makes Java simpler by wrapping certain things and looking at things at a higher level coding by making certain assumptions. At the same time, it is taking away a certain amount of low level control which sometime is necessary. It's so hard to find the perfect spot between simplicity and functionalities.


Re: Drawing before the end of draw()
Reply #6 - Dec 24th, 2008, 11:38am
 
Note: if the costly operation is to load an image, you can now use the requestImage() function which was made specifically for that...

And you are right about simplicity vs. power. But Processing is flexible enough to allow (nearly) any amount of Java in it, to the state of being a simple library in a full blown Java program.
Re: Drawing before the end of draw()
Reply #7 - Dec 24th, 2008, 12:20pm
 
Code:

Ladebalken lb; // ladebalken == loading bar

void setup ()
{
size( 150, 150 );
lb = new Ladebalken();
lb.start();
}

void draw()
{
background( 0 );
rect( 10, height/2, lb.cnt, 10 );
}


class Ladebalken
extends Thread
{
float cnt = 0.0;

void run ()
{
while ( true ) // never stops
{
cnt += 0.001;
int i = 0;
while ( i < 100000 ) // waste some time here ..
{
i++;
}
}
}
}


as you see threads are easy to implement. how these are distributed to your # of cpus depends on jvm and your system.

F
Re: Drawing before the end of draw()
Reply #8 - Dec 24th, 2008, 5:21pm
 
Just in case OP is wondering about the difference between Runnable and Thread:

http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=24&t=016473


Quote:
Distancing myself from this request, I can see the simplification dilemma. Processing makes Java simpler by wrapping certain things and looking at things at a higher level coding by making certain assumptions. At the same time, it is taking away a certain amount of low level control which sometime is necessary. It's so hard to find the perfect spot between simplicity and functionalities.


IMHO, I think the mantra (as much as I am suspicious of mantras) of "you're not gonna need it" and "don't repeat yourself" is in line with my lazy way of programming and answers the dilemma - the problem dictates the simplicity (or complexity) and the convenience dictates the functionalities.  Not very original, but hey, I think it works.

I think having something working at the basic level is better than not having anything to show at the end of the day.  But then again, I'm pretty new to Java and any programming in general, so I may be wrong.  OK, I'll stop rambling.
Re: Drawing before the end of draw()
Reply #9 - Dec 24th, 2008, 10:07pm
 
Summing up some of the discussion, and also coming back to the main topic, I wonder if this is close to the render() function.  I think PhiLho brings up really relevant point because I would like to have expensive operation like sphere() to be deferred when it is slowing down the rest of the operations.


Maybe it's meaningless for now because it still uses a flag to lock.  I thought of subclassing PApplet and merging the threads but can't quite figure out how that would work within Processing:

Code:

//enum Appmode {SETUP, DRAW, LOCK}
//Appmode appmode;
String appmode;
PApplet pa;

void setup(){
 size(500,500, P2D);
 smooth();
 appmode = "SETUP";
}

void draw(){
 if(appmode.equals("SETUP")){
   pa = this;
   ThreadedDraw threadedDraw = new ThreadedDraw();
   new Thread(threadedDraw).start();
   appmode = "LOCK";
 }
 else if(appmode.equals("DRAW")){
   println("drawing");
 }
 else if(appmode.equals("LOCK")){
   println("locked");
 }
}


class ThreadedDraw implements Runnable{
 void run(){
   if(appmode.equals("SETUP")){
     //throw error
   }
   else if(appmode.equals("DRAW")){
     println("threadlocked");
     }
   else if(appmode.equals("LOCK")){
     draw();
   }
 }
 
 void draw(){
while(true){
appmode = "LOCK";
println("locking);
pa.background(130);
pa.ellipse(10, 10, 10, 10);
render();
pa.rect(200,200,10,10);
render();
}
}
 void render(){
   appmode = "DRAW";
 }
}


I also realize I've been coding in java5, and I can't use enum in Processing Sad

=== edit ==
I found out that it doesn't work as I thought Sad Sad
Re: Drawing before the end of draw()
Reply #10 - Mar 11th, 2009, 10:19pm
 
Reviving this thread to ask if it's really true that there is no way to force the screen to be updated before reaching the end of the draw() routine.

Things would be much better for me and my code if I could flush() the framebuffer for the screen whenever I wanted to rather than waiting for draw() to do it for me,

Thanks for any alternatives or learned confirmation that this is impossible.

Phil

Details

I would like to do this because in a single pass through draw() I'm doing several blocks of number crunching.  Each block of computation corresponds to a different visual element.

I would like to display those elements as they are calculated one-by-one rather than having a static screen for quite a while and then everything updating at once.

I could take my current code and add flags and tests so that different parts of the code are executed during different passes through the draw() routine.  But the logic will be tortured and the code rather ugly.

Thanks,

Phil
Page Index Toggle Pages: 1