Jump to content
  • Advertisement
Sign in to follow this  
Gaiiden

Messaging or Callbacks?

This topic is 5069 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've got a dilemma. When I created my GUI system, I started using Boost Signals to create function callbacks so that game objects could receive data from the UI widgets and act upon that data. All well and good. I think I went with callbacks because that's what I read a lot of GUI systems use. Plus I wanted to look into it anyways, see if I could do it. The problem is that I also already have a quite robust messaging system within my engine. It's already the core of the engine, in fact the callbacks rely on it because the objects first receive messages from the kernel (key presses, mouse clicks, etc) and then act upon that data, and then call back objects. The dilemma I face is that I finally realized I could easily rip out all the callbacks and just use messages instead. Since I can pass arbitrary data with my messages in the form of bitstreams, there's really no need for set callback functions. About the only advantage I can figure callbacks have over my messages is that they provide a more linear flow to the code when it comes to stepping through it. So what I'm wondering here is whether I should ditch callbacks and just stick with my messages, or keep the two combined. If you guys have similar structures in your engine, I'd like to hear how you handle it. Personally I think I went off track implementing callbacks and should have thought to just use messages instead, but if there's some advantage to callbacks over messaging I'm missing I'd like to know about it.

Share this post


Link to post
Share on other sites
Advertisement
As a general rule of thumb: Whenever you can simplify a system where it still retains the same amount of functionality, do it. It means greater readability and easier maintenance later on.

Share this post


Link to post
Share on other sites
I used callbacks in my gui engine, because I have no messaging in engine and it looked simpler.
In your case, I would go with messages only, so engine would use the same system everywhere. And as Enokh pointed oout, it will be probably much simpler, if you have massaging powerful enough.

Share this post


Link to post
Share on other sites
I was under the impression that ALL callback systems had a message loop at their cores, and that callbacks are just a nice way to simplify dispatching messages.

Share this post


Link to post
Share on other sites
Quote:
Original post by C-Junkie
I was under the impression that ALL callback systems had a message loop at their cores, and that callbacks are just a nice way to simplify dispatching messages.

Depends on the implementation of the messaging system. If you have listeners and a message queue that is accessible from every part of the app that wants to broadcast messages you won't necessarily need a message loop.


// pseudo code

void Client::doSomething() {
Message myMessage;
// ...
messageQueue.broadcast(myMessage);
}

// ...
void MessageQueue::broadcast(Message &msg) {
// ...
foreach (listener in listeners) {
if (listener is subscriber_of(msg.Type)) {
listener.onMessage(msg);
}
}
}



...something along that line.

Regards,
Pat.

Share this post


Link to post
Share on other sites
Quote:
Original post by darookie
Depends on the implementation of the messaging system. If you have listeners and a message queue that is accessible from every part of the app that wants to broadcast messages you won't necessarily need a message loop.
You need a message loop somewhere, otherwise it's impossible to poll for input from the user, and the program does nothing.

Share this post


Link to post
Share on other sites
At the abstract level, message systems and callback systems do pretty much the same thing. The major difference is that message dispatching is centralized in a intermediary in a message system, whereas each server dispatches messages directly in a callback system.

The advantages of a message system are flexiblility and convenience. The disadvantages are that such a loose coupling is more prone to bugs and more difficult to debug.

Share this post


Link to post
Share on other sites
Quote:
Original post by C-Junkie
Quote:
Original post by darookie
Depends on the implementation of the messaging system. If you have listeners and a message queue that is accessible from every part of the app that wants to broadcast messages you won't necessarily need a message loop.
You need a message loop somewhere, otherwise it's impossible to poll for input from the user, and the program does nothing.

Yes. I was referring to the engine's internal messaging system, not that of the OS and other external parts (like devices).
Sometimes you don't even need to poll the device (e.g. using the event notification system of DirectInput), though.

Regards,
Pat.

Share this post


Link to post
Share on other sites
I pray for a day when message queues in GUI systems will become a thing of the past. Callbacks have enormously important advantages (easy to debug: if something goes wrong just look at the call stack, type safe: no bit stream idiocy, you clearly see the parameters in the code, taking advantage of language facilities: you can completely replace function calls with messages passing abstract data streams, that'll work but will completely ignore language facilities like *functions*). Please do yourself a favor and leave callbacks.

Note: I may be a little biased. I've worked with a few GUI systems and every time I encountered a message queue it was ten times harder to work with than callbacks.

Share this post


Link to post
Share on other sites
I have a general rule that I use when I run into decisions like this:

make an imperative system first, build a descriptive system on top of it

Imperative systems are naturally more flexible, and easier to write. Once you have an imperative layer, you can then add whatever descriptive layer on top (or more than one, if needed). Basically, it's easier to extend an imperative system than a descriptive one. So with what's easy to begin with.

How does this map to callbacks vs. events? Well you can look at callbacks as an imperative system: the GUI is tell you to do something, and it maps easily into C functions. An event based system, however, is more descriptive: this happened, so you may want to do something...just letting you know.

If you start with callbacks, you can always add events on top. The same goes the other way around too, I suppose: you could add callback on top of events. But events are a more complicated (abstract) system than callbacks, so you'll always be stuck with that complicated layer.

Just look at what happened to Windows message loops: event MS abandonded them in favour of COM dispatches.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!