| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #pragma once |
| |
| #include <map> |
| #include <memory> |
| |
| #include "garnet/bin/zxdb/common/err.h" |
| #include "garnet/bin/zxdb/client/setting_schema.h" |
| #include "garnet/bin/zxdb/client/setting_store_observer.h" |
| #include "garnet/bin/zxdb/client/setting_value.h" |
| #include "lib/fxl/memory/ref_ptr.h" |
| #include "lib/fxl/observer_list.h" |
| |
| namespace zxdb { |
| |
| struct StoredSetting; |
| |
| // SettingStore is in charge of maintaining a structured group of settings. |
| // settings are indexed by a unique key. |
| class SettingStore { |
| public: |
| SettingStore(fxl::RefPtr<SettingSchema> schema, |
| SettingStore* fallback); |
| |
| SettingStore* fallback() const { return fallback_; } |
| void set_fallback(SettingStore* fallback) { fallback_ = fallback; } |
| |
| fxl::RefPtr<SettingSchema> schema() const { return schema_; } |
| |
| void AddObserver(const std::string& setting_name, SettingStoreObserver*); |
| void RemoveObserver(const std::string& setting_name, SettingStoreObserver*); |
| |
| // What level is this store associated with. |
| SettingSchema::Level level() const { return schema_->level(); } |
| |
| Err SetBool(const std::string& key, bool); |
| Err SetInt(const std::string& key, int); |
| Err SetString(const std::string& key, std::string); |
| Err SetList(const std::string& key, std::vector<std::string> list); |
| |
| bool GetBool(const std::string& key) const; |
| int GetInt(const std::string& key) const; |
| std::string GetString(const std::string& key) const; |
| std::vector<std::string> GetList(const std::string& key) const; |
| |
| // Normally we know zxdb defined setting types, so we can confidently used the |
| // type getters. But frontend code might want to check for dynamically defined |
| // settings and check their type. |
| // |
| // |return_default| specifies whether the call should return the schema's |
| // default value. This is needed because this SettingStore will call a |
| // fallback for its value "recursively", so we need to tell _that_ store not |
| // to return its default value because it belongs to another schema. |
| // |
| // Returns a null setting if the key is not found. |
| StoredSetting GetSetting(const std::string& key, |
| bool return_default = true) const; |
| std::map<std::string, StoredSetting> GetSettings() const; |
| |
| bool HasSetting(const std::string& key) const; |
| |
| protected: |
| std::map<std::string, fxl::ObserverList<SettingStoreObserver>>& observers() { |
| return observer_map_; |
| } |
| |
| private: |
| // Actual function that traverses the path and creates the intermediate |
| // nodes. |add_value_fn| is called to add the correct value to the newly |
| // created node. These functions will be provided by the public interface |
| // which is the one the user cals (eg. AddBool, AddString, etc.). |
| |
| // Adding a setting if the same, only that the value differs. This will call |
| // the correct overload for the setting value and store it is valid. |
| template <typename T> |
| Err SetSetting(const std::string& key, T t); |
| |
| void NotifySettingChanged(const std::string& setting_name) const; |
| |
| // Should always exist. All settings are validated against this. |
| fxl::RefPtr<SettingSchema> schema_; |
| |
| // SettingStore this store lookup settings when it cannot find them locally. |
| // Can be null. If set, should outlive |this|. |
| SettingStore* fallback_; |
| std::map<std::string, SettingValue> settings_; |
| |
| std::map<std::string, fxl::ObserverList<SettingStoreObserver>> observer_map_; |
| |
| FXL_DISALLOW_COPY_AND_ASSIGN(SettingStore); |
| }; |
| |
| // Represents a value of a setting with some metadata associated to it so |
| // the frontend can show it. |
| struct StoredSetting { |
| SettingValue value; |
| SettingSchemaItem schema_item; |
| // From what context level the value actually came from. |
| SettingSchema::Level level = SettingSchema::Level::kDefault; |
| }; |
| |
| } // namespace zxdb |