stella/src/emucore/Settings.hxx

170 lines
5.4 KiB
C++

//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2020 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#ifndef SETTINGS_HXX
#define SETTINGS_HXX
#include <map>
#include "Variant.hxx"
#include "bspf.hxx"
#include "repository/KeyValueRepository.hxx"
/**
This class provides an interface for accessing all configurable options,
both from the settings file and from the commandline.
Note that options can be configured as 'permanent' or 'temporary'.
Permanent options are ones that the app registers with the system, and
always saves when the app exits. Temporary options are those that are
used when appropriate, but never saved to the settings file.
Each c'tor (both in the base class and in any derived classes) are
responsible for registering all options as either permanent or temporary.
If an option isn't registered as permanent, it will be considered
temporary and will not be saved.
@author Stephen Anthony
*/
class Settings
{
public:
/**
Create a new settings abstract class
*/
explicit Settings();
virtual ~Settings() = default;
using Options = std::map<string, Variant>;
static constexpr int SETTINGS_VERSION = 1;
static constexpr const char* SETTINGS_VERSION_KEY = "settings.version";
public:
/**
This method should be called to display usage information.
*/
void usage() const;
void setRepository(shared_ptr<KeyValueRepository> repository);
/**
This method is called to load settings from the settings file,
and apply commandline options specified by the given parameter.
@param options A list of options that overrides ones in the
settings file
*/
void load(const Options& options);
/**
This method is called to save the current settings to the
settings file.
*/
void save();
/**
Get the value assigned to the specified key.
@param key The key of the setting to lookup
@return The value of the setting; EmptyVariant if none exists
*/
const Variant& value(const string& key) const;
/**
Set the value associated with the specified key.
@param key The key of the setting
@param value The value to assign to the key
*/
void setValue(const string& key, const Variant& value, bool persist = true);
/**
Convenience methods to return specific types.
@param key The key of the setting to lookup
@return The specific type value of the variant
*/
int getInt(const string& key) const { return value(key).toInt(); }
float getFloat(const string& key) const { return value(key).toFloat(); }
bool getBool(const string& key) const { return value(key).toBool(); }
const string& getString(const string& key) const { return value(key).toString(); }
const Common::Size getSize(const string& key) const { return value(key).toSize(); }
const Common::Point getPoint(const string& key) const { return value(key).toPoint(); }
protected:
/**
Add key/value pair to specified map. Note that these should only be called
directly within the c'tor, to register the 'key' and set it to the
appropriate 'value'. Elsewhere, any derived classes should call 'setValue',
and let it decide where the key/value pair will be saved.
*/
void setPermanent(const string& key, const Variant& value);
void setTemporary(const string& key, const Variant& value);
// Trim leading and following whitespace from a string
static string trim(const string& str)
{
string::size_type first = str.find_first_not_of(' ');
return (first == string::npos) ? EmptyString :
str.substr(first, str.find_last_not_of(' ')-first+1);
}
// FIXME - Rework so that these aren't needed; hence no commenting added
const Options& getPermanentSettings() const
{ return myPermanentSettings; }
const Options& getTemporarySettings() const
{ return myTemporarySettings; }
private:
/**
This method must be called *after* settings have been fully loaded
to validate (and change, if necessary) any improper settings.
*/
void validate();
/**
Migrate settings over one version.
*/
void migrateOne();
/**
Migrate settings.
*/
void migrate();
private:
// Holds key/value pairs that are necessary for Stella to
// function and must be saved on each program exit.
Options myPermanentSettings;
// Holds auxiliary key/value pairs that shouldn't be saved on
// program exit.
Options myTemporarySettings;
shared_ptr<KeyValueRepository> myRespository;
private:
// Following constructors and assignment operators not supported
Settings(const Settings&) = delete;
Settings(Settings&&) = delete;
Settings& operator=(const Settings&) = delete;
Settings& operator=(Settings&&) = delete;
};
#endif