Jump to content
  • Advertisement
Sign in to follow this  
  • entries
    73
  • comments
    131
  • views
    55001

Coke with lime = amazing

Sign in to follow this  
okonomiyaki

279 views


Alrighty, I'm going to code again. It's just a little hard to have a programming job and still be motivated to code in my free time. But I'm interested in graphics enough to get back into it. That, and I like C++, and at work I do mostly shell/php/perl. I miss compiled languages.

I worked on how I want to incorporate settings into my "engine." I put that in quotes because that makes it seem like such a large-scale project, when this is really just a little machine to help me learn design and advanced rendering techniques.

I initially wrote a settings class that parses a file and stores a vector of name/value pairs (of type string/string). Then I created one instance of this class as a global object. As I thought about it and roughly sketched out how I would use this, I realized how bad this design was.

My first improvement was to store the value of each setting as boost::any instead of a string (which was lexical-casted to convert into appropriate type). boost::any gives me greater flexibility in the types of values stored and is also faster. I have a templated "GetSetting" function that performs an any_cast on the value to the requested type.

I'm still having some problems with casting though. With boost::any, if you don't any_cast the value back to the original type, it throws an exception (even if the value is an int and you request a long, for example). This was annoying because if a value is an int but I wanted a long, I'd have to do:

(long)settings->GetSetting("width");

I could add code to use typeid() and detect the requested type and do all the conversion for me, but that means I would have to enable RTTI. Is it worth it? Honestly I don't know how RTTI affects the performance.

Because this isn't a huge deal, I don't think I really care about it. This still lets me the configure the system in a pretty flexible way, especially with my second improvement.

My second improvement involved the scope of the settings object. More and more I'm realizing how to avoid those global objects, and even how global objects indicates bad design. Why do I need to store settings for the renderer in the same place as settings for my logger? I used to have one long ValidateSettings function that would make sure everything in there is in tact. When the renderer is initializing it trusts everything in the global settings object. Ew, we have objects relying on this global object declared somewhere else, etc, etc.

I ended up putting a Settings object as a public member of any class that I wanted configurable. So the renderer has an object called "Settings" and to configure it, you actually call, for example: Renderer->Settings->SetSetting("FOV", 90.0f);

This can be done for the logger, renderer, kernel, etc. For any object that I want to configure. Whenever these objects initialize, it calls its own ValidateSettings function which makes sure all the settings that object needs are in there and valid.

Before it does that though, it parses the settings file. I like this part. Every settings object parses the same settings file, but retrieves whatever portion it needs. The settings file is broken into sections, indicated by a [header] then a list of name/value pairs, and when a Settings object is fired to parse the file, it requests a section name to parse. So an example file would look like:

[renderer]
deviceType=hal
autogenMipMaps=1
useSpecularLighting=1
...

[window]
windowedWidth=563
windowedHeight=335
fullscreen=0
...

[logger]
logApplicationMessages=1
logSystemMessages=0
...
Sign in to follow this  


1 Comment


Recommended Comments

How about implementing arrays (or lists) as possible values? Simply serialize them using a delimeter character should do the trick.

Share this comment


Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!