• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Tispe

Struct with child struct

13 posts in this topic

Hi

 

I am pondering how I should implement a GUI class. I figured I should have a root parent and then have child windows attached to that root parent. But how should the parent and the child be connected? Should I "new" each child and put a pointer to the child on the vector? Should the vector itself be a pointer to a vector which can hold children? What makes more sense, heap or stack or something in between?

 

struct GuiWindow
{
WinParam parameters;
std::vector<WindowObject> WindowObjects;
std::vector<GuiWindow> ChildWindows;
}
struct GuiWindow
{
WinParam parameters;
std::vector<*WindowObject> WindowObjects;
std::vector<*GuiWindow> ChildWindows;
}
struct GuiWindow
{
WinParam parameters;
std::vector<WindowObject> *WindowObjects;
std::vector<GuiWindow> *ChildWindows;
}
struct GuiWindow
{
WinParam parameters;
std::vector<*WindowObject> *WindowObjects;
std::vector<*GuiWindow> *ChildWindows;
}

 

0

Share this post


Link to post
Share on other sites
Chances are very small that your child elements will actually all be of the same type. You might have child buttons, child text boxes, child scrollbars, etc. Since you can't stuff different derived objects into a vector of base objects by value, you need to make a vector of (smart) pointers. And since a window with child elements is a pretty common use case, I'd go with holding the vector by value rather than by pointer.
2

Share this post


Link to post
Share on other sites

I presume where you've written *Type you actually meant Type*.

 

The simplest solution is the first. If you need polymorphism, then the second option (corrected for the above) is what you want - though use smart pointers if possible. Making the vectors pointers is unnecessary.

 

[quote]

What makes more sense, heap or stack or something in between?

[/quote]

If you can allocate objects on the stack, do. However, don't bend over backwards to achieve this, the heap is fine too. Particularly for a GUI, you aren't likely to be allocating often so performance probably isn't a concern.

 

The main thing is to ensure you leverage RAII where possible so your GUI doesn't leak - hence the smart pointer suggestion.

0

Share this post


Link to post
Share on other sites

You might also consider going with some form of immediate mode GUI, and doing away with the class structure altogether.

 

It's not necessarily a panacea, but it's a concept well worth wrapping your mind around. IMGUIs also tend to be much simpler than traditional retained GUI frameworks, especially for small-scale projects.

1

Share this post


Link to post
Share on other sites
As rip-off mentioned, it's Type* not *Type. Also, a vector of pointers is completely proper, but a pointer to a vector is definitely not what you want.
 
struct GuiWindow
{
WinParam parameters;
std::vector<WindowObject*> WindowObjects;
std::vector<GuiWindow*> ChildWindows;
}

But isn't a Window a type of object itself? Most widget-based GUIs have buttons and text entry fields and pop-up windows and child-windows and toolbars and tooltips are inherit from the same base class. Either 'inherit' in the C++ sense, or in just the 'concept' of inheritance, without C++ inheritance.

So:
class WindowObject //Also often called 'widgets', but not always.
{
    public:
    WindowObject(WindowObject *parent);

    //Overridable function to handle a mouse click. The default implementation forwards it to whatever child window
    //at that location, and that child returns true if it handled the event, or false if it ignored it, letting
    //the event propagate to the bottom of the child hierarchy (which is visibly the widgets 'on top' of everything), before
    //bubbling back up through all the parent windows.
    virtual bool onMouseClick(const MouseClickEvent &mouseClick);
    virtual bool onMouseMove(const MouseMoveEvent &mouseMove);
    virtual bool onKeyPress(const KeyPressEvent &keyPress);
    virtual bool onShow();
    virtual bool onHide(); 
    
    //...and a half-dozen other events.

    private:
    unsigned int posX, posY; //Relative to the parent's position.
    unsigned int width, height;
    std::vector<WindowObject*> children; //Any buttons, sub-windows, pop-up windows, side-panels, text edits, text objects, image objects, etc...
};
0

Share this post


Link to post
Share on other sites
You might also consider going with some form of immediate mode GUI, and doing away with the class structure altogether.

 

It's not necessarily a panacea, but it's a concept well worth wrapping your mind around. IMGUIs also tend to be much simpler than traditional retained GUI frameworks, especially for small-scale projects.

 

This made no sense to me at all. Is there a tutorial that explains this concept better?

0

Share this post


Link to post
Share on other sites

Looking into IMGUI I find it hard to belive it is "that much" simpler then the standard RMGUI as it claims. Because every button, window, slide, label and list still needs to be defined somewhere. IMGUI just puts that away and says "it is not my responsibility", but then IMGUI is not a GUI is it? It is just a wrapper for a sprite or text drawcall...

 

If I were to try and roll my own IMGUI class I still need a place that retains all info on the layout of the GUI, what textures different buttons have etc. And what better place to keep that information other then inside the IMGUI class? Then the IMGUI class suddenly transforms into a RMGUI class.

 

I just don't get it is what I am trying to say :p

0

Share this post


Link to post
Share on other sites

So... how does people do IMGUI in terms of defining the gui layout? Say I have windows that contain 20 buttons, a health bar, a text edit box, some labels, check boxes and so on. Where would I go about saving where each of these wedgets gets placed on the screen? I surely can't have each widget as a global or static variable? So is it implied that the IMGUI class should contain a std::vector<widget*> which holds this info?

 

I think it is just too easy to claim the IMGUI class is not responsible for saving this data. What am I missing here?

0

Share this post


Link to post
Share on other sites
In IMGUI, each widget is a function call. All the information needed to create it goes into the function parameters. It isn't stored anywhere, other than in the code.

You call the function every frame, and that's your button. No initialisation, no clean-up, and no callbacks. In many cases, that really is simpler.
0

Share this post


Link to post
Share on other sites
Hi there! Just registered in, only to shout out my 2 cents on this biggrin.png

Around 3 years ago I have made my own IMGUI, heavily based on sol's tutorials mentioned above, but using pure OpenGL instead of SDL. It has no fancy stuff, just the usual suspects of widgets. Button, Slider, Checkbox, Group box. ID's are hardcoded, and for the layout I have a rectangle object that I offset by its height or width via rect.NextRow() or rect.NextCol(). Its pretty clear to me that this is most useless for any larger project. However, it really shines when I quickly want to try something out. Some voronoi library, a new particle system or whatever comes along while surfing the web. I simply include my IMGUI library and can most effortlessly expose variables to the GUI. Lets say I have a softbody simulation going on, and I want to have the damping variable accessible, I just put something like

gui.rect.NextRow();
gui.Slider(109, &damping, 1.0f, 50.0f, "Damping");

into the code and I am done. Nothing more neccessary. For me it kinda feels a little bit like the console for OpenGl based applications. It is ridiculously simple, but comes in too handy to be neglected smile.png

cheers, boogi Edited by Boogiwoogie
1

Share this post


Link to post
Share on other sites

Thanks boogi for your input.

 

I have some more questions if you don't mind to answer.

 

Since you want to be able "to widget" any variable in the whole application, then you need access to the GUI instance  (i'm using C++ here) in all of the code. Meaning you need to either pass the GUI around to all parts of the code as a parameter, make a singleton or a global. People advise against the last two options. How would you get access to the GUI from any part of the application?

 

Also, before rendering the scene there is alot of stuff to be done. And in IMGUI it is before you render you pass through a variable you want to display with a widget. So in my mind, the IMGUI needs carry with it a render target and make a scene for each widget you want to draw... How  would this then affect performance when the GUI keps using drawcalls in all parts of the application?

 

The next logical solution is to defer the draws until the scene is drawn in the render code. Piling up the drawcalls into a vector to be drawn at a later time. So yet again we need to carry retained data for each widget in the GUI. That means a copy of any value, text, textures and layout info for each widget to complete the defered rendering. Only the functionality of the widget is immediate in where you place the code.

 

Is there a solution to this I don't see here?

0

Share this post


Link to post
Share on other sites

[quote name='Tispe' timestamp='1358450824' post='5022615']
Since you want to be able "to widget" any variable in the whole application, then you need access to the GUI instance (i'm using C++ here) in all of the code. Meaning you need to either pass the GUI around to all parts of the code as a parameter, make a singleton or a global. People advise against the last two options. How would you get access to the GUI from any part of the application?
[/quote]

Good point there. The good thing is that the main loop (the "update frame" method, not the "render frame") should have access to all data that is dealt with. So you would define your IMGUI object there. The bad part is all the private variables of your data. In the example above, if the softbody object has SetDamping() and GetDamping() methods around a private variable, it just won't work as easily. I can recall making variables public for that purpose, which is ugly. Maybe some pedantic OO-guru may come up with some generic-template-based-operator-overloading-behind-the-back-reflection-super-solution to this to make it look like OO where it isn't. I didn't bother tho.

 

[quote name='Tispe' timestamp='1358450824' post='5022615']
Also, before rendering the scene there is alot of stuff to be done. And in IMGUI it is before you render you pass through a variable you want to display with a widget. So in my mind, the IMGUI needs carry with it a render target and make a scene for each widget you want to draw... How would this then affect performance when the GUI keps using drawcalls in all parts of the application?
[/quote]

"Make a scene" sounds like setting up a scene graph for a widget smile.png Well, It makes use of a pretty regular graphics class which provides basic drawing for OpenGL. Nothing too complex here. It uses the main (and only) OpenGL context. And its based on vertex arrays, all draw calls put vertices/colors into point/line/triangle arrays. Just for the record, its a cheap and hackish port of the http://code.google.com/p/glcanvas/ library. The 2D part of it. Strings are rendered into textures and glDeleteTexture'd when the string is not drawn for 5 frames.

 

[quote name='Tispe' timestamp='1358450824' post='5022615']
The next logical solution is to defer the draws until the scene is drawn in the render code. Piling up the drawcalls into a vector to be drawn at a later time. So yet again we need to carry retained data for each widget in the GUI. That means a copy of any value, text, textures and layout info for each widget to complete the defered rendering. Only the functionality of the widget is immediate in where you place the code.
[/quote]

Well, I wouldn't say that filled up vertex and text arrays is a copy of the variables and its layouts. So "No" to that part (in my case! you may do it differently).

However, the last part is so true and is outing you as someone who has fully understood the concept. Only the interface to the GUI is immediate! Yes! In fact, it is up to you how much data is stored "behind the scenes". It is implementation details. It may even store more data than a retained mode GUI.

0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0