Ion
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
settingmanager.cc
Go to the documentation of this file.
1 
19 
20 #include <set>
21 #include <vector>
22 
23 #include "ion/base/allocator.h"
24 #include "ion/base/lockguards.h"
25 #include "ion/base/logging.h"
26 #include "ion/base/shareable.h"
28 #include "ion/base/stringutils.h"
29 #include "ion/port/mutex.h"
30 
31 namespace ion {
32 namespace base {
33 
34 namespace {
35 
36 static const char kListenerKey[] = "SettingManager";
37 
38 } // anonymous namespace
39 
40 class SettingManager::SettingData : public Shareable {
41  public:
44  void SettingListener(SettingBase* setting);
45 
47  SettingBase* GetSetting(const std::string& name);
48  void RegisterSetting(SettingBase* setting);
49  void UnregisterSetting(SettingBase* setting);
50  void RegisterGroupListener(const std::string& group,
51  const std::string& key,
52  const SettingBase::Listener& listener);
53  void EnableGroupListener(const std::string& group, const std::string& key,
54  bool enable);
55  void UnregisterGroupListener(const std::string& group,
56  const std::string& key);
57 
58  const SettingMap& GetAllSettings() { return settings_; }
59 
63  void UnregisterSettingLocked(SettingBase* setting);
64 
65  private:
67  typedef std::map<std::string, std::vector<std::string> > GroupMap;
68 
71  struct SettingGroupInfo {
72  typedef std::map<std::string, SettingBase::ListenerInfo> ListenerMap;
73  std::set<SettingBase*> settings;
74  ListenerMap listeners;
75  };
77  typedef std::map<std::string, SettingGroupInfo> SettingGroupMap;
78 
79  typedef base::SharedPtr<SettingData> SettingDataPtr;
80 
82  ~SettingData() override {}
83 
84  port::Mutex mutex_;
85  SettingMap settings_;
86  GroupMap setting_groups_;
87  SettingGroupMap groups_;
88 };
89 
91 
96 
97 
98 void SettingManager::SettingData::SettingListener(SettingBase* setting) {
99  SettingMap::iterator it = settings_.find(setting->GetName());
100  DCHECK(it != settings_.end());
102  const std::vector<std::string>& group_names =
103  setting_groups_[setting->GetName()];
104  const size_t count = group_names.size();
105  for (size_t i = 0; i < count; ++i) {
106  const SettingGroupInfo& group_info = groups_[group_names[i]];
107  for (SettingGroupInfo::ListenerMap::const_iterator it =
108  group_info.listeners.begin(); it != group_info.listeners.end();
109  ++it)
110  if (it->second.enabled)
111  it->second.listener(setting);
112  }
113 }
114 
115 SettingBase* SettingManager::SettingData::GetSetting(const std::string& name) {
116  SettingMap::const_iterator it = settings_.find(name);
117  return it == settings_.end() ? NULL : it->second;
118 }
119 
120 void SettingManager::SettingData::RegisterSetting(SettingBase* setting) {
121  DCHECK(setting);
122  const std::string& name = setting->GetName();
123 
125  {
126  LockGuard lock(&mutex_);
127 
128  SettingMap::const_iterator it = settings_.find(name);
129  if (it != settings_.end()) {
130  LOG(WARNING) << "Duplicate setting named '" << name
131  << "' registered in SettingManager";
133  UnregisterSettingLocked(setting);
134  }
135  std::vector<std::string> group_names = SplitString(name, "/");
138  if (group_names.size() > 1)
139  group_names.pop_back();
140 
142  const size_t count = group_names.size();
143  for (size_t i = 0; i < count; ++i) {
144  if (i)
145  group_names[i] = group_names[i - 1U] + "/" + group_names[i];
146  groups_[group_names[i]].settings.insert(setting);
147  }
148 
150  settings_[name] = setting;
151  setting_groups_[name] = group_names;
152 
155  setting->RegisterListener(
156  kListenerKey,
157  std::bind(&SettingData::SettingListener, this, std::placeholders::_1));
158 
160  setting->data_ref_ = this;
161  } // unlock mutex
162 }
163 
164 void SettingManager::SettingData::UnregisterSetting(SettingBase* setting) {
165  DCHECK(setting);
166 
167  LockGuard lock(&mutex_);
168  UnregisterSettingLocked(setting);
169 }
170 
171 void SettingManager::SettingData::UnregisterSettingLocked(
172  SettingBase* setting) {
173  DCHECK(mutex_.IsLocked());
174  SettingMap::iterator it = settings_.find(setting->GetName());
175  if (it != settings_.end() && it->second == setting) {
176  const std::vector<std::string>& group_names =
177  setting_groups_[setting->GetName()];
178 
180  const size_t count = group_names.size();
181  for (size_t i = 0; i < count; ++i)
182  groups_[group_names[i]].settings.erase(it->second);
183 
184  settings_.erase(it);
185  }
186  setting->UnregisterListener(kListenerKey);
187 }
188 
189 void SettingManager::SettingData::RegisterGroupListener(
190  const std::string& group,
191  const std::string& key,
192  const SettingBase::Listener& listener) {
193  SettingGroupMap::iterator it = groups_.find(group);
194  if (it != groups_.end())
195  it->second.listeners[key] = SettingBase::ListenerInfo(listener, true);
196 }
197 
198 void SettingManager::SettingData::EnableGroupListener(const std::string& group,
199  const std::string& key,
200  bool enable) {
201  SettingGroupMap::iterator it = groups_.find(group);
202  if (it != groups_.end())
203  it->second.listeners[key].enabled = enable;
204 }
205 
206 void SettingManager::SettingData::UnregisterGroupListener(
207  const std::string& group,
208  const std::string& key) {
209  SettingGroupMap::iterator it = groups_.find(group);
210  if (it != groups_.end())
211  it->second.listeners.erase(key);
212 }
213 
215 
220 
221 
222 SettingManager::SettingManager() : data_(new SettingData) {
223 }
224 
225 SettingManager::~SettingManager() {
226 }
227 
228 SettingBase* SettingManager::GetSetting(const std::string& name) {
229  return GetInstance()->data_->GetSetting(name);
230 }
231 
232 const SettingManager::SettingMap& SettingManager::GetAllSettings() {
233  return GetInstance()->data_->GetAllSettings();
234 }
235 
236 void SettingManager::RegisterSetting(SettingBase* setting) {
237  GetInstance()->data_->RegisterSetting(setting);
238 }
239 
240 void SettingManager::UnregisterSetting(SettingBase* setting) {
244  SettingData* data = static_cast<SettingData*>(setting->data_ref_.Get());
245  data->UnregisterSetting(setting);
246 }
247 
248 void SettingManager::RegisterGroupListener(
249  const std::string& group,
250  const std::string& key,
251  const SettingBase::Listener& listener) {
252  GetInstance()->data_->RegisterGroupListener(group, key, listener);
253 }
254 
255 void SettingManager::EnableGroupListener(const std::string& group,
256  const std::string& key,
257  bool enable) {
258  GetInstance()->data_->EnableGroupListener(group, key, enable);
259 }
260 
261 void SettingManager::UnregisterGroupListener(const std::string& group,
262  const std::string& key) {
263  GetInstance()->data_->UnregisterGroupListener(group, key);
264 }
265 
266 SettingManager* SettingManager::GetInstance() {
268  return manager;
269 }
270 
271 } // namespace base
272 } // namespace ion
#define ION_DECLARE_SAFE_STATIC_POINTER(type, variable)
Declare a static non-array pointer and calls a default constructor.
static void RegisterGroupListener(const std::string &group, const std::string &key, const SettingBase::Listener &listener)
Adds a function that will be called when any setting in the passed group changes. ...
Base class for Setting, which encapsulates the name of the setting and any functors that should be ca...
Definition: setting.h:43
#define DCHECK(expr)
Definition: logging.h:331
GenericLockGuard< port::Mutex > LockGuard
Convenient typedefs for ion::port::Mutex.
Definition: lockguards.h:192
#define LOG(severity)
Logs the streamed message unconditionally with a severity of severity.
Definition: logging.h:216
std::vector< std::string > ION_API SplitString(const std::string &str, const std::string &delimiters)
Splits a string into a vector of substrings, given a set of delimiter characters (expressed as a stri...
Definition: stringutils.cc:187
static void RegisterSetting(SettingBase *setting)
Adds the setting to the manager and its groups.
static SettingBase * GetSetting(const std::string &name)
Returns the setting with the passed name.
std::map< std::string, SettingBase * > SettingMap
Maps a setting's name to setting itself and its groups.
static void EnableGroupListener(const std::string &group, const std::string &key, bool enable)
Enables or disables the group listener identified by key.
std::string name
Definition: printer.cc:324
std::function< void(SettingBase *setting)> Listener
A function that is called when the value changes.
Definition: setting.h:46
Copyright 2016 Google Inc.
static const SettingMap & GetAllSettings()
Returns all settings keyed by their names.
SettingManager tracks all existing SettingBase instances, and allows callers to obtain a map of all s...
static void UnregisterSetting(SettingBase *setting)
Removes the setting from the manager and its groups.
static void UnregisterGroupListener(const std::string &group, const std::string &key)
Removes the group listener identified by key.
port::Mutex mutex_
Protects shared access to the Allocator and FT_Library.