Sunday, March 26, 2006

Never fear, boost is here!

I don't think I provided the link before to the Boost library, but here it is: http://www.boost.org.

I successfully used the unit test framework to test the initial version of the config file system for Block Drop. It was a cinch to setup and get running. With the test framework working, I should have more confidence to get new features out. Although, I am curious about how I am going use the unit test framework to test some of the graphics related systems. I am also wondering if there is a decent mocking toolset for C++. This would definately be a big plus so I can test the communication between the system interfaces. Looks like it is time to do more research.

Anyways, the config system was a breeze to get going. It is built ontop of the boost::program_options library. Boost does all the hard work. It provides all of the parsing/storing functionality in just two step:

1.) Define the option-value type pairs
2.) Parse the values from the config file

Here is a simple example of using the boost::program_options library.

...

#include
namespace po = boost::program_options;

po::options_description description("Config File Options");
description.add_options()
("myOption", po::value<int>()->default_value(5), "My type of option")
("mySecondOption", po::value<std::vector<std::string>>(), "My second type of option")
;

po::variables_map map;
po::store(po::parse_config_file("configFile.cfg", description), map);
po::notify(map);

And that is all there is to it for loading the contents of a config file. Then whenever you need a specific value you just reference it through the map like this: map["myOption"].as(). The overloaded () operator makes it a breeze for organizing and adding options to the the list to be parsed.

The Monkeyboy Framework wraps this interface into its Configuration class which is meant to overriden by any system that uses the framework so that each new application can define its own configuration file and option-value pairs.

So Block Drop has a class called BlockDropConfiguration that inherits from the Monkeyboy Framework Configuration class. Here is how it defines its configuration file and option-value pairs:

BlockDropConfiguration::BlockDropConfiguration()
: Configuration(std::string("blockDrop.cfg"))
{
this->optionsDescription.add_options()
("title", po::value<std::string>(), "Title of the application")
("width", po::value<int>()->default_value(800), "Width of the application window")
("height", po::value<int>()->default_value(600), "Height of the application window")
;
}

Now the main Block Drop class owns an instance of the BlockDropConfiguration class and uses it to initialize its subsystems. Here is a sneek peek at it initializing the graphics subsystem.

...

class BlockDrop : GameDemoApplication
{
BlockDrop::BlockDrop() {
configuration.parse();
configuration.loadGraphicsProperties(graphicsSystem);

... //Add more subsystem initialization calls
}

...

private:
BlockDropConfiguration configuration;
Graphics graphicsSystem;
};

I decided on this approach since the configuration class is specific to the application so it should know what the graphics system needs to be initialized. I figured at the time of creation this appeared the be the easiest approach. I am open to input on this as well if anyone has any thoughts on a different approach.

OOH OOH EEH EEH

No comments: