I’ve tried to call draw() myself to better control the framerate during long calculations, but it doesn’t seem to draw anything when i call it myself. Is it normal?
How can u understand that something happens while the draw() executes itself 60 times per second? The way I can visualize it, is like issuing just a “break” on the function calling it?
Draw has to be called within the correct context for it to work properly (i.e. drawing commands only work in setup() and draw() and only if called by Codea not yourself). If you are performing long calculations within draw, you still wont see anything because Codea won’t display anything until draw has actually ended and it gets the chance to present the contents of the framebuffer to the screen. You may want to look using coroutines to perform long calculations and yield every so often to allow draw to finish.
.@John thanks for the answer. I dont really understand why the drawing could not be triggered by the user? If i call draw myself, then that means i give Codea the priority to draw at this moment, so it should not return until it has finished to refresh the screen. If an explicit command is needed then why not refreshDisplay() at the end of Draw()?
Anyway, i’ll take that as a rule, and will find some solution. It’s just direct call to draw would have been easier that using coroutines (when long loops are in functions called several levels below the top level, then the use of coroutines is more complex to setup, because co.yield() has to be managed all along the calling chain, which is not really what coroutines are made for)
.@panoGR the problem is that during a long calculation (10s for instance) the draw() will not be called 60 times per seconds, but only when the calculation is finished. Codea does not call it at 60fps, but just try to call it: if the computing is busy with another routine, then it gives up.
Given that draw() is called automatically, you really ought to reorganise your long calculations so that you do them bit by bit and then at the end of each cycle or part you can update a progress meter so that the user (or you) knows that the app hasn’t crashed.
@Jmv38 I came upon that issue trying to implement a “pause” command. “While do …end” didn’t work exactly as It was expected (with serial programming approach) . If draw() has a “serial” behavior I can not understand why the following code crash:
-- test -- Use this function to perform your initial setup function setup() print("Hello World!") end -- This function gets called once every frame function draw() -- This sets a dark background color print("test") background(40, 40, 50) fontSize(40) fill(255) for i=1,10 do sound(SOUND_PICKUP, 28331) j=1 while j<200 do print("hello") j=j+1 end end end
.@PanosGR - the reason your app crashed is because you are trying to print out the string “hello” 2000 times and you are trying to do it ~60 times per second.
What you have to remember is that OUTSIDE of your Codea app is an engine that is actually running and THAT code is basically doing something like this…
... Run the Setup function ... set a counter to the current time Repeat FOREVER do ... ... has ~16 ms elapsed since the last loop (compare current time against counter) if YES then run Draw() and reset the counter ... ... End ``` This is why you shouldn't take too long or put an infinite loop in the Draw() function because if it blocks then the rest of the Codea engine can't run and your Draw() function will never be called again.
… @PanosGR One thing you don’t want to do is put a print statement in the draw routine without some way of stoping the print by using an if statement. You will never see anything print and the program will lock up. Here is a simple example of using pause to stop the drawing of a random circle on the screen. Just tap the screen to pause/not pause the drawing of the circle. You can’t add code inside the draw routine to stop it. The only thing you can do is not execute all of the code to simulate a pause.
displayMode(FULLSCREEN) function setup() x=0 y=0 end function draw() -- always do this code background(40, 40, 50) fill(255) ellipse(x,y,50,50) -- draw ellipse at last x,y position -- if pause is true, then exit draw routine if pause then return end -- only do this code if pause is false -- calculate a new x,y position x=math.random(WIDTH) y=math.random(HEIGHT) end function touched(t) if t.state==BEGAN then pause = not pause -- toggle pause, true, false end end
@TechDojo, Actually I did I not fully got it, but I will try, thank you both a lot.
It’s the print statements. By having prints inside draw, you’re trying to shove out thousands of lines of print each second. The output buffer buckles.
consider draw() a low-level call. you can’t get faster than ~16ms per execution cycle.
I have situations that need to implement a delay; I architected my code to be driven by events instead of being heavily procedural.
I used a Heartbeat() function inside of classes , and only drew classes when my heartbeat determines it needs to be drawn.