Jump to content



Issue with program (class) design. Engine design question.

  • You cannot reply to this topic
7 replies to this topic

#1 James Leighe   Members   -  Reputation: 126

Like
0Likes
Like

Posted 19 February 2012 - 09:17 AM

(C++)
I have a question about the class design in my game engine, but first, a little backstory. Any feedback, especially negative, is more than welcome!


States manage the flow of the game code.
Usualy, one state when finished starts another, and shuts itself down.


For example, the following states are run in order.

ClientStateMainMenu:
This state displays the main menu and runs the apporopreate state depending on what the user selects.
If the user selects 'New Game' the state 'ServerStatePlay' and 'ClientStateConnect' are run.

ClientStateConnect:
This state connects to a server, verifies some things like entity lists, and then runs 'ClientStatePlay'.

ClientStatePlay:
This is the state that handles the main gameplay.
It has many responsibilities.


The code to run a state looks like this:
EngineAPI()->RunState( "ClientStateConnect" );
Versus
EngienAPI()->RunState( new ClientStateConnect );

This start state-by-name system prevents cross-includes.

An example potential cross-include:
'ClientStateMainMenu' runs 'ClientStateConnect' and if the connection fails, 'ClientStateConnect' needs to run 'ClientStateMainMenu' again.


=Primary Issue=
I have no way cleanly send data to a state I am starting. For example, sending the servers ip address to 'ClientStateConnect' when I start it from 'clientStateMainMenu'.

The way this is currently handled is through console variables (an idea shamelessly stolen from the Source engine, my favorite). However, not all inter-state data makes sense as a console variable.

An example of that is, if a connection fails, 'ClientStateMainMenu' is run again from 'ClientStateConnect'. However, 'ClientStateMainMenu' needs to display a message telling the user that the connection has failed. How can I tell it that it should do that?

One (horrible) idea I had was to have a generic system whereby I could send data casted as a void* into the state.
EngineAPI()->RunState( "ClientStateMainMenu", (void*)someData );
Which has obvious issues.

How could I best do somthing like this? I'm not even married to the whole state idea honestly.

Ad:

#2 Sudi   Members   -  Reputation: 146

Like
1Likes
Like

Posted 19 February 2012 - 09:55 AM

Sry but i don't see the problem of Cross-Includes.

You may pass any data you want to

ClientStateMainMenu.h
class Engine;
class ClientStateMainMenu
{
public:
ClientStateMainMenu(Engine* e);

protected:
Engine* engine;
};

ClientStateMainMenu.cpp
#include "ClientStateMainMenu.h"
#include "ClientStateConnect.h"
#include "Engine.h"
ClientStateMainMenu::ClientStateMainMenu(Engine* e) : engine(e)
{
Engine->RunState(new ClientStateConnect());
}

ClientStateConnect.h
class Engine;
class ClientStateConnect
{
public:
ClientStateConnect(Engine* e);

protected:
Engine* engine;
};

ClientStateConnect.cpp
#include "ClientStateConnect.h"
#include "ClientStateMainMenu.h"
#include "Engine.h"
ClientStateConnect::ClientStateConnect(Engine* e) : engine(e)
{
if (!connect())
  Engine->RunState(new ClientStateMainMenu());
}


#3 James Leighe   Members   -  Reputation: 126

Like
0Likes
Like

Posted 19 February 2012 - 10:46 AM

Whoa you can do that?!
Black magics.

Is that considered bad form or anything?

#4 James Leighe   Members   -  Reputation: 126

Like
0Likes
Like

Posted 19 February 2012 - 10:49 AM

I have always only included one header in .cpps (the matching header file).

So including other headers in the .cpp would sure help allot.

#5 return0   Members   -  Reputation: 330

Like
1Likes
Like

Posted 19 February 2012 - 06:38 PM

Include all the headers in the cpp that you need. Use forward declarations in headers. This is not bad form.

#6 Sudi   Members   -  Reputation: 146

Like
1Likes
Like

Posted 19 February 2012 - 06:46 PM

View PostJames Leighe, on 19 February 2012 - 10:46 AM, said:

Whoa you can do that?!
Black magics.

Is that considered bad form or anything?

No its not BlackMagic...
In Header files you should only include what is really needed and if possible forward declarations.
What i showed is actually good practice and how it should be done.

#7 James Leighe   Members   -  Reputation: 126

Like
0Likes
Like

Posted 19 February 2012 - 10:05 PM

Thanks, dunno why I was ever doing it the other way!

#8 owiley   Members   -  Reputation: 100

Like
0Likes
Like

Posted 21 February 2012 - 03:56 PM

If I remember correctly Unreal use this style in the engine but with unreal scripts.
Bring more Pain






We are working on generating results for this topic
PARTNERS