Posts
Search
Contact
Cookies
About
RSS

So what is a callback anyway? (Raylib)

Added 7 Mar 2021, 10:37 a.m. edited 18 Jun 2023, 1:12 a.m.

I happened to notice that Raylib has started implementing callbacks for some functions, and this is very welcome as its a small part of what makes libraries like GLFW so nice.

Given that Raylib is intended also for novice users and those learning, I thought this concept bore an explanation as in the comment in raylib says:

// Set custom callbacks
// WARNING: Callbacks setup is intended for advance users

Yes if you're just starting out with C maybe wait till you have a little experience under your belt, but as you'll see callbacks need not be scary!

A callback is simply a function in your own application that a library calls, often (but not always) as a result of you calling a library function. While I could give some contrived simile regarding land lines and mobile phones, I don't think its needed !

Here's the complete code for a trivial and entirely none useful example.

// SaveFileTextCallback simple example
#include "raylib.h"

char msg[] = "\nHello World\n\nFrom a callback!";

void mySaveTextFile(const char *fn, char *txt)
{
    TraceLog(LOG_INFO, "I'm supposed to be saving to: %s", fn);
    TraceLog(LOG_INFO, "The text is: %s", txt);
}

int main(void) 
{
    SetSaveFileTextCallback(mySaveTextFile);
    
    // this following Raylib function now no longer does what its supposed to !
    SaveFileText("afile.txt", msg);
}

The first thing to notice is that your call back function should have the correct signature

// typedef for function prototype 
typedef void (*SaveFileTextCallback)(const char *fileName, char *text);

This means in this case that your function must return void and take a const char pointer and a char pointer. Notice that this typedef is a pointer this is known as a function pointer.

Looking at line 14 of the example you can see that the parameter is mySaveTextFile the function name but without brackets or parameters, all setting the callback is doing is setting a simple variable that happens to be a function pointer.

See told you it wasn't that scary !

So why was this even done, simply its very powerful and adds lots of flexibility, for example say rather than save to a file I wanted to send the data across the internet, the application could then have a setting to save local or remote, changing the option would change the callback. This means you wouldn't need lots of if/else clauses everywhere you need to save some text.

I hope I've made this clear and not muddied the waters for you!