# GUI events system redesign

## Recommended Posts

MajinMusashi    182
CONTEXT: I'm in the final stages of development of my C++ and OpenGL GUI, and I've found that the current events system design need improvements regarding flexibility (the user hasn't much control over the entire thing). I plan to use the "listeners" approach (implemented in both Java AWT and Java Swing). PROBLEM: Besides everything is good on paper, a little detail still annoys me: WHAT will be responsible for handling the events triggered by the GUI. The "Java way" seems a little bloatead, as an entire class must be created (inherited from, for example, "ActionListener"), a pure virtual method must be implemented (for example, "actionPerformed( ActionEvent e )"), and then passed to the "addListener" method. Look at the example bellow:
// Java way (pseudo-code)
// User class created ONLY to handle "action events" (eg. mouse click) on button1
class User_ActionListenerButton1 : public ActionListener {
void actionPerformed( ActionEvent e ) {
// Do whathever the user wants, like close the application or change the background color
}
};

// "Bind" the listener to a button, so the "actionPerformed" method will be invoked
// when an "action event" is triggered
JButton button1;

QUESTION: Do you know any solution that will do the same as the "Java way", but without having to spreaded "event classes" all over the application? Or do you think this is the way to go? The solutions that came in mind that could help me out are to use function pointers (I really dislike them, but they could give me enough freedom) or to make a SINGLE class inherit from MANY listener classes, like this:
class User_ListenerButton1 : public ActionListener : FocusListener : KeyListener {
void ActionPerformed( ActionEvent e ) { ... }
void FocusPerformed( FocusEvent e ) { ... }
void KeyPerformed( KeyEvent e ) { ... }
};

JButton button1;

Thanks a lot, guys! Please, send me some suggestions!

##### Share on other sites
snk_kid    1312
Quote:
 Original post by MajinMusashido you think this is the way to go?

I don't, i recommend using a generic signals & slots library like Boost.Signals (it's not the only one available) that allows you to use free & member functions, and "functors".

##### Share on other sites
Simagery    732
I'd definitely go the "C#" route on this one... build some type of delegate/functor object into your GUI and bind events to functions that way instead of binding to interfaces. In general, it shouldn't be necessary to create new *types* to respond to events, just *functions* to handle them.

##### Share on other sites
Telastyn    3777
In C++, I like to use boost::functions for that.

class button{protected:    boost::function<void()>     onClick;public:    void      set_onClick(boost::function<void()> f){onClick=f;}    void      click(){if(onClick){onClick();}};struct echo_functor{    string  s;    void operator()(){        cout << s;    }    void echo_mem_function(){        cout << s;    }    echo(string ss):s(ss){}};void echo_function(){    cout << "moo.";}button         b1,b2,b3;echo_functor   echoer("moo.");b1.set_onClick(echo_function);b2.set_onClick(echoer);          // uses operator()b3.set_onClick(boost::bind(&echo_functor::echo_mem_function, echoer, _1));b1.click();b2.click();b3.click();// same thing, 3 ways.

##### Share on other sites
TrueTom    110
Use FastDelegates to bind your event to everything that has the right signature.

##### Share on other sites
lightbringer    1070
For variety, here's another solution: The way I'm doing this (in java) is by moving all the event handling code to scripts. UI classes have script hooks, and they implement their Listener interfaces with a call to the scripting system to execute the respective script that was assigned for the event. The scripts to be used are specified during interface definition (ie: in the xml files). Seems elegant to me, although I'm sure someone will find a reason why this is bad or ugly. ^_^;

##### Share on other sites
Simagery    732
Quote:
 Original post by TrueTomUse FastDelegates to bind your event to everything that has the right signature.

Another vote for FastDelegates... it's what I use. And even though it relies on specific implementation details of the compiler (usually a no-no in my book), the fact that it works on virtually all major compilers in use (including the big two, GCC and MSVC.NET), it's a safe bet in my mind.

##### Share on other sites
snk_kid    1312
Quote:
Original post by Simagery
Quote:
 Original post by TrueTomUse FastDelegates to bind your event to everything that has the right signature.

Another vote for FastDelegates... it's what I use.

The only issue with that (feature-wise) as far as i'm aware it does not come with direct support for multicasting or/and asynchronous calls although they can be added it's not like .NET delegates in every-sense. A signals & slots framework almost always comes with support for multicasting out of the box.

##### Share on other sites
Simagery    732
Quote:
Original post by snk_kid
Quote:
 Original post by SimageryAnother vote for FastDelegates... it's what I use.

The only issue with that (feature-wise) as far as i'm aware it does not come with direct support for multicasting or/and asynchronous calls although they can be added it's not like .NET delegates in every-sense. A signals & slots framework almost always comes with support for multicasting out of the box.

I always forget about that. The first thing I did with the FastDelegate code was to add multi-cast support (very trivial, suprised the author didn't do it originally).

Also, what do you mean by "asynchronous" delegates? I always use them as a nicer, cleaner form of function pointer. I'm assuming you don't actually mean delegating on a separate thread but instead mean gathering dispatches then dispatching them all at once at a later point? An example, perhaps?

##### Share on other sites
snk_kid    1312
Quote:
 Original post by SimageryAn example, perhaps?

clickly

##### Share on other sites
Simagery    732
Quote:
Original post by snk_kid
Quote:
 Original post by SimageryAn example, perhaps?

clickly

Alright, I guess that's what I expected from the name. I could see where that would definitely be useful in a GUI scenario, but I personally don't use delegates to that end -- I use them as better callbacks. To be honest, considering the dramatic difference between an asychronous delegate and a synchronous delegate I'd probably call the asynchronous delegate something different, just to impart to the user (and future code reader) that it's not a synchronous call and thus non-equivalent to a function call.

So, have you added asynch support to the FastDelegate example, or does the boost libraries provide that? If so, how is the threading pool implemented (or does the C++ version just spawn a new thread pthreads style?)?