Game Development Reference
In-Depth Information
int main(int argc, char **argv)
{
std::ifstream f("engine.yaml"); Config cfg(f);
unsigned int width = cfg["screen/width"];
unsigned int height = cfg["screen/height"];
std::map<std::string, double> consts = cfg["constants"];
}
Listing 20.4. Excerpt from Engine.cpp, game engine implementation file.
The only extension we have added to yaml-cpp's implementation is the ability
to access nested objects without necessarily chaining calls to the square-bracket
operator ( [] ) by using the slash character ( / ) as a delimiter; see, for example,
Listing 20.4.
Instead of describing every feature of our generic solution, we will demonstrate
its strengths and practicality through three real-world scenarios, thus validating
the third requirement for DDD adoption: ease of integration into C++ code.
20.4 Applying DDD to Real-World Scenarios
20.4.1 General Engine Configuration
Our wrapper can be used for simple configuration, to read key/value pairs from
a YAML file (Listing 20.5). When values are nested, hierarchical key paths can
be used to directly access them. Scalar values can be deserialized into basic C++
types like int , double ,or std::string , while mapping and sequence structures can
be automatically deserialized into the appropriate STL containers without having
to explicitly specify their type (Listing 20.4).
screen:
# each key/value under "screen" will
width: 1920
#
be read independently
height: 1080
constants:
# the whole "constants" mapping will
e: 2.7183
#
be read in one row in a std::map
pi: 3.1415
Listing 20.5. Excerpt from engine.yaml, configuration file read by Engine.cpp.
20.4.2 Data-Driven Class Deserialization
More complex classes can be deserialized from YAML node objects by extending
them with the C++ right stream operator ( >> ).Thisway,wecanreadanarbitrary
Search WWH ::




Custom Search