Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper implementation of global configuration

My goal is to have global constants in a C++ game I'm working on (to represent some graphics info and the like). My current implementation is to toss them all in a .h and include them everywhere. This works, except that every time I change a setting, the entire code base must be recompiled.

So, my next idea was to toss them in some configuration txt file and parse them in, that way no code is actually changed when settings change. The parser was simple enough, and I could put the values into the constants, but because the parser was a code block, the constants were no longer global.

Is there a good way to solve this? Perhaps some way to make them global despite being in a block or some way to avoid recompiling everything when changing settings?

like image 649
Cannoliopsida Avatar asked Jun 05 '12 05:06

Cannoliopsida


People also ask

What is a global configuration?

A global configuration represents a physical or logical piece of a product offering. It gathers configurations for itself and other contributing Rational® solution for Collaborative Lifecycle Management (CLM) applications.

What is global configuration management?

Global Configuration Management (GCM) is an optional application in the ELM solution. This solution integrates several products to provide a complete set of applications for software or systems development. For a roadmap of how to get started with the GCM tasks, see Getting started with global configurations.

How do I enter global configuration mode?

To enter global configuration mode, enter the configure command. Global configuration From privileged EXEC mode, enter the configure command. To exit to privileged EXEC mode, enter the exit or end command, or press Ctrl-Z. To enter interface configuration mode, enter the interface configuration command.

What is global configuration IBM?

Global Configuration Management (GCM) is an application that assembles configurations for itself and other contributing applications so teams can gain an overall view of the physical and logical parts of their product offering. A configuration is a baseline or stream that contains a set of versioned artifacts.


2 Answers

The way I used solve this is to put the variables in a separate global namespace, which is in a header file named something like config.h, then include that file everywhere.

// In config.h

#ifndef CONFIG_H
#define CONFIG_H

namespace config
{
    extern int some_config_int;
    extern std::string some_config_string;

    bool load_config_file();
}

#endif

Then in a source file, you define the variable and also set them to a default value. This source file also have the code to load the variables from your configuration file.

// In config.cpp

namespace config
{
    int some_config_int = 123;
    std::string some_config_string = "foo";
}

bool config::load_config_file()
{
    // Code to load and set the configuration variables
}

Now in every source file you need the configuration variables, include config.h and access them like config::some_config_int.

However, there is no "proper" way of solving this, all ways that work are proper in my eyes.

like image 181
Some programmer dude Avatar answered Oct 20 '22 15:10

Some programmer dude


Another way to do this would be to create a singleton class.

#include <fstream>
#include <map>
#include <string>

class ConfigStore
{
public:
    static ConfigStore& get()
    {
        static ConfigStore instance;
        return instance;
    }
    void parseFile(std::ifstream& inStream);
    template<typename _T>
    _T getValue(std::string key);
private:
    ConfigStore(){};
    ConfigStore(const ConfigStore&);
    ConfigStore& operator=(const ConfigStore&);
    std::map<std::string,std::string> storedConfig;
};

Here the configuration is saved in a map, meaning as long as parseFile can read the file and getValue can parse the type there is no need to recompile the config class if you add new keys.

Usage:

std::ifstream input("somefile.txt");
ConfigStore::get().parseFile(input);
std::cout<<ConfigStore::get().getValue<std::string>(std::string("thing"))<<std::endl;
like image 39
denahiro Avatar answered Oct 20 '22 15:10

denahiro