#### Archived

This topic is now archived and is closed to further replies.

# Very quick engine design question

This topic is 5124 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I am planning an engine right now, and i am trying to go for a very organized engine. What would be wrong with the following line of code? Would it be slow? Engine->SubSystems->TextureObject->CreateTexture(&WaterTex); That looks very organized but it also looks very slow. I guess i would only be calling those type of functions at the initalize phase, because in runtime, i would just do WaterTex.UseTexture(); What do you guys think, please give me advice. Thanks "What we do in life, echos in eternity" -- Gladiator

##### Share on other sites
It seems convoluted. I dont think speed would be an issue. You would have nightmares tracking down all of the memory access errors your going to encounter by exposing all those pointers.

Here are a few design philosophies i adhere to:

- Isolate everything
- Keep interfaces simple
- Be consistent (especially with naming)
- Automate simple tasks (they are easier to program and easier to reuse)

In this case, you want to keep your texture creation code interface simple - the separation by modules should keep things fairly organised. Its much easier for example to do this:

#include "texture.h"void use_texture(void){   tex_img_typ   image, sepia_img;   tex_typ       texture, sepia_tex;   image = tex_load("c:/img.bmp");   texture = tex_create(image);   //convert the original texture to sepia   sepia_img = tex_sepia(image);   sepia_tex = tex_create(image);   //release images from memory   tex_free(image);   tex_free(sepia_img);}

Using simple commands, the user of your engine can do many complex tasks easier because the interfaces are so simple.

This doesnt mean that all the functions in your engine are going to be simple. They can be as complex as you want; the tex_load function for example can at first only support bitmaps if your pressed for time. Then later on, you can easily add support for jpegs, tga, ect because the interface to that function is fairly universal to use and doesnt have to be changed.

Another good design technique is to provide only references to objects in memory stored somewhere else by the engine. This is how opengl manages textures. The idea is that you can potentially add support for extra chanels (like an alpha channel) without changing code already written.

[edited by - llvllatrix on May 6, 2004 9:05:28 PM]

##### Share on other sites
Speed wouldn''t be an issue if your only doing all those dereferences during initialization.

However...ever heard of over-engineering a problem? IMHO you''d be better off using namespaces instead of separate objects for your Engine and SubSystems:

Engine::SubSystem::Object->Function(...)

Where Engine is whatever your engine name is and SubSystem is the name of a subsystem, for example:

MyEngine::Display::TextureObject->CreateTexture(&WaterTex);

Even then, unless your dealing with a fairly large engine I think that you could suffice with not bothering with the SubSystem namespaces. Another point, what''s wrong with using

WaterTex = new MyEngine::TextureObject;

There are reasons that the approach your using may be a Good Thing(tm) for an engine design, but is it necessary for YOUR design?

##### Share on other sites

My C++ is a bit fuzzy on this kind of thing:
MyEngine::Display::TextureObject->CreateTexture(&WaterTex);
WaterTex = new MyEngine::TextureObject;

Would doing MyEngine::Display::TextureObject, that would return the default instance of TextureObject right?
Like for example, If i dont have a instance of MyEngine declared, you could still do MyEngine::Varible = 5; right?

Am sorry, i am really fuzzy on those :: operators. I have only ever used them for static varibles in a private section of a class though.

Please can someone give me quick run through of them, i really dont want to read an entire tutorial when i can probley deduce what it does from a little base knowledge.

So if anyone could clear that up.

Also on llvllatrix reply, that code that he did, if i did it that way, wouldnt that get rid of the whole OOP programming? Can you explain that to me?

Also on the :: operator. Just a short quick thing would do me wonders. Thanks alot

"What we do in life, echos in eternity" -- Gladiator

##### Share on other sites
quote:

Also on llvllatrix reply, that code that he did, if i did it that way, wouldnt that get rid of the whole OOP programming? Can you explain that to me?

Yep You dont always have to use classes to do something in c++. Why do you think most games are written in c? Use what you need to get the job done easiest; that way you can spend the time where you need it: debugging your code

##### Share on other sites

I think it would be more like this.

class cGame
{
public:

struct sConfig
{
char data[256];
char name[20];
};

cGame();
bool SetConfig(sConfig *config);

};

void dosomething()
{

cout<<"Config?: "<SetConfig(newconfig)<}

Actualy I think I''m probably wrong. I''d like to be clarified also please.

}

##### Share on other sites
lol, you would make a game a class? Are you expecting to have one or more instances of a game? jk (...yes i know about singletons...)

Whenever you approach a design issue, especially in the real world, you evaluate the advantages and disadvantages of implementing a design a certain way.

Classes work great when you need multiple instances of the class; they were originally designed as a tool that associates functions and data into one object. The constructor and destructor also lend themselves to doing some nifty things. This doesnt mean that you should use classes because they are avaliable, and in fact there are many cases where using classes can hurt your program.

This also doesn''t mean that you abandon procedural based programming because its old; it is in fact still very powerful. I typically use a synergy of both procedural (typically for interface) and class based programming methods (for the complex implementation of the interface).

A bit on game design:

Games are wierd programs to write because you are trying to mix a whole bunch of different elements into one. This makes them one of the hardest type of programs to write. Classes (specifically the way they are used in MFC) do not lend themselves to typical game design because the whole inheritance "this is a type of that" does not apply. One big reason using classes can hurt you here is because inheritance limits code reuse; to reuse one segment, you have to inherit the entire tree.

Instead you have to start from the ground up; you need to build a whole bunch of different subsystems that do a basic job. For example one will do sound, another graphics. You keep building higher level systems that continue to integrate these subsystems into one until you arrive at the game. Procedural based programming lends itself easily to this.

For example lets say we used opengl to produce the example of the texture loading system i had above. If we wanted to make a model that used the texturing engine, all we have to do is include and use the appropriate functions. The if we want to create a character management system, all we have to do is include the model system as a subsystem of the new one and bingo.

##### Share on other sites
Not sure if I understood that earlier post SkinnyM ... so maybe this doesn't answer anything.
It sounds a little as if false pride prevents you from taking a look at the basics again

The :: operator is called the scope operator.

I think this part of the cplusplus.com language tutorial might be interesting.
Section 4.1 - Classes

Quote:
The scope operator (: specifies the class to which the member being declared belongs, granting exactly the same scope properties as if it was directly defined within the class.
For example, in the function set_values() of the previous code, we have referred to the variables x and y, that are members of class CRectangle and that are only visible inside it and its members (since they are private).

---
If nothing works the way it should ... maybe you need a break!?
Get cracking and double-check the switch statements!!
Tolop|Andyart.de

[edited by - Clueless on May 6, 2004 11:43:30 PM]

##### Share on other sites
quote:
Original post by llvllatrix
Classes work great when you need multiple instances of the class;

Hmmm there''s a situation where I like to use singleton classes: to handle subsystems that depend on each other. Say the texture manager depends on the display subsystem ; both depend on the logging utilities...

Singleton classes help creating objects in the right order without actually "writing the right order" in your code (and add a bit of ref counting and you''ll also delete everything in the right order as well...). And that adds flexibility to your code.

Note that it can impact performance as well... Using a singleton for the "logging class" is a good idea ; using one for the "class that draws a particle" is not (stupid example, but you''ll get the idea

SaM3d!, a cross-platform API for 3d based on SDL and OpenGL.
The trouble is that things never get better, they just stay the same, only more so. -- (Terry Pratchett, Eric)

##### Share on other sites
quote:
Original post by SkinnyM
Would doing MyEngine::Display::TextureObject, that would return the default instance of TextureObject right?
Like for example, If i dont have a instance of MyEngine declared, you could still do MyEngine::Varible = 5; right?

Not quite, take a look at this code:
namespace MyEngine{    int Variable;    namespace Display    {        class TextureObject        {            // Your TextureObject class...        }    }}

Now namespaces aren't classes and they can't be instantiated, so there will never be an instantiated object of type MyEngine or Display. Instead, they act as a way of providing separation of code. For this example, your TextureObject would be within the Display namespace which is within the MyEngine namespace. This means that someone else using your code could also have their own TextureObject so long as they place it in a different namespace. A namespace can containing anything you would be able to put globally, so you can have classes, functions, variables, etc contained within the namespace. Because I've declared Variable in the MyEngine namespace in the above code, you can go MyEngine::Variable=5;, but Variable is really a global variable that isn't part of a class that can be instantiated. To accessing 'stuff' inside a namespace you need to use the scope resolution operator, ::. Accessing your TextureObject would be done as
MyEngine::Display::TextureObject...rest as normal for a class

quote:
Am sorry, i am really fuzzy on those :: operators. I have only ever used them for static varibles in a private section of a class though.

In this case, you use the :: again because the static variables aren't instantiated with the new objects of that class. Namespaces could in a way be considered as a class with ALL its members declared as static.

quote:
Also on llvllatrix reply, that code that he did, if i did it that way, wouldnt that get rid of the whole OOP programming? Can you explain that to me?

As has already been said... Yep
If you want to use this approach you can place all of your 'normal' functions inside of namespaces in order to help you organize your code. You then access them using the :: operator just as with my above example.

Joanus D'Mentia

[edited by - joanusdmentia on May 7, 2004 7:20:51 PM]

• 10
• 18
• 14
• 18
• 15