1 | //============================================================================ |
2 | // |
3 | // SSSS tt lll lll |
4 | // SS SS tt ll ll |
5 | // SS tttttt eeee ll ll aaaa |
6 | // SSSS tt ee ee ll ll aa |
7 | // SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" |
8 | // SS SS tt ee ll ll aa aa |
9 | // SSSS ttt eeeee llll llll aaaaa |
10 | // |
11 | // Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony |
12 | // and the Stella Team |
13 | // |
14 | // See the file "License.txt" for information on usage and redistribution of |
15 | // this file, and for a DISCLAIMER OF ALL WARRANTIES. |
16 | //============================================================================ |
17 | |
18 | #ifndef SETTINGS_HXX |
19 | #define SETTINGS_HXX |
20 | |
21 | #include <map> |
22 | |
23 | #include "Variant.hxx" |
24 | #include "bspf.hxx" |
25 | #include "repository/KeyValueRepository.hxx" |
26 | |
27 | /** |
28 | This class provides an interface for accessing all configurable options, |
29 | both from the settings file and from the commandline. |
30 | |
31 | Note that options can be configured as 'permanent' or 'temporary'. |
32 | Permanent options are ones that the app registers with the system, and |
33 | always saves when the app exits. Temporary options are those that are |
34 | used when appropriate, but never saved to the settings file. |
35 | |
36 | Each c'tor (both in the base class and in any derived classes) are |
37 | responsible for registering all options as either permanent or temporary. |
38 | If an option isn't registered as permanent, it will be considered |
39 | temporary and will not be saved. |
40 | |
41 | @author Stephen Anthony |
42 | */ |
43 | class Settings |
44 | { |
45 | public: |
46 | /** |
47 | Create a new settings abstract class |
48 | */ |
49 | explicit Settings(); |
50 | virtual ~Settings() = default; |
51 | |
52 | using Options = std::map<string, Variant>; |
53 | |
54 | public: |
55 | /** |
56 | This method should be called to display usage information. |
57 | */ |
58 | void usage() const; |
59 | |
60 | void setRepository(shared_ptr<KeyValueRepository> repository); |
61 | |
62 | /** |
63 | This method is called to load settings from the settings file, |
64 | and apply commandline options specified by the given parameter. |
65 | |
66 | @param options A list of options that overrides ones in the |
67 | settings file |
68 | */ |
69 | void load(const Options& options); |
70 | |
71 | /** |
72 | This method is called to save the current settings to the |
73 | settings file. |
74 | */ |
75 | void save(); |
76 | |
77 | /** |
78 | Get the value assigned to the specified key. |
79 | |
80 | @param key The key of the setting to lookup |
81 | @return The value of the setting; EmptyVariant if none exists |
82 | */ |
83 | const Variant& value(const string& key) const; |
84 | |
85 | /** |
86 | Set the value associated with the specified key. |
87 | |
88 | @param key The key of the setting |
89 | @param value The value to assign to the key |
90 | */ |
91 | void setValue(const string& key, const Variant& value, bool persist = true); |
92 | |
93 | /** |
94 | Convenience methods to return specific types. |
95 | |
96 | @param key The key of the setting to lookup |
97 | @return The specific type value of the variant |
98 | */ |
99 | int getInt(const string& key) const { return value(key).toInt(); } |
100 | float getFloat(const string& key) const { return value(key).toFloat(); } |
101 | bool getBool(const string& key) const { return value(key).toBool(); } |
102 | const string& getString(const string& key) const { return value(key).toString(); } |
103 | const Common::Size getSize(const string& key) const { return value(key).toSize(); } |
104 | const Common::Point getPoint(const string& key) const { return value(key).toPoint(); } |
105 | |
106 | protected: |
107 | /** |
108 | Add key/value pair to specified map. Note that these should only be called |
109 | directly within the c'tor, to register the 'key' and set it to the |
110 | appropriate 'value'. Elsewhere, any derived classes should call 'setValue', |
111 | and let it decide where the key/value pair will be saved. |
112 | */ |
113 | void setPermanent(const string& key, const Variant& value); |
114 | void setTemporary(const string& key, const Variant& value); |
115 | |
116 | // Trim leading and following whitespace from a string |
117 | static string trim(const string& str) |
118 | { |
119 | string::size_type first = str.find_first_not_of(' '); |
120 | return (first == string::npos) ? EmptyString : |
121 | str.substr(first, str.find_last_not_of(' ')-first+1); |
122 | } |
123 | |
124 | // FIXME - Rework so that these aren't needed; hence no commenting added |
125 | const Options& getPermanentSettings() const |
126 | { return myPermanentSettings; } |
127 | const Options& getTemporarySettings() const |
128 | { return myTemporarySettings; } |
129 | |
130 | private: |
131 | /** |
132 | This method must be called *after* settings have been fully loaded |
133 | to validate (and change, if necessary) any improper settings. |
134 | */ |
135 | void validate(); |
136 | |
137 | private: |
138 | // Holds key/value pairs that are necessary for Stella to |
139 | // function and must be saved on each program exit. |
140 | Options myPermanentSettings; |
141 | |
142 | // Holds auxiliary key/value pairs that shouldn't be saved on |
143 | // program exit. |
144 | Options myTemporarySettings; |
145 | |
146 | shared_ptr<KeyValueRepository> myRespository; |
147 | |
148 | private: |
149 | // Following constructors and assignment operators not supported |
150 | Settings(const Settings&) = delete; |
151 | Settings(Settings&&) = delete; |
152 | Settings& operator=(const Settings&) = delete; |
153 | Settings& operator=(Settings&&) = delete; |
154 | }; |
155 | |
156 | #endif |
157 | |