Which way to control the engine?

Started by
8 comments, last by storage 18 years, 11 months ago
I'm currently making a 2D tile engine in OpenGL and SDL, and I'm wondering which way to initialize and control the engine you think is the easiest to use. Examples: 1. Like SDL/OpenGL
Engine_Init(...);
Engine_ClearScene();
2. Pre-declared engine class
Engine->Init(...);
Engine->ClearScene();
3. Engine class that has be declared by the user
Engine *myengine;
myengine->Init(...);
myengine->ClearScene();
Thanks in advance, storage :)
Advertisement
I would go with 3. Let the user declare the engine instance and do stuff with it. This way, the user can destroy and restart the engine without terminating the application all together.

Toolmaker

Thanks, then that's how I will do it! :)

Another thing, how should my sprites be?

1. struct/global functions
typedef struct Sprite{    int w, h;} Sprite;Sprite *mysprite;mysprite = Engine_NewSprite(w, h);Engine_DrawSprte(mysprite, x, y);

2. Class
class Sprite{    int w, h;    void New(int width, int height);    void Draw(int x, int y);};Sprite *mysprite;mysprite->New(w, h);mysprite->Draw(x, y);


Thanks in advance once again :)
Quote:Original post by storage
Thanks, then that's how I will do it! :)

Another thing, how should my sprites be?

1. struct/global functions
typedef struct Sprite{    int w, h;} Sprite;Sprite *mysprite;mysprite = Engine_NewSprite(w, h);Engine_DrawSprte(mysprite, x, y);

2. Class
class Sprite{    int w, h;    void New(int width, int height);    void Draw(int x, int y);};Sprite *mysprite;mysprite->New(w, h);mysprite->Draw(x, y);


Thanks in advance once again :)


The second choice, without doubt.

Also, I'm not saying this is a better way to do it, but a fourth way of doing the Engine class is with a singleton. Anyway, just thought I'd throw that out there.
Quote:Original post by storage
1. struct/global functions
typedef struct Sprite{    int w, h;} Sprite;Sprite *mysprite;mysprite = Engine_NewSprite(w, h);Engine_DrawSprte(mysprite, x, y);


I've used all of those, but number one is my personal preference by far. by the way, it makes more sense for it to be

Engine_DrawAllSprites();
mysprite = Sprite_Create(w, h);
Sprite_Draw(sprite...)

or something like that or else you'd have Engine_ for everything.
Quote:Original post by storage
I'm currently making a 2D tile engine in OpenGL and SDL, and I'm wondering which way to initialize and control the engine you think is the easiest to use.

Examples:
1. Like SDL/OpenGL
Engine_Init(...);Engine_ClearScene();

2. Pre-declared engine class
Engine->Init(...);Engine->ClearScene();

3. Engine class that has be declared by the user
Engine *myengine;myengine->Init(...);myengine->ClearScene();


Thanks in advance, storage :)


Assuming you aren't allowing multiple instances of the Engine, then I would go with a variation on number 1. Wrap the functions in a namespace and call them like this:

// engine sourcenamespace Engine{...};// client (game) sourceEngine::Init(...);Engine::ClearScene();


There's just no need to use a class instance if all you will ever have is one instance. Not everything need be a class in C++, so always do what makes the most sense for the problem at hand.
however if your "engine" is tracking any sort of state then placing everything in a class makes sense from an encapsulation pov.
I'd have to agree with the classes.
Since you're going with an OO Engine you might as well go all the way.

But look in to that singlton idea. It may prove useful.
Quote:Original post by storage
Thanks, then that's how I will do it! :)

Another thing, how should my sprites be?

1. struct/global functions
typedef struct Sprite{    int w, h;} Sprite;Sprite *mysprite;mysprite = Engine_NewSprite(w, h);Engine_DrawSprte(mysprite, x, y);

2. Class
class Sprite{    int w, h;    void New(int width, int height);    void Draw(int x, int y);};Sprite *mysprite;mysprite->New(w, h);mysprite->Draw(x, y);


Thanks in advance once again :)

Neither.

Approaches I might use are:

[sources]// 1. Factories: Classes are used to construct other classes. Classes are// thereby specific to their factories and cannot be arbitrarily mixed with// classes constructed by other factories.Engine * myEngine = LoadEngine("engine.dll");Sprite * mySprite = myEngine->CreateSpriteFromFile("supermonkey.sprite");Context * myContext = myEngine->CreateContext();myContext->EnableBlending();MySprite->Draw(myContext, x, y);// Classes from different factories may be incompatible.Engine * myEngine2 = Factory::LoadEngine("engine2.dll");Context * myContext2 = myEngine2->CreateContext();myContext2->EnableBlending();// This would probably not be allowed.MySprite->Draw(myContext, x, y);// 2. Wrappers: Classes are wrappers around hidden implementation classes. // Classes may be mixed and matched arbitrarily, and implementation specific// data structures are created behind-the-scenes.Engine * myEngine = LoadEngine("engine.dll");Sprite * mySprite = Sprite::CreateFromFile("supermonkey.sprite");Context * myContext = new Context;myContext->EnableBlending();// This creates internal structures which associate the engine with the context,// the sprite with the engine, and possibly the sprite with the context.// Maintaining this state is nontrivial.mySprite.Draw(myEngine, myContext, x, y);// 3. Attached wrappers: Classes are wrappers around hidden implementation // classes. Classes may not be mixed and matched arbitrarily, but must instead// be attached to particular classes in order to be used with them.Engine * myEngine = LoadEngine("engine.dll");Sprite * mySprite = Sprite::CreateFromFile("supermonkey.sprite");Context * myContext = new Context();myContext->EnableBlending();myContext->attach(myEngine);mySprite->attach(myContext);mySprite.Draw(x, y);


The factory solution is the easiest to implement, and the more efficient. The wrapper solution is the easiest to use, and the more flexible. The attached wrappers solution is somewhere between.
Thanks a lot everyone! :)

I decided to make everything a class, looks much cleaner now.

Quote:Original post by Nathan Baum
Quote:Original post by storage
Thanks, then that's how I will do it! :)

Another thing, how should my sprites be?

1. struct/global functions
typedef struct Sprite{    int w, h;} Sprite;Sprite *mysprite;mysprite = Engine_NewSprite(w, h);Engine_DrawSprte(mysprite, x, y);

2. Class
class Sprite{    int w, h;    void New(int width, int height);    void Draw(int x, int y);};Sprite *mysprite;mysprite->New(w, h);mysprite->Draw(x, y);


Thanks in advance once again :)

Neither.

Approaches I might use are:

*** Source Snippet Removed ***

The factory solution is the easiest to implement, and the more efficient. The wrapper solution is the easiest to use, and the more flexible. The attached wrappers solution is somewhere between.


I'll look into factories, thanks :).

This topic is closed to new replies.

Advertisement