Xmipp  v3.23.11-Nereus
userSettings.h
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * Authors: David Strelak (davidstrelak@gmail.com)
4  *
5  * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20  * 02111-1307 USA
21  *
22  * All comments concerning this program package may be sent to the
23  * e-mail address 'xmipp@cnb.csic.es'
24  ***************************************************************************/
25 
31 #ifndef USERSETTINGS_H_
32 #define USERSETTINGS_H_
33 
34 #include <string>
35 #include <algorithm>
36 #include <map>
37 #include <list>
38 #include <fstream>
39 #include <iosfwd>
40 #include <sstream>
41 #include <typeinfo>
42 #include <mutex>
43 
44 class UserSettings {
45 public:
49  static UserSettings& get(const std::string &path = std::string()) {
50  static std::mutex mtx;
51  auto res = find_if(storages.begin(), storages.end(),
52  [&path](const UserSettings& obj)
53  {return obj.identifier.compare(path) == 0;});
54  if (storages.end() == res) {
55  // it seems that we don't have such a storage yet
56  mtx.lock();
57  // make sure that nobody did it meanwhile
58  res = find_if(storages.begin(), storages.end(),
59  [&path](const UserSettings& obj)
60  {return obj.identifier.compare(path) == 0;});
61  if (storages.end() == res) {
62  storages.emplace_front(UserSettings(path));
63  res = storages.begin();
64  }
65  mtx.unlock();
66  }
67  // now we have to have it
68  return *res;
69  }
70 
74  bool store();
75 
79  bool reload();
80 
90  template<typename T, typename U>
91  bool insert(const T &obj, const std::string &key, const U &value) {
92  auto fullKey = getFullName(obj, key);
93  auto result = data.find(fullKey);
94  std::stringstream ss;
95  ss << value;
96  std::string valStr = ss.str();
97  bool newRec = result == data.end();
98  bool update = !newRec && (valStr.compare(result->second) != 0);
99 
100  if (newRec || update) {
101  data[fullKey] = valStr;
102  wasChanged = true;
103  return true;
104  }
105  return false;
106  }
107 
115  template<typename T, typename U>
116  bool find(const T &obj, const std::string &key, U &value) {
117  auto result = data.find(getFullName(obj, key));
118  if (result != data.end()) {
119  std::stringstream ss (result->second);
120  ss >> value;
121  return true;
122  } else {
123  return false;
124  }
125  }
126 
127  UserSettings(UserSettings&&) = default; // Move construct
128 
130  ~UserSettings() { if (wasChanged) store(); };
131 
132 protected:
134  UserSettings(const std::string &path = std::string()) : wasChanged(false),
135  identifier(path), path(path) {
136  if (path.empty()) {
137  this->path = std::string(getenv("HOME")) + "/.xmipp.settings";
138  }
139  reload();
140  };
141 
147  template<typename T>
148  const std::string getFullName(const T &obj, const std::string &key) {
149  std::stringstream ss;
150  ss << typeid(obj).name() << key;
151  return ss.str();
152  }
153 
154 private:
155  // delete copy and move constructors and assign operators
156  UserSettings(UserSettings const&) = delete; // Copy construct
157  UserSettings& operator=(UserSettings const&) = delete; // Copy assign
158  UserSettings& operator=(UserSettings &&) = delete; // Move assign
159 
161  std::map<std::string, std::string> data;
162 
164  bool wasChanged;
165 
167  char delim = '\t';
168 
170  std::string path;
171 
173  std::string identifier;
174 
175  static std::list<UserSettings> storages;
176 };
177 
178 #endif /* USERSETTINGS_H_ */
Mutex mutex
const std::string getFullName(const T &obj, const std::string &key)
Definition: userSettings.h:148
bool insert(const T &obj, const std::string &key, const U &value)
Definition: userSettings.h:91
UserSettings(UserSettings &&)=default
UserSettings(const std::string &path=std::string())
Definition: userSettings.h:134
bool find(const T &obj, const std::string &key, U &value)
Definition: userSettings.h:116
void(* obj)()
virtual void lock()