• entries
    743
  • comments
    1924
  • views
    579117

Configuration files

Sign in to follow this  
Aardvajk

76 views

Sorted out the changing zone ID stuff in Map. I did need to put a dialog box together as text in the .rc file but it wasn't too bad. Enemy activation zones are now working in Udo as well so the sheep do not appear until you enter a zone that has the same ID as each sheep's ActivationZone property.

Got a bit distracted from the zones thing then because I decided I wanted to have text-based configuration files for storing game options. Since I will probably always want this in games, I decided to build a static library to deal with nice and simple option files. It presents this interface:


#ifndef config_H
#define config_H

#include
#include
#include
#include

#pragma comment(lib,"config.lib")

class configuration
{
private:
bool error(const std::string &m,const std::string &p="");

enum type { eof,err,eq,text };
typedef std::map map_type;

int skip(std::istream &is);
type next(std::istream &is,std::string &token);
bool match(bool get,std::istream &is,std::string &token,type t);
bool process_line(const std::string &line);

template<class T> bool string_to_T(const std::string &s,T &i);

map_type map;
std::string err_str,path_str;
type last_type;

public:
configuration();
configuration(const std::string &path);

bool fail() const;
bool open(const std::string &path);

std::string error_text() const;

enum result { no_key,invalid_value,ok };

result operator()(const std::string &key,std::string &value);
template<class T> result operator()(const std::string &key,T &value);
};

template<class T> bool configuration::string_to_T(const std::string &s,T &i)
{
std::istringstream is(s); is >> i; if(is.fail()) return false; std::string x; is >> x; return(x=="");
}

template<class T> configuration::result configuration::operator()(const std::string &key,T &value)
{
std::string s; if((*this)(key,s)!=ok) return no_key; return(string_to_T(s,value) ? ok : invalid_value);
}

#endif







It can then cope with .cfg files like:


; this is a comment

key=value
another_key = "a string value" ; this is another comment

number = 10
real_number=-23.0


and so on. The groovy little template and stringstream stuff means you can query the configuration for a value of any type that std::stringstream can deal with converting and it will tell you if:

a) the key doesn't exist
b) the value is invalid for the type

So you can do something like:


bool f()
{
configuration con("x.cfg");

if(con.fail())
{
std::cerr << con.error_text() << "\n"; return false;
}

std::string s;
if(con("key",s)==configuration::ok) std::cout << s << std::endl;

float f;
configuration::result r=con("real_number",f);

if(r==configuration::no_key) std::cout << "real_number not in the file\n";
if(r==configuration::invalid_value) std::cout << "value not a float\n";
if(r==configuration::ok) std::cout << f << "\n";

return true;
}


Nice and simple but pretty robust. In case anyone cares, the dummy >> into a std::string at the end of the template conversion method is to prevent something like "123x" from returning a valid int (123) and leaving "x" in the stringstream.

Udo has now been updated to use the above so I can manually edit the resolution and turn the sound on and off with notepad. Woohoo.

Should probably stop spending evenings on details like this and get on with the game really.
Sign in to follow this  


0 Comments


Recommended Comments

There are no comments to display.

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