Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Game Engine Design Questions

Reply
Thread Tools

Game Engine Design Questions

 
 
Mark
Guest
Posts: n/a
 
      01-11-2008
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.
 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      01-11-2008
Mark wrote:
> [... first solution, second solution ...]
>
> I'm fairly pleased with the second solution, but comments are welcome.


Looks acceptable. If your objects are really "stacked" on top of
each other, why not follow the same concept in the object model?
I think you did OK.

> 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.


Now, you need to think that if your object covers everything, you
might want to make it control everything but not necessarily by
doing anything meaningful. If something only responds to 'Enter'
key (and no buttons exist in that window), you still might want to
"capture" the mouse, but simply ignore any events...

> 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?


You could do it that way. Or you could simply let the program know
that your eidtor is no longer in business. As soon as this event
is dispatched (queued), the program will delete the editor at the
moment of processing that event.

It is usually better that the _owner_ disposes of objects it owns.

> 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 signal goes to the program, the program shuts down the editor,
then closes.

> 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 unspecified in the language.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
 
 
 
Mark
Guest
Posts: n/a
 
      01-12-2008
On Jan 11, 2:31 pm, "Victor Bazarov" <(E-Mail Removed)> wrote:
> You could do it that way. Or you could simply let the program know
> that your eidtor is no longer in business. As soon as this event
> is dispatched (queued), the program will delete the editor at the
> moment of processing that event.
>
> It is usually better that the _owner_ disposes of objects it owns.


Just thinking about this for a bit. I have a Main class that simply
brings up the TitleScreen at the start of the program.

Main::Main()
{
new TitleScreen();
}

Since it created the TitleScreen, it should be responsible for
deleting it. So, I could set up a pointer like

TitleScreen *ts = new TitleScreen();

and then I could

delete ts;

When it's done. That's fine. But how is the TitleScreen supposed to
signal the Main class? There is no function that returns to Main, Main
is no longer control of the idle() loop, so it can't periodically
check for any boolean flags. The only thing I can think of is to set
up yet another callback. When TitleScreen decides its done, it calls
some function in Main to let it know that it's done. But that means
that TitleScreen also needs to know who created it, so it can call the
appropriate function, so then I need to do something like

TitleScreen *ts = new TitleScreen(this);

Don't I? Is that really a better solution?

It does however, solve the other problem of cleaning up. If
TitleScreen can inform Main that it's done, then it doesn't need to
call exit(0) and Main can properly finish deleting any other data.

I guess then I should ask, what is the best way for me to make my
objects communicate to each other? (Can anyone point me to an
article?) I've never had to do anything quite like that before.

> Now, you need to think that if your object covers everything, you
> might want to make it control everything but not necessarily by
> doing anything meaningful. If something only responds to 'Enter'
> key (and no buttons exist in that window), you still might want to
> "capture" the mouse, but simply ignore any events...


I just include an empty function. That way it keeps control, but
doesn't do anything.
 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      01-12-2008
* Mark:
>
> I have a Main class that simply
> brings up the TitleScreen at the start of the program.
>
> Main::Main()
> {
> new TitleScreen();
> }
>
> Since it created the TitleScreen, it should be responsible for
> deleting it. So, I could set up a pointer like
>
> TitleScreen *ts = new TitleScreen();
>
> and then I could
>
> delete ts;
>
> When it's done. That's fine. But how is the TitleScreen supposed to
> signal the Main class? There is no function that returns to Main, Main
> is no longer control of the idle() loop, so it can't periodically
> check for any boolean flags.


The above looks very much like functions. It's seems you're using
constructors as functions. There are some cases where that is
appropriate, but I think you would be better served by doing

void titleScreen()
{
// ...
}

int main()
{
titleScreen();
}

Cheers, & hth.

- Alf

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
Reply With Quote
 
Mark
Guest
Posts: n/a
 
      01-12-2008
On Jan 11, 5:55 pm, "Alf P. Steinbach" <(E-Mail Removed)> wrote:
> The above looks very much like functions. It's seems you're using
> constructors as functions. There are some cases where that is
> appropriate, but I think you would be better served by doing
>
> void titleScreen()
> {
> // ...
> }
>
> int main()
> {
> titleScreen();
> }
>



Not all my constructors look like that. Some of them need to set
member variables, which isn't possible with a static function.
Basically, I'm making the constructors responsible for doing all the
loading, which is necessary to do before calling any of the display(),
idle(), keyboard() etc functions. The reason I made Main() a class was
so that I could have a base layer for my callback functions. For
example, it's in charge of the reshape() function, which none of the
other "layers" need to override. It also prevents errors when
attempting to pop off the TitleScreen (accessing empty stacks), since
the Main class should never be deleted. It did occur to me that I was
using the constructors a bit like ordinary functions, but I think it
makes more sense when they do all the loading.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
OO and game design questions dex Python 24 11-15-2010 10:52 PM
.Net Search Engine - Has anyone used dtSearch .Net Engine? Sasha ASP .Net 3 05-22-2007 04:20 PM
wiki engine (just engine) available? loguser@almad.net Python 1 04-10-2006 07:58 AM
Sweet! I found a worthwhile game engine! Luc The Perverse Java 4 12-19-2005 07:37 AM
Is ASP Validator Regex Engine Same As VS2003 Find Regex Engine? =?Utf-8?B?SmViQnVzaGVsbA==?= ASP .Net 2 10-22-2005 02:43 PM



Advertisments