Setup(), update(), draw(), when ?, why?

Hi all,
like many people I’m coming from the Processing wonderful world…

In beginner’s tutorials, it’s pretty easy to find how to implement classes.
I don’t know when to override setup(), update() and draw() (I think we can talk about “overriding” ?).

In all classes ? In “displaying dedicated” classes ? Just in “myApp” class (like empty example) ?

Hi @badaf,

Welcome and congrats for making the step towards OF!

Not sure I understand completely your question, but here’s what I would answer:

  • Use the setup/update/draw convention for your “root” class, i.e. testapp in OF 0.7.4 or ofApp for 0.8 and above, or simply myApp, whatever you want to name it. Thanks to that naming convention, the framework will call your setup()/update()/draw() function at the right moment, and you don’t really need to know all the stuff that happens behind the scene.

  • In addition to setup/update/draw, you have another bunch of function that follow the OF convention: exit(), keyPressed(), etc

  • If you go deeper, i.e. you break your code down to more classes, you need to propagate the functions calls yourself. What I mean here is that, although the setup/update/draw function seem to be called automatically for your myApp class, it is not the case for the other classes because you decide what the other classes do and how they should be executed. See the following example:

    class myClass{
    public:
    void setup();
    void update();
    void draw();
    }
    class ofApp : public ofBaseApp{
    public:
    void setup();
    void update();
    void draw();
    myClass myObject;
    };
    Then if you want myClass to follow the convention, you could do this:

    void ofApp::setup(){
    myObject.setup();
    }
    //--------------------------------------------------------------
    void ofApp::update(){
    myObject.update();
    }
    //--------------------------------------------------------------
    void ofApp::draw(){
    myObject.draw();
    }
    Note that for myClass, you don’t have to follow the naming convention, because you make your function calls yourself. You could rename myClass::update() to myClass::step() or myClass::KeepCalmAndCarryOn(). But for readability’s sake, it’s a good practice to stay consistent. Note that some classes don’t even need to be setup, updated or drawn.

  • Remember, for you myApp class, the setup() function will be called once when your app starts. This is the perfect place to initialize your variables, allocate memory, retrieve constants from a file, etc. The update() function is called on every frame (e.g. 30 times or 60 times per second typically) and is the right place to make your calculations. Finally, the draw() function may be called more than once per frame, so use it only to call function to draw stuff. Try to avoid any computations in the draw function.

  • You’re right about overriding, as your myApp class actually inherits from ofBaseApp, which already defines setup/update/draw as virtual functions. Thanks to the keyword virtual, when the frameworks calls update() on your app, the function that will be executed is myApp::update() and not ofBaseApp::update(). Why does myApp need to inherit from ofBaseApp? Because that how you define a convention. Thanks to polymorphism, the framework will be able to execute any apps that inherits from ofBaseApp.

Hope it helps!

2 Likes

Thank you sachaventura, your answer will be useful for me…

Here is my real asking,
how to know when I must add these functions to my class(es) ?

Actually you should ONLY make your ofApp or testApp class inherit from ofBaseApp. Well you might make other classes inherit from it but it wont mean that their methods will get called automatically.
When to add one of these methods to your class? when ever you need it. If you dont add it it does not matter.
I one of your classes need it’s draw or update or mouse or key methods to get called you can either call it from the respective class of your ofApp or register your class to the respective event. Check the events examples.
hope it helps.
best

Thanks a lot, I now understand better :smile:

Thank you sachaventura! You answer was really helpful!

Hello, I try to understand why use void update() seppartly of void draw(). At the first when I read the explication

I think I can write the code like that and I have a differente answer for the count_drawand the count_uptate and that’s can be good because my draw stay faste of my update, but the console show me it’s on the same thread because the answer of the two variables is the same. So why use the method update() except to be clearest in the code ?

#include "ofApp.h"

void ofApp::setup() {
	ofBackground(255);
}
void ofApp::update() {
	count_update++;
	for(int i = 0 ; i < 1000000000 ; i++) {
		// nothing just count
	}
	std::cout << "count update: " << count_update << std::endl; 
}

void ofApp::draw() {
	count_draw++;
	std::cout << "count draw: " << count_draw << std::endl; 
	ofBackground(255);
	ofSetColor(0);
	ofSetLineWidth(2);
	ofDrawLine(0,0,ofGetWidth(),ofGetHeight());
}

console log

2020-08-11 11:19:09.690588+0200 basics_openframeworksDebug[2622:261872] Metal API Validation Enabled
count update: 1
count draw: 1
count update: 2
count draw: 2
count update: 3
count draw: 3
count update: 4
count draw: 4
count update: 5
count draw: 5
count update: 6
count draw: 6
.../...