Config: Flatten structures

Originally, Layer contained a std::map of Sections, which containted a std::map
containing the (key, value) pairs. Here we flattern this structure so that only
one std::map is required, reducing the number of indirections required and
vastly simplifying the code.
This commit is contained in:
MerryMage
2017-10-29 19:11:15 +00:00
parent f3b52c07d7
commit 4c24629b95
13 changed files with 220 additions and 551 deletions

View File

@ -8,10 +8,47 @@
#include "Common/Config/Config.h"
#include "Common/Config/Layer.h"
#include "Common/Config/Section.h"
namespace Config
{
namespace detail
{
std::string ValueToString(u16 value)
{
return StringFromFormat("0x%04x", value);
}
std::string ValueToString(u32 value)
{
return StringFromFormat("0x%08x", value);
}
std::string ValueToString(float value)
{
return StringFromFormat("%#.9g", value);
}
std::string ValueToString(double value)
{
return StringFromFormat("%#.17g", value);
}
std::string ValueToString(int value)
{
return std::to_string(value);
}
std::string ValueToString(bool value)
{
return StringFromBool(value);
}
std::string ValueToString(const std::string& value)
{
return value;
}
}
ConfigLayerLoader::ConfigLayerLoader(LayerType layer) : m_layer(layer)
{
}
@ -38,56 +75,44 @@ Layer::~Layer()
Save();
}
bool Layer::Exists(System system, const std::string& section_name, const std::string& key)
bool Layer::Exists(const ConfigLocation& location) const
{
Section* section = GetSection(system, section_name);
if (!section)
return false;
return section->Exists(key);
const auto iter = m_map.find(location);
return iter != m_map.end() && iter->second.has_value();
}
bool Layer::DeleteKey(System system, const std::string& section_name, const std::string& key)
bool Layer::DeleteKey(const ConfigLocation& location)
{
Section* section = GetSection(system, section_name);
if (!section)
return false;
return section->Delete(key);
m_is_dirty = true;
bool had_value = m_map[location].has_value();
m_map[location].reset();
return had_value;
}
Section* Layer::GetSection(System system, const std::string& section_name)
void Layer::DeleteAllKeys()
{
for (auto& section : m_sections[system])
if (!strcasecmp(section->m_name.c_str(), section_name.c_str()))
return section.get();
return nullptr;
}
Section* Layer::GetOrCreateSection(System system, const std::string& section_name)
{
Section* section = GetSection(system, section_name);
if (!section)
m_is_dirty = true;
for (auto& pair : m_map)
{
m_sections[system].emplace_back(std::make_unique<Section>(m_layer, system, section_name));
section = m_sections[system].back().get();
pair.second.reset();
}
return section;
}
void Layer::Load()
{
if (m_loader)
m_loader->Load(this);
ClearDirty();
m_is_dirty = false;
InvokeConfigChangedCallbacks();
}
void Layer::Save()
{
if (!m_loader || !IsDirty())
if (!m_loader || !m_is_dirty)
return;
m_loader->Save(this);
ClearDirty();
m_is_dirty = false;
InvokeConfigChangedCallbacks();
}
@ -98,22 +123,6 @@ LayerType Layer::GetLayer() const
const LayerMap& Layer::GetLayerMap() const
{
return m_sections;
}
bool Layer::IsDirty() const
{
return std::any_of(m_sections.begin(), m_sections.end(), [](const auto& system) {
return std::any_of(system.second.begin(), system.second.end(),
[](const auto& section) { return section->IsDirty(); });
});
}
void Layer::ClearDirty()
{
std::for_each(m_sections.begin(), m_sections.end(), [](auto& system) {
std::for_each(system.second.begin(), system.second.end(),
[](auto& section) { section->ClearDirty(); });
});
return m_map;
}
}