I was pondering the entity creation problem and came up with the following.
I wanted a solution that allows a new entity type to be added without
modifying any existing code and the following approach seems to deliver...
( direct copy-paste from updated technical_design)
Please give an opinion. Especially if you have ideas for the number 2
Entity creation explained
EntityManager is the class responsible for creating entities. To allow
us to add new entity types (even if this is very unlikely) we will use
a sort of factory pattern in entity construction (this same pattern
can / will be applied to Action construction too).
We have an abstract base class AbstractEntityMaker. This class has a
pure virtual method create() that takes as argument a map (or any
associative container) of (parameter name, parameter value) pairs.
Both parameter names and values are in string form. The create()
method returns a pointer to a BaseGameEntity.
From this abstract class concrete classes are derived; one for each
type of entity. So there would be BaseGameEntityMaker,
InteractiveEntityMaker and so on. Each of these classes implements the
create() method. This way each of these derived maker classes knows
how to create one specific entity; InteractiveEntityMaker only creates
InteractiveEntity instances and so on.
For each derived maker class the return type of create() is a pointer
to the class the maker is able to create. For example, the create() in
InteractiveEntityMaker returns a pointer to InteractiveEntity,
BaseGameEntityMaker returns a pointer to BaseGameEntity and so on. C++
supports this type of return type covariance when the return type is a
pointer or a reference.
Now we have our makers in place, each of them being able to create
one entity. Next we have to somehow tie these with the EntityManager
class. A simple approach is as follows.
EntityManager has a create() method that takes a map<string, string>
of entity parameters as argument as well as the type of entity to be
created (in string form). EntityManager then indexes a registry of
some sort with this entity type to get a handle to the correct maker
and calls the maker's create() with the given argument map.
There are two problems: 1) What registry? and 2) the caller of
EntityManager::create() must cast the returned pointer to the correct
The registry problem
One way to solve the registry issue is to have a static member
variable in the AbstractEntityMaker class that maps a type name with a
maker. Each derived maker class could then have a static instance of
the maker class itself. This static instance would be automatically
initialized at program startup. The constructor of each derived maker
could call a method in AbstractEntityMaker that adds a mapping to the
This way at program startup each static instance would be initialized
and each of them would add itself to the maker registry. The method
that handles the registry in the base class only has to check if the
given key is already used.
The return type problem