3 /////////////////////////////////////////////////////////////////////////////
5 // Copyright (c) 2008 Iain Murray
7 /////////////////////////////////////////////////////////////////////////////
9 #include "../Common/Common.h"
11 #include "SettingsStore.h"
13 #include "Observable.h"
20 using namespace Dasher
;
21 using namespace Dasher::Settings
;
23 // Track memory leaks on Windows to the line that new'd the memory
25 #ifdef _DEBUG_MEMLEAKS
26 #define DEBUG_NEW new( _NORMAL_BLOCK, THIS_FILE, __LINE__ )
29 static char THIS_FILE
[] = __FILE__
;
33 static CSettingsStore
*s_pSettingsStore
= NULL
;
35 CSettingsStore::CSettingsStore() {
38 void CSettingsStore::LoadPersistent() {
39 // Load each of the persistent parameters. If we fail loading for the store, then
40 // we'll save the settings with the default value that comes from Parameters.h
41 AddParameters(boolparamtable
, NUM_OF_BPS
);
42 AddParameters(longparamtable
, NUM_OF_LPS
);
43 AddParameters(stringparamtable
, NUM_OF_SPS
);
46 void CSettingsStore::AddParameters(const Settings::bp_table
* table
, size_t count
) {
47 for (size_t i
= 0; i
< count
; ++i
) {
48 const auto& e
= table
[i
];
49 auto ¶meter
= parameters_
[e
.key
];
50 DASHER_ASSERT(parameter
.type
== Settings::ParamInvalid
);
51 parameter
.type
= ParamBool
;
52 parameter
.name
= e
.regName
;
53 parameter
.bool_default
= e
.defaultValue
;
54 parameter
.persistence
= e
.persistent
;
55 if (!LoadSetting(e
.regName
, ¶meter
.bool_value
)) {
56 parameter
.bool_value
= e
.defaultValue
;
57 SaveSetting(e
.regName
, e
.defaultValue
);
62 void CSettingsStore::AddParameters(const Settings::lp_table
* table
, size_t count
) {
63 for (size_t i
= 0; i
< count
; ++i
) {
64 const lp_table
& e
= table
[i
];
65 auto ¶meter
= parameters_
[e
.key
];
66 DASHER_ASSERT(parameter
.type
== Settings::ParamInvalid
);
67 parameter
.type
= ParamLong
;
68 parameter
.name
= e
.regName
;
69 parameter
.long_default
= e
.defaultValue
;
70 parameter
.persistence
= e
.persistent
;
71 if (!LoadSetting(e
.regName
, ¶meter
.long_value
)) {
72 parameter
.long_value
= e
.defaultValue
;
73 SaveSetting(e
.regName
, e
.defaultValue
);
78 void CSettingsStore::AddParameters(const Settings::sp_table
* table
, size_t count
) {
79 for (size_t i
= 0; i
< count
; ++i
) {
80 const auto& e
= table
[i
];
81 auto ¶meter
= parameters_
[e
.key
];
82 DASHER_ASSERT(parameter
.type
== Settings::ParamInvalid
);
83 parameter
.type
= ParamString
;
84 parameter
.name
= e
.regName
;
85 parameter
.string_default
= e
.defaultValue
;
86 parameter
.persistence
= e
.persistent
;
87 if (!LoadSetting(e
.regName
, ¶meter
.string_value
)) {
88 parameter
.string_value
= e
.defaultValue
;
89 SaveSetting(e
.regName
, std::string(e
.defaultValue
));
94 // Return 0 on success, an error string on failure.
95 const char * CSettingsStore::ClSet(const std::string
&strKey
, const std::string
&strValue
) {
96 for (auto& p
: parameters_
) {
97 if(strKey
== p
.second
.name
) {
98 switch (p
.second
.type
) {
100 if ((strValue
== "0") || (strValue
== _("true")) || (strValue
== _("True")))
101 SetBoolParameter(p
.first
, false);
102 else if((strValue
== "1") || (strValue
== _("false")) || (strValue
== _("False")))
103 SetBoolParameter(p
.first
, true);
105 // Note to translators: This message will be output for a command line
106 // with "--options foo=VAL" and foo is a boolean valued parameter, but
107 // "VAL" is not true or false.
108 return _("boolean value must be specified as 'true' or 'false'.");
113 // TODO: check the string to int conversion result.
114 SetLongParameter(p
.first
, atoi(strValue
.c_str()));
119 SetStringParameter(p
.first
, strValue
);
123 // Show unknown options.
128 // Note to translators: This is output when command line "--options" doesn't
129 // specify a known option.
130 return _("unknown option, use \"--help-options\" for more information.");
134 /* TODO: Consider using Template functions to make this neater. */
136 void CSettingsStore::SetBoolParameter(int iParameter
, bool bValue
) {
137 auto p
= parameters_
.find(iParameter
);
138 // Check that the parameter is in fact in the right spot in the table
139 DASHER_ASSERT(p
!= parameters_
.end() && p
->second
.type
== ParamBool
);
141 if(bValue
== GetBoolParameter(iParameter
))
144 pre_set_observable_
.DispatchEvent(iParameter
);
147 p
->second
.bool_value
= bValue
;
149 // Initiate events for changed parameter
150 DispatchEvent(iParameter
);
151 if (p
->second
.persistence
== Persistence::PERSISTENT
) {
152 // Write out to permanent storage
153 SaveSetting(p
->second
.name
, bValue
);
157 void CSettingsStore::SetLongParameter(int iParameter
, long lValue
) {
158 auto p
= parameters_
.find(iParameter
);
159 // Check that the parameter is in fact in the right spot in the table
160 DASHER_ASSERT(p
!= parameters_
.end() && p
->second
.type
== ParamLong
);
162 if(lValue
== GetLongParameter(iParameter
))
165 pre_set_observable_
.DispatchEvent(iParameter
);
168 p
->second
.long_value
= lValue
;
170 // Initiate events for changed parameter
171 DispatchEvent(iParameter
);
172 if (p
->second
.persistence
== Persistence::PERSISTENT
) {
173 // Write out to permanent storage
174 SaveSetting(p
->second
.name
, lValue
);
178 void CSettingsStore::SetStringParameter(int iParameter
, const std::string sValue
) {
179 auto p
= parameters_
.find(iParameter
);
180 // Check that the parameter is in fact in the right spot in the table
181 DASHER_ASSERT(p
!= parameters_
.end() && p
->second
.type
== ParamString
);
183 if(sValue
== GetStringParameter(iParameter
))
186 pre_set_observable_
.DispatchEvent(iParameter
);
189 p
->second
.string_value
= sValue
;
191 // Initiate events for changed parameter
192 DispatchEvent(iParameter
);
193 if (p
->second
.persistence
== Persistence::PERSISTENT
) {
194 // Write out to permanent storage
195 SaveSetting(p
->second
.name
, sValue
);
199 bool CSettingsStore::GetBoolParameter(int iParameter
) const {
200 auto p
= parameters_
.find(iParameter
);
201 // Check that the parameter is in fact in the right spot in the table
202 DASHER_ASSERT(p
!= parameters_
.end() && p
->second
.type
== ParamBool
);
203 return p
->second
.bool_value
;
206 long CSettingsStore::GetLongParameter(int iParameter
) const {
207 auto p
= parameters_
.find(iParameter
);
208 // Check that the parameter is in fact in the right spot in the table
209 DASHER_ASSERT(p
!= parameters_
.end() && p
->second
.type
== ParamLong
);
210 return p
->second
.long_value
;
213 const std::string
&CSettingsStore::GetStringParameter(int iParameter
) const {
214 auto p
= parameters_
.find(iParameter
);
215 // Check that the parameter is in fact in the right spot in the table
216 DASHER_ASSERT(p
!= parameters_
.end() && p
->second
.type
== ParamString
);
217 return p
->second
.string_value
;
220 void CSettingsStore::ResetParameter(int iParameter
) {
221 auto p
= parameters_
.find(iParameter
);
222 switch(p
->second
.type
) {
224 SetBoolParameter(iParameter
, p
->second
.bool_default
);
227 SetLongParameter(iParameter
, p
->second
.long_default
);
230 SetStringParameter(iParameter
, std::string(p
->second
.string_default
));
233 // TODO: Error handling?
238 /* Private functions -- Settings are not saved between sessions unless these
239 functions are over-ridden.
240 --------------------------------------------------------------------------*/
242 bool CSettingsStore::LoadSetting(const std::string
&, bool *) {
246 bool CSettingsStore::LoadSetting(const std::string
&, long *) {
250 bool CSettingsStore::LoadSetting(const std::string
&, std::string
*) {
254 void CSettingsStore::SaveSetting(const std::string
&, bool ) {
257 void CSettingsStore::SaveSetting(const std::string
&, long ) {
260 void CSettingsStore::SaveSetting(const std::string
&, const std::string
&) {
263 /* SettingsUser and SettingsObserver definitions... */
265 CSettingsUser::CSettingsUser(CSettingsStore
*pSettingsStore
) {
266 //ATM, we only allow one settings store, total...
267 DASHER_ASSERT(s_pSettingsStore
==NULL
);
268 //but in future, remove that if we're allowing multiple settings stores to exist
270 s_pSettingsStore
= pSettingsStore
;
273 CSettingsUser::CSettingsUser(CSettingsUser
*pCreateFrom
) {
274 //No need to do anything atm; but in future, copy CSettingsStore pointer
276 DASHER_ASSERT(pCreateFrom
);
279 CSettingsUser::~CSettingsUser() {
282 bool CSettingsUser::GetBoolParameter(int iParameter
) const {return s_pSettingsStore
->GetBoolParameter(iParameter
);}
283 long CSettingsUser::GetLongParameter(int iParameter
) const {return s_pSettingsStore
->GetLongParameter(iParameter
);}
284 const std::string
&CSettingsUser::GetStringParameter(int iParameter
) const {return s_pSettingsStore
->GetStringParameter(iParameter
);}
285 void CSettingsUser::SetBoolParameter(int iParameter
, bool bValue
) {s_pSettingsStore
->SetBoolParameter(iParameter
, bValue
);}
286 void CSettingsUser::SetLongParameter(int iParameter
, long lValue
) {s_pSettingsStore
->SetLongParameter(iParameter
, lValue
);}
287 void CSettingsUser::SetStringParameter(int iParameter
, const std::string
&strValue
) {s_pSettingsStore
->SetStringParameter(iParameter
, strValue
);}
289 CSettingsObserver::CSettingsObserver(CSettingsUser
*pCreateFrom
) {
290 DASHER_ASSERT(pCreateFrom
);
291 s_pSettingsStore
->Register(this);
294 CSettingsObserver::~CSettingsObserver() {
295 s_pSettingsStore
->Unregister(this);
298 CSettingsUserObserver::CSettingsUserObserver(CSettingsUser
*pCreateFrom
)
299 : CSettingsUser(pCreateFrom
), CSettingsObserver(pCreateFrom
) {