7
\$\begingroup\$

I've just learned basics of Data oriented programming design, but I'm not very familiar with that yet. I've also read Pitfalls of Object Oriented Programming GCAP 09. It seems that data oriented programming is much better idea for games, than OOP.

I'm just creating my own GUI system and it's completely OOP. I'm thinking if is data oriented programming design applicable for structured things like GUI.

The main problem I see is that every type widget has different data, so I can hardly group them into arrays. Also every type of widget renders differently so I still need to call virtual functions.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Well you can just extract your gui code to scripts and poof, you have data instead of code... But most gui is too complex to be described in anything less then code, sou you still need something like on button click get username from textbox and invoke some game event with username as argument \$\endgroup\$
    – Kikaimaru
    Sep 27, 2012 at 14:46
  • 1
    \$\begingroup\$ Of course it is, why wouldn't it be applicable? Data oriented development is simply a different way to structure your code, it doesn't mean that you can't accomplish something that you normally would with OOP. \$\endgroup\$
    – Dadgron
    Sep 27, 2012 at 14:46
  • 1
    \$\begingroup\$ (Quite a long time ago now) Mike Dunlavey outlined a technique on Stack Overflow called differential execution, which is one possible approach for a data-oriented UI API. \$\endgroup\$
    – user744
    Sep 27, 2012 at 21:19

3 Answers 3

4
\$\begingroup\$

First of all, like snake5 said, only use DOD when necessary. If your GUI code already works and takes only 1-5% execution time, don't even try to rewrite it. It's not worth it. If you haven't written most of it, you could consider it, but only if you have a really fancy UI that's going to take a lot of processing power. Or maybe you just feel like writing some code using DOD, in that case just go ahead and play with it.

Now to answer your question. Yes you're right, different widgets have different data and maybe they're rendered differently. Are they really that different though? I don't know the features you need for your UI, but I can imagine lots of components share a lot of data. Some examples:

  • All widgets have a position and size (and bounding box)
  • Buttons, checkboxes, textboxes, etc all listen to mouse events using the bounding box
  • Images, buttons, labels can all have images to render
  • Buttons, labels, textboxes, textfields etc all have to render text

I'm sure there are more similarities if you take some more time to think about it. So we've established similarities and if you look at the description above, you can see that each widget type is composed of several (let's call them) "components". Let's take a button for example, it consists of:

  • Spatial element
  • Text renderer
  • Image renderer
  • Mouse handler

While a textbox consists of:

  • Spatial element
  • Text renderer
  • Mouse event listener
  • Keyboard handler

So let's create a struct (or class) with the data for each component. For instance:

struct Spatial {
    vector2 position;
    vector2 size;
    float depth;
    rectangle boundingBox;
    bool dirty; //set to true when pos or size is changed, calculates bBox again
}

Then, create a manager for Spatial. The manager has a flat list of Spatial structs, and when update is called it will go through all of them and update the boundingBox if dirty is true Do the same for each of the other components. TextRenderer updates and renders text on the screen, MouseHandler can call button callbacks or set checkbox state or determine which element has focus. KeyboardHandler updates the text of a textfield if it has focus.

Now, when we want to add a button, we don't actually add a button, but a set of components to the respective managers. The last thing we need is a UIElement class which has pointers/indices of all the components in the different handlers, so we can find them back, for instance when we want to delete it, or when one component needs info from another component.

So there you have the pitfall of OOP. You think of widgets as an object. Therefore, you naturally come to the conclusion that it's full of unique data and needs a class hierarchy and virtual functions. When you take DOD, you look at the data and you immediately notice the similarities between the widget's data and functionality. By splitting the UI elements into separate components, you can now update these components in batches, which improves things like cache utilization. Another advantage, you've made the codebase a whole lot easier to read. Instead of spreading (and sometimes even duplicating) code over a whole hierarchy of widget classes and subclasses, code is now located in a component that simply does what the name implies.

Now before I leave it at this, a few disclaimers. Let's start with the fact that I just thought this system up while writing. So there is loooots of room for improvement here. Take your time when you create your own system and think things through before you create something. Another thing to note is that I have no idea if my system is that much faster than a OO-based UI system. It depends (as always) on the data, how much there is and what usage patterns there are. Maybe OO is faster in your case. Maybe a hybrid approach works best. I don't know :) My idea is just a simple example of how you can apply DOD principles to what may seem like a perfect example for OOP at first sight.

One last thing, I don't want to take credit for the approach above. It is heavily based on component systems, which are used in lots of games and have been developed by people a lot smarter than I am. If you want to read more about it, there is a lot of info to be found just on google (just search "game component system") or on Stack Exchange.

\$\endgroup\$
6
\$\begingroup\$

Everything depends on (the amount of) data. If you need thousands of UI controls for some reason, it will become very applicable to nearly every part of a GUI system. If all you need is a few windows and buttons, my only advice would be "keep it simple".

P.S. It's not about "structured things vs. arrays" or something like that. It is about designing data and algorithms to work well together. And if OOP weren't so popular, DOD would just be labeled "common sense".

Some stuff for reading about DOD:

There are more publications about this but I picked these two as a good introduction to things. Most of the others were focusing on the heavy stuff that requires some assembly & profiling knowledge.

\$\endgroup\$
1
  • \$\begingroup\$ Could you post some good articles about DOD to correct my understanding. I'll accept it then :) \$\endgroup\$
    – kravemir
    Sep 27, 2012 at 19:07
0
\$\begingroup\$

GUIs tend to be messy and look like Spaghetti Code. Using Model–view–controller with Mediator pattern can help. If your data is in a database, take a look at data binding.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ It could be good answer if it was human readable :) \$\endgroup\$
    – kravemir
    Sep 27, 2012 at 16:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .