Files
dolphin/Source/Core/Common/Config/Layer.h
T

158 lines
3.5 KiB
C++
Raw Normal View History

2017-02-16 16:58:40 +01:00
// Copyright 2016 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#pragma once
#include <map>
#include <memory>
2017-10-29 19:11:15 +00:00
#include <optional>
2017-02-16 16:58:40 +01:00
#include <string>
2018-05-11 22:38:44 +02:00
#include <type_traits>
2017-02-16 16:58:40 +01:00
#include <vector>
2017-10-29 19:11:15 +00:00
#include "Common/Config/ConfigInfo.h"
2017-02-16 16:58:40 +01:00
#include "Common/Config/Enums.h"
2017-10-29 19:11:15 +00:00
#include "Common/StringUtil.h"
2017-02-16 16:58:40 +01:00
namespace Config
{
2017-10-29 19:11:15 +00:00
namespace detail
{
2018-05-11 22:38:44 +02:00
template <typename T, std::enable_if_t<!std::is_enum<T>::value>* = nullptr>
2017-10-29 19:11:15 +00:00
std::optional<T> TryParse(const std::string& str_value)
{
T value;
if (!::TryParse(str_value, &value))
return std::nullopt;
return value;
}
2018-05-11 22:38:44 +02:00
template <typename T, std::enable_if_t<std::is_enum<T>::value>* = nullptr>
std::optional<T> TryParse(const std::string& str_value)
{
const auto result = TryParse<std::underlying_type_t<T>>(str_value);
if (result)
return static_cast<T>(*result);
return {};
}
2017-10-29 19:11:15 +00:00
template <>
inline std::optional<std::string> TryParse(const std::string& str_value)
{
return str_value;
}
}
2017-08-03 01:20:52 +08:00
template <typename T>
struct ConfigInfo;
2017-10-29 19:11:15 +00:00
class Layer;
using LayerMap = std::map<ConfigLocation, std::optional<std::string>>;
2017-02-16 16:58:40 +01:00
class ConfigLayerLoader
{
public:
explicit ConfigLayerLoader(LayerType layer);
virtual ~ConfigLayerLoader();
virtual void Load(Layer* config_layer) = 0;
virtual void Save(Layer* config_layer) = 0;
LayerType GetLayer() const;
private:
const LayerType m_layer;
};
class Section
{
public:
using iterator = LayerMap::iterator;
Section(iterator begin_, iterator end_) : m_begin(begin_), m_end(end_) {}
iterator begin() const { return m_begin; }
iterator end() const { return m_end; }
2018-04-12 14:18:04 +02:00
private:
iterator m_begin;
iterator m_end;
};
class ConstSection
{
public:
using iterator = LayerMap::const_iterator;
ConstSection(iterator begin_, iterator end_) : m_begin(begin_), m_end(end_) {}
iterator begin() const { return m_begin; }
iterator end() const { return m_end; }
2018-04-12 14:18:04 +02:00
private:
iterator m_begin;
iterator m_end;
};
2017-02-16 16:58:40 +01:00
class Layer
{
public:
explicit Layer(LayerType layer);
explicit Layer(std::unique_ptr<ConfigLayerLoader> loader);
virtual ~Layer();
// Convenience functions
2017-10-29 19:11:15 +00:00
bool Exists(const ConfigLocation& location) const;
bool DeleteKey(const ConfigLocation& location);
void DeleteAllKeys();
2017-02-16 16:58:40 +01:00
2017-08-03 01:20:52 +08:00
template <typename T>
T Get(const ConfigInfo<T>& config_info)
{
2017-10-29 19:11:15 +00:00
return Get<T>(config_info.location).value_or(config_info.default_value);
}
template <typename T>
std::optional<T> Get(const ConfigLocation& location)
{
const std::optional<std::string>& str_value = m_map[location];
if (!str_value)
return std::nullopt;
return detail::TryParse<T>(*str_value);
2017-08-03 01:20:52 +08:00
}
template <typename T>
void Set(const ConfigInfo<T>& config_info, const std::common_type_t<T>& value)
2017-08-03 01:20:52 +08:00
{
Set(config_info.location, value);
2017-10-29 19:11:15 +00:00
}
template <typename T>
void Set(const ConfigLocation& location, const T& value)
{
Set(location, ValueToString(value));
}
void Set(const ConfigLocation& location, const std::string& new_value)
{
2017-10-29 19:11:15 +00:00
std::optional<std::string>& current_value = m_map[location];
if (current_value == new_value)
return;
m_is_dirty = true;
current_value = new_value;
2017-08-03 01:20:52 +08:00
}
Section GetSection(System system, const std::string& section);
ConstSection GetSection(System system, const std::string& section) const;
2017-02-16 16:58:40 +01:00
// Explicit load and save of layers
void Load();
void Save();
LayerType GetLayer() const;
const LayerMap& GetLayerMap() const;
protected:
2017-10-29 19:11:15 +00:00
bool m_is_dirty = false;
LayerMap m_map;
2017-02-16 16:58:40 +01:00
const LayerType m_layer;
std::unique_ptr<ConfigLayerLoader> m_loader;
};
2017-10-29 19:11:15 +00:00
}