So, back again, still working on My First Shitty C++/SDL2 Game Engine.
Plenty of progress. I have my renderer chugging away slapping pretty things all over the screen, a system for creating/caching text textures from ttfs, and a handful of gui objects reading mouse input and talking back and forth with data-only objects. Wow!
So... I've gotten this far without actually having ever used inheritance. Just now dipping my toe in with my GUI classes, but I suspect the way I'm doing things can definitely be improved on.
What I have right now is a base class "GUI_object" that has nothing in it but three pure virtual methods representing the three things a GUI object will ever need to do: "draw()", "handleinput()", and "update()". Everything so far just defines their own implementation of those, and then all the GUI objects are added (via unique_ptr) to a vector which the game loop goes through and calls each function on at the appropriate time.
This has a pretty obvious flaw: Every derived GUI_object uses one-or-more of those functions, but not necessarily
all of them. You could have images that need to be draw()n and update() their appearance from a data-only object but couldn't care less about input, or invisible objects which are never draw()n but DO need to handeinput()... etc.
Right now I'm just leaving those functions empty when not needed, which is obviously not ideal since they're still being called regardless. The other thing I wanted to consider was the ability to turn the three features on and off separately for each thing, which would involve tracking whether they
can be drawn as well as whether they
should currently be drawn. Haven't got that far yet but it seems like a good idea?
So... The idea I've been mulling over for improving things goes something like:
Instead of having one GUI_object base class, I have three: GUI_drawable, GUI_interactive, GUI_updatable, each of which contain nothing but a pure virtual method (e.g. draw()) and a boolean showing whether it should currently be used (e.g. currently_visible=true), plus ways to change/check said boolean. Then, the derived objects inherit from each of the three they actually need and implement their own versions of the methods.
Then, when initializing all the GUI stuff, instead of having one vector of unique_ptr GUI_objects, I have three vectors of shared_ptrs to my three base types. An object with more than one base class would end up in multiple vectors. Then the rendering step is just calling draw() on all the GUI_drawable-derived objects, and the input handling step just calls handleinput() on all the GUI_interactive-derived objects, etc.
So... Can anyone tell me if this is stupid?
My reading so far has definitely given me the impression that multiple inheritance is a Bad Thing That Will Cause You Future Sadness, but it seems like this case would be pretty safe... right?
...Also, my earliest idea for initializing was to keep the GUI_object base class and have the other three bases derive from it, so I could still have one master GUI_object vector with unique_ptrs, and then just somehow go through it and use it to automatically populate the three derived vectors with raw (non-owning) pointers. But I have no idea how to do that or if the only-real-benefit of keeping all my GUI_object ownership centralized in one place is actually worth the trouble. I also can't think of any methods/variables that would actually belong in the base GUI_object class in that case, and leaving it empty seems... weird.
(I understand I am reinventing the wheel and it's probably coming out a
little bit square, but I'm trying to learn.)