Advantage of a callback functions? (graphics) - c++

I'm relatively new to writing input-based applications. I'm using OpenGL and GLFW to write games at the moment and user input is at the heart of it. From what I understand, OpenGL being a C program means that I cannot use classes to encapsulate the existing, predefined keycallback functions.
One way around this, is to use a self-defined callback as a global function or as a static method in a class. Link provides quite a few interesting ways to do this. Some of these are better than what I'm doing right now but my question remains- is it worth such an effort?
void glfwKeyCallBack(some parameters) // GLFW-defined
{ // does something}
void SelfDefinedFun(some parameters) // my definition of it
{ // does something}
int main()
{
while(gamelooptrue) // inside game loop here
{
1. SelfDefinedFun(some parameters) // call function here instead of using glfwKeyCallBack
2. action 2
3. action 3
...
}
}
Callback functions are automatically called the moment the corresponding action takes place. This means that regardless of how slow my game loop is, each time a key is pressed, glfwkeyCallBack will be called. I can vaguely see some of the advantages such a method provides as opposed to calling SelfDefinedFun repeatedly in the game loop.
However... the game loop requires that the drawing of a scene take place each frame. Given current standards, this is usually 60 times a second but I imagine we would need at least 15fps to have a non-jerky visualization of movement on a screen. Given that, I can forget about the callback and simply check for key-press every frame. The advantage here is that I can easily encapsulate the function and this allows me to perform more complex event-based operations.
So, why are callbacks even necessary if we are drawing the game so many times a second?
One reason I think callbacks could be better is because you don't check for user-actions unless there is one => more time for drawing. Since my application is simple, this is negligible time. But would it be different in full-blown 3D games like Skyrim, Bioshock etc.?

Related

Disadvantages of using a function pointer as an UI-Button callback

I am currently creating my own GUI-Library based on SFML.
At the moment i am working on a Button. So when creating a button you also have to specify a callback which is a function, executed on the button click.
Now, I'm answering me what the disadvantages are of using just a pointer to a function as a button-callback, because I don't know any popular GUI-Library doing it so simply, too.
If the callback function is a long process, I would execute it in a new thread, but i'm not sure about that in the moment.
So, what would be reasons, not to use such simple solution and especially, what would be a better way?
It's a tricky problem!
Function pointers are simple to implement on the sender side, but they are difficult to use on the receiver side because they they don't have any context.
One issue is that a function pointer cannot point to a member function. That's why you often see (C-style) frameworks pass an arbitrary void *userData to their callbacks, so you can cast your this pointer and retrieve it in that way. This still needs you to write a static wrapper function to cast the pointer back and call the member function.
A more modern solution would be to use std::function. This can contain a regular function pointer, a member function pointer, but also a lambda or a functor.
However, when you add context like this (or in some other way), you quickly run into difficulties with lifetimes. When the receiving class is destroyed before the sender, what is supposed to happen? If you don't do anything, this situation will result in undefined behaviour. A solution is to track on the receiver side to which events the receiver is subscribed, and unbind them before the receiver is destroyed. And this needs to be done in both directions: when the sender is destroyed, it also needs to notify the receiver that it should forget about the sender, otherwise the receiver would later try to unbind an event that no longer exists.
And I haven't even begun to think about multithreading yet...
There are libraries that solve these problems in various ways, for example eventpp (just found through a web search, this is not an endorsement).
Another one to mention would be the Qt toolkit, which went so far as to write their own small signals and slots extension to the C++ language (implemented as a code generator and a pile of macros) to solve this problem in a very ergonomical way.
what the disadvantages are of using just a pointer to a function as a button-callback
Passing some context argument to that function would come handy.
I mean, the UI may have a lot of buttons performing the same action on various objects. Think maybe of "send message" button next to each nick in a friend list.
So you may want your buttom to pass some context arguments to the call.
But since we're talking C++, this'd better be abstracted as
struct IButtonAction
{
virtual void OnAttached() = 0;
virtual void OnDetached() = 0;
virtual void OnClick() = 0;
};
And let the client code implement this interface storing whichever Arg1, Arg2, etc in each instance object.
The button class would call OnAttached/OnDetached when it begins/ends using the pointer to an instance of this callback interface. These calls must be paired. Client implementation of these methods may perform lifetime management and synchronization with OnClick, if required.
OnClick method performs the action.
I don't think the button should bother with threads. It's the responsibility of the client code to decide whether to spawn a thread for a lengthy action.

(OOP) Events in a main loop, and updating dependencies in constructor

Recently I started a project in hopes to learn OpenGL in C++,and I got stuck on a problem regarding code architecture.
First Question, should I avoid using events in a main loop?
Example:
Event* UpdateEvent = new Event();
int main(){
while(1)
UpdateEvent->Invoke();
}
SomeOtherClass::SomeOtherClass(){
UpdateEvent->Hook(this->DoSomethingAlways);
}
Events from my understanding of C++ code, have a certain amount of penalty in their codes (virtual methods, looping throught events, handling the event stack/array). If i were to implement it in such a way there would definitely be a fair amount of calls on it (Controllers, Coroutines etc.) and this might prove to not be as performant.
Secondly, Should I avoid subscribing to events / update outside variables in constructor?
Or should I instead implement factories? Example:
//Constructor
MyClass::MyClass(){
Dependency::Instance->AddObject(this);
}
Dependency::AddObject(MyClass obj){
InternalList.push(obj);
InternalEvent.Hook(obj->EventHandler);
}
Seen from previous code, I have a habit of subscribing to events in a constructor, and doing other automatic tasks in constructor (Eg. Adding a constructed to some singleton manager). I like doing this because it avoids a need for factories, and creates a little bit more elegant code. But on the other hand, if someone else were to work on this after (Like me in the future) he might not know that certain objects automatically update their dependency objects.

Runtime event handler in cpp?

Working on a cpp project, where I need something like runtime event handler. My primary goal is to keep a track of various events that takes place in a sample program and based on the events specific handlers are triggered.
These event triggering handlers/functions are not contributing anything to the global objective of the sample program, but are just keeping track over various events in the cpp sample program.
My question is it prossible to create soemthing like custom eventhandlers in cpp?
If yes, is there any tutorial for creating such custom eventhandler?
eg:
Event are like failed to enter while loop. successfully entered while loop, created object, deleted object, changed global variable etc.
The simplest form of event handler is a registered callback function pointer:
enum Events {
FailedEnteringWhileLoop ,
SuccessfullyEnteredWhileLoop ,
};
typedef void(EventHandler*)(Events);
void MyEventHandler(Events ev) {
switch(ev) {
case FailedEnteringWhileLoop:
// Do something
break;
case SuccessfullyEnteredWhileLoop:
// Do something
break;
}
}
EventHandler evh = MyEventHandler;
bool whileLoopEntered = false;
while(condition) {
if(!whileLoopEntered) {
whileLoopEntered = true;
(*evh)(SuccessfullyEnteredWhileLoop);
}
}
if(!whileLoopEntered) {
(*evh)(FailedEnteringWhileLoop);
}
I am looking for events like failed to enter while loop. successfully
entered while loop, created object, deleted object, changed global
variable etc.
The C++ language itself does not track these kinds of things as "events". Generally speaking it doesn't provide hooks into any of the various fundamental activities that happen across code.
So to do what you're asking for requires building an infrastructure yourself and working it into your code in various ways. (Or finding someone else who has done the same sort of work already and made it available. Although you still would have to integrate it into your code.)
To give some idea of what might have to be done:
For creating and deleting objects you can override the new and delete operators. But that doesn't cover stack/local/etc objects. Otherwise you could wedge something the constructors and destructors of every class you want to track, or even have all of them derive from a common base class which encapsulates the tracking.
For changes to a variable, you would have to wrap that variable in a container which only exposes the ability to change it through member functions. Then those could be coded to raise events.
For entering loops... You're out of luck because a loop isn't an entity that can be extended or hooked. You literally have to put some kind of call at every loop you want to track.
As for the rest of the infrastructure, you would probably end up doing something like having all of those various "events" call to some kind of global logging object. If you need different things catch different events over the course of a program, then you might also need to build a way of registering and de-registering listeners (the listeners themselves being based on an interface to derive from or std::function or whatever suits your use case).
But in the end since there isn't an out-of-the-box way provided by the language, you might want to re-consider what you really want and what you hope to achieve with it. In fact you might be better off asking your question in terms how to accomplish the end goal you wanted this for rather than how to do this "event" system.

Implementing Realtime in a Text-Adventure?

I'm making a text-based RPG, and I'd really like to emulate time.
I could just make some time pass between each time the player types something, but id like it to be better than that if possible. I was wondering if multithreading would be a good way to do this.
I was thinking maybe just have a second, really simple thread in the background that just has a loop, looping every 1000ms. For every pass though its loop the world time would increase by 1 sec and the player would regenerate a bit of health and mana.
Is this something that multithreading could do, or is there some stuff i don't know about that would make this not work? (I'd prefer not to spend a bunch of time struggling to learn this if its not going to help me with this project.)
Yes, mutlithreading could certainly do this, but be weary that threading is usually more complicated than the alternative (which would be the main thread polling various update events as part of its main loop, which should be running at least once every 100ms or so anyway).
In your case, if the clock thread follows pretty strict rules, you'll probably be "ok."
The clock thread is the only thread allowed to set/modify the time variables.
The main/ui thread is only allowed to read the time.
You must still use a system time function, since the thread sleep functions cannot be trusted for accuracy (depending on system activity, the thread's update loop may not run until some milliseconds after you requested it run).
If you implement it like that, then you won't even need to familiarize yourself with mutexes in order to get the thread up and running safely, and your time will be accurate.
But! Here's some food for thought: what if you want to bind in-game triggers at specific times of the day? For example, a message that would be posted to the user "The sun has set" or similar. The code needed to do that will need to be running on the main thread anyway (unless you want to implement cross-thread message communication queues!), and will probably look an awful lot like basic periodic-check-and-update-clock code. So at that point you would be better off just keeping a simple unified thread model anyway.
I usually use a class named Simulation to step forward time. I don't have it in C++ but I've done threading in Java that is stepping time forward and activating events according to schedule (or a random event at a planned time). You can take this and translate to C++ or use to see how an object-oriented implementation is.
package adventure;
public class Simulation extends Thread {
private PriorityQueue prioQueue;
Simulation() {
prioQueue = new PriorityQueue();
start();
}
public void wakeMeAfter(Wakeable SleepingObject, double time) {
prioQueue.enqueue(SleepingObject, System.currentTimeMillis() + time);
}
public void run() {
while (true) {
try {
sleep(5);
if (prioQueue.getFirstTime() <= System.currentTimeMillis()) {
((Wakeable) prioQueue.getFirst()).wakeup();
prioQueue.dequeue();
}
} catch (InterruptedException e) {
}
}
}
}
To use it, you just instantiate it and add your objects:
` Simulation sim = new Simulation();
// Load images to be used as appearance-parameter for persons
Image studAppearance = loadPicture("Person.gif");
// --- Add new persons here ---
new WalkingPerson(sim, this, "Peter", studAppearance);
I'm going to assume that your program currently spends the majority of its time waiting for user input - which blocks your main thread irregularly and for a relatively long period of time, preventing you from having short time-dependant updates. And that you want to avoid complicated solutions (threading).
If you want to access the time in the main thread, accessing it without a separate thread is relatively easy (look at the example).
If you don't need to do anything in the background while waiting for user input, couldn't you write a function to calculate the new value, based on the amount of time that has passed while waiting? You can have some variable LastSystemTimeObserved that gets updated every time you need to use one of your time-dependant variables - calling some function that calculates the variable's changed value based on how much time has passed since it was last called, instead of recalculating values every second.
If you do make a separate thread, be sure that you properly protect any variables that are accessed by both threads.

Iterating without incurring the cost of IF statements

My question is based on curiosity and not whether there is another approach to the problem or not. It is a strange/interesting question, so please read it with an open mind.
Let's assume there is a game loop that is being called every frame. The game loop in turn calls several functions through a myriad of if statements. For example, if the user has GUI to false then don't refresh the GUI otherwise call RefreshGui(). There are many other if statements in the loop and they call their respective functions if they are true. Some are if/if-else.../else which are more costly in the worst case. Even the functions that are called, if the if statement is true, have logic. If user wants raypicking on all objects call FunctionA(), if user wants raypicking on lights, call FunctionB(), ... , else call all functions. Hopefully you get the idea.
My point is, that is a lot of redundant if statements. So I decided to use function pointers instead. Now my assumption is that a function pointer is always going to be faster than an if statement. It is a replacement for if/else. So if the user wants to switch between two different camera modes, he/she presses the C key to toggle between them. The callback function for the keyboard changes the function pointer to the correct UpdateCamera function (in this case, the function pointer can point to either UpdateCameraFps() or UpdateCameraArcBall() )... you get the gist of it.
Now to the question itself. What if I have several update functions all with the same signature (let's say void (*Update)(float time) ), so that a function pointer can potentially point to any one of them. Then, I have a vector which is used to store the pointers. Then in my main update loop, I go through the vector and call each update function. I can remove/add and even change the order of the updates, without changing the underlying code. In the best case, I might only be calling one update function or in the worst case all of them, all with a very clean while loop and no nasty (potentially nested) if statements. I have implemented this part and it works great. I am aware, that, with each iteration of the while loop responsible for iterating through the vector, I am checking whether the itrBegin == itrEnd. More specifically while (itrBegin != itrEnd). Is there any way to avoid the call to the if statements? Can I use branch prediction to my advantage (or am I taking advantage of it already without knowing)?
Again, please take the question as-is, i.e. I am not looking for a different approach (although you are more than welcome to give one).
EDIT: A few replies state that this is an unneeded premature optimization and I should not be focusing on it and that the if-statement(s) cost is minuscule compared to the work done in all the separate update functions. Very true, and I completely agree, but that was not the point of the question and I apologize if I did not make the question clearer. I did learn quite a few new things with all the replies though!
there is a game loop that is being called every frame
That's a backwards way of describing it. A game loop doesn't run during a frame, a frame is handled in the body of the game loop.
my assumption is that a function pointer is always going to be faster than an if statement
Have you tested that? It's not likely to be true, especially if you're changing the pointer frequently (which really messes with the CPU's branch prediction).
Can I use branch prediction to my advantage (or am I taking advantage of it already without knowing)?
This is just wishful thinking. By having one indirect call inside your loop calling a bunch of different functions you are definitely working against the CPU branch prediction logic.
More specifically while (itrBegin != itrEnd). Is there any way to avoid the call to the if statements?
One thing you could do in order to avoid conditionals as you iterate the chain of functions is to use a linked list. Then each function can call the next one unconditionally, and you simply install your termination logic as the last function in the chain (longjmp or something). Or you could hopefully just never terminate, include glSwapBuffers (or the equivalent for your graphics API) in the list and just link it back to the beginning.
First, profile your code. Then optimize the parts that need it.
"if" statements are the least of your concerns. Typically, with optimization, you focus on loops, I/O operations, API calls (e.g. SQL), containers/algorithms that are inefficient and used frequently.
Using function pointers to try to optimize is typically the worst thing you can do. You kill any chance at code readability and work against the CPU and compiler. I recommend using polymorphism or just use the "if" statements.
To me, this is asking for an event-driven approach. Rather than checking every time if you need to do something, monitor for the incoming request to do something.
I don't know if you consider it a deviation from your approach, but it would reduce the number of if...then statements to 1.
while( active )
{
// check message queue
if( messages )
{
// act on each message and update flags accordingly
}
// draw based on flags (whether or not they changed is irrelevant)
}
EDIT: Also I agree with the poster who stated that the loop should not be based on frames; the frames should be based on the loop.
If the conditions checked by your ifs are not changing during the loop, you could check them all once, and set a function pointer to the function you'd like to call in that case. Then in the loop call the function the function pointer points to.