M
Mark
I'm writing a game engine and I would like some opinions on the way I
have set it up (good or bad), and how I might improve it.
I'm using OpenGL which utilizes callbacks for events (such as when a
mouse is moved or clicked, the window is displayed or resized, a
keyboard button is pressed, etc). I can only pass in static functions
to the callback functions, which means I can't place the callback
functions inside an appropriate class (my title screen, map editor,
and actual game all have different keyboard functions, display
functions, etc, so it would make sense to separate them into the their
respective classes).
So, my first idea was to place the callback functions in the
appropriate classes but make them all static. However, I needed to
address member variables within those classes, so I had to make all
the member variables static too. This meant I could only have one
instance of each class, which wasn't much of a problem since it
wouldn't make much sense to have more than one title screen, or game
editor, running at the same time. However, what if I wanted to have
multiple dialog boxes popping up over top of each other? That might
cause a problem down the road. Also, it's a major pain to make
everything static, since I have to declare everything twice (once
inside the class, and once outside the class, making use of the double-
colon notation).
Then I had the clever idea of making a "callback wrapper". Each of my
classes (title screen, map editor, etc) inherits this class. The
callback wrapper sets each callback function to a static function,
which "reroutes" the call to a member function. I keep a stack of each
object that is created and call the member function of the object that
is on top of the stack. When the object is destroyed, I pop it off
the stack, and the callback reverts to the previous object. In the
scenario I described above, the top-most dialog box would have
control. This also eliminates the annoyance of having static
variables, and some other tedious aspects. However, I now have 11
object stacks (one for each callback so that one object might get
control of the keyboard, but another might have control of display). I
don't think that will consume too much memory though, since I wouldn't
expect more than about 5 "layers" of dialogs/windows. But I do need to
create an extra stack and wrapper every time I want to add a new
callback.
I'm fairly pleased with the second solution, but comments are welcome.
This however lead me to a new "evil". With the way I have it now, I
create a map editor by calling "new Editor()". This automatically
gives the editor control over displaying, the keyboard, etc., as long
as those functions are defined, otherwise the previous class maintains
control. When I "close" the editor (by hitting escape) I call "delete
this", and the callback wrapper automatically gives control back to
the previous class. My concern is that generally objects should not be
in control of deleting themselves. Might this be an exception? The
other question has to do with memory leaks. What if the user wants to
directly close the program from within the map editor? The map editor
is a layer on top of the title screen. So if I just call "delete this"
and then exit(0) from inside the map editor, the title screen would
never get destroyed, would it? Or is everything freed when a program
exits?
That's all for now, thanks for taking the time to read this.
have set it up (good or bad), and how I might improve it.
I'm using OpenGL which utilizes callbacks for events (such as when a
mouse is moved or clicked, the window is displayed or resized, a
keyboard button is pressed, etc). I can only pass in static functions
to the callback functions, which means I can't place the callback
functions inside an appropriate class (my title screen, map editor,
and actual game all have different keyboard functions, display
functions, etc, so it would make sense to separate them into the their
respective classes).
So, my first idea was to place the callback functions in the
appropriate classes but make them all static. However, I needed to
address member variables within those classes, so I had to make all
the member variables static too. This meant I could only have one
instance of each class, which wasn't much of a problem since it
wouldn't make much sense to have more than one title screen, or game
editor, running at the same time. However, what if I wanted to have
multiple dialog boxes popping up over top of each other? That might
cause a problem down the road. Also, it's a major pain to make
everything static, since I have to declare everything twice (once
inside the class, and once outside the class, making use of the double-
colon notation).
Then I had the clever idea of making a "callback wrapper". Each of my
classes (title screen, map editor, etc) inherits this class. The
callback wrapper sets each callback function to a static function,
which "reroutes" the call to a member function. I keep a stack of each
object that is created and call the member function of the object that
is on top of the stack. When the object is destroyed, I pop it off
the stack, and the callback reverts to the previous object. In the
scenario I described above, the top-most dialog box would have
control. This also eliminates the annoyance of having static
variables, and some other tedious aspects. However, I now have 11
object stacks (one for each callback so that one object might get
control of the keyboard, but another might have control of display). I
don't think that will consume too much memory though, since I wouldn't
expect more than about 5 "layers" of dialogs/windows. But I do need to
create an extra stack and wrapper every time I want to add a new
callback.
I'm fairly pleased with the second solution, but comments are welcome.
This however lead me to a new "evil". With the way I have it now, I
create a map editor by calling "new Editor()". This automatically
gives the editor control over displaying, the keyboard, etc., as long
as those functions are defined, otherwise the previous class maintains
control. When I "close" the editor (by hitting escape) I call "delete
this", and the callback wrapper automatically gives control back to
the previous class. My concern is that generally objects should not be
in control of deleting themselves. Might this be an exception? The
other question has to do with memory leaks. What if the user wants to
directly close the program from within the map editor? The map editor
is a layer on top of the title screen. So if I just call "delete this"
and then exit(0) from inside the map editor, the title screen would
never get destroyed, would it? Or is everything freed when a program
exits?
That's all for now, thanks for taking the time to read this.