Game Development Reference
std::map<std::pair<attribute name, attribute type>, attribute data>
Listing 1.1. Using a map to store attributes.
In reality, all searching, insertion, and removal of data should ideally be re-
stricted to the initialization and shutdown of objects, making the choice of con-
tainer less vital. Custom allocators can be written to further reduce the impact
of memory reallocation from containers, although their implementation is beyond
the scope of this article.
The attribute data can be of any type. However, a container may only hold
objects of a single type. Therefore, a layer of indirection must be introduced by
storing a set of uniform pointers to the nonuniform set of attribute data. Data
could be constructed on the heap and then the pointer returned cast to void .
This has the notable drawback of discarding any type information regarding the
data and the possibility of calling its destructor without being able to cast it back
to the original type.
Another solution is to construct an attribute interface class from which a
templated class can be automatically derived for each attribute type. This will
allow information about the type to be accessible via the interface class as well
as provide the appropriate virtual destructor to clean up the attribute data.
Through the use of compile time features, generally provided as part of runtime
type information (RTTI), it is possible to retrieve a simple type information
object that represents the type of data being stored, allowing it to be identified
will allow the attribute objects to not only store correctly typed pointers to their
respective data, but also to store the identifying name of the attribute and provide
access to a type info object. As such, a separate key is not required to identify
the attribute when searching, and the contents of the node can be stored using
a set constructed with a custom sorting algorithm that interrogates the interface
pointer for the name and type of the attribute.
Aspects are deliberately independent of one another, and the core of the engine
interacts with them all through a generic interface. The only code that knows
about the composition of the engine will be the project-specific code used to
assemble all the relevant modules, aspects, factories, and conditioners, though
even this could theoretically be performed through data.
During the course of a session, the core of the engine will be initialized, then
each aspect will be initialized in turn before being registered with the core to
receive events and be provided with access to the scene representation.