blob: c8bbcae594b95f1b9a8b5bec55fff7e4d7965878 [file] [log] [blame]
// 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