Sign in to follow this  
storage

Which way to control the engine?

Recommended Posts

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 :)

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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 :)

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 source
namespace Engine
{
...
};

// client (game) source
Engine::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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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 :).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this