Jump to content
  • Advertisement
Sign in to follow this  
lordimmortal2

Updating a GUI

This topic is 2141 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'm developing a GUI system for my game and I've been in the process of redoing all of the positional information for widgets and I've run into a problem. 

 

All widgets derive from a base class - GuiObject - that contains all positional information needed for an object: widths, heights, points, bounds, etc. Whenever you modify one of these attributes, the function that changes it calls another function - Update - to make sure everything stays in sync.

 

The problem comes in when trying to extend this to the widgets themselves. A widget sometimes needs to update itself as well - maybe it needs to move a child widget around or adjust its own size based upon some children widgets. My question would be how to handle this as elegantly as possible.

 

If I were to override the Update function in my derived widget classes like so:

void Widget::Update()
{
    GuiObject::Update(); // Update the underlying GuiObject
    // Do updating of the widget itself here
}

And I tried to put a GuiObject's modification function in this overridden function, like trying to change the size of the underlying GuiObject, then it'll get stuck in an infinite loop and crash from a stack overflow:

void Widget::Update()
{
    GuiObject::Update(); // Update the underlying GuiObject
    
    SetSize(100, 100); // Set width and height to 100
}

SetSize will set the width and height of the base GuiObject, and then call Update, which resolves to the Widget::Update overridden function, which calls SetSize, which calls Update, etc.

 

I've tried various things, like splitting up the implementation of GuiObject::Update, setting a new pure virtual function in GuiObject to call at the end of Update to allow derived classes to put in specialized updating logic, but they all result in the end at an infinite loop. 

 

My current thought would be to make new functions in GuiObject that are versions of the functions that you can use to modify a GuiObject with public access, make them protected, give them a new name, not include the GuiObject::Update() call from their public counterparts, and then only call them from within the Update function of derived widget classes; but that doesn't seem very appealing because it'd be very easy to mess up (calling the public version in a derived class' Update function would result in the infinite loop) and it'd essentially double the amount of functions GuiObject has to maintain.

 

So what I'm wondering, for everyone who has made it through this moderate wall of text, is there a better way to handle automatic updating of a widget derived from a GuiObject? The least error prone way to do it would be to somehow update the widget whenever a modifying function from the GuiObject is called and I can't seem to figure out anyway to elegantly break the infinite loop.

 

Thanks for reading and I appreciate any and all replies.

Share this post


Link to post
Share on other sites
Advertisement

Your problem lies in the fact that SetSize calls Update, so if you use these in each other then you have created an infinte loop and the only way to break that is to not call one of them.

 

It is best to not call Update from SetSize and let Update deal with these changes on the next frame, you won't notice a 1-2 frame delay on 30FPS.

Share this post


Link to post
Share on other sites

Your problem lies in the fact that SetSize calls Update, so if you use these in each other then you have created an infinte loop and the only way to break that is to not call one of them.

 

It is best to not call Update from SetSize and let Update deal with these changes on the next frame, you won't notice a 1-2 frame delay on 30FPS.

That would indeed work. What would be the best way to do this? Push the object into a container to be iterated through next frame with its changes marked somehow?

Share this post


Link to post
Share on other sites

 

Your problem lies in the fact that SetSize calls Update, so if you use these in each other then you have created an infinte loop and the only way to break that is to not call one of them.

 

It is best to not call Update from SetSize and let Update deal with these changes on the next frame, you won't notice a 1-2 frame delay on 30FPS.

That would indeed work. What would be the best way to do this? Push the object into a container to be iterated through next frame with its changes marked somehow?

 

Just mark the object as dirty and look for that in the update function, if it is dirty it might also need to check the children. Reset the flag after that update iteration and continue on as usual.

Share this post


Link to post
Share on other sites

 

 

Your problem lies in the fact that SetSize calls Update, so if you use these in each other then you have created an infinte loop and the only way to break that is to not call one of them.

 

It is best to not call Update from SetSize and let Update deal with these changes on the next frame, you won't notice a 1-2 frame delay on 30FPS.

That would indeed work. What would be the best way to do this? Push the object into a container to be iterated through next frame with its changes marked somehow?

 

Just mark the object as dirty and look for that in the update function, if it is dirty it might also need to check the children. Reset the flag after that update iteration and continue on as usual.

 

Done. And it works. Thanks a bunch for the help.

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!