mirror of https://github.com/PCSX2/pcsx2.git
Common: Add MemorySettingsInterface
This commit is contained in:
parent
3289cd1e2b
commit
e7c4894833
|
@ -21,6 +21,7 @@ target_sources(common PRIVATE
|
|||
FileSystem.cpp
|
||||
Image.cpp
|
||||
HTTPDownloader.cpp
|
||||
MemorySettingsInterface.cpp
|
||||
Misc.cpp
|
||||
MD5Digest.cpp
|
||||
PrecompiledHeader.cpp
|
||||
|
@ -72,10 +73,12 @@ target_sources(common PRIVATE
|
|||
FileSystem.h
|
||||
General.h
|
||||
HashCombine.h
|
||||
HeterogeneousContainers.h
|
||||
Image.h
|
||||
LRUCache.h
|
||||
HTTPDownloader.h
|
||||
MemcpyFast.h
|
||||
MemorySettingsInterface.h
|
||||
MemsetFast.inl
|
||||
MD5Digest.h
|
||||
MRCHelpers.h
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides a map template which doesn't require heap allocations for lookups.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace detail
|
||||
{
|
||||
struct transparent_string_hash
|
||||
{
|
||||
using is_transparent = void;
|
||||
|
||||
std::size_t operator()(const std::string_view& v) const { return std::hash<std::string_view>{}(v); }
|
||||
std::size_t operator()(const std::string& s) const { return std::hash<std::string>{}(s); }
|
||||
std::size_t operator()(const char* s) const { return operator()(std::string_view(s)); }
|
||||
};
|
||||
|
||||
struct transparent_string_equal
|
||||
{
|
||||
using is_transparent = void;
|
||||
|
||||
bool operator()(const std::string& lhs, const std::string_view& rhs) const { return lhs == rhs; }
|
||||
bool operator()(const std::string& lhs, const std::string& rhs) const { return lhs == rhs; }
|
||||
bool operator()(const std::string& lhs, const char* rhs) const { return lhs == rhs; }
|
||||
bool operator()(const std::string_view& lhs, const std::string& rhs) const { return lhs == rhs; }
|
||||
bool operator()(const char* lhs, const std::string& rhs) const { return lhs == rhs; }
|
||||
};
|
||||
|
||||
struct transparent_string_less
|
||||
{
|
||||
using is_transparent = void;
|
||||
|
||||
bool operator()(const std::string& lhs, const std::string_view& rhs) const { return lhs < rhs; }
|
||||
bool operator()(const std::string& lhs, const std::string& rhs) const { return lhs < rhs; }
|
||||
bool operator()(const std::string& lhs, const char* rhs) const { return lhs < rhs; }
|
||||
bool operator()(const std::string_view& lhs, const std::string& rhs) const { return lhs < rhs; }
|
||||
bool operator()(const char* lhs, const std::string& rhs) const { return lhs < rhs; }
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
template <typename ValueType>
|
||||
using UnorderedStringMap =
|
||||
std::unordered_map<std::string, ValueType, detail::transparent_string_hash, detail::transparent_string_equal>;
|
||||
template <typename ValueType>
|
||||
using UnorderedStringMultimap =
|
||||
std::unordered_multimap<std::string, ValueType, detail::transparent_string_hash, detail::transparent_string_equal>;
|
||||
using UnorderedStringSet =
|
||||
std::unordered_set<std::string, detail::transparent_string_hash, detail::transparent_string_equal>;
|
||||
using UnorderedStringMultiSet =
|
||||
std::unordered_multiset<std::string, detail::transparent_string_hash, detail::transparent_string_equal>;
|
||||
|
||||
template <typename ValueType>
|
||||
using StringMap = std::map<std::string, ValueType, detail::transparent_string_less>;
|
||||
template <typename ValueType>
|
||||
using StringMultiMap = std::multimap<std::string, ValueType, detail::transparent_string_less>;
|
||||
using StringSet = std::set<std::string, detail::transparent_string_less>;
|
||||
using StringMultiSet = std::multiset<std::string, detail::transparent_string_less>;
|
|
@ -0,0 +1,290 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "common/MemorySettingsInterface.h"
|
||||
#include "common/StringUtil.h"
|
||||
|
||||
MemorySettingsInterface::MemorySettingsInterface() = default;
|
||||
|
||||
MemorySettingsInterface::~MemorySettingsInterface() = default;
|
||||
|
||||
bool MemorySettingsInterface::Save()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void MemorySettingsInterface::Clear()
|
||||
{
|
||||
m_sections.clear();
|
||||
}
|
||||
|
||||
bool MemorySettingsInterface::GetIntValue(const char* section, const char* key, s32* value) const
|
||||
{
|
||||
const auto sit = m_sections.find(section);
|
||||
if (sit == m_sections.end())
|
||||
return false;
|
||||
|
||||
const auto iter = sit->second.find(key);
|
||||
if (iter == sit->second.end())
|
||||
return false;
|
||||
|
||||
std::optional<s32> parsed = StringUtil::FromChars<s32>(iter->second, 10);
|
||||
if (!parsed.has_value())
|
||||
return false;
|
||||
|
||||
*value = parsed.value();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MemorySettingsInterface::GetUIntValue(const char* section, const char* key, u32* value) const
|
||||
{
|
||||
const auto sit = m_sections.find(section);
|
||||
if (sit == m_sections.end())
|
||||
return false;
|
||||
|
||||
const auto iter = sit->second.find(key);
|
||||
if (iter == sit->second.end())
|
||||
return false;
|
||||
|
||||
std::optional<u32> parsed = StringUtil::FromChars<u32>(iter->second, 10);
|
||||
if (!parsed.has_value())
|
||||
return false;
|
||||
|
||||
*value = parsed.value();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MemorySettingsInterface::GetFloatValue(const char* section, const char* key, float* value) const
|
||||
{
|
||||
const auto sit = m_sections.find(section);
|
||||
if (sit == m_sections.end())
|
||||
return false;
|
||||
|
||||
const auto iter = sit->second.find(key);
|
||||
if (iter == sit->second.end())
|
||||
return false;
|
||||
|
||||
std::optional<float> parsed = StringUtil::FromChars<float>(iter->second);
|
||||
if (!parsed.has_value())
|
||||
return false;
|
||||
|
||||
*value = parsed.value();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MemorySettingsInterface::GetDoubleValue(const char* section, const char* key, double* value) const
|
||||
{
|
||||
const auto sit = m_sections.find(section);
|
||||
if (sit == m_sections.end())
|
||||
return false;
|
||||
|
||||
const auto iter = sit->second.find(key);
|
||||
if (iter == sit->second.end())
|
||||
return false;
|
||||
|
||||
std::optional<double> parsed = StringUtil::FromChars<double>(iter->second);
|
||||
if (!parsed.has_value())
|
||||
return false;
|
||||
|
||||
*value = parsed.value();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MemorySettingsInterface::GetBoolValue(const char* section, const char* key, bool* value) const
|
||||
{
|
||||
const auto sit = m_sections.find(section);
|
||||
if (sit == m_sections.end())
|
||||
return false;
|
||||
|
||||
const auto iter = sit->second.find(key);
|
||||
if (iter == sit->second.end())
|
||||
return false;
|
||||
|
||||
std::optional<bool> parsed = StringUtil::FromChars<bool>(iter->second);
|
||||
if (!parsed.has_value())
|
||||
return false;
|
||||
|
||||
*value = parsed.value();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MemorySettingsInterface::GetStringValue(const char* section, const char* key, std::string* value) const
|
||||
{
|
||||
const auto sit = m_sections.find(section);
|
||||
if (sit == m_sections.end())
|
||||
return false;
|
||||
|
||||
const auto iter = sit->second.find(key);
|
||||
if (iter == sit->second.end())
|
||||
return false;
|
||||
|
||||
*value = iter->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
void MemorySettingsInterface::SetIntValue(const char* section, const char* key, s32 value)
|
||||
{
|
||||
SetValue(section, key, std::to_string(value));
|
||||
}
|
||||
|
||||
void MemorySettingsInterface::SetUIntValue(const char* section, const char* key, u32 value)
|
||||
{
|
||||
SetValue(section, key, std::to_string(value));
|
||||
}
|
||||
|
||||
void MemorySettingsInterface::SetFloatValue(const char* section, const char* key, float value)
|
||||
{
|
||||
SetValue(section, key, std::to_string(value));
|
||||
}
|
||||
|
||||
void MemorySettingsInterface::SetDoubleValue(const char* section, const char* key, double value)
|
||||
{
|
||||
SetValue(section, key, std::to_string(value));
|
||||
}
|
||||
|
||||
void MemorySettingsInterface::SetBoolValue(const char* section, const char* key, bool value)
|
||||
{
|
||||
SetValue(section, key, std::to_string(value));
|
||||
}
|
||||
|
||||
void MemorySettingsInterface::SetStringValue(const char* section, const char* key, const char* value)
|
||||
{
|
||||
SetValue(section, key, value);
|
||||
}
|
||||
|
||||
void MemorySettingsInterface::SetValue(const char* section, const char* key, std::string value)
|
||||
{
|
||||
auto sit = m_sections.find(section);
|
||||
if (sit == m_sections.end())
|
||||
sit = m_sections.emplace(std::make_pair(std::string(section), KeyMap())).first;
|
||||
|
||||
const auto range = sit->second.equal_range(key);
|
||||
if (range.first == sit->second.end())
|
||||
{
|
||||
sit->second.emplace(std::string(key), std::move(value));
|
||||
return;
|
||||
}
|
||||
|
||||
auto iter = range.first;
|
||||
iter->second = std::move(value);
|
||||
++iter;
|
||||
|
||||
// remove other values
|
||||
while (iter != range.second)
|
||||
{
|
||||
auto remove = iter++;
|
||||
sit->second.erase(remove);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> MemorySettingsInterface::GetStringList(const char* section, const char* key) const
|
||||
{
|
||||
std::vector<std::string> ret;
|
||||
|
||||
const auto sit = m_sections.find(section);
|
||||
if (sit != m_sections.end())
|
||||
{
|
||||
const auto range = sit->second.equal_range(key);
|
||||
for (auto iter = range.first; iter != range.second; ++iter)
|
||||
ret.emplace_back(iter->second);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void MemorySettingsInterface::SetStringList(const char* section, const char* key, const std::vector<std::string>& items)
|
||||
{
|
||||
auto sit = m_sections.find(section);
|
||||
if (sit == m_sections.end())
|
||||
sit = m_sections.emplace(std::make_pair(std::string(section), KeyMap())).first;
|
||||
|
||||
const auto range = sit->second.equal_range(key);
|
||||
for (auto iter = range.first; iter != range.second;)
|
||||
sit->second.erase(iter++);
|
||||
|
||||
std::string_view keysv(key);
|
||||
for (const std::string& value : items)
|
||||
sit->second.emplace(keysv, value);
|
||||
}
|
||||
|
||||
bool MemorySettingsInterface::RemoveFromStringList(const char* section, const char* key, const char* item)
|
||||
{
|
||||
auto sit = m_sections.find(section);
|
||||
if (sit == m_sections.end())
|
||||
sit = m_sections.emplace(std::make_pair(std::string(section), KeyMap())).first;
|
||||
|
||||
const auto range = sit->second.equal_range(key);
|
||||
bool result = false;
|
||||
for (auto iter = range.first; iter != range.second;)
|
||||
{
|
||||
if (iter->second == item)
|
||||
{
|
||||
sit->second.erase(iter++);
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool MemorySettingsInterface::AddToStringList(const char* section, const char* key, const char* item)
|
||||
{
|
||||
auto sit = m_sections.find(section);
|
||||
if (sit == m_sections.end())
|
||||
sit = m_sections.emplace(std::make_pair(std::string(section), KeyMap())).first;
|
||||
|
||||
const auto range = sit->second.equal_range(key);
|
||||
for (auto iter = range.first; iter != range.second; ++iter)
|
||||
{
|
||||
if (iter->second == item)
|
||||
return false;
|
||||
}
|
||||
|
||||
sit->second.emplace(std::string(key), std::string(item));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MemorySettingsInterface::ContainsValue(const char* section, const char* key) const
|
||||
{
|
||||
const auto sit = m_sections.find(section);
|
||||
if (sit == m_sections.end())
|
||||
return false;
|
||||
|
||||
return (sit->second.find(key) != sit->second.end());
|
||||
}
|
||||
|
||||
void MemorySettingsInterface::DeleteValue(const char* section, const char* key)
|
||||
{
|
||||
auto sit = m_sections.find(section);
|
||||
if (sit == m_sections.end())
|
||||
return;
|
||||
|
||||
const auto range = sit->second.equal_range(key);
|
||||
for (auto iter = range.first; iter != range.second;)
|
||||
sit->second.erase(iter++);
|
||||
}
|
||||
|
||||
void MemorySettingsInterface::ClearSection(const char* section)
|
||||
{
|
||||
auto sit = m_sections.find(section);
|
||||
if (sit == m_sections.end())
|
||||
return;
|
||||
|
||||
m_sections.erase(sit);
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/* PCSX2 - PS2 Emulator for PCs
|
||||
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
||||
*
|
||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "HeterogeneousContainers.h"
|
||||
#include "SettingsInterface.h"
|
||||
#include <string>
|
||||
|
||||
class MemorySettingsInterface final : public SettingsInterface
|
||||
{
|
||||
public:
|
||||
MemorySettingsInterface();
|
||||
~MemorySettingsInterface();
|
||||
|
||||
bool Save() override;
|
||||
|
||||
void Clear() override;
|
||||
|
||||
bool GetIntValue(const char* section, const char* key, s32* value) const override;
|
||||
bool GetUIntValue(const char* section, const char* key, u32* value) const override;
|
||||
bool GetFloatValue(const char* section, const char* key, float* value) const override;
|
||||
bool GetDoubleValue(const char* section, const char* key, double* value) const override;
|
||||
bool GetBoolValue(const char* section, const char* key, bool* value) const override;
|
||||
bool GetStringValue(const char* section, const char* key, std::string* value) const override;
|
||||
|
||||
void SetIntValue(const char* section, const char* key, s32 value) override;
|
||||
void SetUIntValue(const char* section, const char* key, u32 value) override;
|
||||
void SetFloatValue(const char* section, const char* key, float value) override;
|
||||
void SetDoubleValue(const char* section, const char* key, double value) override;
|
||||
void SetBoolValue(const char* section, const char* key, bool value) override;
|
||||
void SetStringValue(const char* section, const char* key, const char* value) override;
|
||||
bool ContainsValue(const char* section, const char* key) const override;
|
||||
void DeleteValue(const char* section, const char* key) override;
|
||||
void ClearSection(const char* section) override;
|
||||
|
||||
std::vector<std::string> GetStringList(const char* section, const char* key) const override;
|
||||
void SetStringList(const char* section, const char* key, const std::vector<std::string>& items) override;
|
||||
bool RemoveFromStringList(const char* section, const char* key, const char* item) override;
|
||||
bool AddToStringList(const char* section, const char* key, const char* item) override;
|
||||
|
||||
// default parameter overloads
|
||||
using SettingsInterface::GetBoolValue;
|
||||
using SettingsInterface::GetDoubleValue;
|
||||
using SettingsInterface::GetFloatValue;
|
||||
using SettingsInterface::GetIntValue;
|
||||
using SettingsInterface::GetStringValue;
|
||||
using SettingsInterface::GetUIntValue;
|
||||
|
||||
private:
|
||||
using KeyMap = UnorderedStringMultimap<std::string>;
|
||||
using SectionMap = UnorderedStringMap<KeyMap>;
|
||||
|
||||
void SetValue(const char* section, const char* key, std::string value);
|
||||
|
||||
SectionMap m_sections;
|
||||
};
|
|
@ -79,6 +79,7 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="HTTPDownloaderWinHTTP.cpp" />
|
||||
<ClCompile Include="MD5Digest.cpp" />
|
||||
<ClCompile Include="MemorySettingsInterface.cpp" />
|
||||
<ClCompile Include="ProgressCallback.cpp" />
|
||||
<ClCompile Include="StackWalker.cpp" />
|
||||
<ClCompile Include="StringUtil.cpp" />
|
||||
|
@ -151,6 +152,7 @@
|
|||
<ClInclude Include="GL\StreamBuffer.h" />
|
||||
<ClInclude Include="FileSystem.h" />
|
||||
<ClInclude Include="HashCombine.h" />
|
||||
<ClInclude Include="HeterogeneousContainers.h" />
|
||||
<ClInclude Include="Image.h" />
|
||||
<ClInclude Include="LRUCache.h" />
|
||||
<ClInclude Include="HTTPDownloader.h" />
|
||||
|
@ -159,6 +161,7 @@
|
|||
</ClInclude>
|
||||
<ClInclude Include="HTTPDownloaderWinHTTP.h" />
|
||||
<ClInclude Include="MD5Digest.h" />
|
||||
<ClInclude Include="MemorySettingsInterface.h" />
|
||||
<ClInclude Include="ProgressCallback.h" />
|
||||
<ClInclude Include="ScopedGuard.h" />
|
||||
<ClInclude Include="StackWalker.h" />
|
||||
|
|
|
@ -199,6 +199,9 @@
|
|||
<ClCompile Include="HTTPDownloaderWinHTTP.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="MemorySettingsInterface.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="AlignedMalloc.h">
|
||||
|
@ -468,6 +471,12 @@
|
|||
<ClInclude Include="ThreadPool.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="HeterogeneousContainers.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="MemorySettingsInterface.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
|
|
Loading…
Reference in New Issue