0
\$\begingroup\$

In my game engine, here is my mesh factory :-

//GraphicFactory.h
class GraphicFactory{
    enum blueprint{
        TURRET_01,CUBE,GRASS    //a lot of things
    }
    void initialize();  
    BlueprintDatabase db;
}
//GraphicFactory.cpp
void GraphicFactory::initialize{ 
    db.add(TURRET_01,  very long definition about mesh e.g. material color ...);
    db.add(CUBE,       very long definition about mesh ....   );
}

To use, it is easy as :-

graphicFactory()->create(TURRET_01 /* happy ctrl+space */, position, rotation, scale);

Here, I have a problem about compile time:-

The GraphicFactory can be seen from most game systems
because they want to create some graphics.
Thus GraphicFactory.h must be included into every system's .cpp either directly or indirectly.

When one of the systems want a new type of mesh e.g. IRON_BOX,
I have to add IRON_BOX to blueprint in the GraphicFactory's header.
As a result, I have to recompile most of systems.

Question: Where should I store the declation / definition of mesh?
I also faces this issue for managing material, physic object, and game object.

My poor solution: Use string instead of enum - register by string and query by string.

\$\endgroup\$
1
\$\begingroup\$

Enums are just another way to name constants (especially when you use unscoped enums). By having those constants in your GraphicFactory class you are introducing a kind of circular dependency. The users of the GraphicFactory of course have to now about it, but the GraphicFactory also has to know about the details of the needed graphics (i.e. the name of the asset), which I would consider a implementation detail of other code parts.


Solution 1: #define the constants where the assets are used

You could just move the constant definitions out of the GraphicFactory class and #define them in the places where they are actually used. That way the GraphicFactory does not need to know about the names of the assets.

This approach has one (big) issue: You need to coordinate the values of the constants manually across the codebase, which will eventually turn out to be unmaintainable.

Solution 2: Use strings as keys

This is essentially Solution 1, but much more maintainable. Just use strings as keys and define them in the objects where the graphics are needed. This is a lot more maintainable, because you are able to give the constants meaningful names, which is a lot easier to coordinate across a large codebase. It may be a little slower than Solution 1, but this reeks of premature optimization.

Solution 3: Dynamically create handles to registered graphics.

The handier solution would be to create a dynamic handle to the graphic when you are registering the graphics. This would work in the following way:

  1. Objects that need access to specific assets register them with the GraphicFactory class with a name (a string). A handle is returned (an integer type) and stored by the registering classes.
  2. The name-handle pair is stored somewhere.
  3. When another object tries to register an asset under the same name the stored handle is returned.
  4. The asset may now be accessed by passing the handle back into the GraphicFactory. The requested Asset is returned and may be used.
|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ Thank, nice answer! May you point me toward some more links / books? Such high quality essay / description (like yours) is hard to find. \$\endgroup\$ – javaLover Sep 1 '16 at 9:03
  • 1
    \$\begingroup\$ @javaLover There are some questions here on GameDevelopment.SE: How to design an Asset Manager as well as others, some discussing if an Asset Manager is at all necessary. If you google around a bit you will find some ressources on the topic, for example at gamedev.net. I'm not aware of a book which handles this topic in depth. \$\endgroup\$ – LukeG Sep 1 '16 at 9:15
  • 1
    \$\begingroup\$ I personally use "solution 2" but with compiled time hased strings, in this way the compiler associates a unique ID to every string in my game and then I search resource by numbers (whose compare function is faster than strings' one). of course you can't use this IDs as array indices/slots because they're completely random \$\endgroup\$ – Liuka Sep 1 '16 at 21:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.