How do you manage user interface events?

Started by
19 comments, last by Kwizatz 14 years, 5 months ago
Hi friends! What do you think about this topic: Let's say I have these classes: CApp CGame CButton CApp creates a CGame instance, and this one create several instaces of CButton, which has a method called Released(). How can I know which button is being pressed from inside CButton class? How can I send a messege telling a certain button was released (or pressed, it does not matter now) to an appropiate class instance? Should I create another class called CEventProcessor or CEventHandler to centralize all my events and send them to an apropiate class? Should I give to my CButton instance a name when I instantiate it (button name) and on Released() code execute/write something like a switch-case with that name? Thanks a lot for your help.
I've seen things you people wouldn't believe. Attack ships on fire off the shoulder of Orion. I watched C-beams glitter in the dark near the Tannhauser gate. All those moments will be lost in time, like tears in rain. Time to die.
Advertisement
The best way of handling 'things' happening and need to alert other 'things' is by using the event delegate model. I work on a commercial game that has a very large and complex UI and it was orignally architected using messages, we are moving over to events and delegates and things are becoming much more simple because of it. I suggest you look at how C# solves this problem.

Hope that helps,
Quote:Original post by Dave
The best way of handling 'things' happening and need to alert other 'things' is by using the event delegate model. I work on a commercial game that has a very large and complex UI and it was orignally architected using messages, we are moving over to events and delegates and things are becoming much more simple because of it. I suggest you look at how C# solves this problem.

Hope that helps,


Thanks for help, I forgot to say I am using C++/OpenGL. Do you mean using any software engineering pattern?
I've seen things you people wouldn't believe. Attack ships on fire off the shoulder of Orion. I watched C-beams glitter in the dark near the Tannhauser gate. All those moments will be lost in time, like tears in rain. Time to die.
Seen some interesting stuff about so-called "Immediate mode" guis lately in which you effectively specify the GUI like:

res = gui.button("some text");if(res.state == button.pressed){  // do button stuff, maybe fire an event off to the game or something}


It's interesting because it does away with the whole event model and simplifies creating game guis, which are normally quite small anyway.

I believe Unity uses this approach too.
Quote:Original post by evolutional
Seen some interesting stuff about so-called "Immediate mode" guis lately in which you effectively specify the GUI like:

res = gui.button("some text");if(res.state == button.pressed){  // do button stuff, maybe fire an event off to the game or something}


It's interesting because it does away with the whole event model and simplifies creating game guis, which are normally quite small anyway.

I believe Unity uses this approach too.


I looked into this as well and still couldn't quite see the benefit. But hey :D.
Quote:Original post by evolutional
Seen some interesting stuff about so-called "Immediate mode" guis lately in which you effectively specify the GUI like:

res = gui.button("some text");if(res.state == button.pressed){  // do button stuff, maybe fire an event off to the game or something}


It's interesting because it does away with the whole event model and simplifies creating game guis, which are normally quite small anyway.

I believe Unity uses this approach too.


Wow, I'm currently working on a minimalistic UI system, and that is ridiculously simple, and I don't see any obvious drawbacks.

I was going to use function pointers that are triggered on press. I feel like I completely over-complicated the problem.

Unless you need something more powerful (i.e. if you're making an in-game editor or something), I'd recommend going with the "immediate mode" UI system.

On the other hand, I'm not too fond of it myself lol. Dave's got the right idea, the best solution is to use delegates. The easiest way is to use BOOST; either the fuction handler or slots & signal system. Here's how my old system was setup:

struct ClickEventArguments;typedef boost::function<void (Control *, ClickEventArguments &)> ControlClickHandler;class Button : Control{public:    ControlClickHandler OnClick;};// in CGame::Initialize() or whatevermyButton.OnClick = boost::bind(&CGame::myButton_OnClick, this, _1, _2);// in CGamevoid myButton_OnClick(Control *Sender, ClickEventArguments &Arguments){    // do something}


As a note, the function has the Sender argument so that you can use the same function for multiple controls.

Anyway, that's how I would set it up (hopefully nobody notices that this is pretty much exactly how WinForms works >_> <_<.)
Quote:Original post by evolutional
Seen some interesting stuff about so-called "Immediate mode" guis lately in which you effectively specify the GUI like:

res = gui.button("some text");if(res.state == button.pressed){  // do button stuff, maybe fire an event off to the game or something}


It's interesting because it does away with the whole event model and simplifies creating game guis, which are normally quite small anyway.

I believe Unity uses this approach too.


Sorry, I don't understand it very well, can you explain it more?

Thanks.

BTW, I'm using C++
I've seen things you people wouldn't believe. Attack ships on fire off the shoulder of Orion. I watched C-beams glitter in the dark near the Tannhauser gate. All those moments will be lost in time, like tears in rain. Time to die.
Basically, you keep a handle on the instance of a certain button, and manually check if it is pressed.
Quote:Original post by c_olin
Wow, I'm currently working on a minimalistic UI system, and that is ridiculously simple, and I don't see any obvious drawbacks.

I was going to use function pointers that are triggered on press. I feel like I completely over-complicated the problem.


I might be able to see some drawbacks, for example how exactly do you set/unset the pressed property? having each object query the input system to see if the cursor is on top of it and whether a button is pressed doesn't seem that efficient to me as opposed to propagating a single x,y button state event, and if you do that you're back either to the Observer Pattern or some sort of message system, except you'll be doing the same work again when you iterate over the controls to see which one is pressed if any.

So to me, on one side you're just pressing a button and the light turns on, but behind the wall there's a Rube Goldberg machine making it work.

or am I missing something? [smile]

This topic is closed to new replies.

Advertisement