//============================================================================ // // 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 #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; 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 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 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